// 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
0 B
|👍
/👎