Brick icon

datCallback

Brick | PRO | 06/11/17 01:03:22 PM UTC | 0 ⭐ | 235 👁️ | Never ⏰ | []
C++ |

4.05 KB

|

None

|

0 👍

/

0 👎

// OLD        -> NEW        | BYTES       | ADDRESSES
// 0x01000000 -> 0x40000000 | 00 00 00 40 | 4C7A5B + 2, 4C7AC8 + 2, 4C7B70 + 1, 4C7BA6 + 1
// 0x02000000 -> 0x80000000 | 00 00 00 80 | 4C7A90 + 2, 4C7AFB + 2, 4C7B7E + 1, 4C7BB4 + 1
// 0x03000000 -> 0xC0000000 | 00 00 00 C0 | 4C7AB0 + 2, 4C7B2B + 2, 4C7B90 + 1, 4C7BC9 + 1, 4C7B61 + 1
// 0xFCFFFFFF -> 0x3FFFFFFF | FF FF FF 3F | 4C7B5B + 2
 
// InstallPatch("datCallback Fix 1", { 0x00, 0x00, 0x00, 0x40 }, { 0x4C7A5B + 2, 0x4C7AC8 + 2, 0x4C7B70 + 1, 0x4C7BA6 + 1 });
// InstallPatch("datCallback Fix 2", { 0x00, 0x00, 0x00, 0x80 }, { 0x4C7A90 + 2, 0x4C7AFB + 2, 0x4C7B7E + 1, 0x4C7BB4 + 1 });
// InstallPatch("datCallback Fix 3", { 0x00, 0x00, 0x00, 0xC0 }, { 0x4C7AB0 + 2, 0x4C7B2B + 2, 0x4C7B90 + 1, 0x4C7BC9 + 1, 0x4C7B61 + 1 });
// InstallPatch("datCallback Fix 4", { 0xFF, 0xFF, 0xFF, 0x3F }, { 0x4C7B5B + 2 });
 
struct datCallback
{
public:
    class Base;
 
protected:
    enum Flags
    {
        ParamCount0 = 0x40000000,
        ParamCount1 = 0x80000000,
        ParamCount2 = 0xC0000000,
        ParamCountFlags = ParamCount0 | ParamCount1 | ParamCount2
    };
    
    Base* _class;
    unsigned int _callback;
    void* _parameter;
 
    unsigned int _get_flags()
    {
        return _callback & ParamCountFlags;
    }
 
    unsigned int _get_callback()
    {
        return _callback & ~ParamCountFlags;
    }
 
    unsigned int _combine_callback(void* callback, unsigned int flags)
    {
        return reinterpret_cast<unsigned int&>(callback) | flags;
    }
    
public:
    datCallback()
        : _class(NULL)
        , _callback(NULL)
        , _parameter(NULL)
    { }
 
    datCallback(void(*callback)())
        : _class(NULL)
        , _callback(reinterpret_cast<unsigned int&>(callback) | ParamCount0)
        , _parameter(NULL)
    { }
 
    datCallback(void(*callback)(void*), void* param)
        : _class(NULL)
        , _callback(reinterpret_cast<unsigned int&>(callback) | ParamCount1)
        , _parameter(param)
    { }
 
    datCallback(void(*callback)(void*, void*), void* param)
        : _class(NULL)
        , _callback(reinterpret_cast<unsigned int&>(callback) | ParamCount2)
        , _parameter(param)
    { }
 
    datCallback(void(Base::*callback)(), Base* base)
        : _class(base)
        , _callback(reinterpret_cast<unsigned int&>(callback) | ParamCount0)
        , _parameter(NULL)
    { }
 
    datCallback(void(Base::*callback)(void*), Base* base, void* param)
        : _class(base)
        , _callback(reinterpret_cast<unsigned int&>(callback) | ParamCount1)
        , _parameter(param)
    { }
 
    datCallback(void(Base::*callback)(void*, void*), Base* base, void* param)
        : _class(base)
        , _callback(reinterpret_cast<unsigned int&>(callback) | ParamCount2)
        , _parameter(param)
    { }
 
    datCallback(const datCallback& rhs)
        : _class(rhs._class)
        , _callback(rhs._callback)
        , _parameter(rhs._parameter)
    { }
 
    void Call(void* parameter)
    {
        auto callback = _get_callback();
        auto flags    = _get_flags();
 
        if (flags)
        {
            if (_class)
            {
                switch (flags)
                {
                    case ParamCount0: return (_class->*reinterpret_cast<void(Base::*&)()>(callback))();
                    case ParamCount1: return (_class->*reinterpret_cast<void(Base::*&)(void*)>(callback))(_parameter);
                    case ParamCount2: return (_class->*reinterpret_cast<void(Base::*&)(void*, void*)>(callback))(_parameter, parameter);
                }
            }
            else
            {
                switch (flags)
                {
                    case ParamCount0: return reinterpret_cast<void(*&)()>(callback)();
                    case ParamCount1: return reinterpret_cast<void(*&)(void*)>(callback)(_parameter);
                    case ParamCount2: return reinterpret_cast<void(*&)(void*, void*)>(callback)(_parameter, parameter);
                }
            }
        }
    }
};

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎