// 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(callback) | flags; } public: datCallback() : _class(NULL) , _callback(NULL) , _parameter(NULL) { } datCallback(void(*callback)()) : _class(NULL) , _callback(reinterpret_cast(callback) | ParamCount0) , _parameter(NULL) { } datCallback(void(*callback)(void*), void* param) : _class(NULL) , _callback(reinterpret_cast(callback) | ParamCount1) , _parameter(param) { } datCallback(void(*callback)(void*, void*), void* param) : _class(NULL) , _callback(reinterpret_cast(callback) | ParamCount2) , _parameter(param) { } datCallback(void(Base::*callback)(), Base* base) : _class(base) , _callback(reinterpret_cast(callback) | ParamCount0) , _parameter(NULL) { } datCallback(void(Base::*callback)(void*), Base* base, void* param) : _class(base) , _callback(reinterpret_cast(callback) | ParamCount1) , _parameter(param) { } datCallback(void(Base::*callback)(void*, void*), Base* base, void* param) : _class(base) , _callback(reinterpret_cast(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(callback))(); case ParamCount1: return (_class->*reinterpret_cast(callback))(_parameter); case ParamCount2: return (_class->*reinterpret_cast(callback))(_parameter, parameter); } } else { switch (flags) { case ParamCount0: return reinterpret_cast(callback)(); case ParamCount1: return reinterpret_cast(callback)(_parameter); case ParamCount2: return reinterpret_cast(callback)(_parameter, parameter); } } } } };