Page 9 of 10 FirstFirst ... 78910 LastLast
Results 201 to 225 of 239

Thread: Direct-X Plugin (Beta)

  1. #201
    Join Date
    May 2012
    Posts
    499
    Mentioned
    23 Post(s)
    Quoted
    228 Post(s)

    Default

    Great! Take your time, I'm sure it'll be flawless soon enough. (Still hoping the same for ogl).
    Too bad I need perfect text recognition for my next script. And ogl just keeps becoming a lagfest.

    Do you think if I do write that script, but use OGL, it'll be somewhat similar in directx?
    Perhaps it'll still be better to just wait for your release instead of porting over an OGL script and having a sloppy script..

    *edit*

    I'm getting crashes rather often on my laptop. (SMART Client closes)
    Windows 10 Pro 64-bit
    Intel Core 2 Duo P7350 @ 2.00
    nVidia GT130M 1GB.

    Using 800x600 resolution, unsure what kind of crash report I can find.
    Simba doesn't report anything.

    It crashes ingame whenever it tries to load some new stuff, it kind of lags for me once I get logged in, then whenever I do something somewhat requiring CPU/GPU it crashes.

    Just tried my desktop, also crashes the SMART client. It does load them though, and displays the debug in lobby, but once I try to login into a game server it crashes.

    *edit*
    Doesn't crash once I stop the script, atleast on desktop.
    Rightclick options menu has some weird debug on it, like a ton of duplicate debugs stacked it seems.

  2. #202
    Join Date
    Jul 2009
    Posts
    166
    Mentioned
    5 Post(s)
    Quoted
    69 Post(s)

    Default

    Omg performance GAINZ 45-50 fps on my old computer and no performance degradation on teleport. I have amd fx-8320 cpu and r290=)
    Its sad that dont play(bot) rs anymore, I hate this p2w ****.
    java 2015-06-06 01-16-28-94.png
    Last edited by alar82; 06-05-2015 at 10:19 PM.

  3. #203
    Join Date
    Jan 2012
    Location
    East Coast
    Posts
    733
    Mentioned
    81 Post(s)
    Quoted
    364 Post(s)

    Default

    Hi @Brandon, any update on this?

  4. #204
    Join Date
    Mar 2015
    Posts
    10
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    interesting idea

  5. #205
    Join Date
    Apr 2013
    Posts
    11
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default Why did you delete me? :'(

    I don't have the post count to PM, but maybe I can get help with this idea here.

    I found that terrain always has a start index of 0 and the stride is 20 and I can read an array of all the vertices.
    I am trying to map the vertices to 2d points on the screen, but I don't seem to be able to get the proper transformation matrices.
    I hope to be able to map every 3D vertex to a 2D mesh and be able to click every individual tile for onscreen pathing.

    Here is what I am trying to do:
    Code:
    pDevice->GetVertexShaderConstantF(0, WVP_matrix, 4); //This is [D3DXPC_MATRIX_COLUMNS] AKA column major
    
    for (int i = 0; i < num; i++){
    	obj_matrix._11 = vertices[i].x;
    	obj_matrix._12 = vertices[i].y;
    	obj_matrix._13 = vertices[i].z;
    	obj_matrix._14 = 1;
    	D3DXMatrixMultiply(&obj_matrix, &obj_matrix, &WVP_matrix);
    
    	DrawCrosshair(viewPort.Width / 2.0 + obj_matrix._11, viewPort.Height / 2.0 + obj_matrix._12);
    }
    http://www.unknowncheats.me/forum/d3...ven-games.html
    I disassembled the shaders (reference link above)and was shocked to find that all three matrices needed for projection were already multiplied and waiting. (Been trying to find them separately for hours.)
    So now I have a mostly working translation of object vertices to screen coordinates.
    Here debug output of the terrain object. http://imgur.com/ZttWhpJ

    I just realised that because I am pulling these vertices from the vertex buffer in drawIndexedPrimitive, they are all relative to the origin of that model. So I need to grab the models themselves to get the world position and rotation data.
    There are 1388 vertices being draw in this image.
    gxr7HJO.png

    I will probably port this to OpenGL since development seems more active. I hate the DirectX monopoly anyway. :L
    Last edited by Forty Two; 06-26-2015 at 07:41 PM. Reason: I know exactly what I am doing now.

  6. #206
    Join Date
    Jun 2014
    Posts
    463
    Mentioned
    27 Post(s)
    Quoted
    229 Post(s)

    Default

    Seems to work fine for me.


    Tsunami

  7. #207
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Forty Two View Post
    I don't have the post count to PM, but maybe I can get help with this idea here.
    I will probably port this to OpenGL since development seems more active. I hate the DirectX monopoly anyway. :L

    I didn't delete you or anyone. I haven't been getting many tags or PM's recently and I've been extremely busy lately. Not sure if you really want to go the OpenGL route but if you do, you should be careful of fonts/text!

    For those wondering how far I got.. I got as far as sending all the data to Simba.. I just haven't been able to test and do optimizations and stuff lately. That's why I haven't released anything yet.


    Anyway, use the file below for projections and most of the math is done.. I created it because doing it myself is actually faster than using D3DX Math. I use "CalculateStride" to get the stride from the FVF rather than increasing the reference count to the VertexBuffer and Releasing it just to get a stride (extremely costly).

    The bounding box formula is for getting a box around a list of vertices (you can get the bounding box of models, textures, etc..) Below the math class, you'll see an example on how I project the vertices to the screen.


    I'll try to upload the rest to github as soon as I can.. For now:

    C++ Code:
    #ifndef MATH_HXX_INCLUDED
    #define MATH_HXX_INCLUDED

    #include <cmath>
    #include <cstdint>
    #include <algorithm>
    #include <d3dx9.h>

    class Mat4;

    struct Vec3
    {
    public:
        float x, y, z;

        Vec3() : x(0), y(0), z(0) {}
        Vec3(float x, float y, float z) : x(x), y(y), z(z) {}

        inline Vec3 Cross(const Vec3 &v) const;
        inline float Dot(const Vec3 &v) const;
        inline Vec3 Normalise() const;
        inline int Magnitude() const;
        inline Vec3 Scale(const float val) const;

        inline Vec3 operator + (const Vec3 &v) const;
        inline Vec3 operator - (const Vec3 &v) const;
        inline Vec3 operator * (const float val) const;
        inline Vec3 operator / (const float val) const;

        Vec3 Transform(Mat4* mat) const;
        Vec3 Transform(const Mat4 &mat) const;
        Vec3 Project(D3DVIEWPORT9* viewport, Mat4* world, Mat4* view, Mat4* projection) const;
        Vec3 Project(const D3DVIEWPORT9 &viewport, const Mat4 &world, const Mat4 &view, const Mat4 &projection) const;
    };

    class Mat4
    {
    private:
        float mat[4][4];

    public:
        Mat4() : mat{0} {}

        float* operator[](const int index) {return mat[index];}
        const float* operator[](const int index) const {return mat[index];}

        Mat4 operator * (const Mat4 &m) const;
        Mat4 operator + (const Mat4 &m) const;
        Mat4 operator - (const Mat4 &m) const;

        Mat4& Transpose();
        Mat4 Transpose() const;
        static Mat4 Identity();
        static Mat4 Orthagonal(float w, float h, float zNear, float zFar);
        static Mat4 Perspective(float w, float h, float zNear, float zFar);
        static Mat4 FieldOfView(float fov, float aspect, float zNear, float zFar);
        static Mat4 LookAt(const Vec3& Eye, const Vec3& At, const Vec3& Up);

        static Mat4 RotX(float rad);
        static Mat4 RotY(float rad);
        static Mat4 RotZ(float rad);
        static Mat4 Rot(float pitch, float yaw, float roll);

        static Mat4 Scale(float val);
        static Mat4 Scale(float x, float y, float z);
        static Mat4 Translate(float x, float y, float z);
    };

    namespace DXMath
    {
        unsigned int CalculateStride(unsigned int FVF);
        unsigned int CalculateBitsPerPixel(D3DFORMAT format);

        #ifdef D3DX_SUPPORT
        D3DXVECTOR3 WorldToScreen(D3DXMATRIX* WorldViewProjection, D3DVIEWPORT9* ViewPort, const D3DXVECTOR3 &in = {0, 0, 0});
        D3DXVECTOR3 WorldToScreen2(D3DVIEWPORT9* ViewPort, D3DXMATRIX* World, D3DXMATRIX* View, D3DXMATRIX* Projection, const D3DXVECTOR3 &in = {0, 0, 0});
        #else
        Vec3 WorldToScreen(Mat4* WorldViewProjection, D3DVIEWPORT9* ViewPort, const Vec3 &in = {0, 0, 0});
        Vec3 WorldToScreen2(D3DVIEWPORT9* ViewPort, Mat4* World, Mat4* View, Mat4* Projection, const Vec3 &in = {0, 0, 0});
        #endif
    }


    namespace GVMath
    {
        typedef struct {float X1, Y1, X2, Y2;} Box2D;
        typedef struct {float X1, Y1, Z1, X2, Y2, Z2;} Box3D;

        static const double PI = 3.1415926535897932384626433832795;
        Vec3 GetEulerAngles(float (&mat)[16], bool RowMajor);
        Vec3 GetEulerAngles(float (&mat)[4][4], bool RowMajor);

        float Distance(float (&a)[2], float (&b)[2]);
        float Distance(float (&a)[3], float (&b)[3]);
        Box2D BoundingBox(float* x, float* y, std::size_t size);
        Box3D BoundingBox(float* x, float* y, float* z);

        std::uint32_t ColourChecksum(const void* data, std::size_t width, std::size_t height);
        std::uint32_t FullColourChecksum(const void* data, std::size_t width, std::size_t height, std::size_t offset = 0);

        std::uint32_t Adler32(const std::uint8_t* data, std::size_t size);
        std::uint32_t CRC32(const void* Data, size_t Size, std::uint32_t InitialValue = 0xFFFFFFFF);
    }

    #endif // MATH_HXX_INCLUDED


    C++ Code:
    #include "Math.hxx"

    Vec3 Vec3::Cross(const Vec3 &v) const
    {
        return Vec3((y * v.z) - (z * v.y), (z * v.x) - (x * v.z), (x * v.y) - (y * v.x));
    }

    float Vec3::Dot(const Vec3 &v) const
    {
        return ((x * v.x) + (y * v.y) + (z * v.z));
    }

    Vec3 Vec3::Normalise() const
    {
        int size = Magnitude();
        return Vec3(x / size, y / size, z / size);
    }

    int Vec3::Magnitude() const
    {
        return sqrtf((x * x) + (y * y) + (z * z));
    }

    Vec3 Vec3::Scale(const float val) const
    {
        return Vec3(x * val, y * val, z * val);
    }

    Vec3 Vec3::operator + (const Vec3 &v) const
    {
        return Vec3(x + v.x, y + v.y, z + v.z);
    }

    Vec3 Vec3::operator - (const Vec3 &v) const
    {
        return Vec3(x - v.x, y - v.y, z - v.z);
    }

    Vec3 Vec3::operator * (const float val) const
    {
        return Vec3(x * val, y * val, z * val);
    }

    Vec3 Vec3::operator / (const float val) const
    {
        return Vec3(x / val, y / val, z / val);
    }

    Vec3 Vec3::Transform(Mat4* mat) const
    {
        Vec3 res;
        float normal = (*mat)[0][3] * x + (*mat)[1][3] * y + (*mat)[2][3] * z + (*mat)[3][3];
        if (normal)
        {
            res.x = ((*mat)[0][0] * x + (*mat)[1][0] * y + (*mat)[2][0] * z + (*mat)[3][0]) / normal;
            res.y = ((*mat)[0][1] * x + (*mat)[1][1] * y + (*mat)[2][1] * z + (*mat)[3][1]) / normal;
            res.z = ((*mat)[0][2] * x + (*mat)[1][2] * y + (*mat)[2][2] * z + (*mat)[3][2]) / normal;
        }
        return res;
    }

    Vec3 Vec3::Transform(const Mat4 &mat) const
    {
        Vec3 res;
        float normal = mat[0][3] * x + mat[1][3] * y + mat[2][3] * z + mat[3][3];
        if (normal)
        {
            res.x = (mat[0][0] * x + mat[1][0] * y + mat[2][0] * z + mat[3][0]) / normal;
            res.y = (mat[0][1] * x + mat[1][1] * y + mat[2][1] * z + mat[3][1]) / normal;
            res.z = (mat[0][2] * x + mat[1][2] * y + mat[2][2] * z + mat[3][2]) / normal;
        }
        return res;
    }

    Vec3 Vec3::Project(D3DVIEWPORT9* viewport, Mat4* world, Mat4* view, Mat4* projection) const
    {
        for (short i = 0; i < 4; ++i)
        {
            for (short j = 0; j < 4; ++j)
            {
                (*world)[i][j] = (*world)[i][0] * (*view)[0][j] + (*world)[i][1] * (*view)[1][j] + (*world)[i][2] * (*view)[2][j] + (*world)[i][3] * (*view)[3][j];
            }
        }

        for (short i = 0; i < 4; ++i)
        {
            for (short j = 0; j < 4; ++j)
            {
                (*world)[i][j] = (*world)[i][0] * (*projection)[0][j] + (*world)[i][1] * (*projection)[1][j] + (*world)[i][2] * (*projection)[2][j] + (*world)[i][3] * (*projection)[3][j];
            }
        }

        Vec3 res = this->Transform(world);
        res.x = viewport->X + (1.0f + res.x) * viewport->Width / 2.0f;
        res.y = viewport->Y + (1.0f - res.y) * viewport->Height / 2.0f;
        res.z = viewport->MinZ + res.z * (viewport->MaxZ - viewport->MinZ);
        return res;
    }

    Vec3 Vec3::Project(const D3DVIEWPORT9 &viewport, const Mat4 &world, const Mat4 &view, const Mat4 &projection) const
    {
        Mat4 wv = world * view;
        Mat4 wvp = wv * projection;
        Vec3 res = this->Transform(wvp);
        res.x = viewport.X + (1.0f + res.x) * viewport.Width / 2.0f;
        res.y = viewport.Y + (1.0f - res.y) * viewport.Height / 2.0f;
        res.z = viewport.MinZ + res.z * (viewport.MaxZ - viewport.MinZ);
        return res;
    }


    Mat4 Mat4::operator * (const Mat4 &m) const
    {
        Mat4 res;
        for (short i = 0; i < 4; ++i)
        {
            for (short j = 0; j < 4; ++j)
            {
                //#error come back..
                /*float sum = 0.0f;
                for (short k = 0; k < 4; ++k)
                {
                    sum += mat[i][k] * res[k][j];
                }
                res[i][j] = sum;*/


                res[i][j] = mat[i][0] * m[0][j] + mat[i][1] * m[1][j] + mat[i][2] * m[2][j] + mat[i][3] * m[3][j];
            }
        }
        return res;
    }

    Mat4 Mat4::operator + (const Mat4 &m) const
    {
        Mat4 res;
        for (short i = 0; i < 4; ++i)
        {
            for (short j = 0; j < 4; ++j)
            {
                res[i][j] = mat[i][j] + m[i][j];
            }
        }
        return res;
    }

    Mat4 Mat4::operator - (const Mat4 &m) const
    {
        Mat4 res;
        for (short i = 0; i < 4; ++i)
        {
            for (short j = 0; j < 4; ++j)
            {
                res[i][j] = mat[i][j] - m[i][j];
            }
        }
        return res;
    }

    Mat4& Mat4::Transpose()
    {
        for (int i = 0; i < 4; ++i)
        {
            for (int j = 0; j < 4; ++j)
            {
                mat[j][i] = mat[i][j];
            }
        }
        return *this;
    }

    Mat4 Mat4::Transpose() const
    {
        Mat4 res;
        for (int i = 0; i < 4; ++i)
        {
            for (int j = 0; j < 4; ++j)
            {
                res[j][i] = mat[i][j];
            }
        }
        return res;
    }

    Mat4 Mat4::Identity()
    {
        Mat4 res;
        res[0][0] = 1.0f;
        res[1][1] = 1.0f;
        res[2][2] = 1.0f;
        res[3][3] = 1.0f;
        return res;
    }

    Mat4 Mat4::Orthagonal(float w, float h, float zNear, float zFar)
    {
        Mat4 res;
        res[0][0] = 2.0f / w;
        res[1][1] = 2.0f / h;
        res[2][2] = 1.0f / (zNear - zFar);
        res[3][2] = zNear / (zNear - zFar);
        res[3][3] = 1.0f;
        return res;
    }

    Mat4 Mat4::Perspective(float w, float h, float zNear, float zFar)
    {
        Mat4 res;
        res[0][0] = 2.0f * zNear / w;
        res[1][1] = 2.0f * zNear / h;
        res[2][2] = zFar / (zNear - zFar);
        res[3][2] = zFar * zNear / (zNear - zFar);
        res[2][3] = -1.0f;
        return res;
    }

    Mat4 Mat4::FieldOfView(float fov, float aspect, float zNear, float zFar)
    {
        Mat4 res;
        res[0][0] = 1.0f / tanf(fov / 2.0f);
        res[1][1] = aspect / tanf(fov / 2.0f);
        res[2][2] = zFar / (zFar - zNear);
        res[3][2] = (zFar * zNear) / (zNear - zFar);
        res[2][3] = -1.0f;
        res[3][3] = 0.0f;
        return res;
    }

    Mat4 Mat4::LookAt(const Vec3& Eye, const Vec3& At, const Vec3& Up)
    {
        Vec3 XAxis, YAxis, ZAxis;
        ZAxis = (Eye - At).Normalise();
        XAxis = (Up.Cross(ZAxis)).Normalise();
        YAxis = (ZAxis.Cross(XAxis)).Normalise();

        Mat4 res;
        res[0][0] = XAxis.x;
        res[1][0] = XAxis.y;
        res[2][0] = XAxis.z;
        res[3][0] = -XAxis.Dot(Eye);
        res[0][1] = YAxis.x;
        res[1][1] = YAxis.y;
        res[2][1] = YAxis.z;
        res[3][1] = -YAxis.Dot(Eye);
        res[0][2] = ZAxis.x;
        res[1][2] = ZAxis.y;
        res[2][2] = ZAxis.z;
        res[3][2] = -ZAxis.Dot(Eye);
        res[3][3] = 1.0f;
        return res;
    }

    Mat4 Mat4::RotX(float rad)
    {
        float ct = cosf(rad);
        float st = sinf(rad);
        Mat4 res = Identity();
        res[1][1] = ct;
        res[1][2] = st;
        res[2][1] = -st;
        res[2][2] = ct;
        return res;
    }

    Mat4 Mat4::RotY(float rad)
    {
        float ct = cosf(rad);
        float st = sinf(rad);
        Mat4 res = Identity();
        res[0][0] = ct;
        res[0][2] = st;
        res[2][0] = -st;
        res[2][2] = ct;
        return res;
    }

    Mat4 Mat4::RotZ(float rad)
    {
        float ct = cosf(rad);
        float st = sinf(rad);
        Mat4 res = Identity();
        res[0][0] = ct;
        res[0][1] = st;
        res[1][0] = -st;
        res[1][1] = ct;
        return res;
    }

    Mat4 Mat4::Rot(float pitch, float yaw, float roll)
    {
        return RotY(yaw) * RotX(pitch) * RotZ(roll);
    }

    Mat4 Mat4::Scale(float val)
    {
        return Scale(val, val, val);
    }

    Mat4 Mat4::Scale(float x, float y, float z)
    {
        Mat4 res;
        res[0][0] = x;
        res[1][1] = y;
        res[2][2] = z;
        res[3][3] = 1.0f;
        return res;
    }

    Mat4 Mat4::Translate(float x, float y, float z)
    {
        Mat4 res;
        res[3][0] = x;
        res[3][1] = y;
        res[3][2] = z;
        res[0][0] = 1.0f;
        res[1][1] = 1.0f;
        res[2][2] = 1.0f;
        res[3][3] = 1.0f;
        return res;
    }

    namespace DXMath
    {
        unsigned int CalculateStride(unsigned int FVF)
        {
            return ((FVF | D3DFVF_XYZ) == FVF) * 12 +
                   ((FVF | D3DFVF_XYZRHW) == FVF) * 12 +
                   ((FVF | D3DFVF_XYZB1) == FVF) * 12 +
                   ((FVF | D3DFVF_XYZB2) == FVF) * 12 +
                   ((FVF | D3DFVF_XYZB3) == FVF) * 12 +
                   ((FVF | D3DFVF_XYZB4) == FVF) * 12 +
                   ((FVF | D3DFVF_XYZB5) == FVF) * 12 +
                   ((FVF | D3DFVF_XYZW) == FVF) * 12 +
                   ((FVF | D3DFVF_NORMAL) == FVF) * 12 +
                   ((FVF | D3DFVF_DIFFUSE) == FVF) * 4  +
                   ((FVF | D3DFVF_SPECULAR) == FVF) * 4  +
                   ((FVF | D3DFVF_TEX1) == FVF) * 8  +
                   ((FVF | D3DFVF_TEX2) == FVF) * 8  +
                   ((FVF | D3DFVF_TEX3) == FVF) * 8  +
                   ((FVF | D3DFVF_TEX4) == FVF) * 8  +
                   ((FVF | D3DFVF_TEX5) == FVF) * 8  +
                   ((FVF | D3DFVF_TEX6) == FVF) * 8  +
                   ((FVF | D3DFVF_TEX7) == FVF) * 8  +
                   ((FVF | D3DFVF_TEX8) == FVF) * 8;
        }

        unsigned int CalculateBitsPerPixel(D3DFORMAT format)
        {
            switch(format)
            {
                case D3DFMT_A16B16G16R16: return 64;
                case D3DFMT_A8R8G8B8: return 32;
                case D3DFMT_X8R8G8B8: return 32;
                case D3DFMT_A2B10G10R10: return 32;
                case D3DFMT_A8B8G8R8: return 32;
                case D3DFMT_X8B8G8R8: return 32;
                case D3DFMT_G16R16: return 32;
                case D3DFMT_A2R10G10B10: return 32;
                case D3DFMT_R8G8B8: return 24;
                case D3DFMT_R5G6B5: return 16;
                case D3DFMT_X1R5G5B5: return 16;
                case D3DFMT_A1R5G5B5: return 16;
                case D3DFMT_A4R4G4B4: return 16;
                case D3DFMT_A8R3G3B2: return 16;
                case D3DFMT_X4R4G4B4: return 16;
                case D3DFMT_A8P8: return 8;
                case D3DFMT_R3G3B2: return 8;
                case D3DFMT_A8: return 8;
                default: return 8;
            }
        }

        #ifdef D3DX_SUPPORT
        D3DXVECTOR3 WorldToScreen(D3DXMATRIX* WorldViewProjection, D3DVIEWPORT9* ViewPort, const D3DXVECTOR3 &in)
        {
            D3DXVECTOR3 out;
            D3DXMatrixTranspose(WorldViewProjection, WorldViewProjection);
            D3DXVec3TransformCoord(&out, &in, WorldViewProjection);
            return D3DXVECTOR3((out.x + 1.0f) * ViewPort->Width * 0.5f + ViewPort->X, (1.0f - out.y) * ViewPort->Height * 0.5f + ViewPort->Y, out.z);
        }

        D3DXVECTOR3 WorldToScreen2(D3DVIEWPORT9* ViewPort, D3DXMATRIX* World, D3DXMATRIX* View, D3DXMATRIX* Projection, const D3DXVECTOR3 &in)
        {
            D3DXVECTOR3 out;
            D3DXVec3Project(&out, &in, ViewPort, Projection, View, World);
            return out;
        }
        #else
        Vec3 WorldToScreen(Mat4* WorldViewProjection, D3DVIEWPORT9* ViewPort, const Vec3 &in)
        {
            Vec3 out = in.Transform(WorldViewProjection->Transpose());
            return Vec3{(out.x + 1.0f) * ViewPort->Width * 0.5f + ViewPort->X, (1.0f - out.y) * ViewPort->Height * 0.5f + ViewPort->Y, out.z};
        }

        Vec3 WorldToScreen2(D3DVIEWPORT9* ViewPort, Mat4* World, Mat4* View, Mat4* Projection, const Vec3 &in)
        {
            return in.Project(ViewPort, World, View, Projection);
        }
        #endif // D3DX_SUPPORT
    }

    namespace GVMath
    {
        Vec3 GetEulerAngles(float (&mat)[16], bool rowmajor)
        {
            if (rowmajor)
            {
                float x = std::atan2(mat[6], mat[10])  * (180 / GVMath::PI);
                float y = std::atan2(-mat[8], std::sqrt(std::pow(mat[0], 2) + std::pow(mat[1], 2)))  * (180 / GVMath::PI);
                float z = std::atan2(mat[1], mat[0]) * (180 / GVMath::PI);
                return {x < 0 ? 360 - x : x, y < 0 ? 360 - y : y, z < 0 ? 360 - z : z};
            }
            else
            {
                float x = std::atan2(mat[9], mat[10])  * (180 / GVMath::PI);
                float y = std::atan2(-mat[8], std::sqrt(std::pow(mat[0], 2) + std::pow(mat[4], 2)))  * (180 / GVMath::PI);
                float z = std::atan2(mat[4], mat[0]) * (180 / GVMath::PI);
                return {x < 0 ? 360 - x : x, y < 0 ? 360 - y : y, z < 0 ? 360 - z : z};
            }
        }

        Vec3 GetEulerAngles(float (&mat)[4][4], bool rowmajor)
        {
            if (rowmajor)
            {
                float x = std::atan2(mat[1][2], mat[2][2])  * (180 / GVMath::PI);
                float y = std::atan2(-mat[0][2], std::sqrt(std::pow(mat[0][0], 2) + std::pow(mat[0][1], 2)))  * (180 / GVMath::PI);
                float z = std::atan2(mat[0][1], mat[0][0]) * (180 / GVMath::PI);
                return {x < 0 ? 360 - x : x, y < 0 ? 360 - y : y, z < 0 ? 360 - z : z};
            }
            else
            {
                float x = std::atan2(mat[2][1], mat[2][2])  * (180 / GVMath::PI);
                float y = std::atan2(-mat[2][0], std::sqrt(std::pow(mat[0][0], 2) + std::pow(mat[1][0], 2)))  * (180 / GVMath::PI);
                float z = std::atan2(mat[1][0], mat[0][0]) * (180 / GVMath::PI);
                return {x < 0 ? 360 - x : x, y < 0 ? 360 - y : y, z < 0 ? 360 - z : z};
            }
        }

        float Distance(float (&a)[2], float (&b)[2])
        {
            float x = a[0] - b[0];
            float y = a[1] - b[1];
            return sqrt((x * x) + (y * y));
        }

        float Distance(float (&a)[3], float (&b)[3])
        {
            float x = a[0] - b[0];
            float y = a[1] - b[1];
            float z = a[2] - b[2];
            return sqrt((x * x) + (y * y) + (z * z));
        }

        Box2D BoundingBox(float* x, float* y, std::size_t size)
        {
            auto xtreme = std::minmax_element(x, x + size, [](const float lhs, const float rhs) {return lhs < rhs;});
            auto ytreme = std::minmax_element(y, y + size, [](const float lhs, const float rhs) {return lhs < rhs;});
            return {*xtreme.first, *ytreme.first, *xtreme.second, *ytreme.second};
        }

        Box3D BoundingBox(float* x, float* y, float* z, std::size_t size)
        {
            auto xtreme = std::minmax_element(x, x + size, [](const float lhs, const float rhs) {return lhs < rhs;});
            auto ytreme = std::minmax_element(y, y + size, [](const float lhs, const float rhs) {return lhs < rhs;});
            auto ztreme = std::minmax_element(z, z + size, [](const float lhs, const float rhs) {return lhs < rhs;});
            return {*xtreme.first, *ytreme.first, *ztreme.first, *xtreme.second, *ytreme.second, *ztreme.second};
        }

        std::uint32_t ColourChecksum(const void* data, std::size_t width, std::size_t height)
        {
            return FullColourChecksum(data, width, height, height < 12 ? 0 : 12);
        }

        std::uint32_t FullColourChecksum(const void* data, std::size_t width, std::size_t height, std::size_t offset)
        {
            std::size_t k = 0;
            std::uint32_t RSum = 0, GSum = 0, BSum = 0, ASum = 0;
            const std::uint8_t* ptr = static_cast<const std::uint8_t*>(data);

            for (std::size_t i = offset; i < height; ++i)
            {
                for (std::size_t j = 0; j < width; ++j, ++k)
                {
                    RSum += *ptr++;
                    GSum += *ptr++;
                    BSum += *ptr++;
                    ASum += *ptr++;
                }
            }

            return k != 0 ? RGB(RSum / k, GSum / k, BSum / k) : RGB(RSum, GSum, BSum);
        }

        std::uint32_t Adler32(const std::uint8_t* data, std::size_t size)
        {
            std::uint32_t a = 1, b = 0;
            for (std::size_t i = 0; i < size; ++i)
            {
                a = (a + data[i]) % 0xFFF1;
                b = (b + a) % 0xFFF1;
            }
            return (b << 0x10) | a;
        }

        std::uint32_t CRC32(const void* data, std::size_t size, std::uint32_t InitialValue)
        {
            static const std::uint32_t LookUpTable[256] =
            {
                0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
                0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
                0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
                0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
                0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
                0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
                0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
                0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
                0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
                0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
                0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
                0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
                0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
                0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
                0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
                0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
                0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
                0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
                0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
                0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
                0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
                0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
                0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
                0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
                0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
                0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
                0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
                0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
                0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
                0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
                0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
                0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
                0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
                0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
                0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
                0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
                0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
                0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
                0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
                0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
                0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
                0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
                0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
                0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
                0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
                0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
                0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
                0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
                0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
                0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
                0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
                0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
                0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
                0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
                0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
                0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
                0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
                0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
                0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
                0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
                0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
                0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
                0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
                0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
            };

            std::uint32_t crc = ~InitialValue;
            const std::uint8_t* ptr = static_cast<const std::uint8_t*>(data);

            for(std::size_t i = 0; i < size; ++i)
            {
                crc = LookUpTable[(crc ^ *ptr++) & 0xFF] ^ (crc >> 8);
            }

            return ~crc;
        }
    }



    C++ Code:
    //Get a vertex from the vertex buffer.
    #ifdef D3DX_SUPPORT
    D3DXVECTOR3 GetVertex(const std::uint8_t* vertices, std::int16_t index, std::uint16_t stride)
    {
        D3DXVECTOR3 res;
        memcpy(&res.x, &vertices[index * stride], sizeof(float));
        memcpy(&res.y, &vertices[index * stride + sizeof(float)], sizeof(float));
        memcpy(&res.z, &vertices[index * stride + sizeof(float) * 2], sizeof(float));
        return res;
    }
    #else
    Vec3 GetVertex(const std::uint8_t* vertices, std::int16_t index, std::uint16_t stride)
    {
        Vec3 res;
        memcpy(&res.x, &vertices[index * stride], sizeof(float));
        memcpy(&res.y, &vertices[index * stride + sizeof(float)], sizeof(float));
        memcpy(&res.z, &vertices[index * stride + sizeof(float) * 2], sizeof(float));
        return res;
    }
    #endif // D3DX_SUPPORT


    #ifdef D3DX_SUPPORT
    void GetVertices(std::vector<D3DXVECTOR3> &verts, IDirect3DVertexBuffer9Proxy *VertexBuffer, IDirect3DIndexBuffer9Proxy *IndexBuffer, std::uint32_t BaseVertexIndex, std::uint32_t StartIndex, std::uint32_t PrimCount, std::uint32_t Stride)
    {
        const std::uint8_t* vertices = NULL;
        const std::uint16_t* indices = NULL;
        UINT EndIndex = StartIndex + (PrimCount * 3);

        vertices = reinterpret_cast<const std::uint8_t*>(VertexBuffer->InternalBuffer());
        indices = reinterpret_cast<const std::uint16_t*>(IndexBuffer->InternalBuffer()) + PrimCount * 3 * sizeof(std::uint16_t);
        verts.resize(EndIndex - StartIndex);

        for (UINT I = StartIndex, J = 0; I < EndIndex; ++I, ++J)
        {
            verts[J] = GetVertex(vertices, indices[I] + BaseVertexIndex, Stride);
        }
    }
    #else
    void GetVertices(std::vector<Vec3> &verts, IDirect3DVertexBuffer9Proxy *VertexBuffer, IDirect3DIndexBuffer9Proxy *IndexBuffer, std::uint32_t BaseVertexIndex, std::uint32_t StartIndex, std::uint32_t PrimCount, std::uint32_t Stride)
    {
        const std::uint8_t* vertices = NULL;
        const std::uint16_t* indices = NULL;
        UINT EndIndex = StartIndex + (PrimCount * 3);

        vertices = reinterpret_cast<const std::uint8_t*>(VertexBuffer->InternalBuffer());
        indices = reinterpret_cast<const std::uint16_t*>(IndexBuffer->InternalBuffer()) + PrimCount * 3 * sizeof(std::uint16_t);
        verts.resize(EndIndex - StartIndex);

        for (UINT I = StartIndex, J = 0; I < EndIndex; ++I, ++J)
        {
            verts[J] = GetVertex(vertices, indices[I] + BaseVertexIndex, Stride);
        }
    }
    #endif // D3DX_SUPPORT


    //Create memory map for Simba to send and retrieve information to/from. One for the Image buffer if needed (for browsers) and one for hooks (split into four parts.. Fonts, Textures, Models, Other). All info is stored directly in the map rather than copied. That allows simba to access exactly what the plugin sees and not a copy of it. As soon as the plugin gets something, simba can see it without having to ask and wait every frame. Note to self: OpenGL plugin should really do this!
    void IDirect3DDevice9ProxyHook::HandleMemory(bool AllocateImage)
    {
        if (!CommMap)
        {
            CommMap.reset(new Communication(RequestEventName, ResponseEventName, MemName, HookSize, std::ios::in | std::ios::out));
        }

        if (AllocateImage)
        {
            static std::uint32_t BestSize = 0;
            static std::uint32_t Width = 0, Height = 0, Size = 0;

            if (!ImgMap)
            {
                RECT rect = {0};
                D3DDEVICE_CREATION_PARAMETERS params;
                IDirect3DDevice9Proxy::GetCreationParameters(&params);
                GetWindowRect(params.hFocusWindow, &rect);
                Width = rect.right - rect.left;
                Height = rect.bottom - rect.top;
                Size = Width * Height * 4;
                BestSize = TotalImageSize > Size ? TotalImageSize : Size <= 0 ? TotalImageSize : Size;

                char buffer[256] = {0};
                sprintf(buffer, "%s%lu", MemName, GetCurrentProcessId());
                ImgMap.reset(new MemoryMap(buffer, BestSize, std::ios::in | std::ios::out));

                if (ImgMap->open())
                {
                    ImgMap->map();
                }
            }
        }
    }

    void IDirect3DDevice9ProxyHook::HandleCommunication()
    {
        if (CommMap)
        {
            CommMap->ProcessRequests(); //process special requests from Simba controller.
        }
    }

    //Draw texture ID's on the screen. Draw model ID's on the screen.
    void IDirect3DDevice9ProxyHook::HandleDebugDrawing()
    {
        if (font)
        {
             for (auto&& tex : textures)
            {
                font->Draw(tex.X, tex.Y, D3DCOLOR_XRGB(0, 0xFF, 0), "%", tex.ID);
            }

            for (auto&& mod : models)
            {
                font->Draw(mod.X, mod.Y, D3DCOLOR_XRGB(0xFF, 0, 0), "%", mod.ID);
            }
        }

        textures.clear();
        models.clear();
    }


    IDirect3DDevice9ProxyHook::IDirect3DDevice9ProxyHook(IDirect3DDevice9* pOriginal) : IDirect3DDevice9Proxy(pOriginal) {}

    IDirect3DDevice9ProxyHook::~IDirect3DDevice9ProxyHook() {}

    ULONG IDirect3DDevice9ProxyHook::AddRef()
    {
        ++references;
        return IDirect3DDevice9ProxyHook::AddRef();
    }

    ULONG IDirect3DDevice9ProxyHook::Release()
    {
        if (--references == 0)
        {
            //destroy resources.
            font.reset(nullptr);
            pTexture = nullptr;
            pIndexBuffer = nullptr;
            pVertexBuffer = nullptr;
        }

        return IDirect3DDevice9ProxyHook::Release();
    }



    //Override rendering
    HRESULT IDirect3DDevice9ProxyHook::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
    {
        if (pTexture)
        {
            //ID of the compass and animated textures in here sometimes..
            //D3DXVECTOR3 vertex = WorldToScreen(pOriginal);
            //font->Draw(vertex.x, vertex.y, "%", curr->ID);
        }
        return IDirect3DDevice9Proxy::DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount);
    }

    HRESULT IDirect3DDevice9ProxyHook::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount)
    {
        if (pTexture && pIndexBuffer && pVertexBuffer && (primCount == 2 || NumVertices == 4))
        {
            if (PrimitiveType == D3DPT_TRIANGLELIST)
            {
                DWORD fvf = 0;
                IDirect3DDevice9Proxy::GetFVF(&fvf); //OPTIMIZATION! Get FVF instead of vertex buffer!

                #ifdef D3DX_SUPPORT
                std::vector<D3DXVECTOR3> verts;
                GetVertices(verts, pVertexBuffer, pIndexBuffer, BaseVertexIndex, startIndex, primCount, DXMath::CalculateStride(fvf));
                #else
                std::vector<Vec3> verts; //BAD! Should just store it in the map directly instead of copy :(
                GetVertices(verts, pVertexBuffer, pIndexBuffer, BaseVertexIndex, startIndex, primCount, DXMath::CalculateStride(fvf));
                #endif // D3DX_SUPPORT


                //Project texture vertices to the screen.. Draw ID at the center of the texture..
                if (verts.size())
                {
                    #ifdef D3DX_SUPPORT
                    D3DXVECTOR3 in = {(verts[0].x + verts[4].x) / 2.0f, (verts[0].y + verts[4].y) / 2.0f, 0};
                    D3DXVECTOR3 out = DXMath::WorldToScreen2(&ViewPort, &World, &View, &Projection, in);
                    #else
                    Vec3 in = {(verts[0].x + verts[4].x) / 2.0f, (verts[0].y + verts[4].y) / 2.0f, 0};
                    Vec3 out = DXMath::WorldToScreen2(&ViewPort, &World, &View, &Projection, in);
                    #endif // D3DX_SUPPORT

                    textures.emplace_back(TextureInfo{ //Bad.. Copy for testing.. TODO: Move it to the memory map instead.
                        pTexture->GetID(),
                        pTexture->GetFID(),
                        static_cast<std::uint32_t>(out.x),
                        static_cast<std::uint32_t>(out.y),
                        {verts[0].x, verts[0].y, verts[0].z,
                        verts[1].x, verts[1].y, verts[1].z,
                        verts[2].x, verts[2].y, verts[2].z,
                        verts[3].x, verts[3].y, verts[3].z,
                        verts[4].x, verts[4].y, verts[4].z,
                        verts[5].x, verts[5].y, verts[5].z}
                    });
                }
            }
        }
        else if (pVertexBuffer)
        {
            //Bad ID generation. Should use the vertex buffer hash.
            //Get vertex shader and project Model BASE to the screen..

            //unsigned int ID = NumVertices | (primCount << 16);
            /*IDirect3DDevice9Proxy::GetVertexShaderConstantF(0, reinterpret_cast<float*>(&WorldViewProjection), 4);

            #ifdef D3DX_SUPPORT
            D3DXVECTOR3 out = DXMath::WorldToScreen(&WorldViewProjection, &ViewPort);
            #else
            Vec3 out = {0, 0, 0};//DXMath::WorldToScreen(&WorldViewProjection, &ViewPort);
            #endif // D3DX_SUPPORT


            //BAD. Copy vertices. TODO: Move to memory map instead.
            std::vector<float> vertices = std::move(pVertexBuffer->GetVertices(pIndexBuffer, BaseVertexIndex, startIndex, primCount));
            models.emplace_back(ModelInfo{
                GVMath::CRC32(&vertices[0], vertices.size() * sizeof(float)),
                static_cast<std::uint32_t>(out.x),
                static_cast<std::uint32_t>(out.y),
                NumVertices,
                primCount,
                PrimitiveType,
                pIndexBuffer->GetID(),
                pIndexBuffer->InternalBufferSize(),
                {out.x, out.y, out.z},
                {WorldViewProjection[0][0], WorldViewProjection[0][1], WorldViewProjection[0][2], WorldViewProjection[0][3],
                 WorldViewProjection[1][0], WorldViewProjection[1][1], WorldViewProjection[1][2], WorldViewProjection[1][3],
                 WorldViewProjection[2][0], WorldViewProjection[2][1], WorldViewProjection[2][2], WorldViewProjection[2][3],
                 WorldViewProjection[3][0], WorldViewProjection[3][1], WorldViewProjection[3][2], WorldViewProjection[3][3]}
            });*/

        }
        return IDirect3DDevice9Proxy::DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
    }

    HRESULT IDirect3DDevice9ProxyHook::BeginScene()
    {
        HRESULT res = IDirect3DDevice9Proxy::BeginScene();

        HandleMemory(false);

        if (!font)
        {
            font.reset(new Font(this->Original(), "Arial", 8));
        }

        //Get the matrices only once! They never ever change after the scene/game has loaded! NOTE: Might be better to call this in a static context block (IE: std::call_once).
        #ifdef D3DX_SUPPORT
        IDirect3DDevice9Proxy::GetViewport(&ViewPort);
        IDirect3DDevice9Proxy::GetTransform(D3DTS_VIEW, &View);
        IDirect3DDevice9Proxy::GetTransform(D3DTS_PROJECTION, &Projection);
        IDirect3DDevice9Proxy::GetTransform(D3DTS_WORLD, &World);
        #else
        IDirect3DDevice9Proxy::GetViewport(&ViewPort);
        IDirect3DDevice9Proxy::GetTransform(D3DTS_VIEW, reinterpret_cast<D3DMATRIX*>(&View[0][0]));
        IDirect3DDevice9Proxy::GetTransform(D3DTS_PROJECTION, reinterpret_cast<D3DMATRIX*>(&Projection[0][0]));
        IDirect3DDevice9Proxy::GetTransform(D3DTS_WORLD, reinterpret_cast<D3DMATRIX*>(&World[0][0]));
        #endif // D3DX_SUPPORT
        return res;
    }

    HRESULT IDirect3DDevice9ProxyHook::EndScene()
    {
        //If the SMART plugin is a valid version.. Capture the back buffer and feed it to SMART. Draw SMART's debug and then the mouse on top.. but only if SMART is NOT minimized!
        if (SMARTIsValid())
        {
            /*static int Width = 0, Height = 0;
            static D3DFORMAT Format = D3DFMT_UNKNOWN;
            SMARTCaptureBackBuffer(IDirect3DDevice9Proxy::Original(), Width, Height, Format);

            if (!SMARTIsMinimised(IDirect3DDevice9Proxy::Original()))
            {
                StateBlock block = {IDirect3DDevice9Proxy::Original()};
                IDirect3DDevice9Proxy::SetRenderState(D3DRS_LIGHTING, FALSE);
                IDirect3DDevice9Proxy::SetRenderState(D3DRS_FOGENABLE, FALSE);
                IDirect3DDevice9Proxy::SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
                IDirect3DDevice9Proxy::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
                IDirect3DDevice9Proxy::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
                IDirect3DDevice9Proxy::SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
                IDirect3DDevice9Proxy::SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
                IDirect3DDevice9Proxy::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

                if (SMARTIsDebugEnabled())
                {
                    SMARTDrawBackBuffer(IDirect3DDevice9Proxy::Original());
                }

                int X = -1, Y = -1;
                if (SMARTGetMousePosition(X, Y))
                {
                    IDirect3DDevice9Proxy::SetTexture(0, nullptr);
                    IDirect3DDevice9Proxy::SetPixelShader(nullptr);
                    IDirect3DDevice9Proxy::SetVertexShader(nullptr);

                    Graphics g = {IDirect3DDevice9Proxy::Original()};
                    g.DrawCircle(X, Y, 2.5f, D3DCOLOR_XRGB(0xFF, 0, 0));
                }
            }*/

        }
        else
        {
            HandleMemory(true);
        }

        //Process Simba special requests.. There shouldn't really be any because everything is stored in a shared segment immediately.
        //HandleCommunication();
        //HandleDebugDrawing();  //for browsers and things other than SMART.

        return IDirect3DDevice9Proxy::EndScene();
    }

    HRESULT IDirect3DDevice9ProxyHook::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters)
    {
        if (font)
            font->OnLostDevice();

        HRESULT res = IDirect3DDevice9Proxy::Reset(pPresentationParameters);

        if (font)
            font->OnResetDevice();

        return res;
    }


    //Override creations! Hell Yes! This allows us to add cookies to the model, backbuffer, textures, etc.. :) Such as ID's, positions, etc.. so they never have to be calculated again unless the model updates (via lock/unlock)!
    HRESULT IDirect3DDevice9ProxyHook::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain)
    {
        HRESULT res = IDirect3DDevice9Proxy::CreateAdditionalSwapChain(pPresentationParameters, pSwapChain);
        if (res == D3D_OK)
        {
            *pSwapChain = new IDirect3DSwapChain9Proxy(*pSwapChain);
        }
        return res;
    }


    HRESULT IDirect3DDevice9ProxyHook::CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle)
    {
        HRESULT res = IDirect3DDevice9Proxy::CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle);
        if (res == D3D_OK)
        {
            *ppTexture = new IDirect3DTexture9Proxy(*ppTexture, Width, Height, Format);
        }
        return res;
    }

    HRESULT IDirect3DDevice9ProxyHook::CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle)
    {
        HRESULT res = IDirect3DDevice9Proxy::CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle);
        if (res == D3D_OK)
        {
            *ppVertexBuffer = new IDirect3DVertexBuffer9Proxy(*ppVertexBuffer, Length, FVF);
        }
        return res;
    }

    HRESULT IDirect3DDevice9ProxyHook::CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle)
    {
        HRESULT res = IDirect3DDevice9Proxy::CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, pSharedHandle);
        if (res == D3D_OK)
        {
            *ppIndexBuffer = new IDirect3DIndexBuffer9Proxy(*ppIndexBuffer, Length, Format);
        }
        return res;
    }


    //Override setters
    HRESULT IDirect3DDevice9ProxyHook::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTexture)
    {
        this->pTexture = nullptr;
        if (pTexture && pTexture->GetType() == D3DRTYPE_TEXTURE)
        {
            this->pTexture = static_cast<IDirect3DTexture9Proxy*>(pTexture);
            return IDirect3DDevice9Proxy::SetTexture(Stage, static_cast<IDirect3DTexture9Proxy*>(pTexture)->Original());
        }
        return IDirect3DDevice9Proxy::SetTexture(Stage, pTexture);
    }

    HRESULT IDirect3DDevice9ProxyHook::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride)
    {
        this->pVertexBuffer = nullptr;
        if (pStreamData && pStreamData->GetType() == D3DRTYPE_VERTEXBUFFER)
        {
            this->pVertexBuffer = static_cast<IDirect3DVertexBuffer9Proxy*>(pStreamData);
            return IDirect3DDevice9Proxy::SetStreamSource(StreamNumber, static_cast<IDirect3DVertexBuffer9Proxy*>(pStreamData)->Original(), OffsetInBytes, Stride);
        }
        return IDirect3DDevice9Proxy::SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride);
    }

    HRESULT IDirect3DDevice9ProxyHook::SetIndices(IDirect3DIndexBuffer9* pIndexData)
    {
        this->pIndexBuffer = nullptr;
        if (pIndexData && pIndexData->GetType() == D3DRTYPE_INDEXBUFFER)
        {
            this->pIndexBuffer = static_cast<IDirect3DIndexBuffer9Proxy*>(pIndexData);
            return IDirect3DDevice9Proxy::SetIndices(static_cast<IDirect3DIndexBuffer9Proxy*>(pIndexData)->Original());
        }
        return IDirect3DDevice9Proxy::SetIndices(pIndexData);
    }


    //Override consumers
    HRESULT IDirect3DDevice9ProxyHook::GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9** pSwapChain)
    {
        HRESULT res = IDirect3DDevice9Proxy::GetSwapChain(iSwapChain, pSwapChain);
        if (res == D3D_OK)
        {
            *pSwapChain = new IDirect3DSwapChain9Proxy(*pSwapChain);
        }
        return res;
    }

    HRESULT IDirect3DDevice9ProxyHook::ProcessVertices(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags)
    {
        return IDirect3DDevice9Proxy::ProcessVertices(SrcStartIndex, DestIndex, VertexCount, static_cast<IDirect3DVertexBuffer9Proxy*>(pDestBuffer)->Original(), pVertexDecl, Flags);
    }



    SMART plugin interface overhaul:
    C++ Code:
    #include "Plugin.hxx"

    const constexpr int DXButtonIDs[2] = {100, 101};
    const constexpr char* DXButtonTexts[2] = {"Disable DirectX_Enable DirectX", "Enable DXDebug_Disable DXDebug"};

    SMARTInfo* SmartGlobal = nullptr;
    bool SMARTDebugEnabled = false;
    bool SMARTCaptureEnabled = true;

    template<typename T>
    void SMARTSafeRelease(T* &Ptr)
    {
        if (Ptr)
        {
            Ptr->Release();
            Ptr = nullptr;
        }
    }

    void SMARTButtonPressed(int ID, bool State)
    {
        switch(ID)
        {
            case DXButtonIDs[0]:
                SmartGlobal->setCapture(!State);
                SMARTCaptureEnabled = State;
                break;

            case DXButtonIDs[1]:
                SMARTDebugEnabled = !State;
                break;

        }
    }

    void SMARTPluginInit(SMARTInfo* ptr, bool* ReplaceButtons, int* ButtonCount, const char* const** ButtonText, const int** ButtonIDs, _SMARTButtonPressed* ButtonCallback)
    {
        SmartGlobal = ptr;
        if (ptr)
        {
            *ReplaceButtons = true;

            *ButtonCount = 2;
            *ButtonIDs = DXButtonIDs;
            *ButtonText = DXButtonTexts;
            *ButtonCallback = &SMARTButtonPressed;
        }
    }

    bool SMARTIsValid()
    {
        return SmartGlobal && SmartGlobal->version;
    }

    bool SMARTIsCaptureEnabled()
    {
        return SMARTCaptureEnabled;
    }

    bool SMARTIsDebugEnabled()
    {
        return SMARTDebugEnabled;
    }

    bool SMARTGetMousePosition(int &X, int &Y)
    {
        SmartGlobal->getMousePos(X, Y);
        return X > -1 && Y > -1;
    }

    bool SMARTIsMinimised(IDirect3DDevice9 *device)
    {
        IDirect3DSurface9* RenderTarget = nullptr;
        HRESULT result = device->GetRenderTarget(0, &RenderTarget);

        if (result == D3D_OK)
        {
            HDC DC = nullptr;
            RenderTarget->GetDC(&DC);
            bool Minimised = IsIconic(WindowFromDC(DC));
            RenderTarget->ReleaseDC(DC);
            SMARTSafeRelease(RenderTarget);
            return Minimised;
        }
        return false;
    }

    void SMARTNormaliseAlphaChannel() //needed because of Simba's non-support of 32-bit proper alpha channels!
    {
        std::uint8_t* Ptr = reinterpret_cast<std::uint8_t*>(SmartGlobal->dbg);
        for (int I = 0; I < SmartGlobal->height; ++I)
        {
            for (int J = 0; J < SmartGlobal->width; ++J)
            {
                std::uint8_t B = *(Ptr++);
                std::uint8_t G = *(Ptr++);
                std::uint8_t R = *(Ptr++);
                *(Ptr++) = (B == 0 && G == 0 && R == 0) ? 0 : 0xFF;
            }
        }
    }

    void SMARTCaptureBackBuffer(IDirect3DDevice9* device, int &Width, int &Height, D3DFORMAT Format)
    {
        IDirect3DSurface9* RenderTarget = nullptr;
        IDirect3DSurface9* DestTarget = nullptr;
        HRESULT result = device->GetRenderTarget(0, &RenderTarget);

        if (result == D3D_OK)
        {
            if (Width == 0 || Height == 0 || Format == D3DFMT_UNKNOWN)
            {
                D3DSURFACE_DESC descriptor = {};
                RenderTarget->GetDesc(&descriptor);
                Width = descriptor.Width;
                Height = descriptor.Height;
                Format = descriptor.Format;
            }

            result = device->CreateOffscreenPlainSurface(Width, Height, Format, D3DPOOL_SYSTEMMEM, &DestTarget, nullptr);
            result = device->GetRenderTargetData(RenderTarget, DestTarget);

            D3DLOCKED_RECT rect;
            DestTarget->LockRect(&rect, 0, D3DLOCK_READONLY);
            memcpy(SmartGlobal->img, rect.pBits, Width * Height * 4);
            DestTarget->UnlockRect();
        }

        SMARTSafeRelease(RenderTarget);
        SMARTSafeRelease(DestTarget);
    }

    void SMARTDrawBackBuffer(IDirect3DDevice9* device)
    {
        SMARTNormaliseAlphaChannel();
        Texture texture = {device, SmartGlobal->width, SmartGlobal->height, D3DFMT_A8R8G8B8};
        memcpy(texture.Lock(), SmartGlobal->dbg, SmartGlobal->width * SmartGlobal->height * 4);
        texture.Unlock();
        texture.Draw(0, 0, SmartGlobal->width, SmartGlobal->height);
    }


    C++ Code:
    typedef struct
    {
        char letter;
        std::uint32_t ID;
        std::uint32_t FID;
        std::uint32_t X, Y;
        float vertices[18];
    } FontInfo;

    typedef struct
    {
        std::uint32_t ID;
        std::uint32_t FID;
        std::uint32_t X, Y;
        float vertices[18];
    } TextureInfo;

    typedef struct
    {
        std::uint32_t ID;
        std::uint32_t X, Y;
        std::uint32_t VertexCount;
        std::uint32_t PrimitiveCount;
        std::uint32_t PrimitiveType;

        std::uint32_t IID;
        std::uint32_t IICount;

        float RealBase[3];
        float Matrix[16];
        SharedMemoryVector<float> vertices;
    } ModelInfo;
    Last edited by Brandon; 07-09-2015 at 01:11 AM.
    I am Ggzz..
    Hackintosher

  8. #208
    Join Date
    Jun 2014
    Posts
    463
    Mentioned
    27 Post(s)
    Quoted
    229 Post(s)

    Default

    but in the long term won't NXT cancel out dx?
    Tsunami

  9. #209
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Bly View Post
    but in the long term won't NXT cancel out dx?
    No.. It'll just shrink the size of some communities. Only the ones with versatile programmers will survive. Besides, on Windows you have 3 options: Safemode/software, OpenGL, Direct-X. Jagex already stated they plan on using Direct-X 12 and the SDK documentation is already public.. so..
    I am Ggzz..
    Hackintosher

  10. #210
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    No.. It'll just shrink the size of some communities. Only the ones with versatile programmers will survive. Besides, on Windows you have 3 options: Safemode/software, OpenGL, Direct-X. Jagex already stated they plan on using Direct-X 12 and the SDK documentation is already public.. so..
    Where did they say that?

  11. #211
    Join Date
    Apr 2013
    Posts
    11
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    At launch though? I was told by a certain 2 people (who are currently viewing this thread :P) that DirectX was being dropped. It is true that DirectX is usually easier to develop for, because it handles most of the device initialisation and such for you. But I was hoping we Jagex would promote OpenGL technology so we can get more games that run on Linux distributions!! If they plan on doing both however, it would be nice to have DirectX for casual botters and then lightweight OpenGL for goldfarmers. Image the potential for headless linux servers running several bots.

    As for your generous post of source material thanks! I have had a sudden workload increase for this month, but I would like to fork your DirectX and OpenGL on Github and help with development. It would be so cool if we could push out a bunch of DirectX and OpenGL methods in preparation for the NXT client. I wonder if it would be more viable to dispose of simba (release of NXT make everything obsolete anyway) and build a new bot client which simply hooks the NXT client directly and reads process memory. That would be a fun project.

    Also it would be slightly more efficient to use a single memcpy rather than 3 in GetVertex. The floats are all contiguous (I assume). In fact you could probably do:
    memcpy(&res, &vertices[index * stride], sizeof(float) * 3); //
    Maybe the compiler already optimises it that way, I dono.

  12. #212
    Join Date
    Dec 2011
    Location
    East Coast, USA
    Posts
    4,231
    Mentioned
    112 Post(s)
    Quoted
    1869 Post(s)

    Default

    Quote Originally Posted by Forty Two View Post
    At launch though? I was told by a certain 2 people (who are currently viewing this thread :P) that DirectX was being dropped. It is true that DirectX is usually easier to develop for, because it handles most of the device initialisation and such for you. But I was hoping we Jagex would promote OpenGL technology so we can get more games that run on Linux distributions!! If they plan on doing both however, it would be nice to have DirectX for casual botters and then lightweight OpenGL for goldfarmers. Image the potential for headless linux servers running several bots.

    As for your generous post of source material thanks! I have had a sudden workload increase for this month, but I would like to fork your DirectX and OpenGL on Github and help with development. It would be so cool if we could push out a bunch of DirectX and OpenGL methods in preparation for the NXT client. I wonder if it would be more viable to dispose of simba (release of NXT make everything obsolete anyway) and build a new bot client which simply hooks the NXT client directly and reads process memory. That would be a fun project.

    Also it would be slightly more efficient to use a single memcpy rather than 3 in GetVertex. The floats are all contiguous (I assume). In fact you could probably do:
    memcpy(&res, &vertices[index * stride], sizeof(float) * 3); //
    Maybe the compiler already optimises it that way, I dono.
    I don't think Simba will ever be disposed of -- it'll never become completely obsolete either. As long as the game has colors, Simba will be a viable method for autoing. SRL will break, and we may even have to dump SMART, but Simba will still be there.

    The next version of SRL has to be 6.9, though. Can't skip that.
    Last edited by KeepBotting; 07-09-2015 at 02:19 AM.
    GitLab projects | Simba 1.4 | Find me on IRC or Discord | ScapeRune scripts | Come play bot ScapeRune!

    <BenLand100> we're just in the transitional phase where society reclassifies guns as Badâ„¢ before everyone gets laser pistols

  13. #213
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Clarity View Post
    Where did they say that?
    I had book marked the QFC: 198-199-113-65596566 but it doesn't seem to exist :S IIRC, there was a post by a mod with something to the effect of "We plan to support OpenGL for multiple platforms and we're looking into/keeping an eye on Direct-X 12".
    I am Ggzz..
    Hackintosher

  14. #214
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    I had book marked the QFC: 198-199-113-65596566 but it doesn't seem to exist :S IIRC, there was a post by a mod with something to the effect of "We plan to support OpenGL for multiple platforms and we're looking into/keeping an eye on Direct-X 12".
    Alright, well I suppose we'll never know for sure until release, or more development blog posts!
    Reason I asked, was that I last heard it was WebGL with DX getting dropped. Perhaps your bookmarked post was more up to date.

  15. #215
    Join Date
    Apr 2013
    Posts
    11
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    All I have seen on the subject. http://runescape.wikia.com/wiki/Upda...nescape_Client
    Look at those screenshots at the bottom of the page!

    Maybe we should ask a J-Mod, "Hey I'm planning on hacking your new C client to pieces, are you planning on using DirectX 12?"

  16. #216
    Join Date
    Apr 2013
    Posts
    11
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    Quote Originally Posted by Clarity View Post
    Alright, well I suppose we'll never know for sure until release, or more development blog posts!
    Reason I asked, was that I last heard it was WebGL with DX getting dropped. Perhaps your bookmarked post was more up to date.
    Java support for all browsers is being dropped soon, "WebGL (Web Graphics Library) is a JavaScript API for rendering interactive 3D computer graphics and 2D graphics within any compatible web browser without the use of plug-ins." - Google
    So I doubt that is going to happen. But hey! C is much easier to reverse engineer, we just ahve to be careful about anti-cheat.

  17. #217
    Join Date
    Jun 2007
    Location
    The land of the long white cloud.
    Posts
    3,702
    Mentioned
    261 Post(s)
    Quoted
    2006 Post(s)

    Default

    Thanks Brandon for the update on this project! When you are ub3r smart like you are then people will always rely on you for stuff

  18. #218
    Join Date
    Apr 2013
    Posts
    11
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    You got all the matrices from device->GetTransform... I swear that was the first thing I tried :S
    I also just realised I have been hooking GetStreamSource and locking the vertex buffer in every draw call. Didn't even think to just grab it once in SetStreamSource. My XY projections are still way off though.

    I see you have a CRC hashing function, do you plan on using texture checksums or vertex counts? I think the checksums change when the texture quality and such changes.

    You base code looks well optimized already, make sure to put it on GitHub when you are free so I can fork it.
    My code is currently a mess of kludged functions, just a proof of concept really.

    On a side note.
    When NXT releases can we expect Simba to be rewritten to read process memory directly? And while we are at it, we should rewrite Simba in C. Then we could use Windows API to send input directly to the client window, and hook game functions all day long.

  19. #219
    Join Date
    Oct 2013
    Location
    East Coast USA
    Posts
    770
    Mentioned
    61 Post(s)
    Quoted
    364 Post(s)

    Default

    @Brandon;
    I was curious if you had a newer codebase to share? I've been trying to get a better understanding of all this. I keep falling down ratholes but it's starting to make sense.

    As far as using it: I downloaded the latest github (v0.6?) and got it compiled under VS2015. I used the project in the d3d9-visual folder.

    I can play in smart/directx like normal when using these DLLs. I could not get it to pass DXISetup() though. I think you said to expect it not to work under smart.

    I got results with the runescape client. At first I got the MAP-ID message box. The RS window was black except the blah text at the bottom. The script ran but the debug was all black.

    Then I commented out the MessageBoxA call. Much better. The debug was off but it tried:


    Full size

    I was unable to get it to work with firefox. It never popped up the dialog so I'm guessing it's not getting loaded at all.

    I used this script after targeting the window and entering the handle that prints:
    Simba Code:
    {$loadlib DXI}

    Function PtrToBmp(Width, Height: Integer; Ptr: Pointer): Integer;
    var
      Bmp: TMufasaBitmap;
    Begin
      Bmp.Init(Client.GetMBitmaps);
      Bmp.SetPersistentMemory(Uint32(Ptr), Width, Height);
      Bmp.SetTransparentColor(0);
      Result := Bmp.GetIndex();
    End;

    Procedure DrawBox(Bmp: Integer; Box: TBox; Fill: Boolean = False; Colour: TColor = $FF);
    var
      TPA: Array Of TPoint;
      TM: TMufasaBitmap;
    Begin
      TM := GetMufasaBitmap(Bmp);
      If (Fill) then
        TM.Rectangle(Box, Colour)
      Else
        Begin
          TPA := EdgeFromBox(Box);
          TM.DrawTPA(TPA, Colour);
        End;
    End;

    Procedure ClearBox(Bmp: Integer; Box: TBox);
    Begin
      DrawBox(Bmp, Box, True, $0);
    End;

    Procedure DebugBitmap(Bmp: Integer);
    var
      W, H: Integer;
    Begin
      GetBitmapSize(Bmp, W, H);
      DisplayDebugImgWindow(W, H);
      DrawBitmapDebugImg(Bmp);
    End;

    var
      Bmp: Integer;
      W, H: Integer;
    begin
      GetClientDimensions(W, H); //this line requires that you drag the crosshairs on the window.
      if (DXISetup(5506142)) then //change the this value to the PID..
      begin
        writeln('DXI setup succeeded');
        Bmp := PtrToBmp(W, H, DXIImagePointer());
        DebugBitmap(Bmp);
        FreeBitmap(Bmp);

        Bmp := PtrToBmp(W, H, DXIDebugPointer());
        ClearBox(Bmp, IntToBox(0, 0, W - 1, H - 1));
        DrawBox(Bmp, IntToBox(0, 0, 100, 100));
        FreeBitmap(Bmp);

      end else
        writeln('Failed to setup DXI.');
    end.

  20. #220
    Join Date
    Dec 2007
    Posts
    2,112
    Mentioned
    71 Post(s)
    Quoted
    580 Post(s)

    Default

    @bonsai; if I had to guess you dont have the alpha values included in the bitmap; 32bit rather than 24bit. Explains the massive black section taking up the screen at the bottom. Either that or you have the wrong width and height set. idno the format of the ptr, but try and debug the values you have in the pointer, also try debug the client sizes.

    @Forty Two; Direct-x is a bitch to debug. OpenGL is easier.
    Last edited by Kasi; 08-03-2015 at 02:12 PM.

  21. #221
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Kasi View Post
    @bonsai; if I had to guess you dont have the alpha values included in the bitmap; 32bit rather than 24bit. Explains the massive black section taking up the screen at the bottom. Either that or you have the wrong width and height set. idno the format of the ptr, but try and debug the values you have in the pointer, also try debug the client sizes.

    @Forty Two; Direct-x is a bitch to debug. OpenGL is easier.

    100% it's the wrong size he's using. @bonsai; are you trying to run it in the browser? The current plugin doesn't do that. I had originally uploaded the code for that but I have no idea where it is :S

    I'm pretty sure I uploaded it somewhere to compiled with VS2012 and Codeblocks. If I can't find it, I'll just rewrite the part that allows it to work in the browser. The thing is, you don't really need Direct-X plugin for the browser because the cross-hairs seem to work fine?

    Anyway, let me know what you need added or debugged. IE: Steps to reproduce the problem you are having. I've got more free-time this week
    I am Ggzz..
    Hackintosher

  22. #222
    Join Date
    Oct 2013
    Location
    East Coast USA
    Posts
    770
    Mentioned
    61 Post(s)
    Quoted
    364 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    100% it's the wrong size he's using. @bonsai; are you trying to run it in the browser? The current plugin doesn't do that. I had originally uploaded the code for that but I have no idea where it is :S

    I'm pretty sure I uploaded it somewhere to compiled with VS2012 and Codeblocks. If I can't find it, I'll just rewrite the part that allows it to work in the browser. The thing is, you don't really need Direct-X plugin for the browser because the cross-hairs seem to work fine?

    Anyway, let me know what you need added or debugged. IE: Steps to reproduce the problem you are having. I've got more free-time this week
    My end goal would be to be able to get at the textures, fonts, etc, like in opengl. But for now I'm just trying to understand it all.

    I was trying to build my own dll and call the DXIxxx functions that are exported.

    I downloaded the newest github and built the visual studio projects. I put d3d9.dll in the runescape client folder and both dlls in the simba plugins folder. I started the rs client and got a popup when it created shared memory. The screen didn't load up after I clicked it.

    I commented out the message box and redid. Then the client painted. I used your test script in simba, dragged the crosshairs and entered the window handle. That's where the debug picture came from. The W/H are from simba.

    The RS client ends up hung.

  23. #223
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by bonsai View Post
    My end goal would be to be able to get at the textures, fonts, etc, like in opengl. But for now I'm just trying to understand it all.

    I was trying to build my own dll and call the DXIxxx functions that are exported.

    I downloaded the newest github and built the visual studio projects. I put d3d9.dll in the runescape client folder and both dlls in the simba plugins folder. I started the rs client and got a popup when it created shared memory. The screen didn't load up after I clicked it.

    I commented out the message box and redid. Then the client painted. I used your test script in simba, dragged the crosshairs and entered the window handle. That's where the debug picture came from. The W/H are from simba.

    The RS client ends up hung.

    EDIT: I updated the Visual Studio source to include the below fixes (didn't update the VS .dll modules though..).


    I see. It's not actually "hung". It's a black screen because the debug is drawing badly due to Simba's 32-bit alpha channel being completely borked + I had not updated the Visual Studio source to handle it at the time.

    Change IDirect3DDevice9Proxy EndScene implementation (and you can remove the popups from the SharedMemory file I forgot to remove it for debugging):

    C++ Code:
    HRESULT Direct3DDevice9Proxy::EndScene()
    {
        bool isMinimised = false;
        if (SmartGlobal && SmartGlobal->version)
        {
            dxReadPixels(ptr_Direct3DDevice9, SmartGlobal->img, isMinimised, SmartGlobal->width, SmartGlobal->height);

            IDirect3DStateBlock9* block;
            ptr_Direct3DDevice9->CreateStateBlock(D3DSBT_ALL, &block);
            block->Capture();

            ptr_Direct3DDevice9->SetRenderState(D3DRS_LIGHTING, FALSE);
            ptr_Direct3DDevice9->SetRenderState(D3DRS_FOGENABLE, FALSE);
            ptr_Direct3DDevice9->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
            ptr_Direct3DDevice9->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
            ptr_Direct3DDevice9->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); //DISABLED 2014-02-28..
            ptr_Direct3DDevice9->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
            ptr_Direct3DDevice9->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
            ptr_Direct3DDevice9->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);


            if (SmartDebugEnabled && !isMinimised)
            {
                BltSmartBuffer(ptr_Direct3DDevice9);
            }

            int X = -1, Y = -1;
            SmartGlobal->getMousePos(X, Y);

            if (X > -1 && Y > -1)
            {
                //ptr_Direct3DDevice9->SetRenderState(D3DRS_ZFUNC,D3DCMP_NEVER);
                ptr_Direct3DDevice9->SetTexture(0, nullptr);
                ptr_Direct3DDevice9->SetPixelShader(nullptr);
                ptr_Direct3DDevice9->SetVertexShader(nullptr);
                DrawCircle(ptr_Direct3DDevice9, X, Y, 2.5f);
            }

            block->Apply();
            block->Release();
        }
        else
        {
            if (!SharedImageData || !SharedImageData->GetDataPointer())
            {
                CreateSharedMemory(GetCurrentProcessId()) || OpenSharedMemory(GetCurrentProcessId());
            }

            int Width = 0, Height = 0;
            void* ImgPtr = SharedImageData->GetDataPointer();
            dxReadPixels(ptr_Direct3DDevice9, ImgPtr, isMinimised, Width, Height);

            if (!isMinimised)
            {
                IDirect3DStateBlock9* block;
                ptr_Direct3DDevice9->CreateStateBlock(D3DSBT_ALL, &block);
                block->Capture();

                ptr_Direct3DDevice9->SetRenderState(D3DRS_LIGHTING, FALSE);
                ptr_Direct3DDevice9->SetRenderState(D3DRS_FOGENABLE, FALSE);
                ptr_Direct3DDevice9->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
                ptr_Direct3DDevice9->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
                ptr_Direct3DDevice9->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); //DISABLED 2014-02-28..
                ptr_Direct3DDevice9->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
                ptr_Direct3DDevice9->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
                ptr_Direct3DDevice9->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

                void* DbgPtr = reinterpret_cast<std::uint8_t*>(SharedImageData->GetDataPointer()) + SharedImageSize;
                BltMappedBuffer(ptr_Direct3DDevice9, DbgPtr, Width, Height);

                block->Apply();
                block->Release();
            }
        }

        return ptr_Direct3DDevice9->EndScene();
    }


    Change DXI's dllmain.cpp (so that it maps both the debug and the game image instead of just one -- TotalImageSize instead of SharedImageSize):

    C++ Code:
    bool OpenSharedMemory(DWORD ProcessID, unsigned int Width, unsigned int Height)
    {
        if (Width == 0 || Height == 0)
        {
            GetDesktopResolution(Width, Height);
        }
        SharedImageData.reset(new SharedMemory(SharedImageName + std::to_string(ProcessID)));
        return SharedImageData->OpenMemoryMap(Width || Height == 0 ? TotalImageSize : Width * Height * 4 * 2);
    }


    Then you can run the below modified script for the latest Simba (Just drag the cross-hairs on the RSWindow and hit play):

    Simba Code:
    {$loadlib DXI}

    Function PtrToBmp(Width, Height: Integer; Ptr: Pointer): Integer;
    var
      Bmp: TMufasaBitmap;
    Begin
      Bmp.Init(Client.GetMBitmaps);
      Bmp.SetPersistentMemory(PtrUInt(Ptr), Width, Height);
      Bmp.SetTransparentColor(0);
      Result := Bmp.GetIndex();
    End;

    Procedure DrawBox(Bmp: Integer; Box: TBox; Fill: Boolean = False; Colour: TColor = $FF);
    var
      TPA: Array Of TPoint;
      TM: TMufasaBitmap;
    Begin
      TM := GetMufasaBitmap(Bmp);
      If (Fill) then
        TM.Rectangle(Box, Colour)
      Else
        Begin
          TPA := EdgeFromBox(Box);
          TM.DrawTPA(TPA, Colour);
        End;
    End;

    Procedure ClearBox(Bmp: Integer; Box: TBox);
    Begin
      DrawBox(Bmp, Box, True, $0);
    End;

    Procedure DebugBitmap(Bmp: Integer);
    var
      W, H: Integer;
    Begin
      GetBitmapSize(Bmp, W, H);
      DisplayDebugImgWindow(W, H);
      DrawBitmapDebugImg(Bmp);
    End;

    var
      Bmp: Integer;
      W, H: Integer;
    begin
      GetClientDimensions(W, H);
      if (DXISetup(GetNativeWindow())) then
      begin
        writeln('DXI setup succeeded');
        Bmp := PtrToBmp(W, H, DXIImagePointer());
        DebugBitmap(Bmp);
        FreeBitmap(Bmp);

        Bmp := PtrToBmp(W, H, DXIDebugPointer());

        ClearBox(Bmp, IntToBox(0, 0, W - 1, H - 1));
        DrawBox(Bmp, IntToBox(0, 0, 100, 100));
        FreeBitmap(Bmp);

      end else
        writeln('Failed to setup DXI.');
    end.

    Results:

    http://i.imgur.com/dQj9eWO.jpg
    Last edited by Brandon; 08-04-2015 at 02:48 AM.
    I am Ggzz..
    Hackintosher

  24. #224
    Join Date
    Oct 2013
    Location
    East Coast USA
    Posts
    770
    Mentioned
    61 Post(s)
    Quoted
    364 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    EDIT: I updated the Visual Studio source to include the below fixes (didn't update the VS .dll modules though..).

    Results:

    http://i.imgur.com/dQj9eWO.jpg
    I duplicated this result, thank you!!

    The size mismatch was targeting the whole window instead of the frame. This fix did the rest.

    Did you mean you checked code in somewhere, because I didn't see anything in github. There was some code you pasted a page back or so that I don't see either.

  25. #225
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by bonsai View Post
    I duplicated this result, thank you!!

    The size mismatch was targeting the whole window instead of the frame. This fix did the rest.

    Did you mean you checked code in somewhere, because I didn't see anything in github. There was some code you pasted a page back or so that I don't see either.
    Glad you got it working.


    https://github.com/Brandon-T/DXI/releases/tag/v0.6

    VisualStudioBuild has the updated source. I will create a branch for VS and check it into it later and maybe update the current code to do the same (allow browser drawing/debugging and mapping via WindowHandle).
    I am Ggzz..
    Hackintosher

Page 9 of 10 FirstFirst ... 78910 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •