From 7fa9f150fb1898d51c0349ecb09eb0ee5323ea68 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 21 Oct 2007 21:47:53 +0000 Subject: [PATCH 02/41] First version of automatic hookman/hookfunc generation functionality + test Currently supports (msvc): all params, ret types: integeral, floating-point Todo: other rettypes (pod/objects, ctors/dtors), gcc support, integration with ISourceHook::AddHook --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40532 --- sourcehook/sourcehook_hookmangen.cpp | 1292 +++++++++++++++ sourcehook/sourcehook_hookmangen.h | 232 +++ sourcehook/sourcehook_hookmangen_x86.h | 1585 ++++++++++++++++++ sourcehook/test/generate.bat | 6 + sourcehook/test/main.cpp | 2 + sourcehook/test/sourcehook_test.h | 1 + sourcehook/test/testevents.h | 26 + sourcehook/test/testhookmangen.cpp | 470 ++++++ sourcehook/test/testhookmangen.h | 2090 ++++++++++++++++++++++++ sourcehook/test/testhookmangen.hxx | 578 +++++++ 10 files changed, 6282 insertions(+) create mode 100644 sourcehook/sourcehook_hookmangen.cpp create mode 100644 sourcehook/sourcehook_hookmangen.h create mode 100644 sourcehook/sourcehook_hookmangen_x86.h create mode 100644 sourcehook/test/generate.bat create mode 100644 sourcehook/test/testhookmangen.cpp create mode 100644 sourcehook/test/testhookmangen.h create mode 100644 sourcehook/test/testhookmangen.hxx diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp new file mode 100644 index 0000000..e00a50d --- /dev/null +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -0,0 +1,1292 @@ +/* ======== SourceHook ======== +* Copyright (C) 2004-2007 Metamod:Source Development Team +* No warranties of any kind +* +* License: zlib/libpng +* +* Author(s): Pavol "PM OnoTo" Marko +* Contributor(s): Borja "faluco" Ferav (many thanks for assitance!) +* David "BAILOPAN" Anderson +* ============================ +*/ + +// recommended literature: +// http://www.cs.umbc.edu/~chang/cs313.s02/stack.shtml +// http://www.angelcode.com/dev/callconv/callconv.html +// http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-1.html + +#include "sourcehook_hookmangen.h" +#include "sourcehook_hookmangen_x86.h" +#include "sh_memory.h" + +// :TODO: test BIG vtable indices + +namespace SourceHook +{ + namespace Impl + { + template + jit_int32_t DownCastPtr(T ptr) + { + return reinterpret_cast(ptr); + } + + jit_uint32_t DownCastSize(size_t size) + { + return static_cast(size); + } + + GenContext::GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr) + : m_Proto(proto), m_VtblOffs(vtbl_offs), m_VtblIdx(vtbl_idx), m_SHPtr(pSHPtr), + m_pHI(NULL), m_HookfuncVfnptr(NULL), m_RegCounter(0) + { + m_pHI = new void*; + m_HookfuncVfnptr = new void*; + m_BuiltPI = new ProtoInfo; + m_BuiltPI_Params = NULL; + m_BuiltPI_Params2 = NULL; + } + + GenContext::~GenContext() + { + Clear(); + delete m_pHI; + delete m_HookfuncVfnptr; + delete m_BuiltPI; + } + + void GenContext::Clear() + { + m_HookFunc.clear(); + m_PubFunc.clear(); + if (m_BuiltPI_Params) + { + delete m_BuiltPI_Params; + m_BuiltPI_Params = NULL; + } + if (m_BuiltPI_Params2) + { + delete m_BuiltPI_Params2; + m_BuiltPI_Params2 = NULL; + } + } + + void GenContext::BuildProtoInfo() + { + m_BuiltPI->convention = m_Proto.GetConvention(); + m_BuiltPI->numOfParams = m_Proto.GetNumOfParams(); + + m_BuiltPI->retPassInfo.size = m_Proto.GetRet().size; + m_BuiltPI->retPassInfo.type = m_Proto.GetRet().type; + m_BuiltPI->retPassInfo.flags = m_Proto.GetRet().flags; + m_BuiltPI->retPassInfo2.pNormalCtor = m_Proto.GetRet().pNormalCtor; + m_BuiltPI->retPassInfo2.pCopyCtor = m_Proto.GetRet().pCopyCtor; + m_BuiltPI->retPassInfo2.pDtor = m_Proto.GetRet().pDtor; + m_BuiltPI->retPassInfo2.pAssignOperator = m_Proto.GetRet().pAssignOperator; + + if (m_BuiltPI_Params) + delete m_BuiltPI_Params; + m_BuiltPI_Params = new PassInfo[m_BuiltPI->numOfParams + 1]; + if (m_BuiltPI_Params2) + delete m_BuiltPI_Params2; + m_BuiltPI_Params2 = new PassInfo::V2Info[m_BuiltPI->numOfParams + 1]; + + m_BuiltPI_Params[0].size = 1; // Version 1 + m_BuiltPI_Params[0].type = 0; + m_BuiltPI_Params[0].flags = 0; + + for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) + { + m_BuiltPI_Params[i+1].size = m_Proto.GetParam(i).size; + m_BuiltPI_Params[i+1].type = m_Proto.GetParam(i).type; + m_BuiltPI_Params[i+1].flags = m_Proto.GetParam(i).flags; + + m_BuiltPI_Params2[i+1].pNormalCtor = m_Proto.GetParam(i).pNormalCtor; + m_BuiltPI_Params2[i+1].pCopyCtor = m_Proto.GetParam(i).pCopyCtor; + m_BuiltPI_Params2[i+1].pDtor = m_Proto.GetParam(i).pDtor; + m_BuiltPI_Params2[i+1].pAssignOperator = m_Proto.GetParam(i).pAssignOperator; + } + + m_BuiltPI->paramsPassInfo = m_BuiltPI_Params; + m_BuiltPI->paramsPassInfo2 = m_BuiltPI_Params2; + } + + jit_int32_t GenContext::GetRealSize(const IntPassInfo &info) + { + if (info.flags & PassInfo::PassFlag_ByRef) + { + return SIZE_PTR; + } + return static_cast(info.size); + } + + // Computes size on the stack + jit_int32_t GenContext::GetStackSize(const IntPassInfo &info) + { + // Align up to 4 byte boundaries + jit_int32_t rs = GetRealSize(info); + if (rs % 4 != 0) + rs = (rs & ~(3)) + 4; + return rs; + } + + jit_int8_t GenContext::NextRegEBX_ECX_EDX() + { + switch ((m_RegCounter++) % 3) + { + case 0: + return REG_EBX; + case 1: + return REG_ECX; + case 2: + default: + m_RegCounter = 0; + return REG_EDX; + } + } + + jit_int32_t GenContext::PushRef(jit_int32_t param_offset, const IntPassInfo &pi) + { + // push [ebp+] + IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_offset); + + return SIZE_PTR; + } + + jit_int32_t GenContext::PushBasic(jit_int32_t param_offset, const IntPassInfo &pi) + { + int reg; + int reg2; + + switch (pi.size) + { + default: + SH_ASSERT(0, ("Unsupported!")); + return 0; + case 1: + reg = NextRegEBX_ECX_EDX(); + //movzx reg, BYTE PTR [ebp+] + //push reg + IA32_Movzx_Reg32_Rm8_DispAuto(&m_HookFunc, reg, REG_EBP, param_offset); + IA32_Push_Reg(&m_HookFunc, reg); + + return 4; + case 2: + reg = NextRegEBX_ECX_EDX(); + //movzx reg, WORD PTR [ebp+] + //push reg + m_HookFunc.write_ubyte(IA32_16BIT_PREFIX); + IA32_Movzx_Reg32_Rm16_DispAuto(&m_HookFunc, reg, REG_EBP, param_offset); + IA32_Push_Reg(&m_HookFunc, reg); + + return 4; + case 4: + reg = NextRegEBX_ECX_EDX(); + //mov reg, DWORD PTR [ebp+] + //push reg + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, reg, REG_EBP, param_offset); + IA32_Push_Reg(&m_HookFunc, reg); + + return 4; + case 8: + reg = NextRegEBX_ECX_EDX(); + reg2 = NextRegEBX_ECX_EDX(); + //mov reg, DWORD PTR [ebp++4] + //mov reg2, DWORD PTR [ebp+] + //push reg + //push reg2 + + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, reg, REG_EBP, param_offset+4); + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, reg2, REG_EBP, param_offset); + IA32_Push_Reg(&m_HookFunc, reg); + IA32_Push_Reg(&m_HookFunc, reg2); + + return 8; + } + } + + jit_int32_t GenContext::PushFloat(jit_int32_t param_offset, const IntPassInfo &pi) + { + switch (pi.size) + { + default: + SH_ASSERT(0, ("Unsupported!")); + return 0; + case 4: + //fld DWORD PTR [ebp+] + //push reg + //fstp DWORD PTR [esp] + IA32_Fld_Mem32_DispAuto(&m_HookFunc, REG_EBP, param_offset); + IA32_Push_Reg(&m_HookFunc, NextRegEBX_ECX_EDX()); + IA32_Fstp_Mem32_ESP(&m_HookFunc); + return 4; + case 8: + //fld QWORD PTR [ebp+] + //sub esp, 8 + //fstp QWORD PTR [esp] + IA32_Fld_Mem64_DispAuto(&m_HookFunc, REG_EBP, param_offset); + IA32_Sub_Rm_Imm8(&m_HookFunc, REG_ESP, 8, MOD_REG); + IA32_Fstp_Mem64_ESP(&m_HookFunc); + return 8; + } + } + + jit_int32_t GenContext::PushObject(jit_int32_t param_offset, const IntPassInfo &pi) + { + // make room on the stack + // sub esp, + IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, GetStackSize(pi), MOD_REG); + + // if there is a copy constructor.. + if (pi.pCopyCtor) + { + // save eax + // push src addr + // this= target addr = esp+12 + // call copy constructor + // restore eax + + IA32_Push_Reg(&m_HookFunc, REG_EAX); + IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_ECX, REG_NOIDX, REG_ESP, NOSCALE, 4); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_offset); + IA32_Push_Reg(&m_HookFunc, REG_EAX); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EDX, DownCastPtr(pi.pCopyCtor)); + IA32_Call_Reg(&m_HookFunc, REG_EDX); + + IA32_Pop_Reg(&m_HookFunc, REG_EAX); + } + else + { + jit_uint32_t dwords = DownCastSize(pi.size) / 4; + jit_uint32_t bytes = DownCastSize(pi.size) % 4; + + // bitwise copy + + //cld + //push edi + //push esi + //lea edi, [esp+8] + //lea esi, [ebp+] + //if dwords + // mov ecx, + // rep movsd + //if bytes + // mov ecx, + // rep movsb + //pop esi + //pop edi + + IA32_Cld(&m_HookFunc); + IA32_Push_Reg(&m_HookFunc, REG_EDI); + IA32_Push_Reg(&m_HookFunc, REG_ESI); + IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_EDI, REG_NOIDX, REG_ESP, NOSCALE, 8); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, param_offset); + if (dwords) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); + IA32_Rep(&m_HookFunc); + IA32_Movsd(&m_HookFunc); + } + if (bytes) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); + IA32_Rep(&m_HookFunc); + IA32_Movsb(&m_HookFunc); + } + IA32_Pop_Reg(&m_HookFunc, REG_ESI); + IA32_Pop_Reg(&m_HookFunc, REG_EDI); + } + + return DownCastSize(pi.size); + } + + // May not touch eax! + jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset) + { + jit_int32_t added_to_stack = 0; + jit_int32_t ret = 0; + + // compute the offset _after_ the last parameter + jit_int32_t cur_offset = param_base_offset; + for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) + { + cur_offset += GetStackSize(m_Proto.GetParam(i)); + } + + // push parameters in reverse order + for (int i = m_Proto.GetNumOfParams() - 1; i >= 0; --i) + { + const IntPassInfo &pi = m_Proto.GetParam(i); + cur_offset -= GetStackSize(pi); + if (pi.flags & PassInfo::PassFlag_ByVal) + { + switch (pi.type) + { + case PassInfo::PassType_Basic: + ret = PushBasic(cur_offset, pi); + break; + case PassInfo::PassType_Float: + ret = PushFloat(cur_offset, pi); + break; + case PassInfo::PassType_Object: + ret = PushObject(cur_offset, pi); + break; + } + } + else if (pi.flags & PassInfo::PassFlag_ByRef) + { + PushRef(cur_offset, pi); + } + else + { + SH_ASSERT(0, ("Unsupported!")); + } + added_to_stack += ret; + } + return added_to_stack; + } + + void GenContext::SaveRetVal(int v_where) + { + // :TODO: assign op support + // :TODO: memory return support + + size_t size = m_Proto.GetRet().size; + if (size == 0) + { + // No return value -> nothing + return; + } + + if (m_Proto.GetRet().type == PassInfo::PassType_Float) + { + if (size == 4) + IA32_Fstp_Mem32_DispAuto(&m_HookFunc, REG_EBP, v_where); + else if (size == 8) + IA32_Fstp_Mem64_DispAuto(&m_HookFunc, REG_EBP, v_where); + } + else if (m_Proto.GetRet().type == PassInfo::PassType_Basic) + { + if (size <= 4) + { + // size <= 4: return in EAX + // We align <4 sizes up to 4 + + + // mov [ebp + v_plugin_ret], eax + IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where); + } + else if (size <= 8) + { + // size <= 4: return in EAX:EDX + // We align 48: return in memory + // :TODO: + // add flag: MSVC_RetInMemory? + } + } + // :TODO: object + } + + void GenContext::ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret) + { + // only for non-void functions! + if (m_Proto.GetRet().size == 0) + return; + + // if (cur_res >= MRES_OVERRIDE) + // *reinterpret_cast(pContext->GetOverrideRetPtr()) = plugin_ret; + + // eax = cur_res + // cmp eax,MRES_OVERRIDE + // jnge thelabel + // pContext->GetOverrideRetPtr() --> overrideretptr in eax + // *eax = plugin_ret + // thelabel: + // + + jitoffs_t tmppos, counter; + + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_cur_res); + + IA32_Cmp_Rm_Imm32(&m_HookFunc, MOD_REG, REG_EAX, MRES_OVERRIDE); + tmppos = IA32_Jump_Cond_Imm8(&m_HookFunc, CC_NGE, 0); + m_HookFunc.start_count(counter); + + // eax = pContext->GetOverrideRetPtr() + // ECX = pContext + // gcc: push ecx + // eax = [ecx] + // eax = [eax + 4] + // call eax + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + + // vtbloffs=0, vtblidx=1 + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 4); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + + // *eax = plugin_ret + if (m_Proto.GetRet().pAssignOperator) + { + // lea edx, [ebp + v_plugin_ret] + // msvc: ecx = eax <-- dest addr + // gcc: push eax <-- dest addr + // push edx <-- src addr + // call it + + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_plugin_ret); +#if SH_COMP == SH_COMP_MSVC + IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); +#elif SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_EAX); +#endif + IA32_Push_Reg(&m_HookFunc, REG_EDX); + + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + else + { + jit_uint32_t dwords = DownCastSize(m_Proto.GetRet().size) / 4; + jit_uint32_t bytes = DownCastSize(m_Proto.GetRet().size) % 4; + + // bitwise copy + + //cld + //push edi + //push esi + //mov edi, eax <-- destination + //lea esi, [ebp+v_plugin_ret] <-- src + //if dwords + // mov ecx, + // rep movsd + //if bytes + // mov ecx, + // rep movsb + //pop esi + //pop edi + + IA32_Cld(&m_HookFunc); + IA32_Push_Reg(&m_HookFunc, REG_EDI); + IA32_Push_Reg(&m_HookFunc, REG_ESI); + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDI, REG_EAX, MOD_REG); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_plugin_ret); + if (dwords) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); + IA32_Rep(&m_HookFunc); + IA32_Movsd(&m_HookFunc); + } + if (bytes) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); + IA32_Rep(&m_HookFunc); + IA32_Movsb(&m_HookFunc); + } + IA32_Pop_Reg(&m_HookFunc, REG_ESI); + IA32_Pop_Reg(&m_HookFunc, REG_EDI); + } + + m_HookFunc.end_count(counter); + m_HookFunc.rewrite(tmppos, static_cast(counter)); + } + + void GenContext::PrepareReturn(int v_status, int v_pContext, int v_retptr) + { + // only for non-void functions! + if (m_Proto.GetRet().size == 0) + return; + + // retptr = status >= MRES_OVERRIDE ? pContext->GetOverrideRetPtr() : pContext->GetOrigRetPtr() + + // OverrideRetPtr: vtblidx = 1 + // OrigRetPtr: vtbldix = 2 + // vtblidx = (status >= MRES_OVERRIDE) ? 1 : 2 + + // + // eax = pContext->GetOverrideRetPtr() + // ECX = pContext + // gcc: push ecx + + // eax = (status < MRES_OVERRIDE) ? 1 : 0 + // xor eax, eax + // cmp [ebp + v_status], MRES_OVERRIDE + // setl al <-- setcc optimization for ternary operators, + + + // lea eax, [4*eax + 0x4] + + // edx = [ecx] + // add edx, eax + // mov edx, [edx] + + // call edx + + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Xor_Reg_Rm(&m_HookFunc, REG_EAX, REG_EAX, MOD_REG); + IA32_Cmp_Rm_Disp8_Imm8(&m_HookFunc, REG_EBP, v_status, MRES_OVERRIDE); + IA32_SetCC_Rm8(&m_HookFunc, REG_EAX, CC_L); + + IA32_Lea_Reg_RegMultImm32(&m_HookFunc, REG_EAX, REG_EAX, SCALE4, 4); + + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_ECX, MOD_MEM_REG); + IA32_Add_Reg_Rm(&m_HookFunc, REG_EDX, REG_EAX, MOD_REG); + + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_EDX, MOD_MEM_REG); + IA32_Call_Reg(&m_HookFunc, REG_EDX); + + IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_retptr); + } + + void GenContext::DoReturn(int v_retptr) + { + size_t size = m_Proto.GetRet().size; + if (!size) + return; + + // :TODO: assign op support + // :TODO: memory return support + + // Get real ret pointer into ecx + // mov ecx, [ebp + v_ret_ptr] + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_retptr); + + if (m_Proto.GetRet().type == PassInfo::PassType_Float) + { + if (size == 4) + IA32_Fld_Mem32(&m_HookFunc, REG_ECX); + else if (size == 8) + IA32_Fld_Mem64(&m_HookFunc, REG_ECX); + } + else if (m_Proto.GetRet().type == PassInfo::PassType_Basic) + { + if (size <= 4) + { + // size <= 4: return in EAX + // We align <4 sizes up to 4 + + + // mov eax, [ecx] + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); + } + else if (size <= 8) + { + // size <= 4: return in EAX:EDX + // We align 48: return in memory + // :TODO: + // add flag: MSVC_RetInMemory? + } + } + // :TODO: object + } + + void GenContext::GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, + int v_pContext, int base_param_offset, int v_plugin_ret) + { + jitoffs_t counter, tmppos; + jitoffs_t counter2, tmppos2; + + jitoffs_t loop_begin_counter; + + // prev_res = MRES_IGNORED + IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_prev_res); + + m_HookFunc.start_count(loop_begin_counter); + + // eax = pContext->GetNext() + // ECX = pContext + // gcc: push ecx + // eax = [ecx] + // eax = [eax] + // call eax + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + + // vtbloffs=0, vtblidx=0 + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_EAX, MOD_MEM_REG); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + // quit on zero + // test eax, eax + // jz exit + IA32_Test_Rm_Reg(&m_HookFunc, REG_EAX, REG_EAX, MOD_REG); + tmppos = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_Z, 0); + m_HookFunc.start_count(counter); + + // prev_res = MRES_IGNORED + IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_cur_res); + + // iter->call() + // push params + // ecx = eax + // gcc: push ecx + // eax = [ecx] + // eax = [eax+2*SIZE_PTR] + // call eax + jit_int32_t gcc_clean_bytes = PushParams(base_param_offset); + + IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 2*SIZE_PTR); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + SaveRetVal(v_plugin_ret); + + // cleanup +#if SH_COMP == SH_COMP_GCC + // params + thisptr + IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG); +#endif + + // process meta return: + // prev_res = cur_res + // if (cur_res > status) status = cur_res; + // + // eax = cur_res + // edx = status + // prev_res = eax + // cmp eax,edx + // jng thelabel + // status = eax + // thelabel: + // + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_cur_res); + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EDX, REG_EBP, v_status); + IA32_Mov_Rm_Reg_Disp8(&m_HookFunc, REG_EBP, REG_EAX, v_prev_res); + + IA32_Cmp_Reg_Rm(&m_HookFunc, REG_EAX, REG_EDX, MOD_REG); + tmppos2 = IA32_Jump_Cond_Imm8(&m_HookFunc, CC_NG, 0); + m_HookFunc.start_count(counter2); + + IA32_Mov_Rm_Reg_Disp8(&m_HookFunc, REG_EBP, REG_EAX, v_status); + + m_HookFunc.end_count(counter2); + m_HookFunc.rewrite(tmppos2, static_cast(counter2)); + + // process retval for non-void functions + ProcessPluginRetVal(v_cur_res, v_pContext, v_plugin_ret); + + // jump back to loop begin + tmppos2 = IA32_Jump_Imm32(&m_HookFunc, 0); + m_HookFunc.end_count(loop_begin_counter); + m_HookFunc.rewrite(tmppos2, -static_cast(loop_begin_counter)); + + m_HookFunc.end_count(counter); + m_HookFunc.rewrite(tmppos, static_cast(counter)); + } + + short GenContext::GetParamsStackSize() + { + short acc = 0; + for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) + { + acc += GetStackSize(m_Proto.GetParam(i)); + } + return acc; + } + + void GenContext::GenerateCallOrig(int v_status, int v_pContext, + int param_base_offs, int v_this, int v_vfnptr_origentry, int v_orig_ret, int v_override_ret) + { + jitoffs_t counter, tmppos; + jitoffs_t counter2, tmppos2; + jitoffs_t counter3, tmppos3; + + // if (status != MRES_SUPERCEDE && pConteext->ShouldCallOrig()) + // *v_orig_ret = orig_call() + // else + // *v_orig_ret = *v_override_ret + + // mov eax, status + // cmp eax, MRES_SUPERCEDE + // je dont_call + // call pContext->ShouldCallOrig() + // test al, al !! important: al, not eax! bool is only stored in the LSbyte + // jz dont_call + // + // orig_call() + // SaveRet(v_orig_ret) + // jmp skip_dont_call: + // + // dont_call: + // *v_orig_ret = *v_override_ret + // skip_dont_call: + + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_status); + IA32_Cmp_Rm_Imm32(&m_HookFunc, MOD_REG, REG_EAX, MRES_SUPERCEDE); + + tmppos = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_E, 0); + m_HookFunc.start_count(counter); + + // eax = pContext->ShouldCallOrig() + // ECX = pContext + // gcc: push ecx + // eax = [ecx] + // eax = [eax + 3*PTR_SIZE] + // call eax + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + + // vtbloffs=0, vtblidx=3 + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); + IA32_Mov_Reg_Rm_Disp8(&m_HookFunc, REG_EAX, REG_EAX, 3*SIZE_PTR); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + IA32_Test_Rm_Reg8(&m_HookFunc, REG_EAX, REG_EAX, MOD_REG); + tmppos2 = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_Z, 0); + m_HookFunc.start_count(counter2); + + // push params + jit_int32_t gcc_clean_bytes = PushParams(param_base_offs); + + // thisptr + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); +#if SH_COMP == SH_COMP_GCC + // on gcc/mingw, this is the first parameter + IA32_Push_Reg(&m_HookFunc, REG_ECX); + // on msvc, simply leave it in ecx +#endif + + // call + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_vfnptr_origentry); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + // cleanup +#if SH_COMP == SH_COMP_GCC + // params + thisptr + IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG); +#endif + + // save retval + SaveRetVal(v_orig_ret); + + // Skip don't call variant + tmppos3 = IA32_Jump_Imm32(&m_HookFunc, 0); + m_HookFunc.start_count(counter3); + + + // don't call: + m_HookFunc.end_count(counter); + m_HookFunc.rewrite(tmppos, static_cast(counter)); + + m_HookFunc.end_count(counter2); + m_HookFunc.rewrite(tmppos2, static_cast(counter2)); + + // *v_orig_ret = *v_override_ret + if (m_Proto.GetRet().pAssignOperator) + { + // lea edx, [ebp + v_override_ret] <-- src addr + // lea ecx, [ebp + v_orig_ret] <-- dest addr + // gcc: push ecx + // push edx <-- src addr + // call it + + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_override_ret); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Push_Reg(&m_HookFunc, REG_EDX); + + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + else + { + jit_uint32_t dwords = DownCastSize(m_Proto.GetRet().size) / 4; + jit_uint32_t bytes = DownCastSize(m_Proto.GetRet().size) % 4; + + // bitwise copy + + //cld + //push edi + //push esi + //lea edi, [ebp+v_orig_ret] <-- destination + //lea esi, [ebp+v_override_ret] <-- src + //if dwords + // mov ecx, + // rep movsd + //if bytes + // mov ecx, + // rep movsb + //pop esi + //pop edi + + IA32_Cld(&m_HookFunc); + IA32_Push_Reg(&m_HookFunc, REG_EDI); + IA32_Push_Reg(&m_HookFunc, REG_ESI); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, v_orig_ret); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_override_ret); + if (dwords) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); + IA32_Rep(&m_HookFunc); + IA32_Movsd(&m_HookFunc); + } + if (bytes) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); + IA32_Rep(&m_HookFunc); + IA32_Movsb(&m_HookFunc); + } + IA32_Pop_Reg(&m_HookFunc, REG_ESI); + IA32_Pop_Reg(&m_HookFunc, REG_EDI); + } + + // skip don't call label target: + m_HookFunc.end_count(counter3); + m_HookFunc.rewrite(tmppos3, static_cast(counter3)); + } + + // Sets *v_pContext to return value + void GenContext::CallSetupHookLoop(int v_orig_ret, int v_override_ret, + int v_cur_res, int v_prev_res, int v_status, int v_vfnptr_origentry, + int v_this, int v_pContext) + { + // call shptr->SetupHookLoop(ms_HI, ourvfnptr, reinterpret_cast(this), + // &vfnptr_origentry, &status, &prev_res, &cur_res, &orig_ret, &override_ret); + // The last two params are null for void funcs. + + if (m_Proto.GetRet().size == 0) + { + // void + IA32_Push_Imm8(&m_HookFunc, 0); // orig_ret + IA32_Push_Imm8(&m_HookFunc, 0); // override_ret + } + else + { + // orig_ret and override_ret + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, v_override_ret); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_orig_ret); + IA32_Push_Reg(&m_HookFunc, REG_EAX); + IA32_Push_Reg(&m_HookFunc, REG_EDX); + } + + // cur_res and prev_res + IA32_Lea_DispRegImm8(&m_HookFunc, REG_EAX, REG_EBP, v_cur_res); + IA32_Lea_DispRegImm8(&m_HookFunc, REG_EDX, REG_EBP, v_prev_res); + IA32_Push_Reg(&m_HookFunc, REG_EAX); + IA32_Push_Reg(&m_HookFunc, REG_EDX); + + // status and vfnptr_origentry + IA32_Lea_DispRegImm8(&m_HookFunc, REG_EAX, REG_EBP, v_status); + IA32_Lea_DispRegImm8(&m_HookFunc, REG_EDX, REG_EBP, v_vfnptr_origentry); + IA32_Push_Reg(&m_HookFunc, REG_EAX); + IA32_Push_Reg(&m_HookFunc, REG_EDX); + + // this + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_this); + IA32_Push_Reg(&m_HookFunc, REG_EAX); + + // our vfn ptr + // *(this + vtbloffs) + SIZE_PTR*vtblidx + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); // get this into ecx (gcc!) + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_ECX, m_VtblOffs); + IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_EAX, m_VtblIdx * SIZE_PTR, MOD_REG); + IA32_Push_Reg(&m_HookFunc, REG_EAX); + + // *m_pHI + IA32_Mov_Rm_Imm32(&m_HookFunc, REG_EDX, DownCastPtr(m_pHI), MOD_REG); + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_EDX, MOD_MEM_REG); + IA32_Push_Reg(&m_HookFunc, REG_EAX); + + // set up thisptr +#if SH_COMP == SH_COMP_GCC + // on gcc/mingw, this is the first parameter + IA32_Push_Imm32(&m_HookFunc, DownCastPtr(m_SHPtr)); +#elif SH_COMP == SH_COMP_MSVC + // on msvc, it's ecx + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, DownCastPtr(m_SHPtr)); +#endif + + // call the function. vtbloffs = 0, vtblidx = 19 + // get vtptr into edx -- we know shptr on jit time -> dereference it here! + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, + (*reinterpret_cast(m_SHPtr))[19]); + + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + // on gcc/mingw, we have to clean up after the call +#if SH_COMP == SH_COMP_GCC + // 9 params + hidden thisptr param + IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 10*SIZE_PTR, MOD_REG); +#endif + + // store return value + IA32_Mov_Rm_Reg_Disp8(&m_HookFunc, REG_EBP, REG_EAX, v_pContext); + } + + void GenContext::CallEndContext(int v_pContext) + { + // call endcontext: + // shptr->EndContext(pContex) + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_pContext); + IA32_Push_Reg(&m_HookFunc, REG_EAX); + + // thisptr +#if SH_COMP == SH_COMP_GCC + // on gcc/mingw, this is the first parameter + IA32_Push_Imm32(&m_HookFunc, DownCastPtr(m_SHPtr)); +#elif SH_COMP == SH_COMP_MSVC + // on msvc, it's ecx + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, DownCastPtr(m_SHPtr)); +#endif + + // get vtptr into edx -- we know shptr on jit time -> dereference it here! + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, + (*reinterpret_cast(m_SHPtr))[20]); + + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + // on gcc/mingw, we have to clean up after the call +#if SH_COMP == SH_COMP_GCC + // 1 param + hidden thisptr param + IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG); +#endif + } + + unsigned char * GenContext::GenerateHookFunc() + { + // prologue + IA32_Push_Reg(&m_HookFunc, REG_EBP); + IA32_Push_Reg(&m_HookFunc, REG_EBX); + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EBP, REG_ESP, MOD_REG); + + // on msvc, save thisptr +#if SH_COMP == SH_COMP_MSVC + const jit_int8_t v_this = -4; + const int addstackoffset = -4; + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#elif SH_COMP == SH_COMP_GCC + const jit_int8_t v_this = 8; // first param + const int addstackoffset = 0; +#endif + + + // ********************** stack frame ********************** + // MSVC + // second param (gcc: first real param) ebp + 16 + // first param (gcc: thisptr) ebp + 12 + // ret address: ebp + 8 + // caller's ebp ebp + 4 + // saved ebx ebp + // MSVC ONLY: current this ebp - 4 + // void *vfnptr_origentry ebp - 4 -4 + // META_RES status = MRES_IGNORED ebp - 8 -4 + // META_RES prev_res ebp - 12 -4 + // META_RES cur_res ebp - 16 -4 + // IMyDelegate *iter ebp - 20 -4 + // IHookContext *pContext ebp - 24 -4 + // == 3 ptrs + 3 enums = 24 bytes + // + // non-void: add: + // my_rettype *ret_ptr ebp - 28 -4 + // my_rettype orig_ret ebp - 28 - sizeof(my_rettype) -4 + // my_rettype override_ret ebp - 28 - sizeof(my_rettype)*2 -4 + // my_rettype plugin_ret ebp - 28 - sizeof(my_rettype)*3 -4 + // == + 3 * sizeof(my_rettype) bytes + + const jit_int8_t v_vfnptr_origentry = -4 + addstackoffset; + const jit_int8_t v_status = -8 + addstackoffset; + const jit_int8_t v_prev_res = -12 + addstackoffset; + const jit_int8_t v_cur_res = -16 + addstackoffset; + const jit_int8_t v_iter = -20 + addstackoffset; + const jit_int8_t v_pContext = -24 + addstackoffset; + +#if SH_COMP == SH_COMP_GCC + const jit_int32_t param_base_offs = 16; +#elif SH_COMP == SH_COMP_MSVC + const jit_int32_t param_base_offs = 12; +#endif + + jit_int32_t v_ret_ptr = -28 + addstackoffset; + jit_int32_t v_orig_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 1; + jit_int32_t v_override_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 2; + jit_int32_t v_plugin_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 3; + + // Hash for temporary storage for byval params with copy constructors + // (param, offset into stack) + short usedStackBytes = 3*SIZE_MWORD + 3*SIZE_PTR + // vfnptr_origentry, status, prev_res, cur_res, iter, pContext + 3 * GetStackSize(m_Proto.GetRet()) + (m_Proto.GetRet().size == 0 ? 0 : SIZE_PTR) // ret_ptr, orig_ret, override_ret, plugin_ret + - addstackoffset; // msvc: current thisptr + + IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, usedStackBytes, MOD_REG); + + // init status localvar + IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_status); + + // Call constructors for ret vars if required + if(m_Proto.GetRet().pNormalCtor) + { + // :TODO: Gcc version + + // orig_reg + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + // override_reg + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + // plugin_ret + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + + // ********************** SetupHookLoop ********************** + CallSetupHookLoop(v_orig_ret, v_override_ret, v_cur_res, v_prev_res, v_status, v_vfnptr_origentry, + v_this, v_pContext); + + // ********************** call pre hooks ********************** + GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, + v_plugin_ret); + + // ********************** call orig func ********************** + GenerateCallOrig(v_status, v_pContext, param_base_offs, v_this, v_vfnptr_origentry, v_orig_ret, + v_override_ret); + + // ********************** call post hooks ********************** + GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, + v_plugin_ret); + + // ********************** end context and return ********************** + + PrepareReturn(v_status, v_pContext, v_ret_ptr); + + CallEndContext(v_pContext); + + // Call destructors of byval object params which have a destructor + jit_int32_t cur_param_pos = param_base_offs; + for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) + { + const IntPassInfo &pi = m_Proto.GetParam(i); + if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ODtor) && + (pi.flags & PassInfo::PassFlag_ByVal)) + { + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, cur_param_pos); + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + cur_param_pos += GetStackSize(pi); + } + + DoReturn(v_ret_ptr); + + // !! :TODO: Call destructors of orig_ret/ ... + + // epilogue + IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESP, REG_EBP, MOD_REG); + IA32_Pop_Reg(&m_HookFunc, REG_EBX); + IA32_Pop_Reg(&m_HookFunc, REG_EBP); + IA32_Return_Popstack(&m_HookFunc, GetParamsStackSize()); + + // Store pointer for later use + // m_HookfuncVfnPtr is a pointer to a void* because SH expects a pointer + // into the hookman's vtable + *m_HookfuncVfnptr = reinterpret_cast(m_HookFunc.GetData()); + return m_HookFunc.GetData(); + } + + // Pre-condition: GenerateHookFunc() has been called! + unsigned char * GenContext::GeneratePubFunc() + { + jitoffs_t counter, tmppos; + + // The pubfunc is a static cdecl function. + // C Code: + // int HookManPubFunc( + // bool store, ebp + 8 + // IHookManagerInfo *hi ebp + 12 + // ) + // { + // if (store) + // *m_pHI = hi; + // if (hi) + // hi->SetInfo(HOOKMAN_VERSION, m_VtblOffs, m_VtblIdx, m_Proto.GetProto(), m_HookfuncVfnptr) + // } + + // prologue + IA32_Push_Reg(&m_PubFunc, REG_EBP); + IA32_Mov_Reg_Rm(&m_PubFunc, REG_EBP, REG_ESP, MOD_REG); + + + // save store in eax, hi in ecx + IA32_Movzx_Reg32_Rm8_Disp8(&m_PubFunc, REG_EAX, REG_EBP, 8); + IA32_Mov_Reg_Rm_DispAuto(&m_PubFunc, REG_ECX, REG_EBP, 12); + + // Check for store == 0 + IA32_Test_Rm_Reg8(&m_PubFunc, REG_EAX, REG_EAX, MOD_REG); + tmppos = IA32_Jump_Cond_Imm8(&m_PubFunc, CC_Z, 0); + m_PubFunc.start_count(counter); + + // nonzero -> store hi + IA32_Mov_Rm_Imm32(&m_PubFunc, REG_EDX, DownCastPtr(m_pHI), MOD_REG); + IA32_Mov_Rm_Reg(&m_PubFunc, REG_EDX, REG_ECX, MOD_MEM_REG); + + // zero + m_PubFunc.end_count(counter); + m_PubFunc.rewrite(tmppos, static_cast(counter)); + + // check for hi == 0 + IA32_Test_Rm_Reg(&m_PubFunc, REG_ECX, REG_ECX, MOD_REG); + tmppos = IA32_Jump_Cond_Imm8(&m_PubFunc, CC_Z, 0); + m_PubFunc.start_count(counter); + + // nonzero -> call vfunc + // push params in reverse order + IA32_Push_Imm32(&m_PubFunc, DownCastPtr(m_HookfuncVfnptr)); + IA32_Push_Imm32(&m_PubFunc, DownCastPtr(m_BuiltPI)); + IA32_Push_Imm32(&m_PubFunc, m_VtblIdx); + IA32_Push_Imm32(&m_PubFunc, m_VtblOffs); + IA32_Push_Imm32(&m_PubFunc, SH_HOOKMAN_VERSION); + + // hi == this is in ecx + // on gcc/mingw, ecx is the first parameter +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_PubFunc, REG_ECX); +#endif + + // call the function. vtbloffs = 0, vtblidx = 0 + // get vtptr into edx + IA32_Mov_Reg_Rm(&m_PubFunc, REG_EDX, REG_ECX, MOD_MEM_REG); + // get funcptr into eax + IA32_Mov_Reg_Rm(&m_PubFunc, REG_EAX, REG_EDX, MOD_MEM_REG); + + IA32_Call_Reg(&m_PubFunc, REG_EAX); + + // on gcc/mingw, we have to clean up after the call +#if SH_COMP == SH_COMP_GCC + // 5 params + hidden thisptr param + IA32_Add_Rm_Imm8(&m_PubFunc, REG_ESP, 6*SIZE_MWORD, MOD_REG); +#endif + + // zero + m_PubFunc.end_count(counter); + m_PubFunc.rewrite(tmppos, static_cast(counter)); + + // return value + IA32_Xor_Reg_Rm(&m_PubFunc, REG_EAX, REG_EAX, MOD_REG); + + // epilogue + IA32_Mov_Reg_Rm(&m_PubFunc, REG_ESP, REG_EBP, MOD_REG); + IA32_Pop_Reg(&m_PubFunc, REG_EBP); + IA32_Return(&m_PubFunc); + + SetMemAccess(reinterpret_cast(m_PubFunc.GetData()), m_PubFunc.GetSize(), + SH_MEM_READ | SH_MEM_EXEC); + + return m_PubFunc; + } + + bool GenContext::PassInfoSupported(const IntPassInfo &pi, bool is_ret) + { + if (pi.type != PassInfo::PassType_Basic && + pi.type != PassInfo::PassType_Float && + pi.type != PassInfo::PassType_Object) + { + return false; + } + + if (pi.type == PassInfo::PassType_Object && + (pi.flags & PassInfo::PassFlag_ByVal)) + { + if ((pi.flags & PassInfo::PassFlag_CCtor) && !pi.pNormalCtor) + return false; + + if ((pi.flags & PassInfo::PassFlag_ODtor) && !pi.pDtor) + return false; + + // only care for assignop and normalctor for return types + if (is_ret && (pi.flags & PassInfo::PassFlag_AssignOp) && !pi.pAssignOperator) + return false; + + if (is_ret && (pi.flags & PassInfo::PassFlag_CCtor) && !pi.pNormalCtor) + return false; + } + + if ((pi.flags & (PassInfo::PassFlag_ByVal | PassInfo::PassFlag_ByRef)) == 0) + { + return false; // Neither byval nor byref! + } + return true; + } + + HookManagerPubFunc GenContext::Generate() + { + Clear(); + + // Check conditions: + // -1) good proto version + // 0) we don't support unknown passtypes, convention, ... + // 1) we don't support functions which return objects by value or take parameters by value + // that have a constructor, a destructor or an overloaded assignment op + // (we wouldn't know how to call it!) + + if (m_Proto.GetVersion() < 1) + { + return NULL; + } + + if (m_Proto.GetConvention() != ProtoInfo::CallConv_Cdecl && + m_Proto.GetConvention() != ProtoInfo::CallConv_ThisCall) + { + return NULL; + } + + + if (m_Proto.GetRet().size != 0 && !PassInfoSupported(m_Proto.GetRet(), true)) + { + return NULL; + } + + for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) + { + if (!PassInfoSupported(m_Proto.GetParam(i), false)) + return NULL; + } + + BuildProtoInfo(); + GenerateHookFunc(); + return reinterpret_cast(GeneratePubFunc()); + } + } +} \ No newline at end of file diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h new file mode 100644 index 0000000..4bfeea7 --- /dev/null +++ b/sourcehook/sourcehook_hookmangen.h @@ -0,0 +1,232 @@ +/* ======== SourceHook ======== +* Copyright (C) 2004-2007 Metamod:Source Development Team +* No warranties of any kind +* +* License: zlib/libpng +* +* Author(s): Pavol "PM OnoTo" Marko +* ============================ +*/ + +#ifndef __SOURCEHOOK_HOOKMANGEN_H__ +#define __SOURCEHOOK_HOOKMANGEN_H__ + +#include "sourcehook_impl.h" +#include "windows.h" + +namespace SourceHook +{ + namespace Impl + { + + // Code gen stuff +#if defined HAVE_STDINT_H && !defined WIN32 +#include + typedef int8_t jit_int8_t; + typedef uint8_t jit_uint8_t; + typedef int32_t jit_int32_t; + typedef uint32_t jit_uint32_t; + typedef int64_t jit_int64_t; + typedef uint64_t jit_uint64_t; +#elif defined WIN32 + typedef __int8 jit_int8_t; + typedef unsigned __int8 jit_uint8_t; + typedef __int32 jit_int32_t; + typedef unsigned __int32 jit_uint32_t; + typedef __int64 jit_int64_t; + typedef unsigned __int64 jit_uint64_t; +#endif + typedef unsigned int jitoffs_t; + typedef signed int jitrel_t; + + + class GenBuffer + { + unsigned char *m_pData; + jitoffs_t m_Size; + jitoffs_t m_AllocatedSize; + + public: + GenBuffer() : m_pData(NULL), m_Size(0), m_AllocatedSize(0) + { + } + ~GenBuffer() + { + clear(); + } + jitoffs_t GetSize() + { + return m_Size; + } + unsigned char *GetData() + { + return m_pData; + } + + template void push(PT what) + { + push((const unsigned char *)&what, sizeof(PT)); + } + + void push(const unsigned char *data, jitoffs_t size) + { + jitoffs_t newSize = m_Size + size; + if (newSize > m_AllocatedSize) + { + m_AllocatedSize = newSize > m_AllocatedSize*2 ? newSize : m_AllocatedSize*2; + if (m_AllocatedSize < 64) + m_AllocatedSize = 64; + + unsigned char *newBuf; + try + { + //!!!! Better use of pages! or something! + newBuf = reinterpret_cast(VirtualAlloc(NULL, m_AllocatedSize, MEM_COMMIT, PAGE_READWRITE)); + } + catch (std::bad_alloc) + { + newBuf = NULL; + } + if (!newBuf) + { + SH_ASSERT(0, ("bad_alloc: couldn't allocate 0x%08X bytes of memory\n", m_AllocatedSize)); + return; + } + memcpy((void*)newBuf, (const void*)m_pData, m_Size); + if (m_pData) + VirtualFree(m_pData, 0, MEM_RELEASE); + m_pData = newBuf; + } + memcpy((void*)(m_pData + m_Size), (const void*)data, size); + m_Size = newSize; + } + + template void rewrite(jitoffs_t offset, PT what) + { + rewrite(offset, (const unsigned char *)&what, sizeof(PT)); + } + + void rewrite(jitoffs_t offset, const unsigned char *data, jitoffs_t size) + { + SH_ASSERT(offset + size <= m_AllocatedSize, ("rewrite too far")); + + memcpy((void*)(m_pData + offset), (const void*)data, size); + } + + void clear() + { + if (m_pData) + VirtualFree(m_pData, 0, MEM_RELEASE); + m_pData = NULL; + m_Size = 0; + m_AllocatedSize = 0; + } + + operator unsigned char *() + { + return GetData(); + } + + void write_ubyte(jit_uint8_t x) { push(x); } + void write_byte(jit_uint8_t x) { push(x); } + + void write_ushort(unsigned short x) { push(x); } + void write_short(signed short x) { push(x); } + + void write_uint32(jit_uint32_t x) { push(x); } + void write_int32(jit_uint32_t x) { push(x); } + + jitoffs_t get_outputpos() + { + return m_Size; + } + + void start_count(jitoffs_t &offs) + { + offs = get_outputpos(); + } + void end_count(jitoffs_t &offs) + { + offs = get_outputpos() - offs; + } + // :TODO: real buffer which uses virtualalloc correctly + }; + + class GenContext + { + const static int SIZE_MWORD = 4; + const static int SIZE_PTR = sizeof(void*); + + CProto m_Proto; + int m_VtblOffs; + int m_VtblIdx; + ISourceHook *m_SHPtr; + + GenBuffer m_HookFunc; + GenBuffer m_PubFunc; + + ProtoInfo *m_BuiltPI; + PassInfo *m_BuiltPI_Params; + PassInfo::V2Info *m_BuiltPI_Params2; + + // For hookfunc + void **m_pHI; + void **m_HookfuncVfnptr; + + // Level 3 - Helpers + int m_RegCounter; + jit_int8_t NextRegEBX_ECX_EDX(); + + // size info + jit_int32_t GetRealSize(const IntPassInfo &info); + jit_int32_t GetStackSize(const IntPassInfo &info); + short GetParamsStackSize(); // sum(GetStackSize(i), 0 <= i < numOfParams) + + + // Param push + jit_int32_t PushParams(jit_int32_t param_base_offset); + jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi); + jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi); + jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi); + jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi); + + // Ret val processing + void SaveRetVal(int v_where); + void ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret); + + void PrepareReturn(int v_status, int v_pContext, int v_retptr); + void DoReturn(int v_retptr); + + // Call hooks + void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, + int v_pContext, int base_param_offset, int v_plugin_ret); + + // Call orig + void GenerateCallOrig(int v_status, int v_pContext, + int param_base_offs, int v_this, int v_vfnptr_origentry, int v_orig_ret, int v_override_ret); + + // Hook loop + void CallSetupHookLoop(int v_orig_ret, int v_override_ret, + int v_cur_res, int v_prev_res, int v_status, int v_vnfptr_origentry, + int v_this, int v_pContext); + + void CallEndContext(int v_pContext); + + // Level 2 -> called from Generate() + bool PassInfoSupported(const IntPassInfo &pi, bool is_ret); + void Clear(); + void BuildProtoInfo(); + unsigned char *GenerateHookFunc(); + unsigned char *GeneratePubFunc(); + public: + // Level 1 -> Public interface + GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr); + ~GenContext(); + + HookManagerPubFunc Generate(); + }; + } +} + + +#endif \ No newline at end of file diff --git a/sourcehook/sourcehook_hookmangen_x86.h b/sourcehook/sourcehook_hookmangen_x86.h new file mode 100644 index 0000000..5a05acc --- /dev/null +++ b/sourcehook/sourcehook_hookmangen_x86.h @@ -0,0 +1,1585 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourcePawn JIT SDK + * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + */ + +#ifndef __SOURCEHOOK_HOOKMANGEN_X86_H__ +#define __SOURCEHOOK_HOOKMANGEN_X86_H__ + +#include + +//MOD R/M +#define MOD_MEM_REG 0 +#define MOD_DISP8 1 +#define MOD_DISP32 2 +#define MOD_REG 3 + +//SIB +#define NOSCALE 0 +#define SCALE2 1 +#define SCALE4 2 +#define SCALE8 3 + +//Register codes +#define REG_EAX 0 +#define REG_ECX 1 +#define REG_EDX 2 +#define REG_EBX 3 +#define REG_ESP 4 +#define REG_SIB 4 +#define REG_NOIDX 4 +#define REG_IMM_BASE 5 +#define REG_EBP 5 +#define REG_ESI 6 +#define REG_EDI 7 + +#define IA32_16BIT_PREFIX 0x66 + +//condition codes (for example, Jcc opcodes) +#define CC_B 0x2 +#define CC_NAE CC_B +#define CC_NB 0x3 +#define CC_AE CC_NB +#define CC_E 0x4 +#define CC_Z CC_E +#define CC_NE 0x5 +#define CC_NZ CC_NE +#define CC_NA 0x6 +#define CC_BE CC_NA +#define CC_A 0x7 +#define CC_NBE CC_A +#define CC_L 0xC +#define CC_NGE CC_L +#define CC_NL 0xD +#define CC_GE CC_NL +#define CC_NG 0xE +#define CC_LE CC_NG +#define CC_G 0xF +#define CC_NLE CC_G + +//Opcodes with encoding information +#define IA32_XOR_RM_REG 0x31 // encoding is /r +#define IA32_XOR_REG_RM 0x33 // encoding is /r +#define IA32_XOR_EAX_IMM32 0x35 // encoding is /r +#define IA32_XOR_RM_IMM32 0x81 // encoding is /6 +#define IA32_XOR_RM_IMM8 0x83 // encoding is /6 +#define IA32_ADD_RM_REG 0x01 // encoding is /r +#define IA32_ADD_REG_RM 0x03 // encoding is /r +#define IA32_ADD_RM_IMM32 0x81 // encoding is /0 +#define IA32_ADD_RM_IMM8 0x83 // encoding is /0 +#define IA32_ADD_EAX_IMM32 0x05 // no extra encoding +#define IA32_SUB_RM_REG 0x29 // encoding is /r +#define IA32_SUB_REG_RM 0x2B // encoding is /r +#define IA32_SUB_RM_IMM8 0x83 // encoding is /5 +#define IA32_SUB_RM_IMM32 0x81 // encoding is /5 +#define IA32_SBB_REG_RM 0x1B // encoding is /r +#define IA32_SBB_RM_IMM8 0x83 // encoding is +#define IA32_JMP_IMM32 0xE9 // encoding is imm32 +#define IA32_JMP_IMM8 0xEB // encoding is imm8 +#define IA32_JMP_RM 0xFF // encoding is /4 +#define IA32_CALL_IMM32 0xE8 // relative call, +#define IA32_CALL_RM 0xFF // encoding is /2 +#define IA32_MOV_REG_IMM 0xB8 // encoding is +r +#define IA32_MOV_RM8_REG 0x88 // encoding is /r +#define IA32_MOV_RM_REG 0x89 // encoding is /r +#define IA32_MOV_REG_RM 0x8B // encoding is /r +#define IA32_MOV_REG8_RM8 0x8A // encoding is /r +#define IA32_MOV_RM8_REG8 0x88 // encoding is /r +#define IA32_MOV_RM_IMM32 0xC7 // encoding is /0 +#define IA32_CMP_RM_IMM32 0x81 // encoding is /7 +#define IA32_CMP_RM_IMM8 0x83 // encoding is /7 +#define IA32_CMP_AL_IMM32 0x3C // no extra encoding +#define IA32_CMP_EAX_IMM32 0x3D // no extra encoding +#define IA32_CMP_RM_REG 0x39 // encoding is /r +#define IA32_CMP_REG_RM 0x3B // encoding is /r +#define IA32_CMPSB 0xA6 // no extra encoding +#define IA32_TEST_RM_REG8 0x84 // encoding is /r +#define IA32_TEST_RM_REG 0x85 // encoding is /r +#define IA32_JCC_IMM 0x70 // encoding is +cc +#define IA32_JCC_IMM32_1 0x0F // opcode part 1 +#define IA32_JCC_IMM32_2 0x80 // encoding is +cc +#define IA32_RET 0xC3 // no extra encoding +#define IA32_RETN 0xC2 // encoding is +#define IA32_NEG_RM 0xF7 // encoding is /3 +#define IA32_INC_REG 0x40 // encoding is +r +#define IA32_INC_RM 0xFF // encoding is /0 +#define IA32_DEC_REG 0x48 // encoding is +r +#define IA32_DEC_RM 0xFF // encoding is /1 +#define IA32_OR_REG_RM 0x0B // encoding is /r +#define IA32_AND_REG_RM 0x23 // encoding is /r +#define IA32_AND_EAX_IMM32 0x25 // encoding is +#define IA32_AND_RM_IMM32 0x81 // encoding is /4 +#define IA32_AND_RM_IMM8 0x83 // encoding is /4 +#define IA32_NOT_RM 0xF7 // encoding is /2 +#define IA32_DIV_RM 0xF7 // encoding is /6 +#define IA32_MUL_RM 0xF7 // encoding is /4 +#define IA32_IDIV_RM 0xF7 // encoding is /7 +#define IA32_IMUL_RM 0xF7 // encoding is /5 +#define IA32_IMUL_REG_IMM32 0x69 // encoding is /r +#define IA32_IMUL_REG_IMM8 0x6B // encoding is /r +#define IA32_IMUL_REG_RM_1 0x0F // encoding is _2 +#define IA32_IMUL_REG_RM_2 0xAF // encoding is /r +#define IA32_SHR_RM_IMM8 0xC1 // encoding is /5 +#define IA32_SHR_RM_1 0xD1 // encoding is /5 +#define IA32_SHL_RM_IMM8 0xC1 // encoding is /4 +#define IA32_SHL_RM_1 0xD1 // encoding is /4 +#define IA32_SAR_RM_CL 0xD3 // encoding is /7 +#define IA32_SAR_RM_1 0xD1 // encoding is /7 +#define IA32_SHR_RM_CL 0xD3 // encoding is /5 +#define IA32_SHL_RM_CL 0xD3 // encoding is /4 +#define IA32_SAR_RM_IMM8 0xC1 // encoding is /7 +#define IA32_SETCC_RM8_1 0x0F // opcode part 1 +#define IA32_SETCC_RM8_2 0x90 // encoding is +cc /0 (8bits) +#define IA32_CMOVCC_RM_1 0x0F // opcode part 1 +#define IA32_CMOVCC_RM_2 0x40 // encoding is +cc /r +#define IA32_XCHG_EAX_REG 0x90 // encoding is +r +#define IA32_LEA_REG_MEM 0x8D // encoding is /r +#define IA32_POP_REG 0x58 // encoding is +r +#define IA32_PUSH_REG 0x50 // encoding is +r +#define IA32_PUSH_RM 0xFF // encoding is /6 +#define IA32_PUSH_IMM32 0x68 // encoding is +#define IA32_PUSH_IMM8 0x6A // encoding is +#define IA32_REP 0xF3 // no extra encoding +#define IA32_MOVSD 0xA5 // no extra encoding +#define IA32_MOVSB 0xA4 // no extra encoding +#define IA32_STOSD 0xAB // no extra encoding +#define IA32_CLD 0xFC // no extra encoding +#define IA32_PUSHAD 0x60 // no extra encoding +#define IA32_POPAD 0x61 // no extra encoding +#define IA32_NOP 0x90 // no extra encoding +#define IA32_INT3 0xCC // no extra encoding +#define IA32_FSTP_MEM32 0xD9 // encoding is /3 +#define IA32_FSTP_MEM64 0xDD // encoding is /3 +#define IA32_FLD_MEM32 0xD9 // encoding is /0 +#define IA32_FLD_MEM64 0xDD // encoding is /0 +#define IA32_FILD_MEM32 0xDB // encoding is /0 +#define IA32_FADD_MEM32 0xD8 // encoding is /0 +#define IA32_FADD_FPREG_ST0_1 0xDC // opcode part 1 +#define IA32_FADD_FPREG_ST0_2 0xC0 // encoding is +r +#define IA32_FSUB_MEM32 0xD8 // encoding is /4 +#define IA32_FMUL_MEM32 0xD8 // encoding is /1 +#define IA32_FDIV_MEM32 0xD8 // encoding is /6 +#define IA32_FSTCW_MEM16_1 0x9B // opcode part 1 +#define IA32_FSTCW_MEM16_2 0xD9 // encoding is /7 +#define IA32_FLDCW_MEM16 0xD9 // encoding is /5 +#define IA32_FISTP_MEM32 0xDB // encoding is /3 +#define IA32_FUCOMIP_1 0xDF // opcode part 1 +#define IA32_FUCOMIP_2 0xE8 // encoding is +r +#define IA32_FSTP_FPREG_1 0xDD // opcode part 1 +#define IA32_FSTP_FPREG_2 0xD8 // encoding is +r +#define IA32_MOVZX_R32_RM8_1 0x0F // opcode part 1 +#define IA32_MOVZX_R32_RM8_2 0xB6 // encoding is /r +#define IA32_MOVZX_R32_RM16_1 0x0F // opcode part 1 +#define IA32_MOVZX_R32_RM16_2 0xB7 // encoding is /r + + +namespace SourceHook +{ + namespace Impl + { + typedef GenBuffer JitWriter; + + inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm) + { + jit_uint8_t modrm = (mode << 6); + + modrm |= (reg << 3); + modrm |= (rm); + + return modrm; + } + + //mode is the scaling method - NOSCALE ... SCALE8 + //index is the register that is scaled + //base is the base register + inline jit_uint8_t ia32_sib(jit_uint8_t mode, jit_uint8_t index, jit_uint8_t base) + { + jit_uint8_t sib = (mode << 6); + + sib |= (index << 3); + sib |= (base); + + return sib; + } + + /*********************** + * INCREMENT/DECREMENT * + ***********************/ + + inline void IA32_Inc_Reg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_INC_REG+reg); + } + + inline void IA32_Inc_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp) + { + jit->write_ubyte(IA32_INC_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, reg)); + jit->write_byte(disp); + } + + inline void IA32_Inc_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp) + { + jit->write_ubyte(IA32_INC_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, reg)); + jit->write_int32(disp); + } + + inline void IA32_Inc_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale) + { + jit->write_ubyte(IA32_INC_RM); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, REG_SIB)); + jit->write_ubyte(ia32_sib(scale, reg, base)); + } + + inline void IA32_Dec_Reg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_DEC_REG+reg); + } + + inline void IA32_Dec_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp) + { + jit->write_ubyte(IA32_DEC_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 1, reg)); + jit->write_byte(disp); + } + + inline void IA32_Dec_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp) + { + jit->write_ubyte(IA32_DEC_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP32, 1, reg)); + jit->write_int32(disp); + } + + inline void IA32_Dec_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale) + { + jit->write_ubyte(IA32_DEC_RM); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 1, REG_SIB)); + jit->write_ubyte(ia32_sib(scale, reg, base)); + } + + /**************** + * BINARY LOGIC * + ****************/ + + inline void IA32_Xor_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode) + { + jit->write_ubyte(IA32_XOR_RM_REG); + jit->write_ubyte(ia32_modrm(dest_mode, src, dest)); + } + + inline void IA32_Xor_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode) + { + jit->write_ubyte(IA32_XOR_REG_RM); + jit->write_ubyte(ia32_modrm(dest_mode, dest, src)); + } + + inline void IA32_Xor_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value) + { + jit->write_ubyte(IA32_XOR_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 6, reg)); + jit->write_byte(value); + } + + inline void IA32_Xor_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value) + { + jit->write_ubyte(IA32_XOR_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 6, reg)); + jit->write_int32(value); + } + + inline void IA32_Xor_Eax_Imm32(JitWriter *jit, jit_int32_t value) + { + jit->write_ubyte(IA32_XOR_EAX_IMM32); + jit->write_int32(value); + } + + inline void IA32_Neg_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_NEG_RM); + jit->write_ubyte(ia32_modrm(mode, 3, reg)); + } + + inline void IA32_Or_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_OR_REG_RM); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_And_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_AND_REG_RM); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_And_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value) + { + jit->write_ubyte(IA32_AND_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 4, reg)); + jit->write_int32(value); + } + + inline void IA32_And_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value) + { + jit->write_ubyte(IA32_AND_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 4, reg)); + jit->write_byte(value); + } + + inline void IA32_And_Eax_Imm32(JitWriter *jit, jit_int32_t value) + { + jit->write_ubyte(IA32_AND_EAX_IMM32); + jit->write_int32(value); + } + + inline void IA32_Not_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_NOT_RM); + jit->write_ubyte(ia32_modrm(mode, 2, reg)); + } + + inline void IA32_Shr_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SHR_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 5, dest)); + jit->write_ubyte(value); + } + + inline void IA32_Shr_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SHR_RM_1); + jit->write_ubyte(ia32_modrm(mode, 5, dest)); + } + + inline void IA32_Shl_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SHL_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 4, dest)); + jit->write_ubyte(value); + } + + inline void IA32_Shl_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SHL_RM_1); + jit->write_ubyte(ia32_modrm(mode, 4, dest)); + } + + inline void IA32_Sar_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SAR_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 7, dest)); + jit->write_ubyte(value); + } + + inline void IA32_Sar_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SAR_RM_CL); + jit->write_ubyte(ia32_modrm(mode, 7, reg)); + } + + inline void IA32_Sar_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SAR_RM_1); + jit->write_ubyte(ia32_modrm(mode, 7, dest)); + } + + inline void IA32_Shr_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SHR_RM_CL); + jit->write_ubyte(ia32_modrm(mode, 5, reg)); + } + + inline void IA32_Shl_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SHL_RM_CL); + jit->write_ubyte(ia32_modrm(mode, 4, reg)); + } + + inline void IA32_Xchg_Eax_Reg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_XCHG_EAX_REG+reg); + } + + /********************** + * ARITHMETIC (BASIC) * + **********************/ + + inline void IA32_Add_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_ADD_RM_REG); + jit->write_ubyte(ia32_modrm(mode, src, dest)); + } + + inline void IA32_Add_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_ADD_REG_RM); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Add_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t value, jit_uint8_t mode) + { + jit->write_ubyte(IA32_ADD_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 0, reg)); + jit->write_byte(value); + } + + inline void IA32_Add_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode) + { + jit->write_ubyte(IA32_ADD_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 0, reg)); + jit->write_int32(value); + } + + inline void IA32_Add_Rm_ImmAuto(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode) + { + if (value >= SCHAR_MIN && value <= SCHAR_MAX) + IA32_Add_Rm_Imm8(jit, reg, static_cast(value), mode); + else + IA32_Add_Rm_Imm32(jit, reg, value, mode); + } + + inline void IA32_Add_Eax_Imm32(JitWriter *jit, jit_int32_t value) + { + jit->write_ubyte(IA32_ADD_EAX_IMM32); + jit->write_int32(value); + } + + inline void IA32_Sub_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SUB_RM_REG); + jit->write_ubyte(ia32_modrm(mode, src, dest)); + } + + inline void IA32_Sub_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SUB_REG_RM); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Sub_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8) + { + jit->write_ubyte(IA32_SUB_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); + jit->write_byte(disp8); + } + + inline void IA32_Sub_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8) + { + jit->write_ubyte(IA32_SUB_RM_REG); + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest)); + jit->write_byte(disp8); + } + + inline void IA32_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SUB_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 5, reg)); + jit->write_byte(val); + } + + inline void IA32_Sub_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SUB_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 5, reg)); + jit->write_int32(val); + } + + inline void IA32_Sub_Rm_ImmAuto(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode) + { + if (val >= SCHAR_MIN && val <= SCHAR_MAX) + IA32_Sub_Rm_Imm8(jit, reg, static_cast(val), mode); + else + IA32_Sub_Rm_Imm32(jit, reg, val, mode); + } + + inline void IA32_Sbb_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SBB_REG_RM); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Sbb_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_int8_t value, jit_uint8_t mode) + { + jit->write_ubyte(IA32_SBB_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 3, dest)); + jit->write_byte(value); + } + + inline void IA32_Div_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_DIV_RM); + jit->write_ubyte(ia32_modrm(mode, 6, reg)); + } + + inline void IA32_IDiv_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_IDIV_RM); + jit->write_ubyte(ia32_modrm(mode, 7, reg)); + } + + inline void IA32_Mul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_MUL_RM); + jit->write_ubyte(ia32_modrm(mode, 4, reg)); + } + + inline void IA32_IMul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_IMUL_RM); + jit->write_ubyte(ia32_modrm(mode, 5, reg)); + } + + inline void IA32_IMul_Reg_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value) + { + jit->write_ubyte(IA32_IMUL_REG_IMM8); + jit->write_ubyte(ia32_modrm(mode, 0, reg)); + jit->write_byte(value); + } + + inline void IA32_IMul_Reg_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value) + { + jit->write_ubyte(IA32_IMUL_REG_IMM32); + jit->write_ubyte(ia32_modrm(mode, 0, reg)); + jit->write_int32(value); + } + + inline void IA32_IMul_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_IMUL_REG_RM_1); + jit->write_ubyte(IA32_IMUL_REG_RM_2); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Add_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) + { + jit->write_ubyte(IA32_ADD_RM_REG); + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest)); + jit->write_byte(disp); + } + + inline void IA32_Add_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) + { + jit->write_ubyte(IA32_ADD_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); + jit->write_byte(disp); + } + + inline void IA32_Add_Rm_Imm8_Disp8(JitWriter *jit, + jit_uint8_t dest, + jit_int8_t val, + jit_int8_t disp8) + { + jit->write_ubyte(IA32_ADD_RM_IMM8); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest)); + jit->write_byte(disp8); + jit->write_byte(val); + } + + inline void IA32_Add_Rm_Imm32_Disp8(JitWriter *jit, + jit_uint8_t dest, + jit_int32_t val, + jit_int8_t disp8) + { + jit->write_ubyte(IA32_ADD_RM_IMM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest)); + jit->write_byte(disp8); + jit->write_int32(val); + } + + inline jitoffs_t IA32_Add_Rm_Imm32_Later(JitWriter *jit, + jit_uint8_t dest, + jit_uint8_t mode) + { + jit->write_ubyte(IA32_ADD_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 0, dest)); + jitoffs_t ptr = jit->get_outputpos(); + jit->write_int32(0); + return ptr; + } + + inline void IA32_Add_Rm_Imm8_Disp32(JitWriter *jit, + jit_uint8_t dest, + jit_int8_t val, + jit_int32_t disp32) + { + jit->write_ubyte(IA32_ADD_RM_IMM8); + jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest)); + jit->write_int32(disp32); + jit->write_byte(val); + } + + inline void IA32_Add_RmEBP_Imm8_Disp_Reg(JitWriter *jit, + jit_uint8_t dest_base, + jit_uint8_t dest_index, + jit_uint8_t dest_scale, + jit_int8_t val) + { + jit->write_ubyte(IA32_ADD_RM_IMM8); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB)); + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); + jit->write_byte(0); + jit->write_byte(val); + } + + inline void IA32_Sub_Rm_Imm8_Disp8(JitWriter *jit, + jit_uint8_t dest, + jit_int8_t val, + jit_int8_t disp8) + { + jit->write_ubyte(IA32_SUB_RM_IMM8); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, dest)); + jit->write_byte(disp8); + jit->write_byte(val); + } + + inline void IA32_Sub_Rm_Imm8_Disp32(JitWriter *jit, + jit_uint8_t dest, + jit_int8_t val, + jit_int32_t disp32) + { + jit->write_ubyte(IA32_SUB_RM_IMM8); + jit->write_ubyte(ia32_modrm(MOD_DISP32, 5, dest)); + jit->write_int32(disp32); + jit->write_byte(val); + } + + inline void IA32_Sub_RmEBP_Imm8_Disp_Reg(JitWriter *jit, + jit_uint8_t dest_base, + jit_uint8_t dest_index, + jit_uint8_t dest_scale, + jit_int8_t val) + { + jit->write_ubyte(IA32_SUB_RM_IMM8); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, REG_SIB)); + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); + jit->write_byte(0); + jit->write_byte(val); + } + + /** + * Memory Instructions + */ + + inline void IA32_Lea_Reg_DispRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale) + { + jit->write_ubyte(IA32_LEA_REG_MEM); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(scale, src_index, src_base)); + } + + inline void IA32_Lea_Reg_DispEBPRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale) + { + jit->write_ubyte(IA32_LEA_REG_MEM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(scale, src_index, src_base)); + jit->write_byte(0); + } + + inline void IA32_Lea_Reg_DispRegMultImm8(JitWriter *jit, + jit_uint8_t dest, + jit_uint8_t src_base, + jit_uint8_t src_index, + jit_uint8_t scale, + jit_int8_t val) + { + jit->write_ubyte(IA32_LEA_REG_MEM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(scale, src_index, src_base)); + jit->write_byte(val); + } + + inline void IA32_Lea_Reg_DispRegMultImm32(JitWriter *jit, + jit_uint8_t dest, + jit_uint8_t src_base, + jit_uint8_t src_index, + jit_uint8_t scale, + jit_int32_t val) + { + jit->write_ubyte(IA32_LEA_REG_MEM); + jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(scale, src_index, src_base)); + jit->write_int32(val); + } + + inline void IA32_Lea_Reg_RegMultImm32(JitWriter *jit, + jit_uint8_t dest, + jit_uint8_t src_index, + jit_uint8_t scale, + jit_int32_t val) + { + jit->write_ubyte(IA32_LEA_REG_MEM); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(scale, src_index, REG_IMM_BASE)); + jit->write_int32(val); + } + + inline void IA32_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val) + { + jit->write_ubyte(IA32_LEA_REG_MEM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src_base)); + jit->write_byte(val); + } + + inline void IA32_Lea_DispRegImm32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val) + { + jit->write_ubyte(IA32_LEA_REG_MEM); + jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src_base)); + jit->write_int32(val); + } + + inline void IA32_Lea_DispRegImmAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val) + { + if (val >= SCHAR_MIN && val <= SCHAR_MAX) + IA32_Lea_DispRegImm8(jit, dest, src_base, static_cast(val)); + else + IA32_Lea_DispRegImm32(jit, dest, src_base, val); + } + + /** + * Stack Instructions + */ + + inline void IA32_Pop_Reg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_POP_REG+reg); + } + + inline void IA32_Push_Reg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_PUSH_REG+reg); + } + + inline void IA32_Push_Imm8(JitWriter *jit, jit_int8_t val) + { + jit->write_ubyte(IA32_PUSH_IMM8); + jit->write_byte(val); + } + + inline void IA32_Push_Imm32(JitWriter *jit, jit_int32_t val) + { + jit->write_ubyte(IA32_PUSH_IMM32); + jit->write_int32(val); + } + + inline void IA32_Pushad(JitWriter *jit) + { + jit->write_ubyte(IA32_PUSHAD); + } + + inline void IA32_Popad(JitWriter *jit) + { + jit->write_ubyte(IA32_POPAD); + } + + inline void IA32_Push_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8) + { + jit->write_ubyte(IA32_PUSH_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, reg)); + jit->write_byte(disp8); + } + + inline void IA32_Push_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp32) + { + jit->write_ubyte(IA32_PUSH_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP32, 6, reg)); + jit->write_int32(disp32); + } + + inline void IA32_Push_Rm_DispAuto(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp) + { + if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) + IA32_Push_Rm_Disp8(jit, reg, static_cast(disp)); + else + IA32_Push_Rm_Disp32(jit, reg, disp); + } + + inline void IA32_Push_Rm_Disp8_ESP(JitWriter *jit, jit_int8_t disp8) + { + jit->write_ubyte(IA32_PUSH_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + jit->write_byte(disp8); + } + + /** + * Moving from REGISTER/MEMORY to REGISTER + */ + + inline void IA32_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_MOV_REG_RM); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Mov_Reg8_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_MOV_REG8_RM8); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Mov_Reg_RmESP(JitWriter *jit, jit_uint8_t dest) + { + jit->write_ubyte(IA32_MOV_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_ESP)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) + { + jit->write_ubyte(IA32_MOV_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); + jit->write_byte(disp); + } + + inline void IA32_Mov_Reg8_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) + { + jit->write_ubyte(IA32_MOV_REG8_RM8); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); + jit->write_byte(disp); + } + + inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t disp) + { + jit->write_ubyte(IA32_MOV_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + jit->write_byte(disp); + } + + inline void IA32_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + jit->write_ubyte(IA32_MOV_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); + jit->write_int32(disp); + } + + inline void IA32_Mov_Reg8_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + jit->write_ubyte(IA32_MOV_REG8_RM8); + jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); + jit->write_int32(disp); + } + + inline void IA32_Mov_Reg_Rm_Disp_Reg(JitWriter *jit, + jit_uint8_t dest, + jit_uint8_t src_base, + jit_uint8_t src_index, + jit_uint8_t src_scale) + { + jit->write_ubyte(IA32_MOV_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); + } + + inline void IA32_Mov_Reg_Rm_Disp_Reg_Disp8(JitWriter *jit, + jit_uint8_t dest, + jit_uint8_t src_base, + jit_uint8_t src_index, + jit_uint8_t src_scale, + jit_int8_t disp8) + { + jit->write_ubyte(IA32_MOV_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); + jit->write_byte(disp8); + } + + inline void IA32_Mov_Reg_RmEBP_Disp_Reg(JitWriter *jit, + jit_uint8_t dest, + jit_uint8_t src_base, + jit_uint8_t src_index, + jit_uint8_t src_scale) + { + jit->write_ubyte(IA32_MOV_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); + jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); + jit->write_byte(0); + } + + inline void IA32_Mov_Reg_Rm_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + if (disp == 0) + IA32_Mov_Reg_Rm(jit, dest, src, MOD_MEM_REG); + else if (disp <= SCHAR_MAX) + IA32_Mov_Reg_Rm_Disp8(jit, dest, src, static_cast(disp)); + else + IA32_Mov_Reg_Rm_Disp32(jit, dest, src, disp); + } + + /** + * Moving from REGISTER to REGISTER/MEMORY + */ + + inline void IA32_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_MOV_RM_REG); + jit->write_ubyte(ia32_modrm(mode, src, dest)); + } + + inline void IA32_Mov_Rm8_Reg8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_MOV_RM8_REG8); + jit->write_ubyte(ia32_modrm(mode, src, dest)); + } + + inline void IA32_Mov_RmESP_Reg(JitWriter *jit, jit_uint8_t src) + { + jit->write_ubyte(IA32_MOV_RM_REG); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src, REG_ESP)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) + { + jit->write_ubyte(IA32_MOV_RM_REG); + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest)); + jit->write_byte(disp); + } + + inline void IA32_Mov_Rm_Reg_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + jit->write_ubyte(IA32_MOV_RM_REG); + jit->write_ubyte(ia32_modrm(MOD_DISP32, src, dest)); + jit->write_int32(disp); + } + + inline void IA32_Mov_Rm_Reg_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) + IA32_Mov_Rm_Reg_Disp8(jit, dest, src, static_cast(disp)); + else + IA32_Mov_Rm_Reg_Disp32(jit, dest, src, disp); + } + + inline void IA32_Mov_RmEBP_Reg_Disp_Reg(JitWriter *jit, + jit_uint8_t dest_base, + jit_uint8_t dest_index, + jit_uint8_t dest_scale, + jit_uint8_t src) + { + jit->write_ubyte(IA32_MOV_RM_REG); + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB)); + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); + jit->write_byte(0); + } + + inline void IA32_Mov_Rm8EBP_Reg_Disp_Reg(JitWriter *jit, + jit_uint8_t dest_base, + jit_uint8_t dest_index, + jit_uint8_t dest_scale, + jit_uint8_t src) + { + jit->write_ubyte(IA32_MOV_RM8_REG); + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB)); + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); + jit->write_byte(0); + } + + inline void IA32_Mov_Rm16EBP_Reg_Disp_Reg(JitWriter *jit, + jit_uint8_t dest_base, + jit_uint8_t dest_index, + jit_uint8_t dest_scale, + jit_uint8_t src) + { + jit->write_ubyte(IA32_16BIT_PREFIX); + jit->write_ubyte(IA32_MOV_RM_REG); + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB)); + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); + jit->write_byte(0); + } + + /** + * Moving from IMMEDIATE to REGISTER + */ + + inline jitoffs_t IA32_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t num) + { + jitoffs_t offs; + jit->write_ubyte(IA32_MOV_REG_IMM+dest); + offs = jit->get_outputpos(); + jit->write_int32(num); + return offs; + } + + inline void IA32_Mov_Rm_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val, jit_uint8_t mode) + { + jit->write_ubyte(IA32_MOV_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 0, dest)); + jit->write_int32(val); + } + + inline void IA32_Mov_Rm_Imm32_Disp8(JitWriter *jit, + jit_uint8_t dest, + jit_int32_t val, + jit_int8_t disp8) + { + jit->write_ubyte(IA32_MOV_RM_IMM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest)); + jit->write_byte(disp8); + jit->write_int32(val); + } + + inline void IA32_Mov_Rm_Imm32_Disp32(JitWriter *jit, + jit_uint8_t dest, + jit_int32_t val, + jit_int32_t disp32) + { + jit->write_ubyte(IA32_MOV_RM_IMM32); + jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest)); + jit->write_int32(disp32); + jit->write_int32(val); + } + + inline void IA32_Mov_RmEBP_Imm32_Disp_Reg(JitWriter *jit, + jit_uint8_t dest_base, + jit_uint8_t dest_index, + jit_uint8_t dest_scale, + jit_int32_t val) + { + jit->write_ubyte(IA32_MOV_RM_IMM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB)); + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); + jit->write_byte(0); + jit->write_int32(val); + } + + inline void IA32_Mov_ESP_Disp8_Imm32(JitWriter *jit, jit_int8_t disp8, jit_int32_t val) + { + jit->write_ubyte(IA32_MOV_RM_IMM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + jit->write_byte(disp8); + jit->write_int32(val); + } + + /** + * Floating Point Instructions + */ + + inline void IA32_Fstcw_Mem16_ESP(JitWriter *jit) + { + jit->write_ubyte(IA32_FSTCW_MEM16_1); + jit->write_ubyte(IA32_FSTCW_MEM16_2); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 7, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Fldcw_Mem16_ESP(JitWriter *jit) + { + jit->write_ubyte(IA32_FLDCW_MEM16); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 5, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Fldcw_Mem16_Disp8_ESP(JitWriter *jit, jit_int8_t disp8) + { + jit->write_ubyte(IA32_FLDCW_MEM16); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + jit->write_byte(disp8); + } + + inline void IA32_Fistp_Mem32_ESP(JitWriter *jit) + { + jit->write_ubyte(IA32_FISTP_MEM32); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Fistp_Mem32_Disp8_Esp(JitWriter *jit, jit_int8_t disp8) + { + jit->write_ubyte(IA32_FISTP_MEM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 3, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + jit->write_byte(disp8); + } + + inline void IA32_Fucomip_ST0_FPUreg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_FUCOMIP_1); + jit->write_ubyte(IA32_FUCOMIP_2+reg); + } + + inline void IA32_Fadd_FPUreg_ST0(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_FADD_FPREG_ST0_1); + jit->write_ubyte(IA32_FADD_FPREG_ST0_2+reg); + } + + inline void IA32_Fadd_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) + { + jit->write_ubyte(IA32_FADD_MEM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src)); + jit->write_byte(val); + } + + inline void IA32_Fadd_Mem32_ESP(JitWriter *jit) + { + jit->write_ubyte(IA32_FADD_MEM32); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Fsub_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) + { + jit->write_ubyte(IA32_FSUB_MEM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 4, src)); + jit->write_byte(val); + } + + inline void IA32_Fmul_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) + { + jit->write_ubyte(IA32_FMUL_MEM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 1, src)); + jit->write_byte(val); + } + + inline void IA32_Fdiv_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) + { + jit->write_ubyte(IA32_FDIV_MEM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, src)); + jit->write_byte(val); + } + + inline void IA32_Fild_Mem32(JitWriter *jit, jit_uint8_t src) + { + jit->write_ubyte(IA32_FILD_MEM32); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src)); + } + + inline void IA32_Fstp_Mem32(JitWriter *jit, jit_uint8_t dest) + { + jit->write_ubyte(IA32_FSTP_MEM32); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, dest)); + } + + inline void IA32_Fstp_Mem32_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_int32_t disp) + { + jit->write_ubyte(IA32_FSTP_MEM32); + + if (disp > SCHAR_MIN && disp < SCHAR_MAX) + { + jit->write_ubyte(ia32_modrm(MOD_DISP8, 3, dest)); + jit->write_byte(static_cast(disp)); + } + else + { + jit->write_ubyte(ia32_modrm(MOD_DISP32, 3, dest)); + jit->write_byte(disp); + } + } + + inline void IA32_Fstp_Mem64(JitWriter *jit, jit_uint8_t dest) + { + jit->write_ubyte(IA32_FSTP_MEM64); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, dest)); + } + + inline void IA32_Fstp_Mem64_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_int32_t disp) + { + jit->write_ubyte(IA32_FSTP_MEM64); + + if (disp > SCHAR_MIN && disp < SCHAR_MAX) + { + jit->write_ubyte(ia32_modrm(MOD_DISP8, 3, dest)); + jit->write_byte(static_cast(disp)); + } + else + { + jit->write_ubyte(ia32_modrm(MOD_DISP32, 3, dest)); + jit->write_byte(disp); + } + } + + inline void IA32_Fstp_Mem32_ESP(JitWriter *jit) + { + jit->write_ubyte(IA32_FSTP_MEM32); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Fstp_Mem64_ESP(JitWriter *jit) + { + jit->write_ubyte(IA32_FSTP_MEM64); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Fstp_FPUreg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_FSTP_FPREG_1); + jit->write_ubyte(IA32_FSTP_FPREG_2+reg); + } + + inline void IA32_Fld_Mem32(JitWriter *jit, jit_uint8_t src) + { + jit->write_ubyte(IA32_FLD_MEM32); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src)); + } + + inline void IA32_Fld_Mem64(JitWriter *jit, jit_uint8_t src) + { + jit->write_ubyte(IA32_FLD_MEM64); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src)); + } + + inline void IA32_Fld_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) + { + jit->write_ubyte(IA32_FLD_MEM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src)); + jit->write_byte(val); + } + + inline void IA32_Fld_Mem64_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) + { + jit->write_ubyte(IA32_FLD_MEM64); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src)); + jit->write_byte(val); + } + + inline void IA32_Fld_Mem32_Disp32(JitWriter *jit, jit_uint8_t src, jit_int32_t val) + { + jit->write_ubyte(IA32_FLD_MEM32); + jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, src)); + jit->write_int32(val); + } + + inline void IA32_Fld_Mem64_Disp32(JitWriter *jit, jit_uint8_t src, jit_int32_t val) + { + jit->write_ubyte(IA32_FLD_MEM64); + jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, src)); + jit->write_int32(val); + } + + inline void IA32_Fld_Mem32_DispAuto(JitWriter *jit, jit_uint8_t src, jit_int32_t disp) + { + if (disp == 0) + IA32_Fld_Mem32(jit, src); + else if (disp <= SCHAR_MAX) + IA32_Fld_Mem32_Disp8(jit, src, static_cast(disp)); + else + IA32_Fld_Mem32_Disp32(jit, src, disp); + } + + inline void IA32_Fld_Mem64_DispAuto(JitWriter *jit, jit_uint8_t src, jit_int32_t disp) + { + if (disp == 0) + IA32_Fld_Mem64(jit, src); + else if (disp <= SCHAR_MAX) + IA32_Fld_Mem64_Disp8(jit, src, static_cast(disp)); + else + IA32_Fld_Mem64_Disp32(jit, src, disp); + } + + /** + * Move data with zero extend + */ + + inline void IA32_Movzx_Reg32_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_MOVZX_R32_RM8_1); + jit->write_ubyte(IA32_MOVZX_R32_RM8_2); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Movzx_Reg32_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) + { + jit->write_ubyte(IA32_MOVZX_R32_RM8_1); + jit->write_ubyte(IA32_MOVZX_R32_RM8_2); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); + jit->write_byte(disp); + } + + inline void IA32_Movzx_Reg32_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + jit->write_ubyte(IA32_MOVZX_R32_RM8_1); + jit->write_ubyte(IA32_MOVZX_R32_RM8_2); + jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); + jit->write_int32(disp); + } + + inline void IA32_Movzx_Reg32_Rm8_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) + IA32_Movzx_Reg32_Rm8_Disp8(jit, dest, src, static_cast(disp)); + else + IA32_Movzx_Reg32_Rm8_Disp32(jit, dest, src, disp); + } + + inline void IA32_Movzx_Reg32_Rm16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_MOVZX_R32_RM16_1); + jit->write_ubyte(IA32_MOVZX_R32_RM16_2); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Movzx_Reg32_Rm16_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) + { + jit->write_ubyte(IA32_MOVZX_R32_RM16_1); + jit->write_ubyte(IA32_MOVZX_R32_RM16_2); + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); + jit->write_byte(disp); + } + + inline void IA32_Movzx_Reg32_Rm16_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + jit->write_ubyte(IA32_MOVZX_R32_RM16_1); + jit->write_ubyte(IA32_MOVZX_R32_RM16_2); + jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); + jit->write_int32(disp); + } + + inline void IA32_Movzx_Reg32_Rm16_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) + IA32_Movzx_Reg32_Rm16_Disp8(jit, dest, src, static_cast(disp)); + else + IA32_Movzx_Reg32_Rm16_Disp32(jit, dest, src, disp); + } + + /** + * Branching/Jumping + */ + + inline jitoffs_t IA32_Jump_Cond_Imm8(JitWriter *jit, jit_uint8_t cond, jit_int8_t disp) + { + jitoffs_t ptr; + jit->write_ubyte(IA32_JCC_IMM+cond); + ptr = jit->get_outputpos(); + jit->write_byte(disp); + return ptr; + } + + inline jitoffs_t IA32_Jump_Imm32(JitWriter *jit, jit_int32_t disp) + { + jitoffs_t ptr; + jit->write_ubyte(IA32_JMP_IMM32); + ptr = jit->get_outputpos(); + jit->write_int32(disp); + return ptr; + } + + inline jitoffs_t IA32_Jump_Imm8(JitWriter *jit, jit_int8_t disp) + { + jitoffs_t ptr; + jit->write_ubyte(IA32_JMP_IMM8); + ptr = jit->get_outputpos(); + jit->write_byte(disp); + return ptr; + } + + inline jitoffs_t IA32_Jump_Cond_Imm32(JitWriter *jit, jit_uint8_t cond, jit_int32_t disp) + { + jitoffs_t ptr; + jit->write_ubyte(IA32_JCC_IMM32_1); + jit->write_ubyte(IA32_JCC_IMM32_2+cond); + ptr = jit->get_outputpos(); + jit->write_int32(disp); + return ptr; + } + + inline void IA32_Jump_Reg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_JMP_RM); + jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg)); + } + + inline void IA32_Jump_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_JMP_RM); + jit->write_ubyte(ia32_modrm(mode, 4, reg)); + } + + inline jitoffs_t IA32_Call_Imm32(JitWriter *jit, jit_int32_t disp) + { + jitoffs_t ptr; + jit->write_ubyte(IA32_CALL_IMM32); + ptr = jit->get_outputpos(); + jit->write_int32(disp); + return ptr; + } + + inline void IA32_Call_Reg(JitWriter *jit, jit_uint8_t reg) + { + jit->write_ubyte(IA32_CALL_RM); + jit->write_ubyte(ia32_modrm(MOD_REG, 2, reg)); + } + + inline void IA32_Call_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) + { + jit->write_ubyte(IA32_CALL_RM); + jit->write_ubyte(ia32_modrm(mode, 4, reg)); + } + + inline void IA32_Return(JitWriter *jit) + { + jit->write_ubyte(IA32_RET); + } + + inline void IA32_Return_Popstack(JitWriter *jit, unsigned short bytes) + { + jit->write_ubyte(IA32_RETN); + jit->write_ushort(bytes); + } + + inline void IA32_Test_Rm_Reg(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_uint8_t mode) + { + jit->write_ubyte(IA32_TEST_RM_REG); + jit->write_ubyte(ia32_modrm(mode, reg2, reg1)); + } + + inline void IA32_Test_Rm_Reg8(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_uint8_t mode) + { + jit->write_ubyte(IA32_TEST_RM_REG8); + jit->write_ubyte(ia32_modrm(mode, reg2, reg1)); + } + + inline void IA32_Cmp_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_CMP_RM_REG); + jit->write_ubyte(ia32_modrm(mode, src, dest)); + } + + inline void IA32_Cmp_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) + { + jit->write_ubyte(IA32_CMP_REG_RM); + jit->write_ubyte(ia32_modrm(mode, dest, src)); + } + + inline void IA32_Cmp_Reg_Rm_ESP(JitWriter *jit, jit_uint8_t cmpreg) + { + jit->write_ubyte(IA32_CMP_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, cmpreg, REG_SIB)); + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); + } + + inline void IA32_Cmp_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_int8_t disp8) + { + jit->write_ubyte(IA32_CMP_REG_RM); + jit->write_ubyte(ia32_modrm(MOD_DISP8, reg1, reg2)); + jit->write_byte(disp8); + } + + inline void IA32_Cmp_Rm_Imm8(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int8_t imm8) + { + jit->write_ubyte(IA32_CMP_RM_IMM8); + jit->write_ubyte(ia32_modrm(mode, 7, rm)); + jit->write_byte(imm8); + } + + inline void IA32_Cmp_Rm_Imm32(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int32_t imm32) + { + jit->write_ubyte(IA32_CMP_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 7, rm)); + jit->write_int32(imm32); + } + + inline void IA32_Cmp_Rm_Imm32_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8, jit_int32_t imm32) + { + jit->write_ubyte(IA32_CMP_RM_IMM32); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg)); + jit->write_byte(disp8); + jit->write_int32(imm32); + } + + inline void IA32_Cmp_Rm_Disp8_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp, jit_int8_t imm8) + { + jit->write_ubyte(IA32_CMP_RM_IMM8); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg)); + jit->write_byte(disp); + jit->write_byte(imm8); + } + + inline void IA32_Cmp_Al_Imm8(JitWriter *jit, jit_int8_t value) + { + jit->write_ubyte(IA32_CMP_AL_IMM32); + jit->write_byte(value); + } + + inline void IA32_Cmp_Eax_Imm32(JitWriter *jit, jit_int32_t value) + { + jit->write_ubyte(IA32_CMP_EAX_IMM32); + jit->write_int32(value); + } + + inline void IA32_SetCC_Rm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t cond) + { + jit->write_ubyte(IA32_SETCC_RM8_1); + jit->write_ubyte(IA32_SETCC_RM8_2+cond); + jit->write_ubyte(ia32_modrm(MOD_REG, 0, reg)); + } + + inline void IA32_CmovCC_Rm(JitWriter *jit, jit_uint8_t src, jit_uint8_t cond) + { + jit->write_ubyte(IA32_CMOVCC_RM_1); + jit->write_ubyte(IA32_CMOVCC_RM_2+cond); + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src)); + } + + inline void IA32_CmovCC_Rm_Disp8(JitWriter *jit, jit_uint8_t src, jit_uint8_t cond, jit_int8_t disp) + { + jit->write_ubyte(IA32_CMOVCC_RM_1); + jit->write_ubyte(IA32_CMOVCC_RM_2+cond); + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src)); + jit->write_byte(disp); + } + + inline void IA32_Cmpsb(JitWriter *jit) + { + jit->write_ubyte(IA32_CMPSB); + } + + inline void IA32_Rep(JitWriter *jit) + { + jit->write_ubyte(IA32_REP); + } + + inline void IA32_Movsd(JitWriter *jit) + { + jit->write_ubyte(IA32_MOVSD); + } + + inline void IA32_Movsb(JitWriter *jit) + { + jit->write_ubyte(IA32_MOVSB); + } + + inline void IA32_Stosd(JitWriter *jit) + { + jit->write_ubyte(IA32_STOSD); + } + + inline void IA32_Cld(JitWriter *jit) + { + jit->write_ubyte(IA32_CLD); + } + + } +} + +#endif //_INCLUDE_JIT_X86_MACROS_H diff --git a/sourcehook/test/generate.bat b/sourcehook/test/generate.bat new file mode 100644 index 0000000..f6d3d65 --- /dev/null +++ b/sourcehook/test/generate.bat @@ -0,0 +1,6 @@ +:: Generates everything +:: Usage: +:: generate.bat + + +..\generate\shworker iter testhookmangen.hxx testhookmangen.h %1 \ No newline at end of file diff --git a/sourcehook/test/main.cpp b/sourcehook/test/main.cpp index db203e2..c7946bf 100644 --- a/sourcehook/test/main.cpp +++ b/sourcehook/test/main.cpp @@ -46,6 +46,7 @@ DECL_TEST(Multi); DECL_TEST(Ref); DECL_TEST(RefRet); DECL_TEST(VPHooks); +DECL_TEST(HookManGen); int main(int argc, char *argv[]) { @@ -68,6 +69,7 @@ int main(int argc, char *argv[]) DO_TEST(Ref); DO_TEST(RefRet); DO_TEST(VPHooks); + DO_TEST(HookManGen); cout << endl << "----" << endl << "Passed: " << passed << endl << "Failed: " << failed << endl; cout << "Total: " << passed + failed << endl; diff --git a/sourcehook/test/sourcehook_test.h b/sourcehook/test/sourcehook_test.h index ee5566e..babb5ba 100644 --- a/sourcehook/test/sourcehook_test.h +++ b/sourcehook/test/sourcehook_test.h @@ -17,6 +17,7 @@ struct CAutoPtrDestruction CAutoPtrDestruction(T *p) : m_Ptr(p) { } ~CAutoPtrDestruction() { if (m_Ptr) delete m_Ptr; } void clear() { m_Ptr = NULL; } + void set(T *ptr) { m_Ptr = ptr; } }; struct CSHPtrAutoDestruction diff --git a/sourcehook/test/testevents.h b/sourcehook/test/testevents.h index ef7c891..1f9f8bf 100644 --- a/sourcehook/test/testevents.h +++ b/sourcehook/test/testevents.h @@ -31,9 +31,25 @@ struct State return (typeid(other) == typeid(this)) ? true : false; } + virtual bool Ignore() + { + return false; + } + virtual void Dump() = 0; }; +struct IgnoreState : public State +{ + virtual bool Ignore() + { + return true; + } + virtual void Dump() + { + } +}; + typedef std::list StateList; namespace { @@ -53,6 +69,8 @@ namespace State *cs = va_arg(argptr, State*); if (!cs) break; + if (cs->Ignore()) + continue; requiredstates.push_back(cs); } va_end(argptr); @@ -86,6 +104,14 @@ namespace } } + if (!ok && g_Verbose) + { + std::cout << std::endl << "FAIL: Should be:" << std::endl; + DumpStates(&requiredstates); + std::cout << std::endl << "FAIL: Is:" << std::endl; + DumpStates(sl); + } + for (StateList::iterator iter = requiredstates.begin(); iter != requiredstates.end(); ++iter) delete *iter; for (StateList::iterator iter = sl->begin(); iter != sl->end(); ++iter) diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp new file mode 100644 index 0000000..76646d6 --- /dev/null +++ b/sourcehook/test/testhookmangen.cpp @@ -0,0 +1,470 @@ +#include +#include "sourcehook.h" +#include "sourcehook_test.h" +#include "testevents.h" +#include "sourcehook_hookmangen.h" + +// TESTHOOKMANGEN +// Test automatic hookman generation +// Tests void and non-void functions +// 0 to 6 params: +// integer-type, float-type, plain-old-data struct and objects with ctors/dtors +// both byval and byref +// also tests ignore/supercede +// also tests recalls + +// :TODO: test override as well + +namespace +{ + #include "testhookmangen.h" + + StateList g_States; + SourceHook::ISourceHook *g_SHPtr; + SourceHook::Plugin g_PLID; + + // PtrBuf(ptr) gives ptrs unique numbers + // in the order they appear + SourceHook::List g_PtrHash; + + bool g_Inside_LeafFunc = false; // inside a hook or a func + + template + int PtrBuf(T ptr) + { + int a = 0; + + const void *vptr = reinterpret_cast(ptr); + for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter) + { + if (*iter == vptr) + return a; + else + ++a; + } + g_PtrHash.push_back(vptr); + return static_cast(g_PtrHash.size()) - 1; + } + + template + T PtrBufPtr(T ptr) + { + PtrBuf(ptr); + return ptr; + } + + void PtrBuf_Clear(int leave_in = 0) + { + for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();) + { + if (--leave_in < 0) + iter = g_PtrHash.erase(iter); + else + ++iter; + } + } + + // POD / Object types + template + struct POD + { + char x[MYSIZE]; + + bool operator==(const POD &other) + { + return memcmp(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE) == 0; + } + }; + + template + std::ostream& operator <<(std::ostream &os, const POD &obj) + { + os << "Some POD!"; + return os; + } + + MAKE_STATE_1(State_ObjOCtor_Called, int /*MYSIZE*/); + MAKE_STATE_1(State_ObjCCtor_Called, int /*MYSIZE*/); + MAKE_STATE_1(State_ObjODtor_Called, int /*MYSIZE*/); + + template + struct Object + { + char x[MYSIZE]; + + Object(char initch) + { + memset(reinterpret_cast(x), initch, MYSIZE); + if (!g_Inside_LeafFunc) + ADD_STATE(State_ObjOCtor_Called(MYSIZE)); + } + + Object() + { + if (!g_Inside_LeafFunc) + ADD_STATE(State_ObjOCtor_Called(MYSIZE)); + } + + Object(const Object & other) + { + memcpy(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE); + if (!g_Inside_LeafFunc) + ADD_STATE(State_ObjCCtor_Called(MYSIZE)); + } + + ~Object() + { + if (!g_Inside_LeafFunc) + ADD_STATE(State_ObjODtor_Called(MYSIZE)); + } + + bool operator==(const Object &other) + { + return memcmp(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE) == 0; + } + }; + + template + std::ostream& operator <<(std::ostream &os, const Object &obj) + { + os << "Some Obj!"; + return os; + } + + + // "Increment" something: (reproducible change for recall tests) + // integer: ++ + // float: += 1.3 + // pod/object: x[i]++, 0 <= i < MYSIZE + template + struct Increment + { + static void Incr(T &what) + { + ++what; + } + }; + + template<> + struct Increment + { + static void Incr(float &what) + { + what += 1.3f; + } + }; + + template<> + struct Increment + { + static void Incr(double &what) + { + what += 1.3; + } + }; + + template + struct Increment< POD > + { + static void Incr(POD &what) + { + for (int i = 0; i < MYSIZE; ++i) + ++ what.x[i]; + } + }; + + template + struct Increment< Object > + { + static void Incr(Object &what) + { + for (int i = 0; i < MYSIZE; ++i) + ++ what.x[i]; + } + }; + + // MyDelegate base class for other delegates + class MyDelegate : public SourceHook::ISHDelegate + { + // Unneeded + // because we don't use old SH_REMOVE_HOOK syntax + virtual bool IsEqual(SourceHook::ISHDelegate *pOtherDeleg) + { + return false; + } + + virtual void DeleteThis() + { + delete this; + } + }; + + THGM_MAKE_TEST0_void(0); + THGM_SETUP_PI0(0); + + THGM_MAKE_TEST1_void(1, char); + THGM_SETUP_PI1(1, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_void(2, short); + THGM_SETUP_PI1(2, short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_void(3, int); + THGM_SETUP_PI1(3, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_void(4, float); + THGM_SETUP_PI1(4, float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_void(5, double); + THGM_SETUP_PI1(5, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST5_void(6, char, short, int, float, double); + THGM_SETUP_PI5(6, + char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, + short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, + float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal, + double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal + ); + + THGM_MAKE_TEST2_void(7, char&, double&); + THGM_SETUP_PI2(7, + char&, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByRef, + double&, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByRef + ); + + THGM_MAKE_TEST1_void(8, POD<7>); + THGM_SETUP_PI1(8, POD<7>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_void(9, POD<600>); + THGM_SETUP_PI1(9, POD<600>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_void(10, POD<600> &); + THGM_SETUP_PI1(10, POD<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef); + + THGM_MAKE_TEST2_void(11, Object<3>, Object<600>&); + THGM_SETUP_PI2(11, + Object<3>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor, + Object<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor + ); + + THGM_MAKE_TEST0(101, char); + THGM_SETUP_PI0(101); + THGM_SETUP_RI(101, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST0(102, short); + THGM_SETUP_PI0(102); + THGM_SETUP_RI(102, short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST0(103, int); + THGM_SETUP_PI0(103); + THGM_SETUP_RI(103, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST0(104, float); + THGM_SETUP_PI0(104); + THGM_SETUP_RI(104, float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST0(105, double); + THGM_SETUP_PI0(105); + THGM_SETUP_RI(105, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); +} + + +bool TestHookManGen(std::string &error) +{ + GET_SHPTR(g_SHPtr); + g_PLID = 1337; + + THGM_DO_TEST_void(0, ()); + + THGM_DO_TEST_void(1, (100)); + + THGM_DO_TEST_void(2, (0x1F00)); + + THGM_DO_TEST_void(3, (0x1F000000)); + + THGM_DO_TEST_void(4, (0.5f)); + + THGM_DO_TEST_void(5, (5.5)); + + THGM_DO_TEST_void(6, (100, 0x1f00, 0x1f000000, 0.5f, 5.5)); + + char a = 5; + double b = 233.33; + THGM_DO_TEST_void(7, (a, b)); + + POD<7> pod7 = {78}; + THGM_DO_TEST_void(8, (pod7)); + + POD<600> pod600 = {34}; + THGM_DO_TEST_void(9, (pod600)); + + THGM_DO_TEST_void(10, (pod600)); + + // Test11: Special: constructors/destructors + PtrBuf_Clear(); + Object<3> obj3(33); + Object<600> obj600(21); + + CHECK_STATES((&g_States, + new State_ObjOCtor_Called(3), + new State_ObjOCtor_Called(600), + NULL), "Test11 Part0"); + + setuppi_11(); + g_Genc11 = new SourceHook::Impl::GenContext(&protoinfo_11, 0, 0, g_SHPtr); + g_Genc_ad11.set(g_Genc11); + SourceHook::HookManagerPubFunc myhookman11 = g_Genc11->Generate(); + int hook1_11, hook2_11, hook3_11, hook4_11; + + TestClass11 *pTest11 = new TestClass11; + CAutoPtrDestruction apd11(pTest11); + + /* no hooks - no hooks */ + PtrBuf_Clear(); + pTest11->Func(obj3, obj600); + + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_ObjCCtor_Called(3), + new State_Func11(pTest11, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + NULL), "Test" "11" " Part1"); + g_Inside_LeafFunc = false; + + /* hook1 - no hooks */ + THGM_ADD_HOOK(11, 1); + + PtrBuf_Clear(); + pTest11->Func(obj3, obj600); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_ObjCCtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg1_11(pTest11, 0, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Func11(pTest11, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjODtor_Called(3), + NULL), "Test" "11" " Part2"); + g_Inside_LeafFunc = false; + + THGM_REMOVE_HOOK(11, 1); + + /* hook1, hook2 - hook3, hook4 */ + THGM_ADD_HOOK(11, 1); + THGM_ADD_HOOK(11, 2); + THGM_ADD_HOOK(11, 3); + THGM_ADD_HOOK(11, 4); + PtrBuf_Clear(); + pTest11->Func(obj3, obj600); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_ObjCCtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg1_11(pTest11, 0, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg2_11(pTest11, 1, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg3_11(pTest11, 2, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg4_11(pTest11, 3, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjODtor_Called(3), + NULL), "Test" "11" " Part3"); + g_Inside_LeafFunc = false; + + /* hook1 - hook3, hook4 WITH RECALLS */ + THGM_REMOVE_HOOK(11, 2); + PtrBuf_Clear(); + TestClass11::ms_DoRecall = true; + pTest11->Func(obj3, obj600); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_ObjCCtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg1_11(pTest11, 0 /* first deleg ptr */, ParamState_m11 (obj3, obj600)), + + // recall ! + // second hookfunc -> new copy + new State_ObjCCtor_Called(3), + + // in second hookfunc now + // -> calls orig func + + new State_ObjCCtor_Called(3), + new State_Func11(pTest11, ParamState_m11 (obj3, obj600)(1)), + new State_ObjODtor_Called(3), + + // calls first posthook + new State_ObjCCtor_Called(3), + new State_Deleg3_11(pTest11, 1 /* second deleg ptr */, ParamState_m11 (obj3, obj600)(1)), + + // recall! + // third hookfunc -> new copy + new State_ObjCCtor_Called(3), + + // calls second posthook + + new State_ObjCCtor_Called(3), + new State_Deleg4_11(pTest11, 2 /* third deleg ptr */, ParamState_m11 (obj3, obj600)(2)), + + // recall! + // fourth hookfunc -> new copy + new State_ObjCCtor_Called(3), + + // has nothing to do though! + + // fourth hookfunc done -> ret + new State_ObjODtor_Called(3), + + // third hookfunc done -> ret + new State_ObjODtor_Called(3), + // ret from hookhandler which did the recall + new State_ObjODtor_Called(3), + + // second hookfunc done -> ret + new State_ObjODtor_Called(3), + // ret from hookhandler which did the recall + new State_ObjODtor_Called(3), + + // deleg1's instance + new State_ObjODtor_Called(3), + // first hookfunc done -> ret + new State_ObjODtor_Called(3), + NULL), "Test" "11" " Part4"); + g_Inside_LeafFunc = false; + + THGM_REMOVE_HOOK(11, 1); + THGM_REMOVE_HOOK(11, 3); + THGM_REMOVE_HOOK(11, 4); + + THGM_DO_TEST(101, ()); + + THGM_DO_TEST(102, ()); + + THGM_DO_TEST(103, ()); + + THGM_DO_TEST(104, ()); + + THGM_DO_TEST(105, ()); + + // Shutdown now! + // If we don't SH will auto-shutdown _after_ genc's destructor is called + // -> crash + + Test_CompleteShutdown(g_SHPtr); + return true; +} diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h new file mode 100644 index 0000000..cd6f3ed --- /dev/null +++ b/sourcehook/test/testhookmangen.h @@ -0,0 +1,2090 @@ +// Strip & +template struct StripRef +{ + typedef T type; +}; + +template struct StripRef +{ + typedef T type; +}; + +// Address of constructor/destructor +// (using wrappers) +template +class Ctor_Thunk +{ +public: + void NormalConstructor() + { + new(this) T; + } + + void CopyConstructor(const T &other) + { + new(this) T(other); + } + + void Destructor() + { + reinterpret_cast(this)->~T(); + } +}; + + +template +void *FindFuncAddr(T mfp) +{ + if (sizeof(mfp) != sizeof(void*)) + return NULL; + else + return fastdelegate::detail::horrible_cast(mfp); +} + +// Reference carrier +template struct MyRefCarrier +{ + typedef T type; +}; + +template struct MyRefCarrier +{ + class type + { + T *m_StoredRef; + public: + type() : m_StoredRef(NULL) + { + } + type(T& ref) : m_StoredRef(&ref) + { + } + + T& operator= (T& ref) + { + m_StoredRef = &ref; + return ref; + } + + operator T& () const + { + return *m_StoredRef; + } + + bool operator== (const typename MyRefCarrier::type &other) + { + return m_StoredRef == other.m_StoredRef; + } + + friend std::ostream& operator <<(std::ostream &os,const typename MyRefCarrier::type &obj) + { + os << *obj.m_StoredRef; + return os; + } + }; +}; + +// Stores parameter status + + +template +struct ParamState0 +{ + + + bool operator==(const ParamState0 &other) + { + return true + + ; + } + ParamState0() + { + } + + ParamState0 & operator() (int incrsteps) + { + + + + return *this; + } +}; + + +std::ostream& operator <<(std::ostream &os,const ParamState0<0> &obj) +{ + ; + return os; +} + + + +template +struct ParamState1 +{ + typename MyRefCarrier::type m_1; + + bool operator==(const ParamState1 &other) + { + return true + && m_1 == other.m_1 + ; + } + ParamState1(p1 a1) : m_1(a1) + { + } + + ParamState1 & operator() (int incrsteps) + { + int i; + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_1); + + + return *this; + } +}; + +template +std::ostream& operator <<(std::ostream &os,const ParamState1<0, p1> &obj) +{ + os << obj.m_1; + return os; +} + + + +template +struct ParamState2 +{ + typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; + + bool operator==(const ParamState2 &other) + { + return true + && m_2 == other.m_2 && m_2 == other.m_2 + ; + } + ParamState2(p1 a1, p2 a2) : m_1(a1), m_2(a2) + { + } + + ParamState2 & operator() (int incrsteps) + { + int i; + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_1); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_2); + + + return *this; + } +}; + +template +std::ostream& operator <<(std::ostream &os,const ParamState2<0, p1, p2> &obj) +{ + os << obj.m_1<< obj.m_2; + return os; +} + + + +template +struct ParamState3 +{ + typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; typename MyRefCarrier::type m_3; + + bool operator==(const ParamState3 &other) + { + return true + && m_3 == other.m_3 && m_3 == other.m_3 && m_3 == other.m_3 + ; + } + ParamState3(p1 a1, p2 a2, p3 a3) : m_1(a1), m_2(a2), m_3(a3) + { + } + + ParamState3 & operator() (int incrsteps) + { + int i; + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_1); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_2); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_3); + + + return *this; + } +}; + +template +std::ostream& operator <<(std::ostream &os,const ParamState3<0, p1, p2, p3> &obj) +{ + os << obj.m_1<< obj.m_2<< obj.m_3; + return os; +} + + + +template +struct ParamState4 +{ + typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; typename MyRefCarrier::type m_3; typename MyRefCarrier::type m_4; + + bool operator==(const ParamState4 &other) + { + return true + && m_4 == other.m_4 && m_4 == other.m_4 && m_4 == other.m_4 && m_4 == other.m_4 + ; + } + ParamState4(p1 a1, p2 a2, p3 a3, p4 a4) : m_1(a1), m_2(a2), m_3(a3), m_4(a4) + { + } + + ParamState4 & operator() (int incrsteps) + { + int i; + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_1); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_2); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_3); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_4); + + + return *this; + } +}; + +template +std::ostream& operator <<(std::ostream &os,const ParamState4<0, p1, p2, p3, p4> &obj) +{ + os << obj.m_1<< obj.m_2<< obj.m_3<< obj.m_4; + return os; +} + + + +template +struct ParamState5 +{ + typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; typename MyRefCarrier::type m_3; typename MyRefCarrier::type m_4; typename MyRefCarrier::type m_5; + + bool operator==(const ParamState5 &other) + { + return true + && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 + ; + } + ParamState5(p1 a1, p2 a2, p3 a3, p4 a4, p5 a5) : m_1(a1), m_2(a2), m_3(a3), m_4(a4), m_5(a5) + { + } + + ParamState5 & operator() (int incrsteps) + { + int i; + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_1); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_2); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_3); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_4); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_5); + + + return *this; + } +}; + +template +std::ostream& operator <<(std::ostream &os,const ParamState5<0, p1, p2, p3, p4, p5> &obj) +{ + os << obj.m_1<< obj.m_2<< obj.m_3<< obj.m_4<< obj.m_5; + return os; +} + + + +template +struct ParamState6 +{ + typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; typename MyRefCarrier::type m_3; typename MyRefCarrier::type m_4; typename MyRefCarrier::type m_5; typename MyRefCarrier::type m_6; + + bool operator==(const ParamState6 &other) + { + return true + && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 + ; + } + ParamState6(p1 a1, p2 a2, p3 a3, p4 a4, p5 a5, p6 a6) : m_1(a1), m_2(a2), m_3(a3), m_4(a4), m_5(a5), m_6(a6) + { + } + + ParamState6 & operator() (int incrsteps) + { + int i; + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_1); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_2); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_3); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_4); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_5); + + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_6); + + + return *this; + } +}; + +template +std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, p5, p6> &obj) +{ + os << obj.m_1<< obj.m_2<< obj.m_3<< obj.m_4<< obj.m_5<< obj.m_6; + return os; +} + + + +#define CAT2(a, b) a##b +#define CAT3(a, b, c) a##b##c +#define CAT4(a, b, c, d) a##b##c##d + +// hook1: pre ignore +// hook2: pre supercede +// hook3: post ignore +// hook4: post supercede + + + + +#define THGM_MAKE_TEST0_void(id) \ + struct TestClass##id; \ + typedef ParamState0<0 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[0+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[0+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 0, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + + +#define THGM_MAKE_TEST0(id, ret_type) \ + struct TestClass##id; \ + typedef ParamState0<0 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + \ + return 0; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 1); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 3); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[0+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[0+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 0, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + +#define THGM_SETUP_PI0(id) \ + void setuppi_##id() \ + { \ + paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ + \ + \ + \ + \ + \ + \ + } + + + +#define THGM_MAKE_TEST1_void(id, param1) \ + struct TestClass##id; \ + typedef ParamState1<0, param1 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[1+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[1+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 1, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + + +#define THGM_MAKE_TEST1(id, ret_type, param1) \ + struct TestClass##id; \ + typedef ParamState1<0, param1 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + \ + return 0; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 1); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 3); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[1+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[1+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 1, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + +#define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ + void setuppi_##id() \ + { \ + paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ + \ + paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; \ + \ + paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ + paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ + paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + } + + + +#define THGM_MAKE_TEST2_void(id, param1, param2) \ + struct TestClass##id; \ + typedef ParamState2<0, param1, param2 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[2+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[2+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 2, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + + +#define THGM_MAKE_TEST2(id, ret_type, param1, param2) \ + struct TestClass##id; \ + typedef ParamState2<0, param1, param2 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + \ + return 0; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 1); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 3); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[2+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[2+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 2, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + +#define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ + void setuppi_##id() \ + { \ + paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ + \ + paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; \ + \ + paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ + paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ + paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + } + + + +#define THGM_MAKE_TEST3_void(id, param1, param2, param3) \ + struct TestClass##id; \ + typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[3+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[3+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 3, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + + +#define THGM_MAKE_TEST3(id, ret_type, param1, param2, param3) \ + struct TestClass##id; \ + typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + \ + return 0; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 1); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 3); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[3+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[3+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 3, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + +#define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ + void setuppi_##id() \ + { \ + paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ + \ + paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; paraminfos_##id[3].size = sizeof(p3_type); paraminfos_##id[3].type = p3_passtype; paraminfos_##id[3].flags = p3_flags; \ + \ + paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ + paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ + paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + } + + + +#define THGM_MAKE_TEST4_void(id, param1, param2, param3, param4) \ + struct TestClass##id; \ + typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[4+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[4+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 4, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + + +#define THGM_MAKE_TEST4(id, ret_type, param1, param2, param3, param4) \ + struct TestClass##id; \ + typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + \ + return 0; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 1); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 3); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[4+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[4+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 4, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + +#define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ + void setuppi_##id() \ + { \ + paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ + \ + paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; paraminfos_##id[3].size = sizeof(p3_type); paraminfos_##id[3].type = p3_passtype; paraminfos_##id[3].flags = p3_flags; paraminfos_##id[4].size = sizeof(p4_type); paraminfos_##id[4].type = p4_passtype; paraminfos_##id[4].flags = p4_flags; \ + \ + paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ + paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ + paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + } + + + +#define THGM_MAKE_TEST5_void(id, param1, param2, param3, param4, param5) \ + struct TestClass##id; \ + typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[5+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[5+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 5, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + + +#define THGM_MAKE_TEST5(id, ret_type, param1, param2, param3, param4, param5) \ + struct TestClass##id; \ + typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + \ + return 0; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 1); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 3); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[5+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[5+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 5, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + +#define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ + void setuppi_##id() \ + { \ + paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ + \ + paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; paraminfos_##id[3].size = sizeof(p3_type); paraminfos_##id[3].type = p3_passtype; paraminfos_##id[3].flags = p3_flags; paraminfos_##id[4].size = sizeof(p4_type); paraminfos_##id[4].type = p4_passtype; paraminfos_##id[4].flags = p4_flags; paraminfos_##id[5].size = sizeof(p5_type); paraminfos_##id[5].type = p5_passtype; paraminfos_##id[5].flags = p5_flags; \ + \ + paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[5].pNormalCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ + paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[5].pCopyCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ + paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[5].pDtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + } + + + +#define THGM_MAKE_TEST6_void(id, param1, param2, param3, param4, param5, param6) \ + struct TestClass##id; \ + typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[6+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[6+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 6, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + + +#define THGM_MAKE_TEST6(id, ret_type, param1, param2, param3, param4, param5, param6) \ + struct TestClass##id; \ + typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + \ + return 0; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 1); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 3); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[6+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[6+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { 6, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + +#define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ + void setuppi_##id() \ + { \ + paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ + \ + paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; paraminfos_##id[3].size = sizeof(p3_type); paraminfos_##id[3].type = p3_passtype; paraminfos_##id[3].flags = p3_flags; paraminfos_##id[4].size = sizeof(p4_type); paraminfos_##id[4].type = p4_passtype; paraminfos_##id[4].flags = p4_flags; paraminfos_##id[5].size = sizeof(p5_type); paraminfos_##id[5].type = p5_passtype; paraminfos_##id[5].flags = p5_flags; paraminfos_##id[6].size = sizeof(p6_type); paraminfos_##id[6].type = p6_passtype; paraminfos_##id[6].flags = p6_flags; \ + \ + paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[5].pNormalCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[6].pNormalCtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ + paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[5].pCopyCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[6].pCopyCtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ + paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[5].pDtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[6].pDtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + } + + + +#define THGM_SETUP_RI(id, ret_type, ret_passtype, ret_flags) \ + void setupri_##id() \ + { \ + protoinfo_##id.retPassInfo.size = sizeof(ret_type); \ + protoinfo_##id.retPassInfo.type = ret_passtype; \ + protoinfo_##id.retPassInfo.flags = ret_flags; \ + \ + protoinfo_##id.retPassInfo2.pNormalCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ + protoinfo_##id.retPassInfo2.pCopyCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ + protoinfo_##id.retPassInfo2.pDtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + } + +#define THGM_ADD_HOOK(id, num) \ + CAT4(hook, num, _, id) = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pTest##id), \ + 0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate##num), num >= 3); + +#define THGM_REMOVE_HOOK(id, num) \ + g_SHPtr->RemoveHookByID(CAT4(hook, num, _, id)); + +#define THGM_CALLS_void(id, call_params) \ + pTest##id->Func call_params; \ + SH_CALL(pTest##id, &TestClass##id::Func) call_params; + +#define THGM_DO_TEST_void(id, call_params) \ + setuppi_##id(); \ + g_Genc##id = new SourceHook::Impl::GenContext(&protoinfo_##id, 0, 0, g_SHPtr); \ + g_Genc_ad##id.set(g_Genc##id); \ + SourceHook::HookManagerPubFunc myhookman##id = g_Genc##id->Generate(); \ + int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ + \ + TestClass##id::ms_DoRecall = false; \ + TestClass##id *pTest##id = new TestClass##id; \ + CAutoPtrDestruction apd##id(pTest##id); \ + \ + /* no hooks - no hooks */ \ + PtrBuf_Clear(); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part1"); \ + \ + /* hook1 - no hooks */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part2"); \ + THGM_REMOVE_HOOK(id, 1); \ + \ + /* no hooks - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part3"); \ + THGM_REMOVE_HOOK(id, 3); \ + \ + /* hook1 - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part4"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 3); \ + \ + /* hook1, hook2 - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 2); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part5"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 2); \ + THGM_REMOVE_HOOK(id, 3); \ + /* hook1, hook2 - hook3, hook4 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 2); \ + THGM_ADD_HOOK(id, 3); \ + THGM_ADD_HOOK(id, 4); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part6"); \ + \ + /* hook1 - hook3, hook4, with recalls! */ \ + \ + TestClass##id::ms_DoRecall = true; \ + THGM_REMOVE_HOOK(id, 2); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params(0)), \ + new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params(1)), \ + new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params(2)), \ + /* sh_call one */ \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part7"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 3); \ + THGM_REMOVE_HOOK(id, 4); + + +#define THGM_CALLS(id, call_params, exp_ret_norm, exp_ret_shcall, err) \ + CHECK_COND(pTest##id->Func call_params == exp_ret_norm, err " /retcallnorm"); \ + CHECK_COND(SH_CALL(pTest##id, &TestClass##id::Func) call_params == exp_ret_shcall, err " /retcallshcall"); + +#define THGM_DO_TEST(id, call_params) \ + setuppi_##id(); \ + setupri_##id(); \ + g_Genc##id = new SourceHook::Impl::GenContext(&protoinfo_##id, 0, 0, g_SHPtr); \ + g_Genc_ad##id.set(g_Genc##id); \ + SourceHook::HookManagerPubFunc myhookman##id = g_Genc##id->Generate(); \ + int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ + \ + TestClass##id::ms_DoRecall = false; \ + TestClass##id *pTest##id = new TestClass##id; \ + CAutoPtrDestruction apd##id(pTest##id); \ + \ + /* no hooks - no hooks */ \ + PtrBuf_Clear(); \ + THGM_CALLS(id, call_params, 0, 0, "Part1"); \ + CHECK_STATES((&g_States, \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part1"); \ + \ + /* hook1 - no hooks */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_CALLS(id, call_params, 0, 0, "Part2"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part2"); \ + THGM_REMOVE_HOOK(id, 1); \ + \ + /* no hooks - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS(id, call_params, 0, 0, "Part3"); \ + CHECK_STATES((&g_States, \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part3"); \ + THGM_REMOVE_HOOK(id, 3); \ + \ + /* hook1 - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS(id, call_params, 0, 0, "Part4"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part4"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 3); \ + \ + /* hook1, hook2 - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 2); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS(id, call_params, 2, 0, "Part5"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part5"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 2); \ + THGM_REMOVE_HOOK(id, 3); \ + /* hook1, hook2 - hook3, hook4 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 2); \ + THGM_ADD_HOOK(id, 3); \ + THGM_ADD_HOOK(id, 4); \ + THGM_CALLS(id, call_params, 4, 0, "Part6"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part6"); \ + \ + /* hook1 - hook3, hook4, with recalls! */ \ + \ + TestClass##id::ms_DoRecall = true; \ + THGM_REMOVE_HOOK(id, 2); \ + THGM_CALLS(id, call_params, 4, 0, "Part7"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params(0)), \ + new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params(1)), \ + new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params(2)), \ + /* sh_call one */ \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part7"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 3); \ + THGM_REMOVE_HOOK(id, 4); diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx new file mode 100644 index 0000000..80800e7 --- /dev/null +++ b/sourcehook/test/testhookmangen.hxx @@ -0,0 +1,578 @@ +// Strip & +template struct StripRef +{ + typedef T type; +}; + +template struct StripRef +{ + typedef T type; +}; + +// Address of constructor/destructor +// (using wrappers) +template +class Ctor_Thunk +{ +public: + void NormalConstructor() + { + new(this) T; + } + + void CopyConstructor(const T &other) + { + new(this) T(other); + } + + void Destructor() + { + reinterpret_cast(this)->~T(); + } +}; + + +template +void *FindFuncAddr(T mfp) +{ + if (sizeof(mfp) != sizeof(void*)) + return NULL; + else + return fastdelegate::detail::horrible_cast(mfp); +} + +// Reference carrier +template struct MyRefCarrier +{ + typedef T type; +}; + +template struct MyRefCarrier +{ + class type + { + T *m_StoredRef; + public: + type() : m_StoredRef(NULL) + { + } + type(T& ref) : m_StoredRef(&ref) + { + } + + T& operator= (T& ref) + { + m_StoredRef = &ref; + return ref; + } + + operator T& () const + { + return *m_StoredRef; + } + + bool operator== (const typename MyRefCarrier::type &other) + { + return m_StoredRef == other.m_StoredRef; + } + + friend std::ostream& operator <<(std::ostream &os,const typename MyRefCarrier::type &obj) + { + os << *obj.m_StoredRef; + return os; + } + }; +}; + +// Stores parameter status +@[$1,0,$a: + +template +struct ParamState$1 +{ + @[$2,1,$1:typename MyRefCarrier::type m_$2; @] + + bool operator==(const ParamState$1 &other) + { + return true + @[$2,1,$1: && m_$1 == other.m_$1@] + ; + } + ParamState$1(@[$2,1,$1|, :p$2 a$2@]) @[$1!=0::@] @[$2,1,$1|, :m_$2(a$2)@] + { + } + + ParamState$1 & operator() (int incrsteps) + { + @[$1!=0:int i;@] + @[$2,1,$1: + for (i = 0; i < incrsteps; ++i) + Increment::type>::Incr(m_$2); + @] + + return *this; + } +}; + +@[$1!=0:template<@[$2,1,$1|, :class p$2@]>@] +std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@]> &obj) +{ + @[$1!=0:os@] @[$2,1,$1:<< obj.m_$2@]; + return os; +} + +@] + +#define CAT2(a, b) a##b +#define CAT3(a, b, c) a##b##c +#define CAT4(a, b, c, d) a##b##c##d + +// hook1: pre ignore +// hook2: pre supercede +// hook3: post ignore +// hook4: post supercede + + +@[$1,0,$a: + +#define THGM_MAKE_TEST$1_void(id@[$2,1,$1:, param$2@]) \ + struct TestClass##id; \ + typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[$1+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[$1+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { $1, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + + +#define THGM_MAKE_TEST$1(id, ret_type@[$2,1,$1:, param$2@]) \ + struct TestClass##id; \ + typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + \ + return 0; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 1); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, 3); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + \ + SourceHook::PassInfo paraminfos_##id[$1+1]; \ + SourceHook::PassInfo::V2Info paraminfos2_##id[$1+1]; \ + SourceHook::ProtoInfo protoinfo_##id = { $1, {0, 0, 0}, paraminfos_##id, \ + SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + \ + SourceHook::Impl::GenContext *g_Genc##id = NULL; \ + CAutoPtrDestruction g_Genc_ad##id(NULL); + +#define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ + void setuppi_##id() \ + { \ + paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ + \ + @[$2,1,$1: paraminfos_##id[$2].size = sizeof(p$2_type); paraminfos_##id[$2].type = p$2_passtype; paraminfos_##id[$2].flags = p$2_flags; @] \ + \ + @[$2,1,$1: paraminfos2_##id[$2].pNormalCtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; @] \ + @[$2,1,$1: paraminfos2_##id[$2].pCopyCtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; @] \ + @[$2,1,$1: paraminfos2_##id[$2].pDtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; @] \ + } + +@] + +#define THGM_SETUP_RI(id, ret_type, ret_passtype, ret_flags) \ + void setupri_##id() \ + { \ + protoinfo_##id.retPassInfo.size = sizeof(ret_type); \ + protoinfo_##id.retPassInfo.type = ret_passtype; \ + protoinfo_##id.retPassInfo.flags = ret_flags; \ + \ + protoinfo_##id.retPassInfo2.pNormalCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ + protoinfo_##id.retPassInfo2.pCopyCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ + protoinfo_##id.retPassInfo2.pDtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + } + +#define THGM_ADD_HOOK(id, num) \ + CAT4(hook, num, _, id) = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pTest##id), \ + 0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate##num), num >= 3); + +#define THGM_REMOVE_HOOK(id, num) \ + g_SHPtr->RemoveHookByID(CAT4(hook, num, _, id)); + +#define THGM_CALLS_void(id, call_params) \ + pTest##id->Func call_params; \ + SH_CALL(pTest##id, &TestClass##id::Func) call_params; + +#define THGM_DO_TEST_void(id, call_params) \ + setuppi_##id(); \ + g_Genc##id = new SourceHook::Impl::GenContext(&protoinfo_##id, 0, 0, g_SHPtr); \ + g_Genc_ad##id.set(g_Genc##id); \ + SourceHook::HookManagerPubFunc myhookman##id = g_Genc##id->Generate(); \ + int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ + \ + TestClass##id::ms_DoRecall = false; \ + TestClass##id *pTest##id = new TestClass##id; \ + CAutoPtrDestruction apd##id(pTest##id); \ + \ + /* no hooks - no hooks */ \ + PtrBuf_Clear(); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part1"); \ + \ + /* hook1 - no hooks */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part2"); \ + THGM_REMOVE_HOOK(id, 1); \ + \ + /* no hooks - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part3"); \ + THGM_REMOVE_HOOK(id, 3); \ + \ + /* hook1 - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part4"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 3); \ + \ + /* hook1, hook2 - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 2); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part5"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 2); \ + THGM_REMOVE_HOOK(id, 3); \ + /* hook1, hook2 - hook3, hook4 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 2); \ + THGM_ADD_HOOK(id, 3); \ + THGM_ADD_HOOK(id, 4); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part6"); \ + \ + /* hook1 - hook3, hook4, with recalls! */ \ + \ + TestClass##id::ms_DoRecall = true; \ + THGM_REMOVE_HOOK(id, 2); \ + THGM_CALLS_void(id, call_params); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params(0)), \ + new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params(1)), \ + new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params(2)), \ + /* sh_call one */ \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part7"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 3); \ + THGM_REMOVE_HOOK(id, 4); + + +#define THGM_CALLS(id, call_params, exp_ret_norm, exp_ret_shcall, err) \ + CHECK_COND(pTest##id->Func call_params == exp_ret_norm, err " /retcallnorm"); \ + CHECK_COND(SH_CALL(pTest##id, &TestClass##id::Func) call_params == exp_ret_shcall, err " /retcallshcall"); + +#define THGM_DO_TEST(id, call_params) \ + setuppi_##id(); \ + setupri_##id(); \ + g_Genc##id = new SourceHook::Impl::GenContext(&protoinfo_##id, 0, 0, g_SHPtr); \ + g_Genc_ad##id.set(g_Genc##id); \ + SourceHook::HookManagerPubFunc myhookman##id = g_Genc##id->Generate(); \ + int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ + \ + TestClass##id::ms_DoRecall = false; \ + TestClass##id *pTest##id = new TestClass##id; \ + CAutoPtrDestruction apd##id(pTest##id); \ + \ + /* no hooks - no hooks */ \ + PtrBuf_Clear(); \ + THGM_CALLS(id, call_params, 0, 0, "Part1"); \ + CHECK_STATES((&g_States, \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part1"); \ + \ + /* hook1 - no hooks */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_CALLS(id, call_params, 0, 0, "Part2"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part2"); \ + THGM_REMOVE_HOOK(id, 1); \ + \ + /* no hooks - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS(id, call_params, 0, 0, "Part3"); \ + CHECK_STATES((&g_States, \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part3"); \ + THGM_REMOVE_HOOK(id, 3); \ + \ + /* hook1 - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS(id, call_params, 0, 0, "Part4"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part4"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 3); \ + \ + /* hook1, hook2 - hook3 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 2); \ + THGM_ADD_HOOK(id, 3); \ + THGM_CALLS(id, call_params, 2, 0, "Part5"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part5"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 2); \ + THGM_REMOVE_HOOK(id, 3); \ + /* hook1, hook2 - hook3, hook4 */ \ + PtrBuf_Clear(); \ + THGM_ADD_HOOK(id, 1); \ + THGM_ADD_HOOK(id, 2); \ + THGM_ADD_HOOK(id, 3); \ + THGM_ADD_HOOK(id, 4); \ + THGM_CALLS(id, call_params, 4, 0, "Part6"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params), \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part6"); \ + \ + /* hook1 - hook3, hook4, with recalls! */ \ + \ + TestClass##id::ms_DoRecall = true; \ + THGM_REMOVE_HOOK(id, 2); \ + THGM_CALLS(id, call_params, 4, 0, "Part7"); \ + CHECK_STATES((&g_States, \ + new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params(0)), \ + new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ + new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params(1)), \ + new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params(2)), \ + /* sh_call one */ \ + new State_Func##id(pTest##id, ParamState_m##id call_params), \ + NULL), "Test" #id " Part7"); \ + THGM_REMOVE_HOOK(id, 1); \ + THGM_REMOVE_HOOK(id, 3); \ + THGM_REMOVE_HOOK(id, 4); From 972229cd9acde4029df78b33e0c063a5485c25f6 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 21 Oct 2007 21:55:17 +0000 Subject: [PATCH 03/41] Changed license in sourcehook_hookmangen_x86.h (agreed to by BAILOPAN and faluco) Updated MSVC7 proj file --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40533 --- sourcehook/sourcehook_hookmangen_x86.h | 39 +++++++------------------- sourcehook/test/msvc7/test.vcproj | 18 ++++++++++++ 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen_x86.h b/sourcehook/sourcehook_hookmangen_x86.h index 5a05acc..034dea4 100644 --- a/sourcehook/sourcehook_hookmangen_x86.h +++ b/sourcehook/sourcehook_hookmangen_x86.h @@ -1,32 +1,13 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourcePawn JIT SDK - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - */ +/* ======== SourceHook ======== +* vim: set ts=4 : +* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. +* No warranties of any kind +* +* License: zlib/libpng +* +* from the SourcePawn JIT SDK +* ============================ +*/ #ifndef __SOURCEHOOK_HOOKMANGEN_X86_H__ #define __SOURCEHOOK_HOOKMANGEN_X86_H__ diff --git a/sourcehook/test/msvc7/test.vcproj b/sourcehook/test/msvc7/test.vcproj index 243cf07..a909ea1 100644 --- a/sourcehook/test/msvc7/test.vcproj +++ b/sourcehook/test/msvc7/test.vcproj @@ -248,6 +248,9 @@ + + @@ -266,6 +269,9 @@ + + @@ -321,6 +327,12 @@ + + + + @@ -354,6 +366,9 @@ + + @@ -378,6 +393,9 @@ popd Outputs="..\sourcehook.h"/> + + Date: Thu, 1 Nov 2007 01:58:44 +0000 Subject: [PATCH 04/41] sh_memory now has CPageAlloc, testhookmangen.cpp contains a small test for it, GenBuffer uses CPageAlloc (with this simple change, thesthookmangen uses 124K less memory!) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40535 --- sourcehook/sh_list.h | 15 ++ sourcehook/sh_memory.h | 253 +++++++++++++++++++++++++++ sourcehook/sourcehook_hookmangen.cpp | 8 +- sourcehook/sourcehook_hookmangen.h | 149 ++++++++-------- sourcehook/test/main.cpp | 2 + sourcehook/test/msvc8/test.vcproj | 28 +++ sourcehook/test/testhookmangen.cpp | 72 +++++++- 7 files changed, 449 insertions(+), 78 deletions(-) diff --git a/sourcehook/sh_list.h b/sourcehook/sh_list.h index d5f37e8..391df29 100644 --- a/sourcehook/sh_list.h +++ b/sourcehook/sh_list.h @@ -103,6 +103,20 @@ namespace SourceHook insert(begin(), obj); } + void push_sorted(const T &obj) + { + iterator iter; + for (iter = begin(); iter != end(); ++iter) + { + if (obj < *iter) + { + insert(iter, obj); + return; + } + } + push_back(obj); + } + size_t size() const { return m_Size; @@ -301,6 +315,7 @@ namespace SourceHook return *this; } }; + }; //NAMESPACE #endif //_INCLUDE_CSDM_LIST_H diff --git a/sourcehook/sh_memory.h b/sourcehook/sh_memory.h index d626bb9..a8e7077 100644 --- a/sourcehook/sh_memory.h +++ b/sourcehook/sh_memory.h @@ -43,6 +43,7 @@ # error Unsupported OS/Compiler # endif +#include "sh_list.h" namespace SourceHook { @@ -181,6 +182,258 @@ namespace SourceHook #endif } } + + /* + Class which lets us allocate memory regions in special pages only meant for on the fly code generation. + + If we alloc with malloc and then set the page access type to read/exec only, other regions returned by + malloc that are in the same page would lose their write access as well and the process could crash. + + Allocating one page per code generation session is usually a waste of memory and on some plattforms also + a waste of virtual address space (Windows’ VirtualAlloc has a granularity of 64K). + + + IMPORTANT: the memory that Alloc() returns is not a in a defined state! + It could be in read+exec OR read+write mode. + -> call SetRE() or SetRW() before using allocated memory! + */ + class CPageAlloc + { + struct AllocationUnit + { + size_t begin_offset; + size_t size; + + AllocationUnit(size_t p_offs, size_t p_size) : begin_offset(p_offs), size(p_size) + { + } + + bool operator < (const AllocationUnit &other) const + { + return begin_offset < other.begin_offset; + } + }; + + typedef List AUList; + + struct AllocatedRegion + { + void *startPtr; + size_t size; + bool isolated; // may contain only one AU + AUList allocUnits; + + bool TryAlloc(size_t reqsize, void * &outAddr) + { + // Check for isolated + if (isolated && !allocUnits.empty()) + return false; + + // Find the smallest gap where req fits + size_t lastend = 0; + size_t smallestgap_pos = size + 1; + size_t smallestgap_size = size + 1; + + for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) + { + if (iter->begin_offset - lastend >= reqsize) + { + if (iter->begin_offset - lastend < smallestgap_size) + { + smallestgap_size = iter->begin_offset - lastend; + smallestgap_pos = lastend; + } + } + lastend = iter->begin_offset + iter->size; + } + + if (size - lastend >= reqsize) + { + if (size - lastend < smallestgap_size) + { + smallestgap_size = size - lastend; + smallestgap_pos = lastend; + } + } + + if (smallestgap_pos < size) + { + outAddr = reinterpret_cast(reinterpret_cast(startPtr) + smallestgap_pos); + allocUnits.push_sorted( AllocationUnit(smallestgap_pos, reqsize) ); + return true; + } + else + { + return false; + } + } + + bool TryFree(void *addr) + { + if (addr < startPtr || addr >= reinterpret_cast(reinterpret_cast(startPtr) + size)) + return false; + + size_t offs = reinterpret_cast(addr) - reinterpret_cast(startPtr); + + for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) + { + if (iter->begin_offset == offs) + { + allocUnits.erase(iter); + return true; + } + } + + return false; + } + + bool Contains(void *addr) + { + return addr >= startPtr && addr < reinterpret_cast(reinterpret_cast(startPtr) + size); + } + + void FreeRegion() + { +#ifdef __linux__ + munmap(startPtr, size); +#else + VirtualFree(startPtr, 0, MEM_RELEASE); +#endif + } + }; + + typedef List ARList; + + size_t m_PageSize; + ARList m_Regions; + + bool AddRegion(size_t minSize, bool isolated) + { + AllocatedRegion newRegion; + newRegion.startPtr = 0; + newRegion.isolated = isolated; + + // Compute real size -> align up to m_PageSize boundary + + newRegion.size = minSize - (minSize % m_PageSize); + if (newRegion.size < minSize) + newRegion.size += m_PageSize; + +#ifdef __linux__ + newRegion.startPtr = mmap(0, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAN_ANONYMOUS, -1); +#else + newRegion.startPtr = VirtualAlloc(NULL, newRegion.size, MEM_COMMIT, PAGE_READWRITE); +#endif + + if (newRegion.startPtr) + { + m_Regions.push_back(newRegion); + return true; + } + else + { + return false; + } + + } + + void *AllocPriv(size_t size, bool isolated) + { + void *addr; + + if (!isolated) + { + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + if (iter->TryAlloc(size, addr)) + return addr; + } + } + + if (!AddRegion(size, isolated)) + return NULL; + + bool tmp = m_Regions.back().TryAlloc(size, addr); + SH_ASSERT(tmp, ("TryAlloc fails after AddRegion")); + return addr; + } + + public: + CPageAlloc() + { +#ifdef __linux__ + m_PageSize = sysconf(_SC_PAGESIZE); +#else + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + m_PageSize = sysInfo.dwPageSize; +#endif + } + + ~CPageAlloc() + { + // Free all regions + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + iter->FreeRegion(); + } + } + + void *Alloc(size_t size) + { + return AllocPriv(size, false); + } + + void *AllocIsolated(size_t size) + { + return AllocPriv(size, true); + } + + void Free(void *ptr) + { + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + if (iter->TryFree(ptr)) + { + if (iter->allocUnits.empty()) + { + iter->FreeRegion(); + m_Regions.erase(iter); + } + break; + } + } + } + + void SetRE(void *ptr) + { + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + if (iter->Contains(ptr)) + { + SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_EXEC); + break; + } + } + } + + void SetRW(void *ptr) + { + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + if (iter->Contains(ptr)) + { + SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_WRITE); + break; + } + } + } + + size_t GetPageSize() + { + return m_PageSize; + } + }; } #endif diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index e00a50d..ef5c6a3 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -25,6 +25,8 @@ namespace SourceHook { namespace Impl { + CPageAlloc GenBuffer::ms_Allocator; + template jit_int32_t DownCastPtr(T ptr) { @@ -1123,6 +1125,9 @@ namespace SourceHook // m_HookfuncVfnPtr is a pointer to a void* because SH expects a pointer // into the hookman's vtable *m_HookfuncVfnptr = reinterpret_cast(m_HookFunc.GetData()); + + m_HookFunc.SetRE(); + return m_HookFunc.GetData(); } @@ -1211,8 +1216,7 @@ namespace SourceHook IA32_Pop_Reg(&m_PubFunc, REG_EBP); IA32_Return(&m_PubFunc); - SetMemAccess(reinterpret_cast(m_PubFunc.GetData()), m_PubFunc.GetSize(), - SH_MEM_READ | SH_MEM_EXEC); + m_PubFunc.SetRE(); return m_PubFunc; } diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 4bfeea7..1d95daf 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -42,84 +42,84 @@ namespace SourceHook class GenBuffer { - unsigned char *m_pData; - jitoffs_t m_Size; - jitoffs_t m_AllocatedSize; - - public: - GenBuffer() : m_pData(NULL), m_Size(0), m_AllocatedSize(0) - { - } - ~GenBuffer() - { - clear(); - } - jitoffs_t GetSize() - { - return m_Size; - } - unsigned char *GetData() - { - return m_pData; - } - - template void push(PT what) - { - push((const unsigned char *)&what, sizeof(PT)); - } - - void push(const unsigned char *data, jitoffs_t size) - { - jitoffs_t newSize = m_Size + size; - if (newSize > m_AllocatedSize) - { - m_AllocatedSize = newSize > m_AllocatedSize*2 ? newSize : m_AllocatedSize*2; - if (m_AllocatedSize < 64) - m_AllocatedSize = 64; - - unsigned char *newBuf; - try - { - //!!!! Better use of pages! or something! - newBuf = reinterpret_cast(VirtualAlloc(NULL, m_AllocatedSize, MEM_COMMIT, PAGE_READWRITE)); - } - catch (std::bad_alloc) - { - newBuf = NULL; - } - if (!newBuf) - { - SH_ASSERT(0, ("bad_alloc: couldn't allocate 0x%08X bytes of memory\n", m_AllocatedSize)); - return; - } - memcpy((void*)newBuf, (const void*)m_pData, m_Size); - if (m_pData) - VirtualFree(m_pData, 0, MEM_RELEASE); - m_pData = newBuf; - } - memcpy((void*)(m_pData + m_Size), (const void*)data, size); - m_Size = newSize; - } - - template void rewrite(jitoffs_t offset, PT what) - { - rewrite(offset, (const unsigned char *)&what, sizeof(PT)); - } - - void rewrite(jitoffs_t offset, const unsigned char *data, jitoffs_t size) + static CPageAlloc ms_Allocator; + + unsigned char *m_pData; + jitoffs_t m_Size; + jitoffs_t m_AllocatedSize; + + public: + GenBuffer() : m_pData(NULL), m_Size(0), m_AllocatedSize(0) + { + } + ~GenBuffer() + { + clear(); + } + jitoffs_t GetSize() + { + return m_Size; + } + unsigned char *GetData() + { + return m_pData; + } + + template void push(PT what) + { + push((const unsigned char *)&what, sizeof(PT)); + } + + void push(const unsigned char *data, jitoffs_t size) + { + jitoffs_t newSize = m_Size + size; + if (newSize > m_AllocatedSize) + { + m_AllocatedSize = newSize > m_AllocatedSize*2 ? newSize : m_AllocatedSize*2; + if (m_AllocatedSize < 64) + m_AllocatedSize = 64; + + unsigned char *newBuf; + newBuf = reinterpret_cast(ms_Allocator.Alloc(m_AllocatedSize)); + ms_Allocator.SetRW(newBuf); + if (!newBuf) + { + SH_ASSERT(0, ("bad_alloc: couldn't allocate 0x%08X bytes of memory\n", m_AllocatedSize)); + return; + } + memcpy((void*)newBuf, (const void*)m_pData, m_Size); + if (m_pData) + ms_Allocator.Free(reinterpret_cast(m_pData)); + m_pData = newBuf; + } + memcpy((void*)(m_pData + m_Size), (const void*)data, size); + m_Size = newSize; + } + + template void rewrite(jitoffs_t offset, PT what) + { + rewrite(offset, (const unsigned char *)&what, sizeof(PT)); + } + + void rewrite(jitoffs_t offset, const unsigned char *data, jitoffs_t size) { SH_ASSERT(offset + size <= m_AllocatedSize, ("rewrite too far")); memcpy((void*)(m_pData + offset), (const void*)data, size); - } - - void clear() - { - if (m_pData) - VirtualFree(m_pData, 0, MEM_RELEASE); - m_pData = NULL; - m_Size = 0; - m_AllocatedSize = 0; + } + + void clear() + { + if (m_pData) + ms_Allocator.Free(reinterpret_cast(m_pData)); + m_pData = NULL; + m_Size = 0; + m_AllocatedSize = 0; + } + + void SetRE() + { + ms_Allocator.SetRE(reinterpret_cast(m_pData)); } operator unsigned char *() @@ -149,7 +149,6 @@ namespace SourceHook { offs = get_outputpos() - offs; } - // :TODO: real buffer which uses virtualalloc correctly }; class GenContext diff --git a/sourcehook/test/main.cpp b/sourcehook/test/main.cpp index c7946bf..bdf3216 100644 --- a/sourcehook/test/main.cpp +++ b/sourcehook/test/main.cpp @@ -47,6 +47,7 @@ DECL_TEST(Ref); DECL_TEST(RefRet); DECL_TEST(VPHooks); DECL_TEST(HookManGen); +DECL_TEST(CPageAlloc); // in testhookmangen.cpp int main(int argc, char *argv[]) { @@ -70,6 +71,7 @@ int main(int argc, char *argv[]) DO_TEST(RefRet); DO_TEST(VPHooks); DO_TEST(HookManGen); + DO_TEST(CPageAlloc); cout << endl << "----" << endl << "Passed: " << passed << endl << "Failed: " << failed << endl; cout << "Total: " << passed + failed << endl; diff --git a/sourcehook/test/msvc8/test.vcproj b/sourcehook/test/msvc8/test.vcproj index ae768e5..a11c8e1 100644 --- a/sourcehook/test/msvc8/test.vcproj +++ b/sourcehook/test/msvc8/test.vcproj @@ -371,6 +371,10 @@ RelativePath="..\..\sourcehook.cpp" > + + @@ -395,6 +399,10 @@ RelativePath="..\testbail2.cpp" > + + @@ -431,6 +439,10 @@ RelativePath="..\testrefret.cpp" > + + + + @@ -460,6 +476,14 @@ RelativePath="..\..\sourcehook.h" > + + + + @@ -500,6 +524,10 @@ /> + + The difference is at least one page + CHECK_COND(static_cast(abs(test4[1] - test4[0])) >= ps, "Part 3.1"); + CHECK_COND(static_cast(abs(test4[2] - test4[1])) >= ps, "Part 3.2"); + CHECK_COND(static_cast(abs(test4[3] - test4[2])) >= ps, "Part 3.3"); + + CHECK_COND(static_cast(abs(test4[5] - test4[4])) >= ps, "Part 3.4"); + CHECK_COND(static_cast(abs(test4[6] - test4[5])) >= ps, "Part 3.5"); + CHECK_COND(static_cast(abs(test4[7] - test4[6])) >= ps, "Part 3.6"); + + // Thus i can set everything except for test4[2] to RE and still write to test4[2] + + alloc.SetRW(test4[2]); + + alloc.SetRE(test4[0]); + alloc.SetRE(test4[1]); + alloc.SetRE(test4[3]); + alloc.SetRE(test4[4]); + alloc.SetRE(test4[5]); + alloc.SetRE(test4[6]); + alloc.SetRE(test4[7]); + + memset((void*)test4[2], 0, ps / 4); + + return true; +} \ No newline at end of file From 83c51e6cfa16ea066bcf4916689ceb434c9387b2 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Thu, 1 Nov 2007 17:29:39 +0000 Subject: [PATCH 05/41] Implemented memory returns on MSVC for POD types. --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40536 --- sourcehook/generate/sourcehook.h | 8 +- sourcehook/generate/sourcehook.hxx | 8 +- sourcehook/sourcehook.h | 8 +- sourcehook/sourcehook_hookmangen.cpp | 203 +++++++++++++++++++--- sourcehook/sourcehook_hookmangen.h | 6 +- sourcehook/sourcehook_impl_chookmaninfo.h | 7 +- sourcehook/sourcehook_impl_cproto.h | 5 + sourcehook/test/msvc8/test.vcproj | 27 ++- sourcehook/test/testhookmangen.cpp | 139 +++++++++------ sourcehook/test/testhookmangen.h | 147 +++++++++------- sourcehook/test/testhookmangen.hxx | 39 ++++- 11 files changed, 447 insertions(+), 150 deletions(-) diff --git a/sourcehook/generate/sourcehook.h b/sourcehook/generate/sourcehook.h index 03149e8..d8003c0 100644 --- a/sourcehook/generate/sourcehook.h +++ b/sourcehook/generate/sourcehook.h @@ -173,7 +173,13 @@ namespace SourceHook PassFlag_ODtor = (1<<2), /**< Object has a destructor */ PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */ PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */ - PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */ + PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */ + + // The following two flags are only relevant for byval return types. + // SH tries to auto-detect these + // If you want to override SH's auto-detection, pass them in yourself + PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */ + PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */ }; size_t size; //!< Size of the data being passed diff --git a/sourcehook/generate/sourcehook.hxx b/sourcehook/generate/sourcehook.hxx index cefaf00..2361b94 100755 --- a/sourcehook/generate/sourcehook.hxx +++ b/sourcehook/generate/sourcehook.hxx @@ -173,7 +173,13 @@ namespace SourceHook PassFlag_ODtor = (1<<2), /**< Object has a destructor */ PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */ PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */ - PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */ + PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */ + + // The following two flags are only relevant for byval return types. + // SH tries to auto-detect these + // If you want to override SH's auto-detection, pass them in yourself + PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */ + PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */ }; size_t size; //!< Size of the data being passed diff --git a/sourcehook/sourcehook.h b/sourcehook/sourcehook.h index 03149e8..d8003c0 100644 --- a/sourcehook/sourcehook.h +++ b/sourcehook/sourcehook.h @@ -173,7 +173,13 @@ namespace SourceHook PassFlag_ODtor = (1<<2), /**< Object has a destructor */ PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */ PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */ - PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */ + PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */ + + // The following two flags are only relevant for byval return types. + // SH tries to auto-detect these + // If you want to override SH's auto-detection, pass them in yourself + PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */ + PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */ }; size_t size; //!< Size of the data being passed diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index ef5c6a3..702434a 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -306,7 +306,7 @@ namespace SourceHook } // May not touch eax! - jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset) + jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to) { jit_int32_t added_to_stack = 0; jit_int32_t ret = 0; @@ -348,14 +348,23 @@ namespace SourceHook } added_to_stack += ret; } + + // Memory return support + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + { + // push address where to save it! + int reg = NextRegEBX_ECX_EDX(); + IA32_Lea_DispRegImmAuto(&m_HookFunc, reg, REG_EBP, save_ret_to); + IA32_Push_Reg(&m_HookFunc, reg); + + added_to_stack += SIZE_PTR; + } + return added_to_stack; } void GenContext::SaveRetVal(int v_where) { - // :TODO: assign op support - // :TODO: memory return support - size_t size = m_Proto.GetRet().size; if (size == 0) { @@ -363,6 +372,11 @@ namespace SourceHook return; } + // Memory return: + // PushParams already did everything that was neccessary + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + return; + if (m_Proto.GetRet().type == PassInfo::PassType_Float) { if (size == 4) @@ -391,14 +405,35 @@ namespace SourceHook IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where); IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EDX, v_where + 4); } - else + } + else if (m_Proto.GetRet().type == PassInfo::PassType_Object) + { + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetReg) { - // size >8: return in memory - // :TODO: - // add flag: MSVC_RetInMemory? + if (size <= 4) + { + // size <= 4: return in EAX + // We align <4 sizes up to 4 + + // mov [ebp + v_plugin_ret], eax + IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where); + } + else if (size <= 8) + { + // size <= 4: return in EAX:EDX + // We align 4 8 !")); + } } } - // :TODO: object } void GenContext::ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret) @@ -559,7 +594,7 @@ namespace SourceHook IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_retptr); } - void GenContext::DoReturn(int v_retptr) + void GenContext::DoReturn(int v_retptr, int v_memret_outaddr) { size_t size = m_Proto.GetRet().size; if (!size) @@ -579,14 +614,14 @@ namespace SourceHook else if (size == 8) IA32_Fld_Mem64(&m_HookFunc, REG_ECX); } - else if (m_Proto.GetRet().type == PassInfo::PassType_Basic) + else if (m_Proto.GetRet().type == PassInfo::PassType_Basic || + ((m_Proto.GetRet().type == PassInfo::PassType_Object) && (m_Proto.GetRet().flags & PassInfo::PassFlag_RetReg)) ) { if (size <= 4) { // size <= 4: return in EAX // We align <4 sizes up to 4 - // mov eax, [ecx] IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); } @@ -603,11 +638,79 @@ namespace SourceHook else { // size >8: return in memory - // :TODO: - // add flag: MSVC_RetInMemory? + // handled later } } - // :TODO: object + + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + { + // *memret_outaddr = plugin_ret + if (m_Proto.GetRet().pAssignOperator) + { + // mov edx, ecx <-- src ( we set ecx to [ebp+v_retptr] before ) + // msvc: ecx = [ebp + v_memret_outaddr] <-- dest addr + // gcc: push [ebp + v_memret_outaddr] <-- dest addr + // push edx <-- src addr + // call it + + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_ECX, MOD_REG); + +#if SH_COMP == SH_COMP_MSVC + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_memret_outaddr); +#elif SH_COMP == SH_COMP_GCC + IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, v_memret_outaddr); +#endif + IA32_Push_Reg(&m_HookFunc, REG_EDX); + + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + else + { + jit_uint32_t dwords = DownCastSize(m_Proto.GetRet().size) / 4; + jit_uint32_t bytes = DownCastSize(m_Proto.GetRet().size) % 4; + + // bitwise copy + + //cld + //push edi + //push esi + //mov edi, [ebp+v_memret_outaddr] <-- destination + //mov esi, ecx <-- src ( we set ecx to [ebp+v_retptr] before ) + //if dwords + // mov ecx, + // rep movsd + //if bytes + // mov ecx, + // rep movsb + //pop esi + //pop edi + + IA32_Cld(&m_HookFunc); + IA32_Push_Reg(&m_HookFunc, REG_EDI); + IA32_Push_Reg(&m_HookFunc, REG_ESI); + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EDI, REG_EBP, v_memret_outaddr); + IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESI, REG_ECX, MOD_REG); + if (dwords) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); + IA32_Rep(&m_HookFunc); + IA32_Movsd(&m_HookFunc); + } + if (bytes) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); + IA32_Rep(&m_HookFunc); + IA32_Movsb(&m_HookFunc); + } + IA32_Pop_Reg(&m_HookFunc, REG_ESI); + IA32_Pop_Reg(&m_HookFunc, REG_EDI); + } + + // In both cases: return the pointer in EAX + // mov eax, [ebp + v_memret_outaddr] + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_memret_outaddr); + } } void GenContext::GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, @@ -656,7 +759,7 @@ namespace SourceHook // eax = [ecx] // eax = [eax+2*SIZE_PTR] // call eax - jit_int32_t gcc_clean_bytes = PushParams(base_param_offset); + jit_int32_t gcc_clean_bytes = PushParams(base_param_offset, v_plugin_ret); IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); #if SH_COMP == SH_COMP_GCC @@ -718,6 +821,13 @@ namespace SourceHook { acc += GetStackSize(m_Proto.GetParam(i)); } + + // Memory return: address is first param + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + acc += SIZE_PTR; + + // :TODO: cdecl: THIS POINTER AS FIRST PARAM!!! + return acc; } @@ -775,7 +885,7 @@ namespace SourceHook m_HookFunc.start_count(counter2); // push params - jit_int32_t gcc_clean_bytes = PushParams(param_base_offs); + jit_int32_t gcc_clean_bytes = PushParams(param_base_offs, v_orig_ret); // thisptr IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); @@ -1032,11 +1142,19 @@ namespace SourceHook const jit_int8_t v_pContext = -24 + addstackoffset; #if SH_COMP == SH_COMP_GCC - const jit_int32_t param_base_offs = 16; + jit_int32_t param_base_offs = 16; #elif SH_COMP == SH_COMP_MSVC - const jit_int32_t param_base_offs = 12; + jit_int32_t param_base_offs = 12; #endif + // Memory return: first param is the address + jit_int32_t v_memret_addr = 0; + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + { + v_memret_addr = param_base_offs; + param_base_offs += SIZE_PTR; + } + jit_int32_t v_ret_ptr = -28 + addstackoffset; jit_int32_t v_orig_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 1; jit_int32_t v_override_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 2; @@ -1111,7 +1229,7 @@ namespace SourceHook cur_param_pos += GetStackSize(pi); } - DoReturn(v_ret_ptr); + DoReturn(v_ret_ptr, v_memret_addr); // !! :TODO: Call destructors of orig_ret/ ... @@ -1254,6 +1372,49 @@ namespace SourceHook return true; } + void GenContext::AutoDetectRetType() + { + IntPassInfo &pi = m_Proto.GetRet(); + + // Only relevant for byval types + if (pi.flags & PassInfo::PassFlag_ByVal) + { + // Basic + float: + if (pi.type == PassInfo::PassType_Basic || + pi.type == PassInfo::PassType_Float) + { + // <= 8 bytes: + // _always_ in registers, no matter what the user says + if (pi.size <= 8) + { + pi.flags &= ~PassInfo::PassFlag_RetMem; + pi.flags |= PassInfo::PassFlag_RetReg; + } + else + { + // Does this even exist? No idea, if it does: in memory! + pi.flags &= ~PassInfo::PassFlag_RetReg; + pi.flags |= PassInfo::PassFlag_RetMem; + } + } + // Object: + else if (pi.type == PassInfo::PassType_Object) + { + // If the user says nothing, auto-detect + if ((pi.flags & (PassInfo::PassFlag_RetMem | PassInfo::PassFlag_RetReg)) == 0) + { +#if SH_COMP == SH_COMP_MSVC + // MSVC seems to return _all_ structs, classes, unions in memory + pi.flags |= PassInfo::PassFlag_RetMem; +#elif SH_COMP == SH_COMP_GCC + // Same goes for GCC :) + pi.flags |= PassInfo::PassFlag_RetMem; +#endif + } + } + } + } + HookManagerPubFunc GenContext::Generate() { Clear(); @@ -1270,6 +1431,8 @@ namespace SourceHook return NULL; } + AutoDetectRetType(); + if (m_Proto.GetConvention() != ProtoInfo::CallConv_Cdecl && m_Proto.GetConvention() != ProtoInfo::CallConv_ThisCall) { diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 1d95daf..7ae3b3d 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -87,6 +87,7 @@ namespace SourceHook SH_ASSERT(0, ("bad_alloc: couldn't allocate 0x%08X bytes of memory\n", m_AllocatedSize)); return; } + memset((void*)newBuf, 0xCC, m_AllocatedSize); // :TODO: remove this ! memcpy((void*)newBuf, (const void*)m_pData, m_Size); if (m_pData) ms_Allocator.Free(reinterpret_cast(m_pData)); @@ -183,7 +184,7 @@ namespace SourceHook // Param push - jit_int32_t PushParams(jit_int32_t param_base_offset); + jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to); // save_ret_to only used for memory returns jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi); @@ -194,7 +195,7 @@ namespace SourceHook void ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret); void PrepareReturn(int v_status, int v_pContext, int v_retptr); - void DoReturn(int v_retptr); + void DoReturn(int v_retptr, int v_memret_outaddr); // Call hooks void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, @@ -212,6 +213,7 @@ namespace SourceHook void CallEndContext(int v_pContext); // Level 2 -> called from Generate() + void AutoDetectRetType(); bool PassInfoSupported(const IntPassInfo &pi, bool is_ret); void Clear(); void BuildProtoInfo(); diff --git a/sourcehook/sourcehook_impl_chookmaninfo.h b/sourcehook/sourcehook_impl_chookmaninfo.h index f79355a..176f164 100644 --- a/sourcehook/sourcehook_impl_chookmaninfo.h +++ b/sourcehook/sourcehook_impl_chookmaninfo.h @@ -13,6 +13,7 @@ #include "sh_list.h" #include "sourcehook_impl_cproto.h" +#include "sourcehook_hookmangen.h" namespace SourceHook { @@ -72,7 +73,7 @@ namespace SourceHook } // *** IHookManagerInfo interface *** - void SetInfo(int hookman_version, int vtbloffs, int vtblidx, + void SetInfo(int hookman_version, int vtbloffs, int vtblidx, ProtoInfo *proto, void *hookfunc_vfnptr); }; @@ -194,5 +195,5 @@ namespace SourceHook } } -#endif - +#endif + diff --git a/sourcehook/sourcehook_impl_cproto.h b/sourcehook/sourcehook_impl_cproto.h index bfe85df..c8e9979 100644 --- a/sourcehook/sourcehook_impl_cproto.h +++ b/sourcehook/sourcehook_impl_cproto.h @@ -92,6 +92,11 @@ namespace SourceHook return m_RetPassInfo; } + IntPassInfo & GetRet() + { + return m_RetPassInfo; + } + int GetConvention() const { return m_Convention; diff --git a/sourcehook/test/msvc8/test.vcproj b/sourcehook/test/msvc8/test.vcproj index a11c8e1..c7c1881 100644 --- a/sourcehook/test/msvc8/test.vcproj +++ b/sourcehook/test/msvc8/test.vcproj @@ -303,6 +303,7 @@ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE" StringPooling="true" MinimalRebuild="true" + ExceptionHandling="1" BasicRuntimeChecks="3" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -488,6 +489,30 @@ RelativePath="..\..\sourcehook_impl.h" > + + + + + + + + + + + + @@ -519,7 +544,7 @@ > diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index ab0557a..7ddcca8 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -18,53 +18,6 @@ namespace { - #include "testhookmangen.h" - - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - // PtrBuf(ptr) gives ptrs unique numbers - // in the order they appear - SourceHook::List g_PtrHash; - - bool g_Inside_LeafFunc = false; // inside a hook or a func - - template - int PtrBuf(T ptr) - { - int a = 0; - - const void *vptr = reinterpret_cast(ptr); - for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter) - { - if (*iter == vptr) - return a; - else - ++a; - } - g_PtrHash.push_back(vptr); - return static_cast(g_PtrHash.size()) - 1; - } - - template - T PtrBufPtr(T ptr) - { - PtrBuf(ptr); - return ptr; - } - - void PtrBuf_Clear(int leave_in = 0) - { - for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();) - { - if (--leave_in < 0) - iter = g_PtrHash.erase(iter); - else - ++iter; - } - } - // POD / Object types template struct POD @@ -75,6 +28,16 @@ namespace { return memcmp(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE) == 0; } + + bool operator==(char other) + { + for (int i = 0; i < MYSIZE; ++i) + { + if (x[i] != other) + return false; + } + return true; + } }; template @@ -132,6 +95,53 @@ namespace return os; } + #include "testhookmangen.h" + + StateList g_States; + SourceHook::ISourceHook *g_SHPtr; + SourceHook::Plugin g_PLID; + + // PtrBuf(ptr) gives ptrs unique numbers + // in the order they appear + SourceHook::List g_PtrHash; + + bool g_Inside_LeafFunc = false; // inside a hook or a func + + template + int PtrBuf(T ptr) + { + int a = 0; + + const void *vptr = reinterpret_cast(ptr); + for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter) + { + if (*iter == vptr) + return a; + else + ++a; + } + g_PtrHash.push_back(vptr); + return static_cast(g_PtrHash.size()) - 1; + } + + template + T PtrBufPtr(T ptr) + { + PtrBuf(ptr); + return ptr; + } + + void PtrBuf_Clear(int leave_in = 0) + { + for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();) + { + if (--leave_in < 0) + iter = g_PtrHash.erase(iter); + else + ++iter; + } + } + // "Increment" something: (reproducible change for recall tests) // integer: ++ @@ -267,6 +277,31 @@ namespace THGM_MAKE_TEST0(105, double); THGM_SETUP_PI0(105); THGM_SETUP_RI(105, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); + + // pod 1-13 + THGM_MAKE_TEST1(106, POD<1>, int); + THGM_SETUP_PI1(106, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal + ); + THGM_SETUP_RI(106, POD<1>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1(107, POD<4>, int); + THGM_SETUP_PI1(107, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal + ); + THGM_SETUP_RI(107, POD<4>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1(108, POD<8>, int); + THGM_SETUP_PI1(108, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal + ); + THGM_SETUP_RI(108, POD<8>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1(109, POD<13>, int); + THGM_SETUP_PI1(109, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal + ); + THGM_SETUP_RI(109, POD<13>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); } bool TestHookManGen(std::string &error) @@ -292,10 +327,10 @@ bool TestHookManGen(std::string &error) double b = 233.33; THGM_DO_TEST_void(7, (a, b)); - POD<7> pod7 = {78}; + POD<7> pod7 = MakeRet< POD<7> >::Do(78); THGM_DO_TEST_void(8, (pod7)); - POD<600> pod600 = {34}; + POD<600> pod600 = MakeRet< POD<600> >::Do(34); THGM_DO_TEST_void(9, (pod600)); THGM_DO_TEST_void(10, (pod600)); @@ -461,6 +496,12 @@ bool TestHookManGen(std::string &error) THGM_DO_TEST(105, ()); + // pod returns + THGM_DO_TEST(106, (5)); + THGM_DO_TEST(107, (5)); + THGM_DO_TEST(108, (5)); + THGM_DO_TEST(109, (5)); + // Shutdown now! // If we don't SH will auto-shutdown _after_ genc's destructor is called // -> crash diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index cd6f3ed..7d839d4 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -84,6 +84,27 @@ template struct MyRefCarrier }; }; +// Return value maker +template +struct MakeRet +{ + static T Do(int a) + { + return static_cast(a); + } +}; + +template +struct MakeRet< POD > +{ + static POD Do(int a) + { + POD x; + memset(reinterpret_cast(x.x), a, SIZE); + return x; + } +}; + // Stores parameter status @@ -509,7 +530,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id())); \ g_Inside_LeafFunc = false; \ \ - return 0; \ + return MakeRet::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -522,10 +543,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 1); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -538,10 +559,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -554,10 +575,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 3); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -570,10 +591,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ }; \ }; \ }; \ @@ -718,7 +739,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \ g_Inside_LeafFunc = false; \ \ - return 0; \ + return MakeRet::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -731,10 +752,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 1); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -747,10 +768,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -763,10 +784,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 3); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -779,10 +800,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ }; \ }; \ }; \ @@ -927,7 +948,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \ g_Inside_LeafFunc = false; \ \ - return 0; \ + return MakeRet::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -940,10 +961,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 1); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -956,10 +977,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -972,10 +993,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 3); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -988,10 +1009,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ }; \ }; \ }; \ @@ -1136,7 +1157,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \ g_Inside_LeafFunc = false; \ \ - return 0; \ + return MakeRet::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -1149,10 +1170,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 1); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -1165,10 +1186,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -1181,10 +1202,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 3); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1197,10 +1218,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ }; \ }; \ }; \ @@ -1345,7 +1366,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \ g_Inside_LeafFunc = false; \ \ - return 0; \ + return MakeRet::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -1358,10 +1379,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 1); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -1374,10 +1395,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -1390,10 +1411,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 3); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1406,10 +1427,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ }; \ }; \ }; \ @@ -1554,7 +1575,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \ g_Inside_LeafFunc = false; \ \ - return 0; \ + return MakeRet::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -1567,10 +1588,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 1); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -1583,10 +1604,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -1599,10 +1620,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 3); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1615,10 +1636,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ }; \ }; \ }; \ @@ -1763,7 +1784,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ g_Inside_LeafFunc = false; \ \ - return 0; \ + return MakeRet::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -1776,10 +1797,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 1); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -1792,10 +1813,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -1808,10 +1829,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 3); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1824,10 +1845,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ }; \ }; \ }; \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 80800e7..7ff9e24 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -84,6 +84,27 @@ template struct MyRefCarrier }; }; +// Return value maker +template +struct MakeRet +{ + static T Do(int a) + { + return a; + } +}; + +template +struct MakeRet< POD > +{ + static POD Do(int a) + { + POD x; + memset(reinterpret_cast(x.x), a, SIZE); + return x; + } +}; + // Stores parameter status @[$1,0,$a: @@ -251,7 +272,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ g_Inside_LeafFunc = false; \ \ - return 0; \ + return MakeRet::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -264,10 +285,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 1); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -280,10 +301,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 2); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -296,10 +317,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, 3); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -312,10 +333,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, 4); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ }; \ }; \ }; \ From ebf7cf8feede57ca083e28cbaa3f5bb71ce3ff0f Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 2 Nov 2007 00:53:32 +0000 Subject: [PATCH 06/41] Return type can now also be an object with normal ctor/copy ctor/dtor/assign op --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40537 --- sourcehook/sourcehook_hookmangen.cpp | 336 +++++++++++++++------------ sourcehook/sourcehook_hookmangen.h | 22 +- sourcehook/test/testhookmangen.cpp | 273 +++++++++++++++++++++- sourcehook/test/testhookmangen.h | 141 ++++++----- sourcehook/test/testhookmangen.hxx | 27 ++- 5 files changed, 554 insertions(+), 245 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 702434a..12eed3d 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -147,6 +147,47 @@ namespace SourceHook } } + void GenContext::BitwiseCopy_Setup() + { + //cld + //push edi + //push esi + + IA32_Cld(&m_HookFunc); + IA32_Push_Reg(&m_HookFunc, REG_EDI); + IA32_Push_Reg(&m_HookFunc, REG_ESI); + } + + void GenContext::BitwiseCopy_Do(size_t size) + { + jit_uint32_t dwords = DownCastSize(size) / 4; + jit_uint32_t bytes = DownCastSize(size) % 4; + + //if dwords + // mov ecx, + // rep movsd + //if bytes + // mov ecx, + // rep movsb + //pop esi + //pop edi + + if (dwords) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); + IA32_Rep(&m_HookFunc); + IA32_Movsd(&m_HookFunc); + } + if (bytes) + { + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); + IA32_Rep(&m_HookFunc); + IA32_Movsb(&m_HookFunc); + } + IA32_Pop_Reg(&m_HookFunc, REG_ESI); + IA32_Pop_Reg(&m_HookFunc, REG_EDI); + } + jit_int32_t GenContext::PushRef(jit_int32_t param_offset, const IntPassInfo &pi) { // push [ebp+] @@ -262,51 +303,24 @@ namespace SourceHook } else { - jit_uint32_t dwords = DownCastSize(pi.size) / 4; - jit_uint32_t bytes = DownCastSize(pi.size) % 4; - // bitwise copy - //cld - //push edi - //push esi + + BitwiseCopy_Setup(); + //lea edi, [esp+8] //lea esi, [ebp+] - //if dwords - // mov ecx, - // rep movsd - //if bytes - // mov ecx, - // rep movsb - //pop esi - //pop edi - - IA32_Cld(&m_HookFunc); - IA32_Push_Reg(&m_HookFunc, REG_EDI); - IA32_Push_Reg(&m_HookFunc, REG_ESI); IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_EDI, REG_NOIDX, REG_ESP, NOSCALE, 8); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, param_offset); - if (dwords) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); - IA32_Rep(&m_HookFunc); - IA32_Movsd(&m_HookFunc); - } - if (bytes) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); - IA32_Rep(&m_HookFunc); - IA32_Movsb(&m_HookFunc); - } - IA32_Pop_Reg(&m_HookFunc, REG_ESI); - IA32_Pop_Reg(&m_HookFunc, REG_EDI); + + BitwiseCopy_Do(pi.size); } return DownCastSize(pi.size); } // May not touch eax! - jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to) + jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to, int v_place_for_memret) { jit_int32_t added_to_stack = 0; jit_int32_t ret = 0; @@ -354,7 +368,8 @@ namespace SourceHook { // push address where to save it! int reg = NextRegEBX_ECX_EDX(); - IA32_Lea_DispRegImmAuto(&m_HookFunc, reg, REG_EBP, save_ret_to); + IA32_Lea_DispRegImmAuto(&m_HookFunc, reg, REG_EBP, + MemRetWithTempObj() ? v_place_for_memret : save_ret_to); IA32_Push_Reg(&m_HookFunc, reg); added_to_stack += SIZE_PTR; @@ -363,7 +378,7 @@ namespace SourceHook return added_to_stack; } - void GenContext::SaveRetVal(int v_where) + void GenContext::SaveRetVal(int v_where, int v_place_for_memret) { size_t size = m_Proto.GetRet().size; if (size == 0) @@ -373,9 +388,65 @@ namespace SourceHook } // Memory return: - // PushParams already did everything that was neccessary if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - return; + { + if (MemRetWithTempObj()) + { + // *v_where = *v_place_for_memret + + // if we have an assign operator, use that + if (m_Proto.GetRet().pAssignOperator) + { + // lea edx, [ebp + v_place_for_memret] <-- src addr + // lea ecx, [ebp + v_where] <-- dest addr + // gcc: push ecx + // push edx + // call it + + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_place_for_memret); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_where); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Push_Reg(&m_HookFunc, REG_EDX); + + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + else + { + // bitwise copy + BitwiseCopy_Setup(); + + //lea edi, [evp+v_where] <-- destination + //lea esi, [ebp+v_place_for_memret] <-- src + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, v_where); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_place_for_memret); + + BitwiseCopy_Do(m_Proto.GetRet().size); + } + + // Then: destruct *v_place_for_memret if required + if (m_Proto.GetRet().pDtor) + { + //lea ecx, [ebp+v_place_for_memret] + //gcc: push ecx + //call it + + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_place_for_memret); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + } + else + { + // Already copied to correct address -> we're done + return; + } + } if (m_Proto.GetRet().type == PassInfo::PassType_Float) { @@ -436,6 +507,13 @@ namespace SourceHook } } + bool GenContext::MemRetWithTempObj() + { + // Memory return AND (has destructor OR has assign operator) + return ((m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + && (m_Proto.GetRet().flags & (PassInfo::PassFlag_ODtor | PassInfo::PassFlag_AssignOp))); + } + void GenContext::ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret) { // only for non-void functions! @@ -500,44 +578,15 @@ namespace SourceHook } else { - jit_uint32_t dwords = DownCastSize(m_Proto.GetRet().size) / 4; - jit_uint32_t bytes = DownCastSize(m_Proto.GetRet().size) % 4; - // bitwise copy - - //cld - //push edi - //push esi + BitwiseCopy_Setup(); + //mov edi, eax <-- destination //lea esi, [ebp+v_plugin_ret] <-- src - //if dwords - // mov ecx, - // rep movsd - //if bytes - // mov ecx, - // rep movsb - //pop esi - //pop edi - - IA32_Cld(&m_HookFunc); - IA32_Push_Reg(&m_HookFunc, REG_EDI); - IA32_Push_Reg(&m_HookFunc, REG_ESI); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDI, REG_EAX, MOD_REG); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_plugin_ret); - if (dwords) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); - IA32_Rep(&m_HookFunc); - IA32_Movsd(&m_HookFunc); - } - if (bytes) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); - IA32_Rep(&m_HookFunc); - IA32_Movsb(&m_HookFunc); - } - IA32_Pop_Reg(&m_HookFunc, REG_ESI); - IA32_Pop_Reg(&m_HookFunc, REG_EDI); + + BitwiseCopy_Do(m_Proto.GetRet().size); } m_HookFunc.end_count(counter); @@ -600,7 +649,6 @@ namespace SourceHook if (!size) return; - // :TODO: assign op support // :TODO: memory return support // Get real ret pointer into ecx @@ -645,7 +693,7 @@ namespace SourceHook if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) { // *memret_outaddr = plugin_ret - if (m_Proto.GetRet().pAssignOperator) + if (m_Proto.GetRet().pCopyCtor) { // mov edx, ecx <-- src ( we set ecx to [ebp+v_retptr] before ) // msvc: ecx = [ebp + v_memret_outaddr] <-- dest addr @@ -662,49 +710,20 @@ namespace SourceHook #endif IA32_Push_Reg(&m_HookFunc, REG_EDX); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pCopyCtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); } else { - jit_uint32_t dwords = DownCastSize(m_Proto.GetRet().size) / 4; - jit_uint32_t bytes = DownCastSize(m_Proto.GetRet().size) % 4; - // bitwise copy + BitwiseCopy_Setup(); - //cld - //push edi - //push esi //mov edi, [ebp+v_memret_outaddr] <-- destination //mov esi, ecx <-- src ( we set ecx to [ebp+v_retptr] before ) - //if dwords - // mov ecx, - // rep movsd - //if bytes - // mov ecx, - // rep movsb - //pop esi - //pop edi - - IA32_Cld(&m_HookFunc); - IA32_Push_Reg(&m_HookFunc, REG_EDI); - IA32_Push_Reg(&m_HookFunc, REG_ESI); IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EDI, REG_EBP, v_memret_outaddr); IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESI, REG_ECX, MOD_REG); - if (dwords) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); - IA32_Rep(&m_HookFunc); - IA32_Movsd(&m_HookFunc); - } - if (bytes) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); - IA32_Rep(&m_HookFunc); - IA32_Movsb(&m_HookFunc); - } - IA32_Pop_Reg(&m_HookFunc, REG_ESI); - IA32_Pop_Reg(&m_HookFunc, REG_EDI); + + BitwiseCopy_Do(m_Proto.GetRet().size); } // In both cases: return the pointer in EAX @@ -714,7 +733,7 @@ namespace SourceHook } void GenContext::GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, - int v_pContext, int base_param_offset, int v_plugin_ret) + int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret) { jitoffs_t counter, tmppos; jitoffs_t counter2, tmppos2; @@ -759,7 +778,7 @@ namespace SourceHook // eax = [ecx] // eax = [eax+2*SIZE_PTR] // call eax - jit_int32_t gcc_clean_bytes = PushParams(base_param_offset, v_plugin_ret); + jit_int32_t gcc_clean_bytes = PushParams(base_param_offset, v_plugin_ret, v_place_for_memret); IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); #if SH_COMP == SH_COMP_GCC @@ -769,7 +788,7 @@ namespace SourceHook IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 2*SIZE_PTR); IA32_Call_Reg(&m_HookFunc, REG_EAX); - SaveRetVal(v_plugin_ret); + SaveRetVal(v_plugin_ret, v_place_for_memret); // cleanup #if SH_COMP == SH_COMP_GCC @@ -831,8 +850,8 @@ namespace SourceHook return acc; } - void GenContext::GenerateCallOrig(int v_status, int v_pContext, - int param_base_offs, int v_this, int v_vfnptr_origentry, int v_orig_ret, int v_override_ret) + void GenContext::GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this, + int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret) { jitoffs_t counter, tmppos; jitoffs_t counter2, tmppos2; @@ -885,7 +904,7 @@ namespace SourceHook m_HookFunc.start_count(counter2); // push params - jit_int32_t gcc_clean_bytes = PushParams(param_base_offs, v_orig_ret); + jit_int32_t gcc_clean_bytes = PushParams(param_base_offs, v_orig_ret, v_place_for_memret); // thisptr IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); @@ -906,7 +925,7 @@ namespace SourceHook #endif // save retval - SaveRetVal(v_orig_ret); + SaveRetVal(v_orig_ret, v_place_for_memret); // Skip don't call variant tmppos3 = IA32_Jump_Imm32(&m_HookFunc, 0); @@ -941,44 +960,15 @@ namespace SourceHook } else { - jit_uint32_t dwords = DownCastSize(m_Proto.GetRet().size) / 4; - jit_uint32_t bytes = DownCastSize(m_Proto.GetRet().size) % 4; - // bitwise copy + BitwiseCopy_Setup(); - //cld - //push edi - //push esi //lea edi, [ebp+v_orig_ret] <-- destination //lea esi, [ebp+v_override_ret] <-- src - //if dwords - // mov ecx, - // rep movsd - //if bytes - // mov ecx, - // rep movsb - //pop esi - //pop edi - - IA32_Cld(&m_HookFunc); - IA32_Push_Reg(&m_HookFunc, REG_EDI); - IA32_Push_Reg(&m_HookFunc, REG_ESI); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, v_orig_ret); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_override_ret); - if (dwords) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); - IA32_Rep(&m_HookFunc); - IA32_Movsd(&m_HookFunc); - } - if (bytes) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); - IA32_Rep(&m_HookFunc); - IA32_Movsb(&m_HookFunc); - } - IA32_Pop_Reg(&m_HookFunc, REG_ESI); - IA32_Pop_Reg(&m_HookFunc, REG_EDI); + + BitwiseCopy_Do(m_Proto.GetRet().size); } // skip don't call label target: @@ -1134,6 +1124,10 @@ namespace SourceHook // my_rettype plugin_ret ebp - 28 - sizeof(my_rettype)*3 -4 // == + 3 * sizeof(my_rettype) bytes + // if required: + // my_rettype place_for_memret ebp - 28 - sizeof(my_rettype)*4 -4 + + const jit_int8_t v_vfnptr_origentry = -4 + addstackoffset; const jit_int8_t v_status = -8 + addstackoffset; const jit_int8_t v_prev_res = -12 + addstackoffset; @@ -1160,10 +1154,13 @@ namespace SourceHook jit_int32_t v_override_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 2; jit_int32_t v_plugin_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 3; + jit_int32_t v_place_for_memret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 4; + // Hash for temporary storage for byval params with copy constructors // (param, offset into stack) - short usedStackBytes = 3*SIZE_MWORD + 3*SIZE_PTR + // vfnptr_origentry, status, prev_res, cur_res, iter, pContext - 3 * GetStackSize(m_Proto.GetRet()) + (m_Proto.GetRet().size == 0 ? 0 : SIZE_PTR) // ret_ptr, orig_ret, override_ret, plugin_ret + short usedStackBytes = 3*SIZE_MWORD + 3*SIZE_PTR // vfnptr_origentry, status, prev_res, cur_res, iter, pContext + + 3 * GetStackSize(m_Proto.GetRet()) + (m_Proto.GetRet().size == 0 ? 0 : SIZE_PTR) // ret_ptr, orig_ret, override_ret, plugin_ret + + (MemRetWithTempObj() ? GetStackSize(m_Proto.GetRet()) : 0) - addstackoffset; // msvc: current thisptr IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, usedStackBytes, MOD_REG); @@ -1190,6 +1187,8 @@ namespace SourceHook IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + + // _don't_ call a constructor for v_place_for_memret ! } // ********************** SetupHookLoop ********************** @@ -1198,15 +1197,15 @@ namespace SourceHook // ********************** call pre hooks ********************** GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, - v_plugin_ret); + v_plugin_ret, v_place_for_memret); // ********************** call orig func ********************** GenerateCallOrig(v_status, v_pContext, param_base_offs, v_this, v_vfnptr_origentry, v_orig_ret, - v_override_ret); + v_override_ret, v_place_for_memret); // ********************** call post hooks ********************** GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, - v_plugin_ret); + v_plugin_ret, v_place_for_memret); // ********************** end context and return ********************** @@ -1231,7 +1230,37 @@ namespace SourceHook DoReturn(v_ret_ptr, v_memret_addr); - // !! :TODO: Call destructors of orig_ret/ ... + // Call destructors of orig_ret/ ... + if(m_Proto.GetRet().pDtor) + { + // Preserve return value in EAX(:EDX) + IA32_Push_Reg(&m_HookFunc, REG_EAX); + IA32_Push_Reg(&m_HookFunc, REG_EDX); + + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + IA32_Pop_Reg(&m_HookFunc, REG_EDX); + IA32_Pop_Reg(&m_HookFunc, REG_EAX); + } // epilogue IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESP, REG_EBP, MOD_REG); @@ -1351,17 +1380,16 @@ namespace SourceHook if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ByVal)) { - if ((pi.flags & PassInfo::PassFlag_CCtor) && !pi.pNormalCtor) + if ((pi.flags & PassInfo::PassFlag_CCtor) && !pi.pCopyCtor) return false; if ((pi.flags & PassInfo::PassFlag_ODtor) && !pi.pDtor) return false; - // only care for assignop and normalctor for return types - if (is_ret && (pi.flags & PassInfo::PassFlag_AssignOp) && !pi.pAssignOperator) + if ((pi.flags & PassInfo::PassFlag_AssignOp) && !pi.pAssignOperator) return false; - if (is_ret && (pi.flags & PassInfo::PassFlag_CCtor) && !pi.pNormalCtor) + if ((pi.flags & PassInfo::PassFlag_OCtor) && !pi.pNormalCtor) return false; } diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 7ae3b3d..cdd0486 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -182,28 +182,34 @@ namespace SourceHook jit_int32_t GetStackSize(const IntPassInfo &info); short GetParamsStackSize(); // sum(GetStackSize(i), 0 <= i < numOfParams) + // Helpers + void BitwiseCopy_Setup(); + void BitwiseCopy_Do(size_t size); // Param push - jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to); // save_ret_to only used for memory returns + jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to, + jit_int32_t v_place_for_memret); // save_ret_to and v_place_for_memret only used for memory returns jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi); // Ret val processing - void SaveRetVal(int v_where); - void ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret); + void SaveRetVal(jit_int32_t v_where, jit_int32_t v_place_for_memret); + void ProcessPluginRetVal(jit_int32_t v_cur_res, jit_int32_t v_pContext, jit_int32_t v_plugin_ret); - void PrepareReturn(int v_status, int v_pContext, int v_retptr); - void DoReturn(int v_retptr, int v_memret_outaddr); + void PrepareReturn(jit_int32_t v_status, jit_int32_t v_pContext, jit_int32_t v_retptr); + void DoReturn(jit_int32_t v_retptr, jit_int32_t v_memret_outaddr); + + bool MemRetWithTempObj(); // do we do a memory return AND need a temporary place for it? // Call hooks void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, - int v_pContext, int base_param_offset, int v_plugin_ret); + int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret); // Call orig - void GenerateCallOrig(int v_status, int v_pContext, - int param_base_offs, int v_this, int v_vfnptr_origentry, int v_orig_ret, int v_override_ret); + void GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this, + int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret); // Hook loop void CallSetupHookLoop(int v_orig_ret, int v_override_ret, diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 7ddcca8..4f75d76 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -41,7 +41,7 @@ namespace }; template - std::ostream& operator <<(std::ostream &os, const POD &obj) + std::ostream& operator <<(std::ostream &os, const POD &obj) { os << "Some POD!"; return os; @@ -50,6 +50,7 @@ namespace MAKE_STATE_1(State_ObjOCtor_Called, int /*MYSIZE*/); MAKE_STATE_1(State_ObjCCtor_Called, int /*MYSIZE*/); MAKE_STATE_1(State_ObjODtor_Called, int /*MYSIZE*/); + MAKE_STATE_1(State_ObjAssignOp_Called, int /*MYSIZE*/); template struct Object @@ -82,6 +83,16 @@ namespace ADD_STATE(State_ObjODtor_Called(MYSIZE)); } + Object & operator = (const Object &other) + { + if (!g_Inside_LeafFunc) + ADD_STATE(State_ObjAssignOp_Called(MYSIZE)); + + memcpy(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE); + + return *this; + } + bool operator==(const Object &other) { return memcmp(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE) == 0; @@ -95,6 +106,51 @@ namespace return os; } + // Because of some weird bug in MSVC < 1400 +#define MAKE_PODRET(size) \ + struct PodRet##size \ + { \ + POD actPod; \ + bool operator==(const PodRet##size &other) { return actPod == other.actPod; } \ + bool operator==(char other) { return actPod == other; } \ + }; \ + std::ostream& operator <<(std::ostream &os, const PodRet##size &obj) \ + { \ + os << obj.actPod; \ + return os; \ + } \ + template <> struct MakeRet< PodRet##size > \ + { \ + static PodRet##size Do(int a) \ + { \ + PodRet##size x; \ + memset(reinterpret_cast(x.actPod.x), a, size); \ + return x; \ + } \ + }; + +#define MAKE_OBJRET(size) \ + struct ObjRet##size \ + { \ + Object actObj; \ + bool operator==(const ObjRet##size &other) { return actObj == other.actObj; } \ + bool operator==(char other) { return actObj == other; } \ + }; \ + std::ostream& operator <<(std::ostream &os, const ObjRet##size &obj) \ + { \ + os << obj.actObj; \ + return os; \ + } \ + template <> struct MakeRet< ObjRet##size > \ + { \ + static ObjRet##size Do(int a) \ + { \ + ObjRet##size x; \ + memset(reinterpret_cast(x.actObj.x), a, size); \ + return x; \ + } \ + }; + #include "testhookmangen.h" StateList g_States; @@ -279,29 +335,43 @@ namespace THGM_SETUP_RI(105, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); // pod 1-13 - THGM_MAKE_TEST1(106, POD<1>, int); + MAKE_PODRET(1); + THGM_MAKE_TEST1(106, PodRet1, int); THGM_SETUP_PI1(106, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal ); - THGM_SETUP_RI(106, POD<1>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + THGM_SETUP_RI(106, PodRet1, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - THGM_MAKE_TEST1(107, POD<4>, int); + MAKE_PODRET(4); + THGM_MAKE_TEST1(107, PodRet4, int); THGM_SETUP_PI1(107, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal ); - THGM_SETUP_RI(107, POD<4>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + THGM_SETUP_RI(107, PodRet4, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - THGM_MAKE_TEST1(108, POD<8>, int); + MAKE_PODRET(8); + THGM_MAKE_TEST1(108, PodRet8, int); THGM_SETUP_PI1(108, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal ); - THGM_SETUP_RI(108, POD<8>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + THGM_SETUP_RI(108, PodRet8, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - THGM_MAKE_TEST1(109, POD<13>, int); + MAKE_PODRET(13); + THGM_MAKE_TEST1(109, PodRet13, int); THGM_SETUP_PI1(109, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal ); - THGM_SETUP_RI(109, POD<13>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + THGM_SETUP_RI(109, PodRet13, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + + MAKE_OBJRET(13); + THGM_MAKE_TEST1(110, ObjRet13, int); + THGM_SETUP_PI1(110, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal + ); + THGM_SETUP_RI(110, ObjRet13, SourceHook::PassInfo::PassType_Object, + SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | + SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); + } bool TestHookManGen(std::string &error) @@ -502,11 +572,196 @@ bool TestHookManGen(std::string &error) THGM_DO_TEST(108, (5)); THGM_DO_TEST(109, (5)); + // Test110: Special: constructors/destructors on return + PtrBuf_Clear(); + ObjRet13 obj13; + + CHECK_STATES((&g_States, + new State_ObjOCtor_Called(13), + NULL), "Test110 Part0"); + + setuppi_110(); + setupri_110(); + + g_Genc110 = new SourceHook::Impl::GenContext(&protoinfo_110, 0, 0, g_SHPtr); + g_Genc_ad110.set(g_Genc110); + SourceHook::HookManagerPubFunc myhookman110 = g_Genc110->Generate(); + int hook1_110, hook2_110, hook3_110, hook4_110; + + TestClass110 *pTest110 = new TestClass110; + CAutoPtrDestruction apd110(pTest110); + + /* no hooks - no hooks */ + PtrBuf_Clear(); + obj13 = pTest110->Func(5); + + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_Func110(pTest110, ParamState_m110 (5)), + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in our stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack + new State_ObjODtor_Called(13), // Func110: destruction of temporary object + NULL), "Test" "110" " Part1"); + g_Inside_LeafFunc = false; + + /* hook1 - no hooks */ + THGM_ADD_HOOK(110, 1); + + PtrBuf_Clear(); + obj13 = pTest110->Func(5); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + // HookFunc: construct orig_ret/override_ret/plugin_ret objects + new State_ObjOCtor_Called(13), + new State_ObjOCtor_Called(13), + new State_ObjOCtor_Called(13), + + // Calling delegate + new State_Deleg1_110(pTest110, 0, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // Calling orig function Func110 + new State_Func110(pTest110, ParamState_m110 (5)), + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: orig_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // hookfunc is returning: + new State_ObjCCtor_Called(13), // copy to temp object in our stack + + // hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret + new State_ObjODtor_Called(13), + new State_ObjODtor_Called(13), + new State_ObjODtor_Called(13), + + // we are in our function: assign + new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack + new State_ObjODtor_Called(13), // Func110: destruction of temporary object + + NULL), "Test" "11" " Part2"); + + CHECK_COND(obj13 == 0, "Test" "11" " Part 2.1"); + g_Inside_LeafFunc = false; + + THGM_REMOVE_HOOK(11, 1); + + /* hook1, hook2 - hook3, hook4 */ + THGM_ADD_HOOK(110, 1); + THGM_ADD_HOOK(110, 2); + THGM_ADD_HOOK(110, 3); + THGM_ADD_HOOK(110, 4); + + PtrBuf_Clear(); + obj13 = pTest110->Func(5); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + // HookFunc: construct orig_ret/override_ret/plugin_ret objects + new State_ObjOCtor_Called(13), + new State_ObjOCtor_Called(13), + new State_ObjOCtor_Called(13), + + // Calling delegate1 + new State_Deleg1_110(pTest110, 0, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + + // Calling delegate2 + new State_Deleg2_110(pTest110, 1, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret + new State_ObjAssignOp_Called(13), + + // SUPERCEDE -> orig function is not called + // instead: orig_ret = override_ret + new State_ObjAssignOp_Called(13), + + // Calling delegate3 + new State_Deleg3_110(pTest110, 2, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // Calling delegate4 + new State_Deleg4_110(pTest110, 3, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret (yes really, we overwrite the old value!) + new State_ObjAssignOp_Called(13), + + // hookfunc is returning: + new State_ObjCCtor_Called(13), // copy to temp object in our stack + + // hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret + new State_ObjODtor_Called(13), + new State_ObjODtor_Called(13), + new State_ObjODtor_Called(13), + + // we are in our function: assign + new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack + new State_ObjODtor_Called(13), // Func110: destruction of temporary object + + NULL), "Test" "11" " Part3"); + + CHECK_COND(obj13 == 4, "Test" "11" " Part 3.1"); + g_Inside_LeafFunc = false; + + THGM_REMOVE_HOOK(110, 1); + THGM_REMOVE_HOOK(110, 2); + THGM_REMOVE_HOOK(110, 3); + THGM_REMOVE_HOOK(110, 4); + // Shutdown now! // If we don't SH will auto-shutdown _after_ genc's destructor is called // -> crash Test_CompleteShutdown(g_SHPtr); + + CHECK_COND(sizeof(PodRet1) == 1, "WTF!"); + CHECK_COND(sizeof(PodRet4) == 4, "WTF!"); + CHECK_COND(sizeof(PodRet8) == 8, "WTF!"); + CHECK_COND(sizeof(PodRet13) == 13, "WTF!"); + return true; } diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index 7d839d4..117e5c0 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -29,6 +29,11 @@ public: { reinterpret_cast(this)->~T(); } + + const T& AssignOp(const T &other) + { + return (*reinterpret_cast(this) = other); + } }; @@ -90,7 +95,7 @@ struct MakeRet { static T Do(int a) { - return static_cast(a); + return a; } }; @@ -530,7 +535,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id())); \ g_Inside_LeafFunc = false; \ \ - return MakeRet::Do(0); \ + return MakeRet< ret_type >::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -543,10 +548,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -559,10 +564,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -575,10 +580,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -591,10 +596,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ }; \ }; \ }; \ @@ -619,6 +624,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, \ \ \ + \ } @@ -739,7 +745,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \ g_Inside_LeafFunc = false; \ \ - return MakeRet::Do(0); \ + return MakeRet< ret_type >::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -752,10 +758,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -768,10 +774,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -784,10 +790,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -800,10 +806,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ }; \ }; \ }; \ @@ -828,6 +834,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ } @@ -948,7 +955,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \ g_Inside_LeafFunc = false; \ \ - return MakeRet::Do(0); \ + return MakeRet< ret_type >::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -961,10 +968,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -977,10 +984,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -993,10 +1000,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1009,10 +1016,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ }; \ }; \ }; \ @@ -1037,6 +1044,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ } @@ -1157,7 +1165,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \ g_Inside_LeafFunc = false; \ \ - return MakeRet::Do(0); \ + return MakeRet< ret_type >::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -1170,10 +1178,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -1186,10 +1194,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -1202,10 +1210,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1218,10 +1226,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ }; \ }; \ }; \ @@ -1246,6 +1254,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[3].pAssignOperator = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ } @@ -1366,7 +1375,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \ g_Inside_LeafFunc = false; \ \ - return MakeRet::Do(0); \ + return MakeRet< ret_type >::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -1379,10 +1388,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -1395,10 +1404,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -1411,10 +1420,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1427,10 +1436,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ }; \ }; \ }; \ @@ -1455,6 +1464,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[3].pAssignOperator = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[4].pAssignOperator = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ } @@ -1575,7 +1585,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \ g_Inside_LeafFunc = false; \ \ - return MakeRet::Do(0); \ + return MakeRet< ret_type >::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -1588,10 +1598,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -1604,10 +1614,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -1620,10 +1630,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1636,10 +1646,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ }; \ }; \ }; \ @@ -1664,6 +1674,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[5].pNormalCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[5].pCopyCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[5].pDtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[3].pAssignOperator = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[4].pAssignOperator = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[5].pAssignOperator = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ } @@ -1784,7 +1795,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ g_Inside_LeafFunc = false; \ \ - return MakeRet::Do(0); \ + return MakeRet< ret_type >::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -1797,10 +1808,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -1813,10 +1824,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -1829,10 +1840,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -1845,10 +1856,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ }; \ }; \ }; \ @@ -1873,6 +1884,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[5].pNormalCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[6].pNormalCtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[5].pCopyCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[6].pCopyCtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[5].pDtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[6].pDtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[3].pAssignOperator = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[4].pAssignOperator = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[5].pAssignOperator = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[6].pAssignOperator = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ } @@ -1887,6 +1899,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, protoinfo_##id.retPassInfo2.pNormalCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ protoinfo_##id.retPassInfo2.pCopyCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ protoinfo_##id.retPassInfo2.pDtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + protoinfo_##id.retPassInfo2.pAssignOperator = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ } #define THGM_ADD_HOOK(id, num) \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 7ff9e24..3b488cd 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -29,6 +29,11 @@ public: { reinterpret_cast(this)->~T(); } + + const T& AssignOp(const T &other) + { + return (*reinterpret_cast(this) = other); + } }; @@ -99,7 +104,7 @@ struct MakeRet< POD > { static POD Do(int a) { - POD x; + POD x; memset(reinterpret_cast(x.x), a, SIZE); return x; } @@ -272,7 +277,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ g_Inside_LeafFunc = false; \ \ - return MakeRet::Do(0); \ + return MakeRet< ret_type >::Do(0); \ } \ \ struct Delegate1 : public MyDelegate \ @@ -285,10 +290,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(1), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(1)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ } \ }; \ struct Delegate2 : public MyDelegate \ @@ -301,10 +306,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(2), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(2)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ } \ }; \ struct Delegate3 : public MyDelegate \ @@ -317,10 +322,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet::Do(3), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet::Do(3)); \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ } \ }; \ struct Delegate4 : public MyDelegate \ @@ -333,10 +338,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet::Do(4), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet::Do(4)); \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ }; \ }; \ }; \ @@ -361,6 +366,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] @[$2,1,$1: paraminfos2_##id[$2].pNormalCtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; @] \ @[$2,1,$1: paraminfos2_##id[$2].pCopyCtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; @] \ @[$2,1,$1: paraminfos2_##id[$2].pDtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; @] \ + @[$2,1,$1: paraminfos2_##id[$2].pAssignOperator = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; @] \ } @] @@ -375,6 +381,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] protoinfo_##id.retPassInfo2.pNormalCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ protoinfo_##id.retPassInfo2.pCopyCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ protoinfo_##id.retPassInfo2.pDtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ + protoinfo_##id.retPassInfo2.pAssignOperator = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ } #define THGM_ADD_HOOK(id, num) \ From 2c8203f263f2b7fe6d9a658531980b27f5c0bb1f Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 2 Nov 2007 11:59:57 +0000 Subject: [PATCH 07/41] First support attempt for reference returns --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40538 --- sourcehook/sourcehook_hookmangen.cpp | 85 +++++++++++++++++++--------- sourcehook/test/testhookmangen.cpp | 1 - 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 12eed3d..6aea6cc 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -380,13 +380,22 @@ namespace SourceHook void GenContext::SaveRetVal(int v_where, int v_place_for_memret) { - size_t size = m_Proto.GetRet().size; + size_t size = GetRealSize(m_Proto.GetRet()); if (size == 0) { // No return value -> nothing return; } + if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef) + { + // mov [ebp + v_plugin_ret], eax + IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where); + return; + } + // else: ByVal + + // Memory return: if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) { @@ -557,36 +566,46 @@ namespace SourceHook // *eax = plugin_ret - if (m_Proto.GetRet().pAssignOperator) + if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef) { - // lea edx, [ebp + v_plugin_ret] - // msvc: ecx = eax <-- dest addr - // gcc: push eax <-- dest addr - // push edx <-- src addr - // call it - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_plugin_ret); -#if SH_COMP == SH_COMP_MSVC - IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); -#elif SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_EAX); -#endif - IA32_Push_Reg(&m_HookFunc, REG_EDX); - - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); - IA32_Call_Reg(&m_HookFunc, REG_EAX); + // mov ecx, [ebp+v_plugin_ret] + // mov [eax], ecx + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); + IA32_Mov_Rm_Reg(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); } else { - // bitwise copy - BitwiseCopy_Setup(); + if (m_Proto.GetRet().pAssignOperator) + { + // lea edx, [ebp + v_plugin_ret] + // msvc: ecx = eax <-- dest addr + // gcc: push eax <-- dest addr + // push edx <-- src addr + // call it - //mov edi, eax <-- destination - //lea esi, [ebp+v_plugin_ret] <-- src - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDI, REG_EAX, MOD_REG); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_plugin_ret); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_plugin_ret); +#if SH_COMP == SH_COMP_MSVC + IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); +#elif SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_EAX); +#endif + IA32_Push_Reg(&m_HookFunc, REG_EDX); - BitwiseCopy_Do(m_Proto.GetRet().size); + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + else + { + // bitwise copy + BitwiseCopy_Setup(); + + //mov edi, eax <-- destination + //lea esi, [ebp+v_plugin_ret] <-- src + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDI, REG_EAX, MOD_REG); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_plugin_ret); + + BitwiseCopy_Do(m_Proto.GetRet().size); + } } m_HookFunc.end_count(counter); @@ -649,12 +668,18 @@ namespace SourceHook if (!size) return; - // :TODO: memory return support - // Get real ret pointer into ecx // mov ecx, [ebp + v_ret_ptr] IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_retptr); + if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef) + { + // mov eax, [ecx] + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); + return; + } + // else: byval + if (m_Proto.GetRet().type == PassInfo::PassType_Float) { if (size == 4) @@ -1441,6 +1466,12 @@ namespace SourceHook } } } + else + { + // byref: make sure that the flag is _not_ set + pi.flags &= ~PassInfo::PassFlag_RetMem; + pi.flags |= PassInfo::PassFlag_RetReg; + } } HookManagerPubFunc GenContext::Generate() diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 4f75d76..1fc307e 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -371,7 +371,6 @@ namespace THGM_SETUP_RI(110, ObjRet13, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); - } bool TestHookManGen(std::string &error) From b7e00841b0f15a01d44c62dfc17e5aa19d25d13b Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 2 Nov 2007 12:41:00 +0000 Subject: [PATCH 08/41] Completed support for reference returns + added simple test for it --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40539 --- sourcehook/sourcehook_hookmangen.cpp | 61 +++++++++++++++++----------- sourcehook/test/testhookmangen.cpp | 47 +++++++++++++++++++++ sourcehook/test/testhookmangen.h | 22 +++++++++- sourcehook/test/testhookmangen.hxx | 16 +++++++- 4 files changed, 118 insertions(+), 28 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 6aea6cc..217d00b 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -965,35 +965,46 @@ namespace SourceHook m_HookFunc.rewrite(tmppos2, static_cast(counter2)); // *v_orig_ret = *v_override_ret - if (m_Proto.GetRet().pAssignOperator) + if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef) { - // lea edx, [ebp + v_override_ret] <-- src addr - // lea ecx, [ebp + v_orig_ret] <-- dest addr - // gcc: push ecx - // push edx <-- src addr - // call it + // mov ecx, [ebp + v_override_ret] + // mov [ebp + v_orig_ret], ecx - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_override_ret); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif - IA32_Push_Reg(&m_HookFunc, REG_EDX); - - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); - IA32_Call_Reg(&m_HookFunc, REG_EAX); + IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); + IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_ECX, v_orig_ret); } else { - // bitwise copy - BitwiseCopy_Setup(); + if (m_Proto.GetRet().pAssignOperator) + { + // lea edx, [ebp + v_override_ret] <-- src addr + // lea ecx, [ebp + v_orig_ret] <-- dest addr + // gcc: push ecx + // push edx <-- src addr + // call it - //lea edi, [ebp+v_orig_ret] <-- destination - //lea esi, [ebp+v_override_ret] <-- src - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, v_orig_ret); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_override_ret); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_override_ret); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); +#if SH_COMP == SH_COMP_GCC + IA32_Push_Reg(&m_HookFunc, REG_ECX); +#endif + IA32_Push_Reg(&m_HookFunc, REG_EDX); - BitwiseCopy_Do(m_Proto.GetRet().size); + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + else + { + // bitwise copy + BitwiseCopy_Setup(); + + //lea edi, [ebp+v_orig_ret] <-- destination + //lea esi, [ebp+v_override_ret] <-- src + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, v_orig_ret); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_override_ret); + + BitwiseCopy_Do(m_Proto.GetRet().size); + } } // skip don't call label target: @@ -1194,7 +1205,8 @@ namespace SourceHook IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_status); // Call constructors for ret vars if required - if(m_Proto.GetRet().pNormalCtor) + if((m_Proto.GetRet().flags & PassInfo::PassFlag_ByVal) && + m_Proto.GetRet().pNormalCtor) { // :TODO: Gcc version @@ -1256,7 +1268,8 @@ namespace SourceHook DoReturn(v_ret_ptr, v_memret_addr); // Call destructors of orig_ret/ ... - if(m_Proto.GetRet().pDtor) + if((m_Proto.GetRet().flags & PassInfo::PassFlag_ByVal) && + m_Proto.GetRet().pDtor) { // Preserve return value in EAX(:EDX) IA32_Push_Reg(&m_HookFunc, REG_EAX); diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 1fc307e..7418e86 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -371,6 +371,40 @@ namespace THGM_SETUP_RI(110, ObjRet13, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); + + MAKE_OBJRET(111); + ObjRet111 g_O111_0; + ObjRet111 g_O111_1; + ObjRet111 g_O111_2; + ObjRet111 g_O111_3; + ObjRet111 g_O111_4; + + template <> + struct MakeRet< ObjRet111& > + { + static ObjRet111 &Do(int a) + { + switch (a) + { + case 0: + return g_O111_0; + case 1: + return g_O111_1; + case 2: + return g_O111_2; + case 3: + return g_O111_3; + default: + return g_O111_4; + } + } + }; + + THGM_MAKE_TEST0(111, ObjRet111& ); + THGM_SETUP_PI0(111); + THGM_SETUP_RI(111, ObjRet111& , SourceHook::PassInfo::PassType_Object, + SourceHook::PassInfo::PassFlag_ByRef | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | + SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); } bool TestHookManGen(std::string &error) @@ -378,6 +412,15 @@ bool TestHookManGen(std::string &error) GET_SHPTR(g_SHPtr); g_PLID = 1337; + // 5 Global constructors (g_O111_*) + CHECK_STATES((&g_States, + new State_ObjOCtor_Called(111), + new State_ObjOCtor_Called(111), + new State_ObjOCtor_Called(111), + new State_ObjOCtor_Called(111), + new State_ObjOCtor_Called(111), + NULL), "GlobCtors"); + THGM_DO_TEST_void(0, ()); THGM_DO_TEST_void(1, (100)); @@ -750,6 +793,10 @@ bool TestHookManGen(std::string &error) THGM_REMOVE_HOOK(110, 3); THGM_REMOVE_HOOK(110, 4); + + // RefRet + THGM_DO_TEST(111, ()); + // Shutdown now! // If we don't SH will auto-shutdown _after_ genc's destructor is called // -> crash diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index 117e5c0..3419315 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -518,6 +518,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_MAKE_TEST0(id, ret_type) \ struct TestClass##id; \ + typedef ret_type RetType##id; \ typedef ParamState0<0 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ @@ -728,6 +729,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_MAKE_TEST1(id, ret_type, param1) \ struct TestClass##id; \ + typedef ret_type RetType##id; \ typedef ParamState1<0, param1 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ @@ -938,6 +940,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_MAKE_TEST2(id, ret_type, param1, param2) \ struct TestClass##id; \ + typedef ret_type RetType##id; \ typedef ParamState2<0, param1, param2 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ @@ -1148,6 +1151,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_MAKE_TEST3(id, ret_type, param1, param2, param3) \ struct TestClass##id; \ + typedef ret_type RetType##id; \ typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ @@ -1358,6 +1362,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_MAKE_TEST4(id, ret_type, param1, param2, param3, param4) \ struct TestClass##id; \ + typedef ret_type RetType##id; \ typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ @@ -1568,6 +1573,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_MAKE_TEST5(id, ret_type, param1, param2, param3, param4, param5) \ struct TestClass##id; \ + typedef ret_type RetType##id; \ typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ @@ -1778,6 +1784,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_MAKE_TEST6(id, ret_type, param1, param2, param3, param4, param5, param6) \ struct TestClass##id; \ + typedef ret_type RetType##id; \ typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ @@ -2015,10 +2022,21 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, THGM_REMOVE_HOOK(id, 3); \ THGM_REMOVE_HOOK(id, 4); +template +T ComparableRef(T x) +{ + return x; +} + +template +T* ComparableRef(T& x) +{ + return &x; +} #define THGM_CALLS(id, call_params, exp_ret_norm, exp_ret_shcall, err) \ - CHECK_COND(pTest##id->Func call_params == exp_ret_norm, err " /retcallnorm"); \ - CHECK_COND(SH_CALL(pTest##id, &TestClass##id::Func) call_params == exp_ret_shcall, err " /retcallshcall"); + CHECK_COND(ComparableRef(pTest##id->Func call_params) == ComparableRef(MakeRet< RetType##id >::Do(exp_ret_norm)), err " /retcallnorm"); \ + CHECK_COND(ComparableRef(SH_CALL(pTest##id, &TestClass##id::Func) call_params) == ComparableRef(MakeRet< RetType##id >::Do(exp_ret_shcall)), err " /retcallshcall"); #define THGM_DO_TEST(id, call_params) \ setuppi_##id(); \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 3b488cd..864973e 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -260,6 +260,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] #define THGM_MAKE_TEST$1(id, ret_type@[$2,1,$1:, param$2@]) \ struct TestClass##id; \ + typedef ret_type RetType##id; \ typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ @@ -497,10 +498,21 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] THGM_REMOVE_HOOK(id, 3); \ THGM_REMOVE_HOOK(id, 4); +template +T ComparableRef(T x) +{ + return x; +} + +template +T* ComparableRef(T& x) +{ + return &x; +} #define THGM_CALLS(id, call_params, exp_ret_norm, exp_ret_shcall, err) \ - CHECK_COND(pTest##id->Func call_params == exp_ret_norm, err " /retcallnorm"); \ - CHECK_COND(SH_CALL(pTest##id, &TestClass##id::Func) call_params == exp_ret_shcall, err " /retcallshcall"); + CHECK_COND(ComparableRef(pTest##id->Func call_params) == ComparableRef(MakeRet< RetType##id >::Do(exp_ret_norm)), err " /retcallnorm"); \ + CHECK_COND(ComparableRef(SH_CALL(pTest##id, &TestClass##id::Func) call_params) == ComparableRef(MakeRet< RetType##id >::Do(exp_ret_shcall)), err " /retcallshcall"); #define THGM_DO_TEST(id, call_params) \ setuppi_##id(); \ From b6f0b74f5b0b0b15cf0b502ca0d0cc5673557c7f Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 2 Nov 2007 20:15:19 +0000 Subject: [PATCH 09/41] First step to gcc support: it compiles now --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40542 --- sourcehook/generate/shworker.bin | Bin 59700 -> 50608 bytes sourcehook/sh_memory.h | 9 ++- sourcehook/sourcehook_hookmangen.cpp | 8 +- sourcehook/sourcehook_hookmangen.h | 15 ++-- sourcehook/sourcehook_hookmangen_x86.h | 10 +++ sourcehook/test/Makefile | 2 +- sourcehook/test/testhookmangen.cpp | 97 +++++++++++++------------ sourcehook/test/testhookmangen.h | 52 +++++++------ sourcehook/test/testhookmangen.hxx | 12 ++- 9 files changed, 118 insertions(+), 87 deletions(-) diff --git a/sourcehook/generate/shworker.bin b/sourcehook/generate/shworker.bin index 62ab6481958fe5aae35eafc7c64e5542003be902..96105b3c726572527d301d27612a2893d65a2beb 100755 GIT binary patch literal 50608 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 diff --git a/sourcehook/sh_memory.h b/sourcehook/sh_memory.h index a8e7077..e9bd163 100644 --- a/sourcehook/sh_memory.h +++ b/sourcehook/sh_memory.h @@ -24,7 +24,10 @@ # elif /******/ defined __linux__ # include # include +namespace LinuxSignal +{ # include +} # include // http://www.die.net/doc/linux/man/man2/mprotect.2.html # include @@ -163,7 +166,7 @@ namespace SourceHook if (setjmp(g_BadReadJmpBuf)) return true; - prevHandler = signal(SIGSEGV, BadReadHandler); + prevHandler = LinuxSignal::signal(SIGSEGV, BadReadHandler); volatile const char *p = reinterpret_cast(addr); char dummy; @@ -173,7 +176,7 @@ namespace SourceHook g_BadReadCalled = false; - signal(SIGSEGV, prevHandler); + LinuxSignal::signal(SIGSEGV, prevHandler); return false; #else @@ -320,7 +323,7 @@ namespace SourceHook newRegion.size += m_PageSize; #ifdef __linux__ - newRegion.startPtr = mmap(0, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAN_ANONYMOUS, -1); + newRegion.startPtr = mmap(0, newRegion.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); #else newRegion.startPtr = VirtualAlloc(NULL, newRegion.size, MEM_COMMIT, PAGE_READWRITE); #endif diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 217d00b..6a3df96 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -1119,7 +1119,7 @@ namespace SourceHook #endif } - unsigned char * GenContext::GenerateHookFunc() + void * GenContext::GenerateHookFunc() { // prologue IA32_Push_Reg(&m_HookFunc, REG_EBP); @@ -1317,7 +1317,7 @@ namespace SourceHook } // Pre-condition: GenerateHookFunc() has been called! - unsigned char * GenContext::GeneratePubFunc() + void * GenContext::GeneratePubFunc() { jitoffs_t counter, tmppos; @@ -1525,7 +1525,7 @@ namespace SourceHook BuildProtoInfo(); GenerateHookFunc(); - return reinterpret_cast(GeneratePubFunc()); + return fastdelegate::detail::horrible_cast(GeneratePubFunc()); } } -} \ No newline at end of file +} diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index cdd0486..6b2c0f3 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -12,7 +12,6 @@ #define __SOURCEHOOK_HOOKMANGEN_H__ #include "sourcehook_impl.h" -#include "windows.h" namespace SourceHook { @@ -20,7 +19,7 @@ namespace SourceHook { // Code gen stuff -#if defined HAVE_STDINT_H && !defined WIN32 +#if SH_COMP == SH_COMP_GCC #include typedef int8_t jit_int8_t; typedef uint8_t jit_uint8_t; @@ -28,7 +27,7 @@ namespace SourceHook typedef uint32_t jit_uint32_t; typedef int64_t jit_int64_t; typedef uint64_t jit_uint64_t; -#elif defined WIN32 +#elif SH_COMP == SH_COMP_MSVC typedef __int8 jit_int8_t; typedef unsigned __int8 jit_uint8_t; typedef __int32 jit_int32_t; @@ -123,9 +122,9 @@ namespace SourceHook ms_Allocator.SetRE(reinterpret_cast(m_pData)); } - operator unsigned char *() + operator void *() { - return GetData(); + return reinterpret_cast(GetData()); } void write_ubyte(jit_uint8_t x) { push(x); } @@ -223,8 +222,8 @@ namespace SourceHook bool PassInfoSupported(const IntPassInfo &pi, bool is_ret); void Clear(); void BuildProtoInfo(); - unsigned char *GenerateHookFunc(); - unsigned char *GeneratePubFunc(); + void *GenerateHookFunc(); + void *GeneratePubFunc(); public: // Level 1 -> Public interface GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr); @@ -236,4 +235,4 @@ namespace SourceHook } -#endif \ No newline at end of file +#endif diff --git a/sourcehook/sourcehook_hookmangen_x86.h b/sourcehook/sourcehook_hookmangen_x86.h index 034dea4..576c2ca 100644 --- a/sourcehook/sourcehook_hookmangen_x86.h +++ b/sourcehook/sourcehook_hookmangen_x86.h @@ -14,6 +14,16 @@ #include +#undef REG_EAX +#undef REG_ECX +#undef REG_EDX +#undef REG_EBX +#undef REG_ESP +#undef REG_SIB +#undef REG_EBP +#undef REG_ESI +#undef REG_EDI + //MOD R/M #define MOD_MEM_REG 0 #define MOD_DISP8 1 diff --git a/sourcehook/test/Makefile b/sourcehook/test/Makefile index 6c859b0..c1d907e 100644 --- a/sourcehook/test/Makefile +++ b/sourcehook/test/Makefile @@ -9,7 +9,7 @@ INCLUDE = -I. -I.. MAX_PARAMS=20 BINARY = sourcehook_test -OBJECTS = main.cpp sourcehook.cpp $(shell ls -t test*.cpp) +OBJECTS = main.cpp sourcehook.cpp ../sourcehook_hookmangen.cpp $(shell ls -t test*.cpp) HEADERS = ../sh_list.h ../sh_tinyhash.h ../sh_memory.h ../sh_string.h ../sh_vector.h ../sourcehook_impl.h ../FastDelegate.h ../sourcehook.h ../sh_memfuncinfo.h ifeq "$(DEBUG)" "true" diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 7418e86..b82e9e4 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -18,6 +18,17 @@ namespace { + StateList g_States; + SourceHook::ISourceHook *g_SHPtr; + SourceHook::Plugin g_PLID; + + // PtrBuf(ptr) gives ptrs unique numbers + // in the order they appear + SourceHook::List g_PtrHash; + + bool g_Inside_LeafFunc = false; // inside a hook or a func + + // POD / Object types template struct POD @@ -151,52 +162,6 @@ namespace } \ }; - #include "testhookmangen.h" - - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - // PtrBuf(ptr) gives ptrs unique numbers - // in the order they appear - SourceHook::List g_PtrHash; - - bool g_Inside_LeafFunc = false; // inside a hook or a func - - template - int PtrBuf(T ptr) - { - int a = 0; - - const void *vptr = reinterpret_cast(ptr); - for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter) - { - if (*iter == vptr) - return a; - else - ++a; - } - g_PtrHash.push_back(vptr); - return static_cast(g_PtrHash.size()) - 1; - } - - template - T PtrBufPtr(T ptr) - { - PtrBuf(ptr); - return ptr; - } - - void PtrBuf_Clear(int leave_in = 0) - { - for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();) - { - if (--leave_in < 0) - iter = g_PtrHash.erase(iter); - else - ++iter; - } - } // "Increment" something: (reproducible change for recall tests) @@ -250,6 +215,44 @@ namespace } }; + #include "testhookmangen.h" + + template + int PtrBuf(T ptr) + { + int a = 0; + + const void *vptr = reinterpret_cast(ptr); + for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter) + { + if (*iter == vptr) + return a; + else + ++a; + } + g_PtrHash.push_back(vptr); + return static_cast(g_PtrHash.size()) - 1; + } + + template + T PtrBufPtr(T ptr) + { + PtrBuf(ptr); + return ptr; + } + + void PtrBuf_Clear(int leave_in = 0) + { + for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();) + { + if (--leave_in < 0) + iter = g_PtrHash.erase(iter); + else + ++iter; + } + } + + // MyDelegate base class for other delegates class MyDelegate : public SourceHook::ISHDelegate { @@ -879,4 +882,4 @@ bool TestCPageAlloc(std::string &error) memset((void*)test4[2], 0, ps / 4); return true; -} \ No newline at end of file +} diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index 3419315..cc8c831 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -43,7 +43,15 @@ void *FindFuncAddr(T mfp) if (sizeof(mfp) != sizeof(void*)) return NULL; else - return fastdelegate::detail::horrible_cast(mfp); + { + union + { + T a; + void *b; + } u; + u.a = mfp; + return u.b; + } } // Reference carrier @@ -166,7 +174,7 @@ struct ParamState1 int i; for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_1); + Increment::type >::Incr(m_1); return *this; @@ -202,10 +210,10 @@ struct ParamState2 int i; for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_1); + Increment::type >::Incr(m_1); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_2); + Increment::type >::Incr(m_2); return *this; @@ -241,13 +249,13 @@ struct ParamState3 int i; for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_1); + Increment::type >::Incr(m_1); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_2); + Increment::type >::Incr(m_2); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_3); + Increment::type >::Incr(m_3); return *this; @@ -283,16 +291,16 @@ struct ParamState4 int i; for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_1); + Increment::type >::Incr(m_1); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_2); + Increment::type >::Incr(m_2); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_3); + Increment::type >::Incr(m_3); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_4); + Increment::type >::Incr(m_4); return *this; @@ -328,19 +336,19 @@ struct ParamState5 int i; for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_1); + Increment::type >::Incr(m_1); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_2); + Increment::type >::Incr(m_2); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_3); + Increment::type >::Incr(m_3); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_4); + Increment::type >::Incr(m_4); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_5); + Increment::type >::Incr(m_5); return *this; @@ -376,22 +384,22 @@ struct ParamState6 int i; for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_1); + Increment::type >::Incr(m_1); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_2); + Increment::type >::Incr(m_2); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_3); + Increment::type >::Incr(m_3); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_4); + Increment::type >::Incr(m_4); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_5); + Increment::type >::Incr(m_5); for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_6); + Increment::type >::Incr(m_6); return *this; diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 864973e..f633ebf 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -43,7 +43,15 @@ void *FindFuncAddr(T mfp) if (sizeof(mfp) != sizeof(void*)) return NULL; else - return fastdelegate::detail::horrible_cast(mfp); + { + union + { + T a; + void *b; + } u; + u.a = mfp; + return u.b; + } } // Reference carrier @@ -133,7 +141,7 @@ struct ParamState$1 @[$1!=0:int i;@] @[$2,1,$1: for (i = 0; i < incrsteps; ++i) - Increment::type>::Incr(m_$2); + Increment::type >::Incr(m_$2); @] return *this; From c5595bd4e537915b05cec8209984d61cf8f2804e Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 4 Nov 2007 16:03:39 +0000 Subject: [PATCH 10/41] Moved CPageAlloc from sh_memory into sh_pagealloc.h --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40545 --- sourcehook/sh_memory.h | 252 -------------------------- sourcehook/sh_pagealloc.h | 273 +++++++++++++++++++++++++++++ sourcehook/sourcehook_hookmangen.h | 1 + sourcehook/test/msvc7/test.vcproj | 6 + sourcehook/test/testhookmangen.cpp | 1 + 5 files changed, 281 insertions(+), 252 deletions(-) create mode 100644 sourcehook/sh_pagealloc.h diff --git a/sourcehook/sh_memory.h b/sourcehook/sh_memory.h index e9bd163..11e4633 100644 --- a/sourcehook/sh_memory.h +++ b/sourcehook/sh_memory.h @@ -185,258 +185,6 @@ namespace SourceHook #endif } } - - /* - Class which lets us allocate memory regions in special pages only meant for on the fly code generation. - - If we alloc with malloc and then set the page access type to read/exec only, other regions returned by - malloc that are in the same page would lose their write access as well and the process could crash. - - Allocating one page per code generation session is usually a waste of memory and on some plattforms also - a waste of virtual address space (Windows’ VirtualAlloc has a granularity of 64K). - - - IMPORTANT: the memory that Alloc() returns is not a in a defined state! - It could be in read+exec OR read+write mode. - -> call SetRE() or SetRW() before using allocated memory! - */ - class CPageAlloc - { - struct AllocationUnit - { - size_t begin_offset; - size_t size; - - AllocationUnit(size_t p_offs, size_t p_size) : begin_offset(p_offs), size(p_size) - { - } - - bool operator < (const AllocationUnit &other) const - { - return begin_offset < other.begin_offset; - } - }; - - typedef List AUList; - - struct AllocatedRegion - { - void *startPtr; - size_t size; - bool isolated; // may contain only one AU - AUList allocUnits; - - bool TryAlloc(size_t reqsize, void * &outAddr) - { - // Check for isolated - if (isolated && !allocUnits.empty()) - return false; - - // Find the smallest gap where req fits - size_t lastend = 0; - size_t smallestgap_pos = size + 1; - size_t smallestgap_size = size + 1; - - for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) - { - if (iter->begin_offset - lastend >= reqsize) - { - if (iter->begin_offset - lastend < smallestgap_size) - { - smallestgap_size = iter->begin_offset - lastend; - smallestgap_pos = lastend; - } - } - lastend = iter->begin_offset + iter->size; - } - - if (size - lastend >= reqsize) - { - if (size - lastend < smallestgap_size) - { - smallestgap_size = size - lastend; - smallestgap_pos = lastend; - } - } - - if (smallestgap_pos < size) - { - outAddr = reinterpret_cast(reinterpret_cast(startPtr) + smallestgap_pos); - allocUnits.push_sorted( AllocationUnit(smallestgap_pos, reqsize) ); - return true; - } - else - { - return false; - } - } - - bool TryFree(void *addr) - { - if (addr < startPtr || addr >= reinterpret_cast(reinterpret_cast(startPtr) + size)) - return false; - - size_t offs = reinterpret_cast(addr) - reinterpret_cast(startPtr); - - for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) - { - if (iter->begin_offset == offs) - { - allocUnits.erase(iter); - return true; - } - } - - return false; - } - - bool Contains(void *addr) - { - return addr >= startPtr && addr < reinterpret_cast(reinterpret_cast(startPtr) + size); - } - - void FreeRegion() - { -#ifdef __linux__ - munmap(startPtr, size); -#else - VirtualFree(startPtr, 0, MEM_RELEASE); -#endif - } - }; - - typedef List ARList; - - size_t m_PageSize; - ARList m_Regions; - - bool AddRegion(size_t minSize, bool isolated) - { - AllocatedRegion newRegion; - newRegion.startPtr = 0; - newRegion.isolated = isolated; - - // Compute real size -> align up to m_PageSize boundary - - newRegion.size = minSize - (minSize % m_PageSize); - if (newRegion.size < minSize) - newRegion.size += m_PageSize; - -#ifdef __linux__ - newRegion.startPtr = mmap(0, newRegion.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -#else - newRegion.startPtr = VirtualAlloc(NULL, newRegion.size, MEM_COMMIT, PAGE_READWRITE); -#endif - - if (newRegion.startPtr) - { - m_Regions.push_back(newRegion); - return true; - } - else - { - return false; - } - - } - - void *AllocPriv(size_t size, bool isolated) - { - void *addr; - - if (!isolated) - { - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - if (iter->TryAlloc(size, addr)) - return addr; - } - } - - if (!AddRegion(size, isolated)) - return NULL; - - bool tmp = m_Regions.back().TryAlloc(size, addr); - SH_ASSERT(tmp, ("TryAlloc fails after AddRegion")); - return addr; - } - - public: - CPageAlloc() - { -#ifdef __linux__ - m_PageSize = sysconf(_SC_PAGESIZE); -#else - SYSTEM_INFO sysInfo; - GetSystemInfo(&sysInfo); - m_PageSize = sysInfo.dwPageSize; -#endif - } - - ~CPageAlloc() - { - // Free all regions - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - iter->FreeRegion(); - } - } - - void *Alloc(size_t size) - { - return AllocPriv(size, false); - } - - void *AllocIsolated(size_t size) - { - return AllocPriv(size, true); - } - - void Free(void *ptr) - { - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - if (iter->TryFree(ptr)) - { - if (iter->allocUnits.empty()) - { - iter->FreeRegion(); - m_Regions.erase(iter); - } - break; - } - } - } - - void SetRE(void *ptr) - { - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - if (iter->Contains(ptr)) - { - SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_EXEC); - break; - } - } - } - - void SetRW(void *ptr) - { - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - if (iter->Contains(ptr)) - { - SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_WRITE); - break; - } - } - } - - size_t GetPageSize() - { - return m_PageSize; - } - }; } #endif diff --git a/sourcehook/sh_pagealloc.h b/sourcehook/sh_pagealloc.h new file mode 100644 index 0000000..8dd8cf3 --- /dev/null +++ b/sourcehook/sh_pagealloc.h @@ -0,0 +1,273 @@ +#ifndef __SH_PAGEALLOC_H__ +#define __SH_PAGEALLOC_H__ + +# if /********/ defined _WIN32 +# include +# define SH_MEM_READ 1 +# define SH_MEM_WRITE 2 +# define SH_MEM_EXEC 4 +# elif /******/ defined __linux__ +# include +# include +# else +# error Unsupported OS/Compiler +# endif + + +namespace SourceHook +{ + + /* + Class which lets us allocate memory regions in special pages only meant for on the fly code generation. + + If we alloc with malloc and then set the page access type to read/exec only, other regions returned by + malloc that are in the same page would lose their write access as well and the process could crash. + + Allocating one page per code generation session is usually a waste of memory and on some plattforms also + a waste of virtual address space (Windows’ VirtualAlloc has a granularity of 64K). + + + IMPORTANT: the memory that Alloc() returns is not a in a defined state! + It could be in read+exec OR read+write mode. + -> call SetRE() or SetRW() before using allocated memory! + */ + class CPageAlloc + { + struct AllocationUnit + { + size_t begin_offset; + size_t size; + + AllocationUnit(size_t p_offs, size_t p_size) : begin_offset(p_offs), size(p_size) + { + } + + bool operator < (const AllocationUnit &other) const + { + return begin_offset < other.begin_offset; + } + }; + + typedef List AUList; + + struct AllocatedRegion + { + void *startPtr; + size_t size; + bool isolated; // may contain only one AU + AUList allocUnits; + + bool TryAlloc(size_t reqsize, void * &outAddr) + { + // Check for isolated + if (isolated && !allocUnits.empty()) + return false; + + // Find the smallest gap where req fits + size_t lastend = 0; + size_t smallestgap_pos = size + 1; + size_t smallestgap_size = size + 1; + + for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) + { + if (iter->begin_offset - lastend >= reqsize) + { + if (iter->begin_offset - lastend < smallestgap_size) + { + smallestgap_size = iter->begin_offset - lastend; + smallestgap_pos = lastend; + } + } + lastend = iter->begin_offset + iter->size; + } + + if (size - lastend >= reqsize) + { + if (size - lastend < smallestgap_size) + { + smallestgap_size = size - lastend; + smallestgap_pos = lastend; + } + } + + if (smallestgap_pos < size) + { + outAddr = reinterpret_cast(reinterpret_cast(startPtr) + smallestgap_pos); + allocUnits.push_sorted( AllocationUnit(smallestgap_pos, reqsize) ); + return true; + } + else + { + return false; + } + } + + bool TryFree(void *addr) + { + if (addr < startPtr || addr >= reinterpret_cast(reinterpret_cast(startPtr) + size)) + return false; + + size_t offs = reinterpret_cast(addr) - reinterpret_cast(startPtr); + + for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) + { + if (iter->begin_offset == offs) + { + allocUnits.erase(iter); + return true; + } + } + + return false; + } + + bool Contains(void *addr) + { + return addr >= startPtr && addr < reinterpret_cast(reinterpret_cast(startPtr) + size); + } + + void FreeRegion() + { +#ifdef __linux__ + munmap(startPtr, size); +#else + VirtualFree(startPtr, 0, MEM_RELEASE); +#endif + } + }; + + typedef List ARList; + + size_t m_PageSize; + ARList m_Regions; + + bool AddRegion(size_t minSize, bool isolated) + { + AllocatedRegion newRegion; + newRegion.startPtr = 0; + newRegion.isolated = isolated; + + // Compute real size -> align up to m_PageSize boundary + + newRegion.size = minSize - (minSize % m_PageSize); + if (newRegion.size < minSize) + newRegion.size += m_PageSize; + +#ifdef __linux__ + newRegion.startPtr = mmap(0, newRegion.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +#else + newRegion.startPtr = VirtualAlloc(NULL, newRegion.size, MEM_COMMIT, PAGE_READWRITE); +#endif + + if (newRegion.startPtr) + { + m_Regions.push_back(newRegion); + return true; + } + else + { + return false; + } + + } + + void *AllocPriv(size_t size, bool isolated) + { + void *addr; + + if (!isolated) + { + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + if (iter->TryAlloc(size, addr)) + return addr; + } + } + + if (!AddRegion(size, isolated)) + return NULL; + + bool tmp = m_Regions.back().TryAlloc(size, addr); + SH_ASSERT(tmp, ("TryAlloc fails after AddRegion")); + return addr; + } + + public: + CPageAlloc() + { +#ifdef __linux__ + m_PageSize = sysconf(_SC_PAGESIZE); +#else + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + m_PageSize = sysInfo.dwPageSize; +#endif + } + + ~CPageAlloc() + { + // Free all regions + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + iter->FreeRegion(); + } + } + + void *Alloc(size_t size) + { + return AllocPriv(size, false); + } + + void *AllocIsolated(size_t size) + { + return AllocPriv(size, true); + } + + void Free(void *ptr) + { + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + if (iter->TryFree(ptr)) + { + if (iter->allocUnits.empty()) + { + iter->FreeRegion(); + m_Regions.erase(iter); + } + break; + } + } + } + + void SetRE(void *ptr) + { + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + if (iter->Contains(ptr)) + { + SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_EXEC); + break; + } + } + } + + void SetRW(void *ptr) + { + for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) + { + if (iter->Contains(ptr)) + { + SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_WRITE); + break; + } + } + } + + size_t GetPageSize() + { + return m_PageSize; + } + }; +} + +#endif \ No newline at end of file diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 6b2c0f3..11ea395 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -12,6 +12,7 @@ #define __SOURCEHOOK_HOOKMANGEN_H__ #include "sourcehook_impl.h" +#include "sh_pagealloc.h" namespace SourceHook { diff --git a/sourcehook/test/msvc7/test.vcproj b/sourcehook/test/msvc7/test.vcproj index a909ea1..561eb34 100644 --- a/sourcehook/test/msvc7/test.vcproj +++ b/sourcehook/test/msvc7/test.vcproj @@ -312,6 +312,12 @@ + + + + diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index b82e9e4..828bd38 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -4,6 +4,7 @@ #include "testevents.h" #include "sourcehook_hookmangen.h" #include "sh_memory.h" +#include "sh_pagealloc.h" // TESTHOOKMANGEN // Test automatic hookman generation From 638cf2e1b69eecde2e3cb1802b0e421aaf501f6c Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Tue, 6 Nov 2007 22:04:38 +0000 Subject: [PATCH 11/41] CPageAlloc now executes before TestHookmanGen, newline at the end of sh_pagealloc.h --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40546 --- sourcehook/sh_pagealloc.h | 3 ++- sourcehook/test/main.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sourcehook/sh_pagealloc.h b/sourcehook/sh_pagealloc.h index 8dd8cf3..6445285 100644 --- a/sourcehook/sh_pagealloc.h +++ b/sourcehook/sh_pagealloc.h @@ -270,4 +270,5 @@ namespace SourceHook }; } -#endif \ No newline at end of file +#endif + diff --git a/sourcehook/test/main.cpp b/sourcehook/test/main.cpp index bdf3216..993c695 100644 --- a/sourcehook/test/main.cpp +++ b/sourcehook/test/main.cpp @@ -46,8 +46,8 @@ DECL_TEST(Multi); DECL_TEST(Ref); DECL_TEST(RefRet); DECL_TEST(VPHooks); -DECL_TEST(HookManGen); DECL_TEST(CPageAlloc); // in testhookmangen.cpp +DECL_TEST(HookManGen); int main(int argc, char *argv[]) { @@ -70,8 +70,8 @@ int main(int argc, char *argv[]) DO_TEST(Ref); DO_TEST(RefRet); DO_TEST(VPHooks); - DO_TEST(HookManGen); DO_TEST(CPageAlloc); + DO_TEST(HookManGen); cout << endl << "----" << endl << "Passed: " << passed << endl << "Failed: " << failed << endl; cout << "Total: " << passed + failed << endl; From 94223941d2fc41ea2b1fee3627ec7e5dc3da03db Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Wed, 7 Nov 2007 15:15:05 +0000 Subject: [PATCH 12/41] Progress in GCC compat; TODO atm: proper passing of byval parameters with destructors (private copy, then byref pass?) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40547 --- sourcehook/sourcehook_hookmangen.cpp | 136 +++++++++++++++---------- sourcehook/sourcehook_hookmangen.h | 1 + sourcehook/sourcehook_hookmangen_x86.h | 5 + sourcehook/sourcehook_impl_cproto.h | 5 + 4 files changed, 92 insertions(+), 55 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 6a3df96..c28cf99 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -19,6 +19,14 @@ #include "sourcehook_hookmangen_x86.h" #include "sh_memory.h" +#if SH_COMP == SH_COMP_MSVC +# define GCC_ONLY(x) +# define MSVC_ONLY(x) x +#elif SH_COMP == SH_COMP_GCC +# define GCC_ONLY(x) x +# define MSVC_ONLY(x) +#endif + // :TODO: test BIG vtable indices namespace SourceHook @@ -293,12 +301,10 @@ namespace SourceHook IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_ECX, REG_NOIDX, REG_ESP, NOSCALE, 4); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_offset); IA32_Push_Reg(&m_HookFunc, REG_EAX); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EDX, DownCastPtr(pi.pCopyCtor)); IA32_Call_Reg(&m_HookFunc, REG_EDX); - + GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); IA32_Pop_Reg(&m_HookFunc, REG_EAX); } else @@ -408,19 +414,19 @@ namespace SourceHook { // lea edx, [ebp + v_place_for_memret] <-- src addr // lea ecx, [ebp + v_where] <-- dest addr - // gcc: push ecx // push edx + // gcc: push ecx // call it + // gcc: clean up IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_place_for_memret); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_where); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif IA32_Push_Reg(&m_HookFunc, REG_EDX); + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); } else { @@ -441,13 +447,13 @@ namespace SourceHook //lea ecx, [ebp+v_place_for_memret] //gcc: push ecx //call it + //gcc: clean up IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_place_for_memret); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); } } else @@ -554,15 +560,15 @@ namespace SourceHook // eax = [ecx] // eax = [eax + 4] // call eax + // gcc: clean up IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); // vtbloffs=0, vtblidx=1 IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 4); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); // *eax = plugin_ret @@ -578,21 +584,23 @@ namespace SourceHook if (m_Proto.GetRet().pAssignOperator) { // lea edx, [ebp + v_plugin_ret] + // push edx <-- src addr // msvc: ecx = eax <-- dest addr // gcc: push eax <-- dest addr - // push edx <-- src addr // call it + // gcc: clean up IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_plugin_ret); + IA32_Push_Reg(&m_HookFunc, REG_EDX); #if SH_COMP == SH_COMP_MSVC IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); #elif SH_COMP == SH_COMP_GCC IA32_Push_Reg(&m_HookFunc, REG_EAX); #endif - IA32_Push_Reg(&m_HookFunc, REG_EDX); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); } else { @@ -642,11 +650,10 @@ namespace SourceHook // mov edx, [edx] // call edx + // gcc: clean up IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Xor_Reg_Rm(&m_HookFunc, REG_EAX, REG_EAX, MOD_REG); IA32_Cmp_Rm_Disp8_Imm8(&m_HookFunc, REG_EBP, v_status, MRES_OVERRIDE); IA32_SetCC_Rm8(&m_HookFunc, REG_EAX, CC_L); @@ -658,6 +665,7 @@ namespace SourceHook IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_EDX, MOD_MEM_REG); IA32_Call_Reg(&m_HookFunc, REG_EDX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_retptr); } @@ -721,22 +729,24 @@ namespace SourceHook if (m_Proto.GetRet().pCopyCtor) { // mov edx, ecx <-- src ( we set ecx to [ebp+v_retptr] before ) + // push edx <-- src addr // msvc: ecx = [ebp + v_memret_outaddr] <-- dest addr // gcc: push [ebp + v_memret_outaddr] <-- dest addr - // push edx <-- src addr // call it + // gcc: clean up IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_ECX, MOD_REG); + IA32_Push_Reg(&m_HookFunc, REG_EDX); #if SH_COMP == SH_COMP_MSVC IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_memret_outaddr); #elif SH_COMP == SH_COMP_GCC IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, v_memret_outaddr); #endif - IA32_Push_Reg(&m_HookFunc, REG_EDX); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pCopyCtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); } else { @@ -776,15 +786,15 @@ namespace SourceHook // eax = [ecx] // eax = [eax] // call eax + // gcc: clean up IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); // vtbloffs=0, vtblidx=0 IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_EAX, MOD_MEM_REG); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); // quit on zero // test eax, eax @@ -803,12 +813,12 @@ namespace SourceHook // eax = [ecx] // eax = [eax+2*SIZE_PTR] // call eax + // gcc: clean up + jit_int32_t gcc_clean_bytes = PushParams(base_param_offset, v_plugin_ret, v_place_for_memret); IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 2*SIZE_PTR); IA32_Call_Reg(&m_HookFunc, REG_EAX); @@ -816,10 +826,8 @@ namespace SourceHook SaveRetVal(v_plugin_ret, v_place_for_memret); // cleanup -#if SH_COMP == SH_COMP_GCC // params + thisptr - IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG); -#endif + GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG)); // process meta return: // prev_res = cur_res @@ -914,15 +922,15 @@ namespace SourceHook // eax = [ecx] // eax = [eax + 3*PTR_SIZE] // call eax + // gcc: clean up IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); // vtbloffs=0, vtblidx=3 IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); IA32_Mov_Reg_Rm_Disp8(&m_HookFunc, REG_EAX, REG_EAX, 3*SIZE_PTR); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); IA32_Test_Rm_Reg8(&m_HookFunc, REG_EAX, REG_EAX, MOD_REG); tmppos2 = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_Z, 0); @@ -979,19 +987,19 @@ namespace SourceHook { // lea edx, [ebp + v_override_ret] <-- src addr // lea ecx, [ebp + v_orig_ret] <-- dest addr - // gcc: push ecx // push edx <-- src addr + // gcc: push ecx // call it + // gcc: clean up IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_override_ret); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif IA32_Push_Reg(&m_HookFunc, REG_EDX); + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG)); } else { @@ -1067,7 +1075,7 @@ namespace SourceHook // set up thisptr #if SH_COMP == SH_COMP_GCC // on gcc/mingw, this is the first parameter - IA32_Push_Imm32(&m_HookFunc, DownCastPtr(m_SHPtr)); + GCC_ONLY(IA32_Push_Imm32(&m_HookFunc, DownCastPtr(m_SHPtr))); #elif SH_COMP == SH_COMP_MSVC // on msvc, it's ecx IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, DownCastPtr(m_SHPtr)); @@ -1081,10 +1089,8 @@ namespace SourceHook IA32_Call_Reg(&m_HookFunc, REG_EAX); // on gcc/mingw, we have to clean up after the call -#if SH_COMP == SH_COMP_GCC // 9 params + hidden thisptr param - IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 10*SIZE_PTR, MOD_REG); -#endif + GCC_ONLY(IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 10*SIZE_PTR, MOD_REG)); // store return value IA32_Mov_Rm_Reg_Disp8(&m_HookFunc, REG_EBP, REG_EAX, v_pContext); @@ -1113,10 +1119,8 @@ namespace SourceHook IA32_Call_Reg(&m_HookFunc, REG_EAX); // on gcc/mingw, we have to clean up after the call -#if SH_COMP == SH_COMP_GCC // 1 param + hidden thisptr param - IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG); -#endif + GCC_ONLY(IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG)); } void * GenContext::GenerateHookFunc() @@ -1132,7 +1136,7 @@ namespace SourceHook const int addstackoffset = -4; IA32_Push_Reg(&m_HookFunc, REG_ECX); #elif SH_COMP == SH_COMP_GCC - const jit_int8_t v_this = 8; // first param + const jit_int8_t v_this = 12; // first param const int addstackoffset = 0; #endif @@ -1212,18 +1216,24 @@ namespace SourceHook // orig_reg IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); // override_reg IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); // plugin_ret IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); // _don't_ call a constructor for v_place_for_memret ! } @@ -1276,25 +1286,22 @@ namespace SourceHook IA32_Push_Reg(&m_HookFunc, REG_EDX); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#endif + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); IA32_Pop_Reg(&m_HookFunc, REG_EDX); IA32_Pop_Reg(&m_HookFunc, REG_EAX); @@ -1304,7 +1311,8 @@ namespace SourceHook IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESP, REG_EBP, MOD_REG); IA32_Pop_Reg(&m_HookFunc, REG_EBX); IA32_Pop_Reg(&m_HookFunc, REG_EBP); - IA32_Return_Popstack(&m_HookFunc, GetParamsStackSize()); + MSVC_ONLY(IA32_Return_Popstack(&m_HookFunc, GetParamsStackSize())); + GCC_ONLY(IA32_Return(&m_HookFunc)); // :TODO: ?? Memory return? Should I pop 4 bytes then? // Store pointer for later use // m_HookfuncVfnPtr is a pointer to a void* because SH expects a pointer @@ -1487,6 +1495,23 @@ namespace SourceHook } } + void GenContext::AutoDetectParamFlags() + { +#if SH_COMP == SH_COMP_GCC + // On GCC, all objects are passed by reference if they have a destructor + for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) + { + IntPassInfo &pi = m_Proto.GetParam(i); + if (pi.type == PassInfo::PassType_Object && + (pi.flags & PassInfo::PassFlag_ODtor)) + { + pi.flags &= ~PassInfo::PassFlag_ByVal; + pi.flags |= PassInfo::PassFlag_ByRef; + } + } +#endif + } + HookManagerPubFunc GenContext::Generate() { Clear(); @@ -1504,6 +1529,7 @@ namespace SourceHook } AutoDetectRetType(); + AutoDetectParamFlags(); if (m_Proto.GetConvention() != ProtoInfo::CallConv_Cdecl && m_Proto.GetConvention() != ProtoInfo::CallConv_ThisCall) diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 11ea395..c1edde5 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -220,6 +220,7 @@ namespace SourceHook // Level 2 -> called from Generate() void AutoDetectRetType(); + void AutoDetectParamFlags(); bool PassInfoSupported(const IntPassInfo &pi, bool is_ret); void Clear(); void BuildProtoInfo(); diff --git a/sourcehook/sourcehook_hookmangen_x86.h b/sourcehook/sourcehook_hookmangen_x86.h index 576c2ca..81b40cd 100644 --- a/sourcehook/sourcehook_hookmangen_x86.h +++ b/sourcehook/sourcehook_hookmangen_x86.h @@ -218,6 +218,11 @@ namespace SourceHook return sib; } + inline void IA32_Int3(JitWriter *jit) + { + jit->write_ubyte(IA32_INT3); + } + /*********************** * INCREMENT/DECREMENT * ***********************/ diff --git a/sourcehook/sourcehook_impl_cproto.h b/sourcehook/sourcehook_impl_cproto.h index c8e9979..949b8ed 100644 --- a/sourcehook/sourcehook_impl_cproto.h +++ b/sourcehook/sourcehook_impl_cproto.h @@ -87,6 +87,11 @@ namespace SourceHook return m_ParamsPassInfo[i]; } + IntPassInfo & GetParam(int i) + { + return m_ParamsPassInfo[i]; + } + const IntPassInfo & GetRet() const { return m_RetPassInfo; From d4bd0261f1754867e90a1067d4bf8ec0919a7bff Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Wed, 7 Nov 2007 16:56:03 +0000 Subject: [PATCH 13/41] ForcedByRef works; next step will be: returns! --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40548 --- sourcehook/sourcehook_hookmangen.cpp | 160 ++++++++++++++++++++------- sourcehook/sourcehook_hookmangen.h | 14 ++- sourcehook/test/testhookmangen.cpp | 2 +- sourcehook/test/testhookmangen.h | 17 +-- sourcehook/test/testhookmangen.hxx | 17 +-- 5 files changed, 142 insertions(+), 68 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index c28cf99..fbe0242 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -196,6 +196,39 @@ namespace SourceHook IA32_Pop_Reg(&m_HookFunc, REG_EDI); } + short GenContext::GetParamsStackSize() + { + short acc = 0; + for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) + { + acc += GetStackSize(m_Proto.GetParam(i)); + } + + // Memory return: address is first param + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + acc += SIZE_PTR; + + // :TODO: cdecl: THIS POINTER AS FIRST PARAM!!! + + return acc; + } + + short GenContext::GetForcedByRefParamOffset(int p) + { + short off = 0; + for (int i = 0; i < p; ++i) + { + if (m_Proto.GetParam(i).flags & PassFlag_ForcedByRef) + off += GetStackSize(m_Proto.GetParam(i)); + } + return off; + } + + short GenContext::GetForcedByRefParamsSize() + { + return GetForcedByRefParamOffset(m_Proto.GetNumOfParams()); + } + jit_int32_t GenContext::PushRef(jit_int32_t param_offset, const IntPassInfo &pi) { // push [ebp+] @@ -282,23 +315,31 @@ namespace SourceHook } } - jit_int32_t GenContext::PushObject(jit_int32_t param_offset, const IntPassInfo &pi) + jit_int32_t GenContext::PushObject(jit_int32_t param_offset, const IntPassInfo &pi, jit_int32_t place_fbrr) { - // make room on the stack - // sub esp, - IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, GetStackSize(pi), MOD_REG); + if ((pi.flags & PassFlag_ForcedByRef) == 0) + { + // make room on the stack + // sub esp, + IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, GetStackSize(pi), MOD_REG); + } // if there is a copy constructor.. if (pi.pCopyCtor) { // save eax // push src addr - // this= target addr = esp+12 + // this= target addr = forcedbyref ? ebp+place_fbrr : esp+12 // call copy constructor // restore eax IA32_Push_Reg(&m_HookFunc, REG_EAX); - IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_ECX, REG_NOIDX, REG_ESP, NOSCALE, 4); + + if (pi.flags & PassFlag_ForcedByRef) + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, place_fbrr); + else + IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_ECX, REG_NOIDX, REG_ESP, NOSCALE, 4); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_offset); IA32_Push_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); @@ -314,19 +355,50 @@ namespace SourceHook BitwiseCopy_Setup(); - //lea edi, [esp+8] + //if forcedbyref: + // lea edi, [ebp_place_fbrr] + //else + // lea edi, [esp+8] - bc_setup pushed two regs onto the stack! //lea esi, [ebp+] - IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_EDI, REG_NOIDX, REG_ESP, NOSCALE, 8); + if (pi.flags & PassFlag_ForcedByRef) + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, place_fbrr); + else + IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_EDI, REG_NOIDX, REG_ESP, NOSCALE, 8); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, param_offset); BitwiseCopy_Do(pi.size); } + // forcedref: push reference to ebp+place_fbrr + if (pi.flags & PassFlag_ForcedByRef) + { + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, place_fbrr); + IA32_Push_Reg(&m_HookFunc, REG_ECX); + return SIZE_PTR; + } + return DownCastSize(pi.size); } + void GenContext::DestroyParams(jit_int32_t fbrr_base) + { + for (int i = m_Proto.GetNumOfParams() - 1; i >= 0; --i) + { + const IntPassInfo &pi = m_Proto.GetParam(i); + if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ODtor) && + (pi.flags & PassInfo::PassFlag_ByVal) && (pi.flags & PassFlag_ForcedByRef)) + { + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, fbrr_base + GetForcedByRefParamOffset(i)); + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + } + } + } + // May not touch eax! - jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to, int v_place_for_memret) + jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to, int v_place_for_memret, + jit_int32_t v_place_fbrr_base) { jit_int32_t added_to_stack = 0; jit_int32_t ret = 0; @@ -354,7 +426,7 @@ namespace SourceHook ret = PushFloat(cur_offset, pi); break; case PassInfo::PassType_Object: - ret = PushObject(cur_offset, pi); + ret = PushObject(cur_offset, pi, v_place_fbrr_base + GetForcedByRefParamOffset(i)); break; } } @@ -768,7 +840,7 @@ namespace SourceHook } void GenContext::GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, - int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret) + int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base) { jitoffs_t counter, tmppos; jitoffs_t counter2, tmppos2; @@ -815,7 +887,7 @@ namespace SourceHook // call eax // gcc: clean up - jit_int32_t gcc_clean_bytes = PushParams(base_param_offset, v_plugin_ret, v_place_for_memret); + jit_int32_t gcc_clean_bytes = PushParams(base_param_offset, v_plugin_ret, v_place_for_memret, v_place_fbrr_base); IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); @@ -823,11 +895,16 @@ namespace SourceHook IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 2*SIZE_PTR); IA32_Call_Reg(&m_HookFunc, REG_EAX); + DestroyParams(v_place_fbrr_base); + SaveRetVal(v_plugin_ret, v_place_for_memret); // cleanup +#if SH_COMP == SH_COMP_GCC + IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG); +#endif + // params + thisptr - GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG)); // process meta return: // prev_res = cur_res @@ -866,25 +943,8 @@ namespace SourceHook m_HookFunc.rewrite(tmppos, static_cast(counter)); } - short GenContext::GetParamsStackSize() - { - short acc = 0; - for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) - { - acc += GetStackSize(m_Proto.GetParam(i)); - } - - // Memory return: address is first param - if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - acc += SIZE_PTR; - - // :TODO: cdecl: THIS POINTER AS FIRST PARAM!!! - - return acc; - } - void GenContext::GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this, - int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret) + int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base) { jitoffs_t counter, tmppos; jitoffs_t counter2, tmppos2; @@ -937,7 +997,7 @@ namespace SourceHook m_HookFunc.start_count(counter2); // push params - jit_int32_t gcc_clean_bytes = PushParams(param_base_offs, v_orig_ret, v_place_for_memret); + jit_int32_t gcc_clean_bytes = PushParams(param_base_offs, v_orig_ret, v_place_for_memret, v_place_fbrr_base); // thisptr IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); @@ -953,10 +1013,11 @@ namespace SourceHook // cleanup #if SH_COMP == SH_COMP_GCC - // params + thisptr IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG); #endif + DestroyParams(v_place_fbrr_base); + // save retval SaveRetVal(v_orig_ret, v_place_for_memret); @@ -1166,6 +1227,9 @@ namespace SourceHook // if required: // my_rettype place_for_memret ebp - 28 - sizeof(my_rettype)*4 -4 + + // gcc only: if required: + // place forced byref params ebp - 28 - sizeof(my_rettype)*{4 or 5} const jit_int8_t v_vfnptr_origentry = -4 + addstackoffset; @@ -1196,11 +1260,14 @@ namespace SourceHook jit_int32_t v_place_for_memret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 4; + jit_int32_t v_place_fbrr_base = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * (MemRetWithTempObj() ? 5 : 4); + // Hash for temporary storage for byval params with copy constructors // (param, offset into stack) short usedStackBytes = 3*SIZE_MWORD + 3*SIZE_PTR // vfnptr_origentry, status, prev_res, cur_res, iter, pContext + 3 * GetStackSize(m_Proto.GetRet()) + (m_Proto.GetRet().size == 0 ? 0 : SIZE_PTR) // ret_ptr, orig_ret, override_ret, plugin_ret + (MemRetWithTempObj() ? GetStackSize(m_Proto.GetRet()) : 0) + + GetForcedByRefParamsSize() - addstackoffset; // msvc: current thisptr IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, usedStackBytes, MOD_REG); @@ -1244,15 +1311,15 @@ namespace SourceHook // ********************** call pre hooks ********************** GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, - v_plugin_ret, v_place_for_memret); + v_plugin_ret, v_place_for_memret, v_place_fbrr_base); // ********************** call orig func ********************** GenerateCallOrig(v_status, v_pContext, param_base_offs, v_this, v_vfnptr_origentry, v_orig_ret, - v_override_ret, v_place_for_memret); + v_override_ret, v_place_for_memret, v_place_fbrr_base); // ********************** call post hooks ********************** GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, - v_plugin_ret, v_place_for_memret); + v_plugin_ret, v_place_for_memret, v_place_fbrr_base); // ********************** end context and return ********************** @@ -1265,8 +1332,9 @@ namespace SourceHook for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) { const IntPassInfo &pi = m_Proto.GetParam(i); + // GCC: NOT of forced byref params. the caller destructs those. if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ODtor) && - (pi.flags & PassInfo::PassFlag_ByVal)) + (pi.flags & PassInfo::PassFlag_ByVal) && !(pi.flags & PassFlag_ForcedByRef)) { IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, cur_param_pos); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); @@ -1420,6 +1488,7 @@ namespace SourceHook pi.type != PassInfo::PassType_Float && pi.type != PassInfo::PassType_Object) { + printf("A\n"); return false; } @@ -1427,16 +1496,28 @@ namespace SourceHook (pi.flags & PassInfo::PassFlag_ByVal)) { if ((pi.flags & PassInfo::PassFlag_CCtor) && !pi.pCopyCtor) + { + printf("B\n"); return false; + } if ((pi.flags & PassInfo::PassFlag_ODtor) && !pi.pDtor) + { + printf("C\n"); return false; - + } + if ((pi.flags & PassInfo::PassFlag_AssignOp) && !pi.pAssignOperator) + { + printf("D\n"); return false; + } if ((pi.flags & PassInfo::PassFlag_OCtor) && !pi.pNormalCtor) + { + printf("D\n"); return false; + } } if ((pi.flags & (PassInfo::PassFlag_ByVal | PassInfo::PassFlag_ByRef)) == 0) @@ -1505,8 +1586,7 @@ namespace SourceHook if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ODtor)) { - pi.flags &= ~PassInfo::PassFlag_ByVal; - pi.flags |= PassInfo::PassFlag_ByRef; + pi.flags |= PassFlag_ForcedByRef; } } #endif diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index c1edde5..8443b2c 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -156,6 +156,7 @@ namespace SourceHook { const static int SIZE_MWORD = 4; const static int SIZE_PTR = sizeof(void*); + const static int PassFlag_ForcedByRef = (1<<30); // ByVal in source, but actually passed by reference (GCC) -> private pass, destruct CProto m_Proto; int m_VtblOffs; @@ -180,19 +181,22 @@ namespace SourceHook // size info jit_int32_t GetRealSize(const IntPassInfo &info); jit_int32_t GetStackSize(const IntPassInfo &info); - short GetParamsStackSize(); // sum(GetStackSize(i), 0 <= i < numOfParams) + short GetParamsStackSize(); // sum(GetStackSize(param[i]), 0 <= i < numOfParams) // Helpers void BitwiseCopy_Setup(); void BitwiseCopy_Do(size_t size); // Param push + short GetForcedByRefParamsSize(); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < numOfParams) + short GetForcedByRefParamOffset(int p); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < p) jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to, - jit_int32_t v_place_for_memret); // save_ret_to and v_place_for_memret only used for memory returns + jit_int32_t v_place_for_memret, jit_int32_t v_place_fbrr_base); // save_ret_to and v_place_for_memret only used for memory returns jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi); - jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi); + jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi, jit_int32_t v_place_fbrr); + void DestroyParams(jit_int32_t fbrr_base); // Ret val processing void SaveRetVal(jit_int32_t v_where, jit_int32_t v_place_for_memret); @@ -205,11 +209,11 @@ namespace SourceHook // Call hooks void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, - int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret); + int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base); // Call orig void GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this, - int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret); + int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base); // Hook loop void CallSetupHookLoop(int v_orig_ret, int v_override_ret, diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 828bd38..475ea64 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -114,7 +114,7 @@ namespace template std::ostream& operator <<(std::ostream &os, const Object &obj) { - os << "Some Obj!"; + os << "Some Obj" << static_cast(obj.x[0]); return os; } diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index cc8c831..c010678 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -40,18 +40,13 @@ public: template void *FindFuncAddr(T mfp) { - if (sizeof(mfp) != sizeof(void*)) - return NULL; - else + union { - union - { - T a; - void *b; - } u; - u.a = mfp; - return u.b; - } + T a; + void *b; + } u; + u.a = mfp; + return u.b; } // Reference carrier diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index f633ebf..49fb473 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -40,18 +40,13 @@ public: template void *FindFuncAddr(T mfp) { - if (sizeof(mfp) != sizeof(void*)) - return NULL; - else + union { - union - { - T a; - void *b; - } u; - u.a = mfp; - return u.b; - } + T a; + void *b; + } u; + u.a = mfp; + return u.b; } // Reference carrier From e9089e6730a04568c90cb1fd66ca5d13e1577a23 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Thu, 8 Nov 2007 18:17:26 +0000 Subject: [PATCH 14/41] POD returns work on GCC --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40549 --- sourcehook/sourcehook_hookmangen.cpp | 39 ++++++++++++++++++++++------ sourcehook/sourcehook_hookmangen.h | 1 + sourcehook/test/testhookmangen.cpp | 5 ++-- sourcehook/test/testhookmangen.h | 6 +++++ sourcehook/test/testhookmangen.hxx | 6 +++++ 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index fbe0242..d528752 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -441,19 +441,25 @@ namespace SourceHook added_to_stack += ret; } + return added_to_stack; + } + + // It is IMPORTANT that PushMemRetPtr doesn't touch ecx and eax + jit_int32_t GenContext::PushMemRetPtr(jit_int32_t save_ret_to, jit_int32_t v_place_for_memret) + { // Memory return support if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) { // push address where to save it! - int reg = NextRegEBX_ECX_EDX(); + int reg = REG_EDX; IA32_Lea_DispRegImmAuto(&m_HookFunc, reg, REG_EBP, MemRetWithTempObj() ? v_place_for_memret : save_ret_to); IA32_Push_Reg(&m_HookFunc, reg); - added_to_stack += SIZE_PTR; + return (SH_COMP==SH_COMP_MSVC) ? 4 : 0; // varargs funcs on msvc might need this. + // gcc doesn't: callee cleans the memret ptr, caller the other params :s } - - return added_to_stack; + return 0; } void GenContext::SaveRetVal(int v_where, int v_place_for_memret) @@ -891,6 +897,7 @@ namespace SourceHook IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); + gcc_clean_bytes += PushMemRetPtr(v_plugin_ret, v_place_for_memret); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 2*SIZE_PTR); IA32_Call_Reg(&m_HookFunc, REG_EAX); @@ -1006,6 +1013,7 @@ namespace SourceHook IA32_Push_Reg(&m_HookFunc, REG_ECX); // on msvc, simply leave it in ecx #endif + gcc_clean_bytes += PushMemRetPtr(v_orig_ret, v_place_for_memret); // call IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_vfnptr_origentry); @@ -1193,11 +1201,11 @@ namespace SourceHook // on msvc, save thisptr #if SH_COMP == SH_COMP_MSVC - const jit_int8_t v_this = -4; + jit_int8_t v_this = -4; const int addstackoffset = -4; IA32_Push_Reg(&m_HookFunc, REG_ECX); #elif SH_COMP == SH_COMP_GCC - const jit_int8_t v_this = 12; // first param + jit_int8_t v_this = 12; // first param const int addstackoffset = 0; #endif @@ -1249,8 +1257,17 @@ namespace SourceHook jit_int32_t v_memret_addr = 0; if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) { +#if SH_COMP == SH_COMP_GCC + // gcc: now: first param = mem ret addr + // second param = this pointer + // third param = actual first param + v_memret_addr = 12; + v_this += 4; + param_base_offs += SIZE_PTR; +#elif SH_COMP == SH_COMP_MSVC v_memret_addr = param_base_offs; param_base_offs += SIZE_PTR; +#endif } jit_int32_t v_ret_ptr = -28 + addstackoffset; @@ -1380,8 +1397,14 @@ namespace SourceHook IA32_Pop_Reg(&m_HookFunc, REG_EBX); IA32_Pop_Reg(&m_HookFunc, REG_EBP); MSVC_ONLY(IA32_Return_Popstack(&m_HookFunc, GetParamsStackSize())); - GCC_ONLY(IA32_Return(&m_HookFunc)); // :TODO: ?? Memory return? Should I pop 4 bytes then? - + // gcc: Remove 4 bytes from stack on memory return +#if SH_COMP == SH_COMP_GCC + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + IA32_Return_Popstack(&m_HookFunc, SIZE_PTR); + else + IA32_Return(&m_HookFunc); +#endif + // Store pointer for later use // m_HookfuncVfnPtr is a pointer to a void* because SH expects a pointer // into the hookman's vtable diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 8443b2c..83e80df 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -196,6 +196,7 @@ namespace SourceHook jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi); jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi, jit_int32_t v_place_fbrr); + jit_int32_t PushMemRetPtr(jit_int32_t save_ret_to, jit_int32_t v_place_for_memret); void DestroyParams(jit_int32_t fbrr_base); // Ret val processing diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 475ea64..7bbbb0c 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -133,7 +133,7 @@ namespace } \ template <> struct MakeRet< PodRet##size > \ { \ - static PodRet##size Do(int a) \ + static PodRet##size Do(int a) NO_OPTIMIZE \ { \ PodRet##size x; \ memset(reinterpret_cast(x.actPod.x), a, size); \ @@ -155,7 +155,7 @@ namespace } \ template <> struct MakeRet< ObjRet##size > \ { \ - static ObjRet##size Do(int a) \ + static ObjRet##size Do(int a) NO_OPTIMIZE \ { \ ObjRet##size x; \ memset(reinterpret_cast(x.actObj.x), a, size); \ @@ -639,6 +639,7 @@ bool TestHookManGen(std::string &error) /* no hooks - no hooks */ PtrBuf_Clear(); + asm("int $3"); obj13 = pTest110->Func(5); g_Inside_LeafFunc = true; diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index c010678..9b5a52e 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -92,6 +92,12 @@ template struct MyRefCarrier }; }; +#if SH_COMP==SH_COMP_GCC +#define NO_OPTIMIZE __attribute__((noinline)) +#else +#define NO_OPTIMIZE +#endif + // Return value maker template struct MakeRet diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 49fb473..ce709d6 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -92,6 +92,12 @@ template struct MyRefCarrier }; }; +#if SH_COMP==SH_COMP_GCC +#define NO_OPTIMIZE __attribute__((noinline)) +#else +#define NO_OPTIMIZE +#endif + // Return value maker template struct MakeRet From 3f34d0aca99062816428e0a8d51b1feee62ca779 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 9 Nov 2007 06:19:18 +0000 Subject: [PATCH 15/41] Tested Object returns (with octor/cctor/dtor/assignop) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40550 --- sourcehook/test/testhookmangen.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 7bbbb0c..858f526 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -133,7 +133,7 @@ namespace } \ template <> struct MakeRet< PodRet##size > \ { \ - static PodRet##size Do(int a) NO_OPTIMIZE \ + static PodRet##size Do(int a) \ { \ PodRet##size x; \ memset(reinterpret_cast(x.actPod.x), a, size); \ @@ -157,9 +157,10 @@ namespace { \ static ObjRet##size Do(int a) NO_OPTIMIZE \ { \ - ObjRet##size x; \ - memset(reinterpret_cast(x.actObj.x), a, size); \ - return x; \ + ObjRet##size *x = new ObjRet##size; /* ptr: otherwise gcc optimizes away the temp obj */ \ + CAutoPtrDestruction< ObjRet##size > apd(x); \ + memset(reinterpret_cast(x->actObj.x), a, size); \ + return *x; \ } \ }; From 50b2b0541a8a183daac040d6b61061387029b62b Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 9 Nov 2007 06:23:08 +0000 Subject: [PATCH 16/41] Removed forgotten debug printfs/int$3 --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40551 --- sourcehook/sourcehook_hookmangen.cpp | 6 +----- sourcehook/test/testhookmangen.cpp | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index d528752..1619e53 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -1507,11 +1507,11 @@ namespace SourceHook bool GenContext::PassInfoSupported(const IntPassInfo &pi, bool is_ret) { + // :TODO: Error returns if (pi.type != PassInfo::PassType_Basic && pi.type != PassInfo::PassType_Float && pi.type != PassInfo::PassType_Object) { - printf("A\n"); return false; } @@ -1520,25 +1520,21 @@ namespace SourceHook { if ((pi.flags & PassInfo::PassFlag_CCtor) && !pi.pCopyCtor) { - printf("B\n"); return false; } if ((pi.flags & PassInfo::PassFlag_ODtor) && !pi.pDtor) { - printf("C\n"); return false; } if ((pi.flags & PassInfo::PassFlag_AssignOp) && !pi.pAssignOperator) { - printf("D\n"); return false; } if ((pi.flags & PassInfo::PassFlag_OCtor) && !pi.pNormalCtor) { - printf("D\n"); return false; } } diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 858f526..a238e5d 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -640,7 +640,6 @@ bool TestHookManGen(std::string &error) /* no hooks - no hooks */ PtrBuf_Clear(); - asm("int $3"); obj13 = pTest110->Func(5); g_Inside_LeafFunc = true; From f3f226444aceb8d7137f9e55257ff338be285693 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 9 Nov 2007 21:14:37 +0000 Subject: [PATCH 17/41] - Removed unnecessary definitions from sh_pagealloc.h - Added CallConv_StdCall - Added CallConv_HasVarArgs and CallConv_HasVafmt --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40552 --- sourcehook/generate/sourcehook.h | 10 +++++++--- sourcehook/generate/sourcehook.hxx | 10 +++++++--- sourcehook/sh_pagealloc.h | 5 +---- sourcehook/sourcehook.h | 10 +++++++--- sourcehook/sourcehook_hookmangen.cpp | 4 ++-- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/sourcehook/generate/sourcehook.h b/sourcehook/generate/sourcehook.h index d8003c0..32cdee9 100644 --- a/sourcehook/generate/sourcehook.h +++ b/sourcehook/generate/sourcehook.h @@ -202,9 +202,13 @@ namespace SourceHook { enum CallConvention { - CallConv_Unknown, /**< Unknown -- no extra info available */ - CallConv_ThisCall, /**< This call (object pointer required) */ - CallConv_Cdecl, /**< Standard C call */ + CallConv_Unknown, /**< Unknown -- no extra info available (0)*/ + CallConv_ThisCall, /**< This call (object pointer required) (1)*/ + CallConv_Cdecl, /**< C call (2)*/ + CallConv_StdCall, /**< Windows "stdcall" (3)*/ + + CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */ + CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */ }; int numOfParams; //!< number of parameters diff --git a/sourcehook/generate/sourcehook.hxx b/sourcehook/generate/sourcehook.hxx index 2361b94..0f349ba 100755 --- a/sourcehook/generate/sourcehook.hxx +++ b/sourcehook/generate/sourcehook.hxx @@ -202,9 +202,13 @@ namespace SourceHook { enum CallConvention { - CallConv_Unknown, /**< Unknown -- no extra info available */ - CallConv_ThisCall, /**< This call (object pointer required) */ - CallConv_Cdecl, /**< Standard C call */ + CallConv_Unknown, /**< Unknown -- no extra info available (0)*/ + CallConv_ThisCall, /**< This call (object pointer required) (1)*/ + CallConv_Cdecl, /**< C call (2)*/ + CallConv_StdCall, /**< Windows "stdcall" (3)*/ + + CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */ + CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */ }; int numOfParams; //!< number of parameters diff --git a/sourcehook/sh_pagealloc.h b/sourcehook/sh_pagealloc.h index 6445285..49fd734 100644 --- a/sourcehook/sh_pagealloc.h +++ b/sourcehook/sh_pagealloc.h @@ -3,9 +3,6 @@ # if /********/ defined _WIN32 # include -# define SH_MEM_READ 1 -# define SH_MEM_WRITE 2 -# define SH_MEM_EXEC 4 # elif /******/ defined __linux__ # include # include @@ -23,7 +20,7 @@ namespace SourceHook If we alloc with malloc and then set the page access type to read/exec only, other regions returned by malloc that are in the same page would lose their write access as well and the process could crash. - Allocating one page per code generation session is usually a waste of memory and on some plattforms also + Allocating one page per code generation session is usually a waste of memory and on some platforms also a waste of virtual address space (Windows’ VirtualAlloc has a granularity of 64K). diff --git a/sourcehook/sourcehook.h b/sourcehook/sourcehook.h index d8003c0..32cdee9 100644 --- a/sourcehook/sourcehook.h +++ b/sourcehook/sourcehook.h @@ -202,9 +202,13 @@ namespace SourceHook { enum CallConvention { - CallConv_Unknown, /**< Unknown -- no extra info available */ - CallConv_ThisCall, /**< This call (object pointer required) */ - CallConv_Cdecl, /**< Standard C call */ + CallConv_Unknown, /**< Unknown -- no extra info available (0)*/ + CallConv_ThisCall, /**< This call (object pointer required) (1)*/ + CallConv_Cdecl, /**< C call (2)*/ + CallConv_StdCall, /**< Windows "stdcall" (3)*/ + + CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */ + CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */ }; int numOfParams; //!< number of parameters diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 1619e53..f72304a 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -1630,8 +1630,8 @@ namespace SourceHook AutoDetectRetType(); AutoDetectParamFlags(); - if (m_Proto.GetConvention() != ProtoInfo::CallConv_Cdecl && - m_Proto.GetConvention() != ProtoInfo::CallConv_ThisCall) + // Basically, we only support ThisCall/thiscall with varargs + if ((m_Proto.GetConvention() & (~ProtoInfo::CallConv_HasVafmt)) != ProtoInfo::CallConv_ThisCall) { return NULL; } From 92c795e830fc599664516e9865b6b085ba473158 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sat, 10 Nov 2007 16:10:55 +0000 Subject: [PATCH 18/41] Added IHookManagerAutoGen interface --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40555 --- sourcehook/generate/sourcehook.h | 16 +++++ sourcehook/generate/sourcehook.hxx | 16 +++++ sourcehook/sourcehook.cpp | 19 ++++++ sourcehook/sourcehook.h | 16 +++++ sourcehook/sourcehook_hookmangen.cpp | 89 +++++++++++++++++++++++++++- sourcehook/sourcehook_hookmangen.h | 32 +++++++++- sourcehook/sourcehook_impl_cproto.h | 17 ++++++ sourcehook/test/main.cpp | 12 ++++ sourcehook/test/sourcehook_test.h | 13 ++++ sourcehook/test/testhookmangen.cpp | 15 +++-- sourcehook/test/testhookmangen.h | 64 +++++++------------- sourcehook/test/testhookmangen.hxx | 28 +++++---- 12 files changed, 274 insertions(+), 63 deletions(-) diff --git a/sourcehook/generate/sourcehook.h b/sourcehook/generate/sourcehook.h index 32cdee9..ee287dc 100644 --- a/sourcehook/generate/sourcehook.h +++ b/sourcehook/generate/sourcehook.h @@ -35,6 +35,11 @@ // 1 - standard #define SH_HOOKMAN_VERSION 1 +// Hookmanautogen versions +// 1 - initial +#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1 +#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1 + // The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook // It's used in various macros #ifndef SH_GLOB_SHPTR @@ -472,6 +477,17 @@ namespace SourceHook virtual void EndContext(IHookContext *pCtx) = 0; }; + + class IHookManagerAutoGen + { + public: + virtual int GetIfaceVersion() = 0; + virtual int GetImplVersion() = 0; + + virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0; + virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0; + }; + // For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET: // These have to be able to return references. If T is a reference, the pointers returned // from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier::type. diff --git a/sourcehook/generate/sourcehook.hxx b/sourcehook/generate/sourcehook.hxx index 0f349ba..bde13ab 100755 --- a/sourcehook/generate/sourcehook.hxx +++ b/sourcehook/generate/sourcehook.hxx @@ -35,6 +35,11 @@ // 1 - standard #define SH_HOOKMAN_VERSION 1 +// Hookmanautogen versions +// 1 - initial +#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1 +#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1 + // The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook // It's used in various macros #ifndef SH_GLOB_SHPTR @@ -472,6 +477,17 @@ namespace SourceHook virtual void EndContext(IHookContext *pCtx) = 0; }; + + class IHookManagerAutoGen + { + public: + virtual int GetIfaceVersion() = 0; + virtual int GetImplVersion() = 0; + + virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0; + virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0; + }; + // For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET: // These have to be able to return references. If T is a reference, the pointers returned // from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier::type. diff --git a/sourcehook/sourcehook.cpp b/sourcehook/sourcehook.cpp index 7296624..c817ac3 100644 --- a/sourcehook/sourcehook.cpp +++ b/sourcehook/sourcehook.cpp @@ -151,6 +151,25 @@ namespace SourceHook return true; } + + bool CProto::ExactlyEqual(const CProto &other) const + { + if (m_Version != other.m_Version || + m_NumOfParams != other.m_NumOfParams || + m_Convention != other.m_Convention || + GetRet() != other.GetRet()) + { + return false; + } + + for (int i = 0; i < m_NumOfParams; ++i) + { + if(GetParam(i) != other.GetParam(i)) + return false; + } + + return true; + } ////////////////////////////////////////////////////////////////////////// // CHookManager diff --git a/sourcehook/sourcehook.h b/sourcehook/sourcehook.h index 32cdee9..ee287dc 100644 --- a/sourcehook/sourcehook.h +++ b/sourcehook/sourcehook.h @@ -35,6 +35,11 @@ // 1 - standard #define SH_HOOKMAN_VERSION 1 +// Hookmanautogen versions +// 1 - initial +#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1 +#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1 + // The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook // It's used in various macros #ifndef SH_GLOB_SHPTR @@ -472,6 +477,17 @@ namespace SourceHook virtual void EndContext(IHookContext *pCtx) = 0; }; + + class IHookManagerAutoGen + { + public: + virtual int GetIfaceVersion() = 0; + virtual int GetImplVersion() = 0; + + virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0; + virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0; + }; + // For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET: // These have to be able to return references. If T is a reference, the pointers returned // from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier::type. diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index f72304a..2113853 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -15,6 +15,7 @@ // http://www.angelcode.com/dev/callconv/callconv.html // http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-1.html +#include "sourcehook_impl.h" #include "sourcehook_hookmangen.h" #include "sourcehook_hookmangen_x86.h" #include "sh_memory.h" @@ -47,7 +48,7 @@ namespace SourceHook } GenContext::GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr) - : m_Proto(proto), m_VtblOffs(vtbl_offs), m_VtblIdx(vtbl_idx), m_SHPtr(pSHPtr), + : m_GeneratedPubFunc(NULL), m_Proto(proto), m_VtblOffs(vtbl_offs), m_VtblIdx(vtbl_idx), m_SHPtr(pSHPtr), m_pHI(NULL), m_HookfuncVfnptr(NULL), m_RegCounter(0) { m_pHI = new void*; @@ -1652,5 +1653,91 @@ namespace SourceHook GenerateHookFunc(); return fastdelegate::detail::horrible_cast(GeneratePubFunc()); } + + HookManagerPubFunc GenContext::GetPubFunc() + { + if (m_GeneratedPubFunc == 0) + m_GeneratedPubFunc = Generate(); + + return m_GeneratedPubFunc; + } + + bool GenContext::Equal(const CProto &proto, int vtbl_offs, int vtbl_idx) + { + return (m_Proto.ExactlyEqual(proto) && m_VtblOffs == vtbl_offs && m_VtblIdx == vtbl_idx); + } + + bool GenContext::Equal(HookManagerPubFunc other) + { + return m_GeneratedPubFunc == other; + } + + // *********************************** class GenContextContainer + CHookManagerAutoGen::CHookManagerAutoGen(ISourceHook *pSHPtr) : m_pSHPtr(pSHPtr) + { + } + + CHookManagerAutoGen::~CHookManagerAutoGen() + { + for (List::iterator iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter) + { + delete iter->m_GenContext; + } + } + + int CHookManagerAutoGen::GetIfaceVersion() + { + return SH_HOOKMANAUTOGEN_IFACE_VERSION; + } + + int CHookManagerAutoGen::GetImplVersion() + { + return SH_HOOKMANAUTOGEN_IMPL_VERSION; + } + + HookManagerPubFunc CHookManagerAutoGen::MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) + { + CProto mproto(proto); + for (List::iterator iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter) + { + if (iter->m_GenContext->Equal(mproto, vtbl_offs, vtbl_idx)) + { + iter->m_RefCnt++; + return iter->m_GenContext->GetPubFunc(); + } + } + + // Not found yet -> new one + StoredContext sctx; + sctx.m_RefCnt = 1; + sctx.m_GenContext = new GenContext(proto, vtbl_offs, vtbl_idx, m_pSHPtr); + + if (sctx.m_GenContext->GetPubFunc() == NULL) + { + return NULL; + } + else + { + m_Contexts.push_back(sctx); + return sctx.m_GenContext->GetPubFunc(); + } + } + + void CHookManagerAutoGen::ReleaseHookMan(HookManagerPubFunc pubFunc) + { + for (List::iterator iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter) + { + if (iter->m_GenContext->Equal(pubFunc)) + { + iter->m_RefCnt--; + if (iter->m_RefCnt == 0) + { + delete iter->m_GenContext; + m_Contexts.erase(iter); + } + break; + } + } + } } } diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 83e80df..b22a3bf 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -11,7 +11,6 @@ #ifndef __SOURCEHOOK_HOOKMANGEN_H__ #define __SOURCEHOOK_HOOKMANGEN_H__ -#include "sourcehook_impl.h" #include "sh_pagealloc.h" namespace SourceHook @@ -158,6 +157,8 @@ namespace SourceHook const static int SIZE_PTR = sizeof(void*); const static int PassFlag_ForcedByRef = (1<<30); // ByVal in source, but actually passed by reference (GCC) -> private pass, destruct + HookManagerPubFunc m_GeneratedPubFunc; + CProto m_Proto; int m_VtblOffs; int m_VtblIdx; @@ -231,13 +232,40 @@ namespace SourceHook void BuildProtoInfo(); void *GenerateHookFunc(); void *GeneratePubFunc(); + + HookManagerPubFunc Generate(); public: // Level 1 -> Public interface GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr); ~GenContext(); - HookManagerPubFunc Generate(); + bool Equal(const CProto &proto, int vtbl_offs, int vtbl_idx); + bool Equal(HookManagerPubFunc other); + + HookManagerPubFunc GetPubFunc(); }; + + class CHookManagerAutoGen : public IHookManagerAutoGen + { + struct StoredContext + { + int m_RefCnt; + GenContext *m_GenContext; + }; + List m_Contexts; + ISourceHook *m_pSHPtr; + + public: + CHookManagerAutoGen(ISourceHook *pSHPtr); + ~CHookManagerAutoGen(); + + int GetIfaceVersion(); + int GetImplVersion(); + + HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx); + void ReleaseHookMan(HookManagerPubFunc pubFunc); + }; + } } diff --git a/sourcehook/sourcehook_impl_cproto.h b/sourcehook/sourcehook_impl_cproto.h index 949b8ed..9521cd2 100644 --- a/sourcehook/sourcehook_impl_cproto.h +++ b/sourcehook/sourcehook_impl_cproto.h @@ -26,6 +26,21 @@ namespace SourceHook void *pCopyCtor; void *pDtor; void *pAssignOperator; + + bool operator == (const IntPassInfo &other) const + { + return size == other.size + && type == other.type + && flags == other.flags + && pNormalCtor == other.pNormalCtor + && pDtor == other.pDtor + && pAssignOperator == other.pAssignOperator; + } + + bool operator != (const IntPassInfo &other) const + { + return !(*this == other); + } }; class CProto @@ -72,6 +87,8 @@ namespace SourceHook bool operator == (const CProto &other) const; + bool ExactlyEqual(const CProto &other) const; + int GetVersion() const { return m_Version; diff --git a/sourcehook/test/main.cpp b/sourcehook/test/main.cpp index 993c695..9b2ba82 100644 --- a/sourcehook/test/main.cpp +++ b/sourcehook/test/main.cpp @@ -13,6 +13,7 @@ #include "sourcehook_impl.h" #include "sourcehook.h" +#include "sourcehook_hookmangen.h" using namespace std; bool g_Verbose; @@ -111,3 +112,14 @@ void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug) { static_cast(shptr)->UnpausePlugin(plug); } + +SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *shptr) +{ + return new SourceHook::Impl::CHookManagerAutoGen(shptr); +} + +void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr) +{ + delete static_cast(ptr); +} + diff --git a/sourcehook/test/sourcehook_test.h b/sourcehook/test/sourcehook_test.h index babb5ba..065b543 100644 --- a/sourcehook/test/sourcehook_test.h +++ b/sourcehook/test/sourcehook_test.h @@ -34,3 +34,16 @@ void Test_CompleteShutdown(SourceHook::ISourceHook *shptr); void Test_UnloadPlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); void Test_PausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); + +SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *pSHPtr); +void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr); + +struct CHMAGAutoDestruction +{ + SourceHook::IHookManagerAutoGen *m_Ptr; + CHMAGAutoDestruction(SourceHook::IHookManagerAutoGen *ptr) : m_Ptr(ptr) {} + ~CHMAGAutoDestruction() { Test_HMAG_Delete(m_Ptr); } +}; + + +#define GET_HMAG(var, shptr) var = Test_HMAG_Factory(shptr); CHMAGAutoDestruction __hmagautodestruction(var); diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index a238e5d..0f7313b 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -2,7 +2,6 @@ #include "sourcehook.h" #include "sourcehook_test.h" #include "testevents.h" -#include "sourcehook_hookmangen.h" #include "sh_memory.h" #include "sh_pagealloc.h" @@ -23,6 +22,8 @@ namespace SourceHook::ISourceHook *g_SHPtr; SourceHook::Plugin g_PLID; + SourceHook::IHookManagerAutoGen *g_HMAGPtr; + // PtrBuf(ptr) gives ptrs unique numbers // in the order they appear SourceHook::List g_PtrHash; @@ -254,7 +255,6 @@ namespace } } - // MyDelegate base class for other delegates class MyDelegate : public SourceHook::ISHDelegate { @@ -415,6 +415,7 @@ namespace bool TestHookManGen(std::string &error) { GET_SHPTR(g_SHPtr); + GET_HMAG(g_HMAGPtr, g_SHPtr); g_PLID = 1337; // 5 Global constructors (g_O111_*) @@ -463,9 +464,8 @@ bool TestHookManGen(std::string &error) NULL), "Test11 Part0"); setuppi_11(); - g_Genc11 = new SourceHook::Impl::GenContext(&protoinfo_11, 0, 0, g_SHPtr); - g_Genc_ad11.set(g_Genc11); - SourceHook::HookManagerPubFunc myhookman11 = g_Genc11->Generate(); + SourceHook::HookManagerPubFunc myhookman11 = g_HMAGPtr->MakeHookMan(&protoinfo_11, 0, 0); \ + CAutoReleaseHookMan arhm_11(myhookman11); \ int hook1_11, hook2_11, hook3_11, hook4_11; TestClass11 *pTest11 = new TestClass11; @@ -630,9 +630,8 @@ bool TestHookManGen(std::string &error) setuppi_110(); setupri_110(); - g_Genc110 = new SourceHook::Impl::GenContext(&protoinfo_110, 0, 0, g_SHPtr); - g_Genc_ad110.set(g_Genc110); - SourceHook::HookManagerPubFunc myhookman110 = g_Genc110->Generate(); + SourceHook::HookManagerPubFunc myhookman110 = g_HMAGPtr->MakeHookMan(&protoinfo_110, 0, 0); \ + CAutoReleaseHookMan arhm_110(myhookman110); \ int hook1_110, hook2_110, hook3_110, hook4_110; TestClass110 *pTest110 = new TestClass110; diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index 9b5a52e..b1caf8c 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -1,3 +1,15 @@ +struct CAutoReleaseHookMan +{ + SourceHook::HookManagerPubFunc m_Ptr; + CAutoReleaseHookMan(SourceHook::HookManagerPubFunc ptr) : m_Ptr(ptr) + { + } + ~CAutoReleaseHookMan() + { + g_HMAGPtr->ReleaseHookMan(m_Ptr); + } +}; + // Strip & template struct StripRef { @@ -520,9 +532,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[0+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 0, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); #define THGM_MAKE_TEST0(id, ret_type) \ @@ -621,8 +630,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::ProtoInfo protoinfo_##id = { 0, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); + CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI0(id) \ void setuppi_##id() \ @@ -731,9 +739,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[1+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 1, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); #define THGM_MAKE_TEST1(id, ret_type, param1) \ @@ -832,8 +837,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::ProtoInfo protoinfo_##id = { 1, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); + CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ void setuppi_##id() \ @@ -942,9 +946,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[2+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 2, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); #define THGM_MAKE_TEST2(id, ret_type, param1, param2) \ @@ -1043,8 +1044,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::ProtoInfo protoinfo_##id = { 2, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); + CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ void setuppi_##id() \ @@ -1153,9 +1153,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[3+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 3, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); #define THGM_MAKE_TEST3(id, ret_type, param1, param2, param3) \ @@ -1254,8 +1251,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::ProtoInfo protoinfo_##id = { 3, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); + CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ void setuppi_##id() \ @@ -1364,9 +1360,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[4+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 4, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); #define THGM_MAKE_TEST4(id, ret_type, param1, param2, param3, param4) \ @@ -1465,8 +1458,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::ProtoInfo protoinfo_##id = { 4, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); + CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ void setuppi_##id() \ @@ -1575,9 +1567,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[5+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 5, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); #define THGM_MAKE_TEST5(id, ret_type, param1, param2, param3, param4, param5) \ @@ -1676,8 +1665,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::ProtoInfo protoinfo_##id = { 5, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); + CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ void setuppi_##id() \ @@ -1786,9 +1774,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[6+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 6, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); #define THGM_MAKE_TEST6(id, ret_type, param1, param2, param3, param4, param5, param6) \ @@ -1887,8 +1872,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::ProtoInfo protoinfo_##id = { 6, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); + CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ void setuppi_##id() \ @@ -1931,9 +1915,8 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_DO_TEST_void(id, call_params) \ setuppi_##id(); \ - g_Genc##id = new SourceHook::Impl::GenContext(&protoinfo_##id, 0, 0, g_SHPtr); \ - g_Genc_ad##id.set(g_Genc##id); \ - SourceHook::HookManagerPubFunc myhookman##id = g_Genc##id->Generate(); \ + SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(&protoinfo_##id, 0, 0); \ + CAutoReleaseHookMan arhm_##id(myhookman##id); \ int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ \ TestClass##id::ms_DoRecall = false; \ @@ -2050,9 +2033,8 @@ T* ComparableRef(T& x) #define THGM_DO_TEST(id, call_params) \ setuppi_##id(); \ setupri_##id(); \ - g_Genc##id = new SourceHook::Impl::GenContext(&protoinfo_##id, 0, 0, g_SHPtr); \ - g_Genc_ad##id.set(g_Genc##id); \ - SourceHook::HookManagerPubFunc myhookman##id = g_Genc##id->Generate(); \ + SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(&protoinfo_##id, 0, 0); \ + CAutoReleaseHookMan arhm_##id(myhookman##id); \ int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ \ TestClass##id::ms_DoRecall = false; \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index ce709d6..0e283dd 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -1,3 +1,15 @@ +struct CAutoReleaseHookMan +{ + SourceHook::HookManagerPubFunc m_Ptr; + CAutoReleaseHookMan(SourceHook::HookManagerPubFunc ptr) : m_Ptr(ptr) + { + } + ~CAutoReleaseHookMan() + { + g_HMAGPtr->ReleaseHookMan(m_Ptr); + } +}; + // Strip & template struct StripRef { @@ -262,9 +274,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] SourceHook::PassInfo::V2Info paraminfos2_##id[$1+1]; \ SourceHook::ProtoInfo protoinfo_##id = { $1, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); #define THGM_MAKE_TEST$1(id, ret_type@[$2,1,$1:, param$2@]) \ @@ -363,8 +372,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] SourceHook::ProtoInfo protoinfo_##id = { $1, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ \ - SourceHook::Impl::GenContext *g_Genc##id = NULL; \ - CAutoPtrDestruction g_Genc_ad##id(NULL); + CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ void setuppi_##id() \ @@ -407,9 +415,8 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] #define THGM_DO_TEST_void(id, call_params) \ setuppi_##id(); \ - g_Genc##id = new SourceHook::Impl::GenContext(&protoinfo_##id, 0, 0, g_SHPtr); \ - g_Genc_ad##id.set(g_Genc##id); \ - SourceHook::HookManagerPubFunc myhookman##id = g_Genc##id->Generate(); \ + SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(&protoinfo_##id, 0, 0); \ + CAutoReleaseHookMan arhm_##id(myhookman##id); \ int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ \ TestClass##id::ms_DoRecall = false; \ @@ -526,9 +533,8 @@ T* ComparableRef(T& x) #define THGM_DO_TEST(id, call_params) \ setuppi_##id(); \ setupri_##id(); \ - g_Genc##id = new SourceHook::Impl::GenContext(&protoinfo_##id, 0, 0, g_SHPtr); \ - g_Genc_ad##id.set(g_Genc##id); \ - SourceHook::HookManagerPubFunc myhookman##id = g_Genc##id->Generate(); \ + SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(&protoinfo_##id, 0, 0); \ + CAutoReleaseHookMan arhm_##id(myhookman##id); \ int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ \ TestClass##id::ms_DoRecall = false; \ From 926a23d0bdb8f3aaef2de4e1decc58b594360263 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sat, 10 Nov 2007 16:32:16 +0000 Subject: [PATCH 19/41] Removed old g_Genc stuff and fixed GenContext::Equal --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40556 --- sourcehook/sourcehook_hookmangen.cpp | 6 +++--- sourcehook/sourcehook_hookmangen.h | 1 + sourcehook/test/testhookmangen.h | 14 -------------- sourcehook/test/testhookmangen.hxx | 2 -- 4 files changed, 4 insertions(+), 19 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 2113853..103029b 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -48,8 +48,8 @@ namespace SourceHook } GenContext::GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr) - : m_GeneratedPubFunc(NULL), m_Proto(proto), m_VtblOffs(vtbl_offs), m_VtblIdx(vtbl_idx), m_SHPtr(pSHPtr), - m_pHI(NULL), m_HookfuncVfnptr(NULL), m_RegCounter(0) + : m_GeneratedPubFunc(NULL), m_OrigProto(proto), m_Proto(proto), m_VtblOffs(vtbl_offs), + m_VtblIdx(vtbl_idx), m_SHPtr(pSHPtr), m_pHI(NULL), m_HookfuncVfnptr(NULL), m_RegCounter(0) { m_pHI = new void*; m_HookfuncVfnptr = new void*; @@ -1664,7 +1664,7 @@ namespace SourceHook bool GenContext::Equal(const CProto &proto, int vtbl_offs, int vtbl_idx) { - return (m_Proto.ExactlyEqual(proto) && m_VtblOffs == vtbl_offs && m_VtblIdx == vtbl_idx); + return (m_OrigProto.ExactlyEqual(proto) && m_VtblOffs == vtbl_offs && m_VtblIdx == vtbl_idx); } bool GenContext::Equal(HookManagerPubFunc other) diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index b22a3bf..ab66e27 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -159,6 +159,7 @@ namespace SourceHook HookManagerPubFunc m_GeneratedPubFunc; + CProto m_OrigProto; // original passed-in prototype CProto m_Proto; int m_VtblOffs; int m_VtblIdx; diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index b1caf8c..ac368b5 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -629,8 +629,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[0+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 0, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI0(id) \ void setuppi_##id() \ @@ -836,8 +834,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[1+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 1, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ void setuppi_##id() \ @@ -1043,8 +1039,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[2+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 2, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ void setuppi_##id() \ @@ -1250,8 +1244,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[3+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 3, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ void setuppi_##id() \ @@ -1457,8 +1449,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[4+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 4, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ void setuppi_##id() \ @@ -1664,8 +1654,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[5+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 5, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ void setuppi_##id() \ @@ -1871,8 +1859,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, SourceHook::PassInfo::V2Info paraminfos2_##id[6+1]; \ SourceHook::ProtoInfo protoinfo_##id = { 6, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ void setuppi_##id() \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 0e283dd..52bafe1 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -371,8 +371,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] SourceHook::PassInfo::V2Info paraminfos2_##id[$1+1]; \ SourceHook::ProtoInfo protoinfo_##id = { $1, {0, 0, 0}, paraminfos_##id, \ SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ - \ - CAutoReleaseHookMan g_Genc_ad##id(NULL); #define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ void setuppi_##id() \ From c45ae8fd7b590c39be58dccae0367454743ffed4 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sat, 10 Nov 2007 16:42:28 +0000 Subject: [PATCH 20/41] Added MMIFACE_SH_HOOKMANAUTOGEN to SMM API --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40557 --- sourcemm/ISmmAPI.h | 1 + sourcemm/episode1/msvc8/sourcemm.vcproj | 5 +++++ sourcemm/episode2/msvc8/sourcemm.vcproj | 4 ++++ sourcemm/metamod.cpp | 9 +++++++++ 4 files changed, 19 insertions(+) diff --git a/sourcemm/ISmmAPI.h b/sourcemm/ISmmAPI.h index 9566e2b..b405579 100644 --- a/sourcemm/ISmmAPI.h +++ b/sourcemm/ISmmAPI.h @@ -49,6 +49,7 @@ #define MMIFACE_SOURCEHOOK "ISourceHook" /**< ISourceHook Pointer */ #define MMIFACE_PLMANAGER "IPluginManager" /**< SourceMM Plugin Functions */ +#define MMIFACE_SH_HOOKMANAUTOGEN "IHookManagerAutoGen" /**< SourceHook::IHookManagerAutoGen Pointer */ #define IFACE_MAXNUM 999 /**< Maximum interface version */ namespace SourceMM diff --git a/sourcemm/episode1/msvc8/sourcemm.vcproj b/sourcemm/episode1/msvc8/sourcemm.vcproj index 5060ab1..48d4c33 100644 --- a/sourcemm/episode1/msvc8/sourcemm.vcproj +++ b/sourcemm/episode1/msvc8/sourcemm.vcproj @@ -331,6 +331,11 @@ RelativePath="..\..\..\sourcehook\sourcehook.cpp" >
+ + +
diff --git a/sourcemm/episode2/msvc8/sourcemm.vcproj b/sourcemm/episode2/msvc8/sourcemm.vcproj index a447f7c..0645613 100644 --- a/sourcemm/episode2/msvc8/sourcemm.vcproj +++ b/sourcemm/episode2/msvc8/sourcemm.vcproj @@ -327,6 +327,10 @@ RelativePath="..\..\..\sourcehook\sourcehook.cpp" > + + diff --git a/sourcemm/metamod.cpp b/sourcemm/metamod.cpp index 9527c9f..1cbb159 100644 --- a/sourcemm/metamod.cpp +++ b/sourcemm/metamod.cpp @@ -94,6 +94,7 @@ CreateInterfaceFn physics_factory = NULL; CreateInterfaceFn filesystem_factory = NULL; CGlobalVars *gpGlobals = NULL; CSourceHookImpl g_SourceHook; +CHookManagerAutoGen g_SH_HookManagerAutoGen(&g_SourceHook); ISourceHook *g_SHPtr = &g_SourceHook; PluginId g_PLID = Pl_Console; META_RES last_meta_res; @@ -1090,6 +1091,14 @@ void *MetamodSource::MetaFactory(const char *iface, int *ret, PluginId *id) } return static_cast(static_cast(&g_PluginMngr)); } + else if (strcmp(iface, MMIFACE_SH_HOOKMANAUTOGEN) == 0) + { + if (ret) + { + *ret = IFACE_OK; + } + return static_cast(static_cast(&g_SH_HookManagerAutoGen)); + } CPluginManager::CPlugin *pl; List::iterator event; From 365d5fc5ee581b16d75246dfa1a8a72cc9ede9b6 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 11 Nov 2007 17:35:24 +0000 Subject: [PATCH 21/41] Added CProtoInfoBuilder helper class (sourcehook_pibuilder.h) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40558 --- sourcehook/sourcehook_pibuilder.h | 108 ++++++++++ sourcehook/test/msvc8/test.vcproj | 4 + sourcehook/test/testhookmangen.cpp | 5 +- sourcehook/test/testhookmangen.h | 310 ++++++++++++++++------------- sourcehook/test/testhookmangen.hxx | 46 ++--- 5 files changed, 308 insertions(+), 165 deletions(-) create mode 100644 sourcehook/sourcehook_pibuilder.h diff --git a/sourcehook/sourcehook_pibuilder.h b/sourcehook/sourcehook_pibuilder.h new file mode 100644 index 0000000..88cbd20 --- /dev/null +++ b/sourcehook/sourcehook_pibuilder.h @@ -0,0 +1,108 @@ +/* ======== SourceHook ======== +* Copyright (C) 2004-2007 Metamod:Source Development Team +* No warranties of any kind +* +* License: zlib/libpng +* +* Author(s): Pavol "PM OnoTo" Marko +* ============================ +*/ + +#ifndef __SOURCEHOOK_PIBUILDER_H__ +#define __SOURCEHOOK_PIBUILDER_H__ + +#include "sourcehook.h" +#include "sh_vector.h" + +namespace SourceHook +{ + // Helper class: protocol information builder + class CProtoInfoBuilder + { + ProtoInfo m_PI; + CVector m_Params; + CVector m_Params2; + public: + CProtoInfoBuilder(ProtoInfo::CallConvention cc) + { + memset(reinterpret_cast(&m_PI), 0, sizeof(ProtoInfo)); + m_PI.convention = cc; + + // dummy 0 params + PassInfo dummy; + PassInfo::V2Info dummy2; + memset(reinterpret_cast(&dummy), 0, sizeof(PassInfo)); + memset(reinterpret_cast(&dummy2), 0, sizeof(PassInfo::V2Info)); + + dummy.size = 1; // Version1 + + m_Params.push_back(dummy); + m_Params2.push_back(dummy2); + } + + void SetReturnType(size_t size, PassInfo::PassType type, int flags, + void *pNormalCtor, void *pCopyCtor, void *pDtor, void *pAssignOperator) + { + if (pNormalCtor) + flags |= PassInfo::PassFlag_OCtor; + + if (pCopyCtor) + flags |= PassInfo::PassFlag_CCtor; + + if (pDtor) + flags |= PassInfo::PassFlag_ODtor; + + if (pAssignOperator) + flags |= PassInfo::PassFlag_AssignOp; + + m_PI.retPassInfo.size = size; + m_PI.retPassInfo.type = type; + m_PI.retPassInfo.flags = flags; + m_PI.retPassInfo2.pNormalCtor = pNormalCtor; + m_PI.retPassInfo2.pCopyCtor = pCopyCtor; + m_PI.retPassInfo2.pDtor = pDtor; + m_PI.retPassInfo2.pAssignOperator = pAssignOperator; + } + + void AddParam(size_t size, PassInfo::PassType type, int flags, + void *pNormalCtor, void *pCopyCtor, void *pDtor, void *pAssignOperator) + { + PassInfo pi; + PassInfo::V2Info pi2; + + if (pNormalCtor) + flags |= PassInfo::PassFlag_OCtor; + + if (pCopyCtor) + flags |= PassInfo::PassFlag_CCtor; + + if (pDtor) + flags |= PassInfo::PassFlag_ODtor; + + if (pAssignOperator) + flags |= PassInfo::PassFlag_AssignOp; + + + pi.size = size; + pi.type = type; + pi.flags = flags; + pi2.pNormalCtor = pNormalCtor; + pi2.pCopyCtor = pCopyCtor; + pi2.pDtor = pDtor; + pi2.pAssignOperator = pAssignOperator; + + m_Params.push_back(pi); + m_Params2.push_back(pi2); + ++m_PI.numOfParams; + } + + operator ProtoInfo*() + { + m_PI.paramsPassInfo = &(m_Params[0]); + m_PI.paramsPassInfo2 = &(m_Params2[0]); + return &m_PI; + } + }; +} + +#endif \ No newline at end of file diff --git a/sourcehook/test/msvc8/test.vcproj b/sourcehook/test/msvc8/test.vcproj index c7c1881..c8df00a 100644 --- a/sourcehook/test/msvc8/test.vcproj +++ b/sourcehook/test/msvc8/test.vcproj @@ -513,6 +513,10 @@ RelativePath="..\..\sourcehook_impl_cvfnptr.h" > + + diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 0f7313b..ffcfd2b 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -4,6 +4,7 @@ #include "testevents.h" #include "sh_memory.h" #include "sh_pagealloc.h" +#include "sourcehook_pibuilder.h" // TESTHOOKMANGEN // Test automatic hookman generation @@ -464,7 +465,7 @@ bool TestHookManGen(std::string &error) NULL), "Test11 Part0"); setuppi_11(); - SourceHook::HookManagerPubFunc myhookman11 = g_HMAGPtr->MakeHookMan(&protoinfo_11, 0, 0); \ + SourceHook::HookManagerPubFunc myhookman11 = g_HMAGPtr->MakeHookMan(protoinfo_11, 0, 0); \ CAutoReleaseHookMan arhm_11(myhookman11); \ int hook1_11, hook2_11, hook3_11, hook4_11; @@ -630,7 +631,7 @@ bool TestHookManGen(std::string &error) setuppi_110(); setupri_110(); - SourceHook::HookManagerPubFunc myhookman110 = g_HMAGPtr->MakeHookMan(&protoinfo_110, 0, 0); \ + SourceHook::HookManagerPubFunc myhookman110 = g_HMAGPtr->MakeHookMan(protoinfo_110, 0, 0); \ CAutoReleaseHookMan arhm_110(myhookman110); \ int hook1_110, hook2_110, hook3_110, hook4_110; diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index ac368b5..1450eba 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -527,11 +527,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[0+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[0+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 0, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_MAKE_TEST0(id, ret_type) \ @@ -624,22 +620,11 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[0+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[0+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 0, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_SETUP_PI0(id) \ void setuppi_##id() \ { \ - paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ - \ - \ - \ - \ - \ - \ \ } @@ -732,11 +717,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[1+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[1+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 1, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_MAKE_TEST1(id, ret_type, param1) \ @@ -829,23 +810,19 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[1+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[1+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 1, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ void setuppi_##id() \ { \ - paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ - \ - paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; \ - \ - paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ - paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ - paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ - paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ + \ + protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ + (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ } @@ -937,11 +914,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[2+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[2+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 2, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_MAKE_TEST2(id, ret_type, param1, param2) \ @@ -1034,23 +1007,26 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[2+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[2+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 2, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ void setuppi_##id() \ { \ - paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ - \ - paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; \ - \ - paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ - paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ - paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ - paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ + \ + protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ + (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ + (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ } @@ -1142,11 +1118,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[3+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[3+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 3, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_MAKE_TEST3(id, ret_type, param1, param2, param3) \ @@ -1239,23 +1211,33 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[3+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[3+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 3, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ void setuppi_##id() \ { \ - paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ - \ - paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; paraminfos_##id[3].size = sizeof(p3_type); paraminfos_##id[3].type = p3_passtype; paraminfos_##id[3].flags = p3_flags; \ - \ - paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ - paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ - paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ - paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[3].pAssignOperator = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ + \ + protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ + (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ + (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p3_type), p3_passtype, p3_flags, \ + (p3_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ } @@ -1347,11 +1329,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[4+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[4+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 4, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_MAKE_TEST4(id, ret_type, param1, param2, param3, param4) \ @@ -1444,23 +1422,40 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[4+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[4+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 4, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ void setuppi_##id() \ { \ - paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ - \ - paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; paraminfos_##id[3].size = sizeof(p3_type); paraminfos_##id[3].type = p3_passtype; paraminfos_##id[3].flags = p3_flags; paraminfos_##id[4].size = sizeof(p4_type); paraminfos_##id[4].type = p4_passtype; paraminfos_##id[4].flags = p4_flags; \ - \ - paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ - paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ - paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ - paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[3].pAssignOperator = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[4].pAssignOperator = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ + \ + protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ + (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ + (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p3_type), p3_passtype, p3_flags, \ + (p3_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p4_type), p4_passtype, p4_flags, \ + (p4_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ } @@ -1552,11 +1547,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[5+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[5+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 5, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_MAKE_TEST5(id, ret_type, param1, param2, param3, param4, param5) \ @@ -1649,23 +1640,47 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[5+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[5+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 5, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ void setuppi_##id() \ { \ - paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ - \ - paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; paraminfos_##id[3].size = sizeof(p3_type); paraminfos_##id[3].type = p3_passtype; paraminfos_##id[3].flags = p3_flags; paraminfos_##id[4].size = sizeof(p4_type); paraminfos_##id[4].type = p4_passtype; paraminfos_##id[4].flags = p4_flags; paraminfos_##id[5].size = sizeof(p5_type); paraminfos_##id[5].type = p5_passtype; paraminfos_##id[5].flags = p5_flags; \ - \ - paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[5].pNormalCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ - paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[5].pCopyCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ - paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[5].pDtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ - paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[3].pAssignOperator = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[4].pAssignOperator = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[5].pAssignOperator = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ + \ + protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ + (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ + (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p3_type), p3_passtype, p3_flags, \ + (p3_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p4_type), p4_passtype, p4_flags, \ + (p4_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p5_type), p5_passtype, p5_flags, \ + (p5_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p5_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p5_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p5_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ } @@ -1757,11 +1772,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[6+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[6+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 6, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_MAKE_TEST6(id, ret_type, param1, param2, param3, param4, param5, param6) \ @@ -1854,23 +1865,54 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[6+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[6+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { 6, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ void setuppi_##id() \ { \ - paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ - \ - paraminfos_##id[1].size = sizeof(p1_type); paraminfos_##id[1].type = p1_passtype; paraminfos_##id[1].flags = p1_flags; paraminfos_##id[2].size = sizeof(p2_type); paraminfos_##id[2].type = p2_passtype; paraminfos_##id[2].flags = p2_flags; paraminfos_##id[3].size = sizeof(p3_type); paraminfos_##id[3].type = p3_passtype; paraminfos_##id[3].flags = p3_flags; paraminfos_##id[4].size = sizeof(p4_type); paraminfos_##id[4].type = p4_passtype; paraminfos_##id[4].flags = p4_flags; paraminfos_##id[5].size = sizeof(p5_type); paraminfos_##id[5].type = p5_passtype; paraminfos_##id[5].flags = p5_flags; paraminfos_##id[6].size = sizeof(p6_type); paraminfos_##id[6].type = p6_passtype; paraminfos_##id[6].flags = p6_flags; \ - \ - paraminfos2_##id[1].pNormalCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[2].pNormalCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[3].pNormalCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[4].pNormalCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[5].pNormalCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; paraminfos2_##id[6].pNormalCtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ - paraminfos2_##id[1].pCopyCtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[2].pCopyCtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[3].pCopyCtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[4].pCopyCtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[5].pCopyCtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; paraminfos2_##id[6].pCopyCtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ - paraminfos2_##id[1].pDtor = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[2].pDtor = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[3].pDtor = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[4].pDtor = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[5].pDtor = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; paraminfos2_##id[6].pDtor = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ - paraminfos2_##id[1].pAssignOperator = (paraminfos_##id[1].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[2].pAssignOperator = (paraminfos_##id[2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[3].pAssignOperator = (paraminfos_##id[3].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[4].pAssignOperator = (paraminfos_##id[4].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[5].pAssignOperator = (paraminfos_##id[5].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; paraminfos2_##id[6].pAssignOperator = (paraminfos_##id[6].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ + \ + protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ + (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ + (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p3_type), p3_passtype, p3_flags, \ + (p3_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p3_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p4_type), p4_passtype, p4_flags, \ + (p4_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p4_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p5_type), p5_passtype, p5_flags, \ + (p5_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p5_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p5_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p5_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ + protoinfo_##id.AddParam(sizeof(p6_type), p6_passtype, p6_flags, \ + (p6_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p6_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p6_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p6_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + \ } @@ -1878,14 +1920,12 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_SETUP_RI(id, ret_type, ret_passtype, ret_flags) \ void setupri_##id() \ { \ - protoinfo_##id.retPassInfo.size = sizeof(ret_type); \ - protoinfo_##id.retPassInfo.type = ret_passtype; \ - protoinfo_##id.retPassInfo.flags = ret_flags; \ - \ - protoinfo_##id.retPassInfo2.pNormalCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ - protoinfo_##id.retPassInfo2.pCopyCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ - protoinfo_##id.retPassInfo2.pDtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ - protoinfo_##id.retPassInfo2.pAssignOperator = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ + protoinfo_##id.SetReturnType(sizeof(ret_type), ret_passtype, ret_flags, \ + (ret_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (ret_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (ret_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (ret_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ } #define THGM_ADD_HOOK(id, num) \ @@ -1901,7 +1941,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_DO_TEST_void(id, call_params) \ setuppi_##id(); \ - SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(&protoinfo_##id, 0, 0); \ + SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \ CAutoReleaseHookMan arhm_##id(myhookman##id); \ int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ \ @@ -2019,7 +2059,7 @@ T* ComparableRef(T& x) #define THGM_DO_TEST(id, call_params) \ setuppi_##id(); \ setupri_##id(); \ - SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(&protoinfo_##id, 0, 0); \ + SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \ CAutoReleaseHookMan arhm_##id(myhookman##id); \ int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 52bafe1..100ee2f 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -269,11 +269,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[$1+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[$1+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { $1, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_MAKE_TEST$1(id, ret_type@[$2,1,$1:, param$2@]) \ @@ -366,23 +362,19 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] }; \ \ bool TestClass##id::ms_DoRecall = false; \ - \ - SourceHook::PassInfo paraminfos_##id[$1+1]; \ - SourceHook::PassInfo::V2Info paraminfos2_##id[$1+1]; \ - SourceHook::ProtoInfo protoinfo_##id = { $1, {0, 0, 0}, paraminfos_##id, \ - SourceHook::ProtoInfo::CallConv_ThisCall, __SH_EPI, paraminfos2_##id }; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); #define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ void setuppi_##id() \ { \ - paraminfos_##id[0].size = 1; paraminfos_##id[0].type = 0; paraminfos_##id[0].flags = 0; \ - \ - @[$2,1,$1: paraminfos_##id[$2].size = sizeof(p$2_type); paraminfos_##id[$2].type = p$2_passtype; paraminfos_##id[$2].flags = p$2_flags; @] \ - \ - @[$2,1,$1: paraminfos2_##id[$2].pNormalCtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; @] \ - @[$2,1,$1: paraminfos2_##id[$2].pCopyCtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; @] \ - @[$2,1,$1: paraminfos2_##id[$2].pDtor = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; @] \ - @[$2,1,$1: paraminfos2_##id[$2].pAssignOperator = (paraminfos_##id[$2].flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; @] \ + @[$2,1,$1: \ + protoinfo_##id.AddParam(sizeof(p$2_type), p$2_passtype, p$2_flags, \ + (p$2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (p$2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (p$2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (p$2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ + @] \ } @] @@ -390,14 +382,12 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] #define THGM_SETUP_RI(id, ret_type, ret_passtype, ret_flags) \ void setupri_##id() \ { \ - protoinfo_##id.retPassInfo.size = sizeof(ret_type); \ - protoinfo_##id.retPassInfo.type = ret_passtype; \ - protoinfo_##id.retPassInfo.flags = ret_flags; \ - \ - protoinfo_##id.retPassInfo2.pNormalCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL; \ - protoinfo_##id.retPassInfo2.pCopyCtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL; \ - protoinfo_##id.retPassInfo2.pDtor = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL; \ - protoinfo_##id.retPassInfo2.pAssignOperator = (protoinfo_##id.retPassInfo.flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL; \ + protoinfo_##id.SetReturnType(sizeof(ret_type), ret_passtype, ret_flags, \ + (ret_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ + (ret_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ + (ret_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ + (ret_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ + ); \ } #define THGM_ADD_HOOK(id, num) \ @@ -413,7 +403,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] #define THGM_DO_TEST_void(id, call_params) \ setuppi_##id(); \ - SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(&protoinfo_##id, 0, 0); \ + SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \ CAutoReleaseHookMan arhm_##id(myhookman##id); \ int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ \ @@ -531,7 +521,7 @@ T* ComparableRef(T& x) #define THGM_DO_TEST(id, call_params) \ setuppi_##id(); \ setupri_##id(); \ - SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(&protoinfo_##id, 0, 0); \ + SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \ CAutoReleaseHookMan arhm_##id(myhookman##id); \ int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ \ From a414deb6fe2ba71050e5dcef9475947b5764021f Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 11 Nov 2007 18:51:56 +0000 Subject: [PATCH 22/41] Added test for big vtable indices Improved testevents.h --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40559 --- sourcehook/test/testevents.h | 20 +++- sourcehook/test/testhookmangen.cpp | 156 +++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+), 1 deletion(-) diff --git a/sourcehook/test/testevents.h b/sourcehook/test/testevents.h index 1f9f8bf..24aa060 100644 --- a/sourcehook/test/testevents.h +++ b/sourcehook/test/testevents.h @@ -19,6 +19,19 @@ extern bool g_Verbose; +static unsigned int MakeHash(const char *name) +{ + int a = 0; + unsigned int res = 0xFFFFFFFF; + + while (*name) + { + res ^= ((unsigned int)*name << ((a++ % 4)*8)); + ++name; + } + return res; +} + struct State { virtual ~State() @@ -28,7 +41,7 @@ struct State virtual bool IsEqual(State *other) { - return (typeid(other) == typeid(this)) ? true : false; + return (MakeHash(GetName()) == MakeHash(other->GetName())) ? true : false; } virtual bool Ignore() @@ -37,6 +50,7 @@ struct State } virtual void Dump() = 0; + virtual const char *GetName() = 0; }; struct IgnoreState : public State @@ -130,6 +144,7 @@ namespace #define MAKE_STATE(name) struct name : State { \ virtual void Dump() { \ std::cout << " " << #name << std::endl; } \ + const char *GetName() { return #name; } \ }; #define MAKE_STATE_1(name, p1_type) struct name : State { \ @@ -143,6 +158,7 @@ namespace } \ virtual void Dump() { \ std::cout << " " << #name << "; Param1=" << m_Param1 << std::endl; } \ + const char *GetName() { return #name; } \ } #define MAKE_STATE_2(name, p1_type, p2_type) struct name : State { \ @@ -157,6 +173,7 @@ namespace } \ virtual void Dump() { \ std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << std::endl; } \ + const char *GetName() { return #name; } \ } #define MAKE_STATE_3(name, p1_type, p2_type, p3_type) struct name : State { \ @@ -172,6 +189,7 @@ namespace } \ virtual void Dump() { \ std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << "; Param3=" << m_Param3 << std::endl; } \ + const char *GetName() { return #name; } \ } #define CHECK_COND(c, err) if (!(c)) { error = err; return false; } diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index ffcfd2b..ccb3cdd 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -411,6 +411,119 @@ namespace THGM_SETUP_RI(111, ObjRet111& , SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); + + MAKE_STATE(State_Hello_Func4_Called); + MAKE_STATE(State_Hello_Func79_Called); + + MAKE_STATE(State_Hello_Func4_PreHook); + MAKE_STATE(State_Hello_Func79_PreHook); + + // Test for larger vtable indices + class Hello + { + public: + virtual void Func0() {} + virtual void Func1() {} + virtual void Func2() {} + virtual void Func3() {} + virtual void Func4() + { + ADD_STATE(State_Hello_Func4_Called); + } + virtual void Func5() {} + virtual void Func6() {} + virtual void Func7() {} + virtual void Func8() {} + virtual void Func9() {} + virtual void Func10() {} + virtual void Func11() {} + virtual void Func12() {} + virtual void Func13() {} + virtual void Func14() {} + virtual void Func15() {} + virtual void Func16() {} + virtual void Func17() {} + virtual void Func18() {} + virtual void Func19() {} + virtual void Func20() {} + virtual void Func21() {} + virtual void Func22() {} + virtual void Func23() {} + virtual void Func24() {} + virtual void Func25() {} + virtual void Func26() {} + virtual void Func27() {} + virtual void Func28() {} + virtual void Func29() {} + virtual void Func30() {} + virtual void Func31() {} + virtual void Func32() {} + virtual void Func33() {} + virtual void Func34() {} + virtual void Func35() {} + virtual void Func36() {} + virtual void Func37() {} + virtual void Func38() {} + virtual void Func39() {} + virtual void Func40() {} + virtual void Func41() {} + virtual void Func42() {} + virtual void Func43() {} + virtual void Func44() {} + virtual void Func45() {} + virtual void Func46() {} + virtual void Func47() {} + virtual void Func48() {} + virtual void Func49() {} + virtual void Func50() {} + virtual void Func51() {} + virtual void Func52() {} + virtual void Func53() {} + virtual void Func54() {} + virtual void Func55() {} + virtual void Func56() {} + virtual void Func57() {} + virtual void Func58() {} + virtual void Func59() {} + virtual void Func60() {} + virtual void Func61() {} + virtual void Func62() {} + virtual void Func63() {} + virtual void Func64() {} + virtual void Func65() {} + virtual void Func66() {} + virtual void Func67() {} + virtual void Func68() {} + virtual void Func69() {} + virtual void Func70() {} + virtual void Func71() {} + virtual void Func72() {} + virtual void Func73() {} + virtual void Func74() {} + virtual void Func75() {} + virtual void Func76() {} + virtual void Func77() {} + virtual void Func78() {} + virtual void Func79() + { + ADD_STATE(State_Hello_Func79_Called); + } + }; + class Hello_Func4_Deleg : public MyDelegate + { + virtual void Func() + { + ADD_STATE(State_Hello_Func4_PreHook); + } + }; + class Hello_Func79_Deleg : public MyDelegate + { + int a; + virtual void Func() + { + ADD_STATE(State_Hello_Func79_PreHook); + } + }; } bool TestHookManGen(std::string &error) @@ -802,6 +915,49 @@ bool TestHookManGen(std::string &error) // RefRet THGM_DO_TEST(111, ()); + // Test for lange vtable indices + Hello *pHello = new Hello; + SourceHook::CProtoInfoBuilder helloPi(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::HookManagerPubFunc helloHM_4 = g_HMAGPtr->MakeHookMan(helloPi, 0, 4); + SourceHook::HookManagerPubFunc helloHM_79 = g_HMAGPtr->MakeHookMan(helloPi, 0, 79); + + pHello->Func4(); + pHello->Func79(); + SH_CALL(pHello, &Hello::Func4)(); + SH_CALL(pHello, &Hello::Func79)(); + CHECK_STATES((&g_States, + new State_Hello_Func4_Called, + new State_Hello_Func79_Called, + new State_Hello_Func4_Called, + new State_Hello_Func79_Called, + NULL), "Test" "Hello" " Part1"); + + int helloHook4 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pHello), + 0, helloHM_4, new Hello_Func4_Deleg, false); + + int helloHook79 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pHello), + 0, helloHM_79, new Hello_Func79_Deleg, false); + + pHello->Func4(); + pHello->Func79(); + SH_CALL(pHello, &Hello::Func4)(); + SH_CALL(pHello, &Hello::Func79)(); + + CHECK_STATES((&g_States, + new State_Hello_Func4_PreHook, + new State_Hello_Func4_Called, + new State_Hello_Func79_PreHook, + new State_Hello_Func79_Called, + new State_Hello_Func4_Called, + new State_Hello_Func79_Called, + NULL), "Test" "Hello" " Part2"); + + g_SHPtr->RemoveHookByID(helloHook4); + g_SHPtr->RemoveHookByID(helloHook79); + + g_HMAGPtr->ReleaseHookMan(helloHM_4); + g_HMAGPtr->ReleaseHookMan(helloHM_79); + // Shutdown now! // If we don't SH will auto-shutdown _after_ genc's destructor is called // -> crash From a81e661fa223070b76643b7b7a2ec39ff1df00e3 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 11 Nov 2007 18:55:34 +0000 Subject: [PATCH 23/41] Newline at the end of file --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40560 --- sourcehook/sourcehook_pibuilder.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sourcehook/sourcehook_pibuilder.h b/sourcehook/sourcehook_pibuilder.h index 88cbd20..7c91738 100644 --- a/sourcehook/sourcehook_pibuilder.h +++ b/sourcehook/sourcehook_pibuilder.h @@ -105,4 +105,5 @@ namespace SourceHook }; } -#endif \ No newline at end of file +#endif + From 784d474507c52d0ca55a6a2a1e015020ba4ca7dd Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sat, 17 Nov 2007 09:53:58 +0000 Subject: [PATCH 24/41] New hookfunc local vars code; first step to vafmt support --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40562 --- sourcehook/sourcehook_hookmangen.cpp | 115 +++++++++++++++++++-------- sourcehook/sourcehook_hookmangen.h | 9 +++ sourcehook/test/Makefile | 2 +- 3 files changed, 90 insertions(+), 36 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 103029b..9bcb671 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -19,6 +19,7 @@ #include "sourcehook_hookmangen.h" #include "sourcehook_hookmangen_x86.h" #include "sh_memory.h" +#include // we might need the address of vsnprintf #if SH_COMP == SH_COMP_MSVC # define GCC_ONLY(x) @@ -988,7 +989,7 @@ namespace SourceHook // ECX = pContext // gcc: push ecx // eax = [ecx] - // eax = [eax + 3*PTR_SIZE] + // eax = [eax + 3*SIZE_PTR] // call eax // gcc: clean up IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); @@ -1193,6 +1194,24 @@ namespace SourceHook GCC_ONLY(IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG)); } + void GenContext::ResetFrame(jit_int32_t startOffset) + { + m_HookFunc_FrameOffset = startOffset; + m_HookFunc_FrameVarsSize = 0; + } + + jit_int32_t GenContext::AddVarToFrame(jit_int32_t size) + { + m_HookFunc_FrameOffset -= size; + m_HookFunc_FrameVarsSize += size; + return m_HookFunc_FrameOffset; + } + + jit_int32_t GenContext::ComputeVarsSize() + { + return m_HookFunc_FrameVarsSize; + } + void * GenContext::GenerateHookFunc() { // prologue @@ -1200,19 +1219,21 @@ namespace SourceHook IA32_Push_Reg(&m_HookFunc, REG_EBX); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EBP, REG_ESP, MOD_REG); + // on msvc, save thisptr #if SH_COMP == SH_COMP_MSVC - jit_int8_t v_this = -4; - const int addstackoffset = -4; + jit_int32_t v_this = -4; IA32_Push_Reg(&m_HookFunc, REG_ECX); #elif SH_COMP == SH_COMP_GCC - jit_int8_t v_this = 12; // first param - const int addstackoffset = 0; + jit_int32_t v_this = 12; // first param #endif + ResetFrame( + (SH_COMP==SH_COMP_MSVC) ? -4 : 0 + ); // on msvc, start on offset -4 because there already is the thisptr variable // ********************** stack frame ********************** - // MSVC + // MSVC // second param (gcc: first real param) ebp + 16 // first param (gcc: thisptr) ebp + 12 // ret address: ebp + 8 @@ -1227,26 +1248,33 @@ namespace SourceHook // IHookContext *pContext ebp - 24 -4 // == 3 ptrs + 3 enums = 24 bytes // + // varargs: + // va_list argptr ebp - 28 -4 + // // non-void: add: - // my_rettype *ret_ptr ebp - 28 -4 - // my_rettype orig_ret ebp - 28 - sizeof(my_rettype) -4 - // my_rettype override_ret ebp - 28 - sizeof(my_rettype)*2 -4 - // my_rettype plugin_ret ebp - 28 - sizeof(my_rettype)*3 -4 + // my_rettype *ret_ptr ebp - 28 (va: -4) -4 + // my_rettype orig_ret ebp - 28 (va: -4) - sizeof(my_rettype) -4 + // my_rettype override_ret ebp - 28 (va: -4) - sizeof(my_rettype)*2 -4 + // my_rettype plugin_ret ebp - 28 (va: -4) - sizeof(my_rettype)*3 -4 // == + 3 * sizeof(my_rettype) bytes // if required: - // my_rettype place_for_memret ebp - 28 - sizeof(my_rettype)*4 -4 + // my_rettype place_for_memret ebp - 28 (va: -4) - sizeof(my_rettype)*4 -4 // gcc only: if required: - // place forced byref params ebp - 28 - sizeof(my_rettype)*{4 or 5} + // place forced byref params ebp - 28 (va: -4) - sizeof(my_rettype)*{4 or 5} - const jit_int8_t v_vfnptr_origentry = -4 + addstackoffset; - const jit_int8_t v_status = -8 + addstackoffset; - const jit_int8_t v_prev_res = -12 + addstackoffset; - const jit_int8_t v_cur_res = -16 + addstackoffset; - const jit_int8_t v_iter = -20 + addstackoffset; - const jit_int8_t v_pContext = -24 + addstackoffset; + const jit_int8_t v_vfnptr_origentry = AddVarToFrame(SIZE_PTR); + const jit_int8_t v_status = AddVarToFrame(sizeof(META_RES)); + const jit_int8_t v_prev_res = AddVarToFrame(sizeof(META_RES)); + const jit_int8_t v_cur_res = AddVarToFrame(sizeof(META_RES)); + const jit_int8_t v_iter = AddVarToFrame(SIZE_PTR); + const jit_int8_t v_pContext = AddVarToFrame(SIZE_PTR); + // Only exists for varargs functions + const jit_int8_t v_va_argptr = (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) ? + AddVarToFrame(sizeof(va_list)) : + 0; #if SH_COMP == SH_COMP_GCC jit_int32_t param_base_offs = 16; @@ -1271,34 +1299,51 @@ namespace SourceHook #endif } - jit_int32_t v_ret_ptr = -28 + addstackoffset; - jit_int32_t v_orig_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 1; - jit_int32_t v_override_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 2; - jit_int32_t v_plugin_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 3; + jit_int32_t v_ret_ptr = 0; + jit_int32_t v_orig_ret = 0; + jit_int32_t v_override_ret = 0; + jit_int32_t v_plugin_ret = 0; + + if (m_Proto.GetRet().size != 0) + { + v_ret_ptr = AddVarToFrame(SIZE_PTR); + v_orig_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet())); + v_override_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet())); + v_plugin_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet())); + } - jit_int32_t v_place_for_memret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 4; + jit_int32_t v_place_for_memret = 0; + if (MemRetWithTempObj()) + { + v_place_for_memret = AddVarToFrame(GetStackSize(m_Proto.GetRet())); + } - jit_int32_t v_place_fbrr_base = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * (MemRetWithTempObj() ? 5 : 4); + jit_int32_t v_place_fbrr_base = 0; + if (GetForcedByRefParamsSize()) + { + v_place_fbrr_base = AddVarToFrame(GetForcedByRefParamsSize()); + } - // Hash for temporary storage for byval params with copy constructors - // (param, offset into stack) - short usedStackBytes = 3*SIZE_MWORD + 3*SIZE_PTR // vfnptr_origentry, status, prev_res, cur_res, iter, pContext - + 3 * GetStackSize(m_Proto.GetRet()) + (m_Proto.GetRet().size == 0 ? 0 : SIZE_PTR) // ret_ptr, orig_ret, override_ret, plugin_ret - + (MemRetWithTempObj() ? GetStackSize(m_Proto.GetRet()) : 0) - + GetForcedByRefParamsSize() - - addstackoffset; // msvc: current thisptr - - IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, usedStackBytes, MOD_REG); + IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, ComputeVarsSize(), MOD_REG); // init status localvar IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_status); + // VarArgs: init argptr + if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) + { + // argptr = first vararg param + // lea eax, [esp + param_base_offs + paramssize] + // mov argptr, eax + + IA32_Lea_Reg_DispRegMultImm32(&m_HookFunc, REG_EAX, REG_NOIDX, REG_ESP, NOSCALE, param_base_offs + GetParamsStackSize()); + IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, v_va_argptr, REG_EAX); + } + // Call constructors for ret vars if required if((m_Proto.GetRet().flags & PassInfo::PassFlag_ByVal) && m_Proto.GetRet().pNormalCtor) { - // :TODO: Gcc version - // orig_reg IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index ab66e27..8014694 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -189,6 +189,15 @@ namespace SourceHook void BitwiseCopy_Setup(); void BitwiseCopy_Do(size_t size); + + // HookFunc frame + jit_int32_t m_HookFunc_FrameOffset; + jit_int32_t m_HookFunc_FrameVarsSize; + + void ResetFrame(jit_int32_t startOffset); + jit_int32_t AddVarToFrame(jit_int32_t size); + jit_int32_t ComputeVarsSize(); + // Param push short GetForcedByRefParamsSize(); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < numOfParams) short GetForcedByRefParamOffset(int p); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < p) diff --git a/sourcehook/test/Makefile b/sourcehook/test/Makefile index c1d907e..18b7275 100644 --- a/sourcehook/test/Makefile +++ b/sourcehook/test/Makefile @@ -20,7 +20,7 @@ else CFLAGS = $(OPT_FLAGS) endif -CFLAGS += -Wall +CFLAGS += -Wall -Wno-non-virtual-dtor # Also, enable SH_ASSERT CFLAGS += -DSH_DEBUG From 3de86ccca848bb0e9b9c284deea8ac770072f387 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 18 Nov 2007 11:58:07 +0000 Subject: [PATCH 25/41] Hookmangen support for vafmt on gcc Added vafmt_void test to testhookmangen Recalls should work now with vafmt --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40564 --- sourcehook/generate/sourcehook.h | 204 ++++ sourcehook/generate/sourcehook.hxx | 12 + sourcehook/sourcehook.h | 204 ++++ sourcehook/sourcehook_hookmangen.cpp | 102 +- sourcehook/sourcehook_hookmangen.h | 4 +- sourcehook/sourcehook_hookmangen_x86.h | 22 + sourcehook/sourcehook_pibuilder.h | 2 +- sourcehook/test/testhookmangen.cpp | 60 + sourcehook/test/testhookmangen.h | 1414 +++++++++++++++++++++++- sourcehook/test/testhookmangen.hxx | 210 +++- 10 files changed, 2198 insertions(+), 36 deletions(-) diff --git a/sourcehook/generate/sourcehook.h b/sourcehook/generate/sourcehook.h index ee287dc..df5a477 100644 --- a/sourcehook/generate/sourcehook.h +++ b/sourcehook/generate/sourcehook.h @@ -5635,204 +5635,408 @@ namespace SourceHook return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)()) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + } #endif diff --git a/sourcehook/generate/sourcehook.hxx b/sourcehook/generate/sourcehook.hxx index bde13ab..04069b7 100755 --- a/sourcehook/generate/sourcehook.hxx +++ b/sourcehook/generate/sourcehook.hxx @@ -1353,11 +1353,23 @@ namespace SourceHook return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(@[$2,1,$1:Param$2, @]...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(@[$2,1,$1|, :Param$2@])) { return reinterpret_cast(shptr->GetIfacePtr()); } + + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(@[$2,1,$1:Param$2, @]...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } @] } diff --git a/sourcehook/sourcehook.h b/sourcehook/sourcehook.h index ee287dc..df5a477 100644 --- a/sourcehook/sourcehook.h +++ b/sourcehook/sourcehook.h @@ -5635,204 +5635,408 @@ namespace SourceHook return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)()) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + template OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) { return OverrideFunctor(); } + template + OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)) + { + return OverrideFunctor(); + } + template Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) { return reinterpret_cast(shptr->GetIfacePtr()); } + template + Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)) + { + return reinterpret_cast(shptr->GetIfacePtr()); + } + } #endif diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 9bcb671..bc985c7 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -848,7 +848,7 @@ namespace SourceHook } void GenContext::GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, - int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base) + int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf) { jitoffs_t counter, tmppos; jitoffs_t counter2, tmppos2; @@ -894,8 +894,17 @@ namespace SourceHook // eax = [eax+2*SIZE_PTR] // call eax // gcc: clean up + + jit_int32_t gcc_clean_bytes = 0; + // vafmt: push va_buf + if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) + { + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); + IA32_Push_Reg(&m_HookFunc, REG_ECX); + gcc_clean_bytes += SIZE_PTR; + } - jit_int32_t gcc_clean_bytes = PushParams(base_param_offset, v_plugin_ret, v_place_for_memret, v_place_fbrr_base); + gcc_clean_bytes += PushParams(base_param_offset, v_plugin_ret, v_place_for_memret, v_place_fbrr_base); IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); @@ -953,7 +962,7 @@ namespace SourceHook } void GenContext::GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this, - int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base) + int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf) { jitoffs_t counter, tmppos; jitoffs_t counter2, tmppos2; @@ -1005,8 +1014,19 @@ namespace SourceHook tmppos2 = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_Z, 0); m_HookFunc.start_count(counter2); + jit_int32_t gcc_clean_bytes = 0; + + // vafmt: push va_buf, then "%s" + if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) + { + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); + IA32_Push_Reg(&m_HookFunc, REG_ECX); + IA32_Push_Imm32(&m_HookFunc, DownCastPtr("%s")); + gcc_clean_bytes += 2*SIZE_PTR; + } + // push params - jit_int32_t gcc_clean_bytes = PushParams(param_base_offs, v_orig_ret, v_place_for_memret, v_place_fbrr_base); + gcc_clean_bytes += PushParams(param_base_offs, v_orig_ret, v_place_for_memret, v_place_fbrr_base); // thisptr IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); @@ -1248,21 +1268,22 @@ namespace SourceHook // IHookContext *pContext ebp - 24 -4 // == 3 ptrs + 3 enums = 24 bytes // - // varargs: - // va_list argptr ebp - 28 -4 - // // non-void: add: - // my_rettype *ret_ptr ebp - 28 (va: -4) -4 - // my_rettype orig_ret ebp - 28 (va: -4) - sizeof(my_rettype) -4 - // my_rettype override_ret ebp - 28 (va: -4) - sizeof(my_rettype)*2 -4 - // my_rettype plugin_ret ebp - 28 (va: -4) - sizeof(my_rettype)*3 -4 + // my_rettype *ret_ptr ebp - 28 -4 + // my_rettype orig_ret ebp - 28 - sizeof(my_rettype) -4 + // my_rettype override_ret ebp - 28 - sizeof(my_rettype)*2 -4 + // my_rettype plugin_ret ebp - 28 - sizeof(my_rettype)*3 -4 // == + 3 * sizeof(my_rettype) bytes // if required: - // my_rettype place_for_memret ebp - 28 (va: -4) - sizeof(my_rettype)*4 -4 + // my_rettype place_for_memret ebp - 28 - sizeof(my_rettype)*4 -4 // gcc only: if required: - // place forced byref params ebp - 28 (va: -4) - sizeof(my_rettype)*{4 or 5} + // place forced byref params ebp - 28 - sizeof(my_rettype)*{4 or 5} + // + // varargs: + // va_list argptr + // char va_buf[something]; const jit_int8_t v_vfnptr_origentry = AddVarToFrame(SIZE_PTR); @@ -1271,10 +1292,6 @@ namespace SourceHook const jit_int8_t v_cur_res = AddVarToFrame(sizeof(META_RES)); const jit_int8_t v_iter = AddVarToFrame(SIZE_PTR); const jit_int8_t v_pContext = AddVarToFrame(SIZE_PTR); - // Only exists for varargs functions - const jit_int8_t v_va_argptr = (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) ? - AddVarToFrame(sizeof(va_list)) : - 0; #if SH_COMP == SH_COMP_GCC jit_int32_t param_base_offs = 16; @@ -1319,25 +1336,60 @@ namespace SourceHook } jit_int32_t v_place_fbrr_base = 0; - if (GetForcedByRefParamsSize()) + if (SH_COMP == SH_COMP_GCC && GetForcedByRefParamsSize()) { v_place_fbrr_base = AddVarToFrame(GetForcedByRefParamsSize()); } + // Only exists for varargs functions + jit_int32_t v_va_argptr = 0; + if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) + { + v_va_argptr = AddVarToFrame(SIZE_PTR); + } + + jit_int32_t v_va_buf = 0; + if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) + { + v_va_buf = AddVarToFrame(SourceHook::STRBUF_LEN); + } + IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, ComputeVarsSize(), MOD_REG); // init status localvar IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_status); - // VarArgs: init argptr + // VarArgs: init argptr & format if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) { // argptr = first vararg param - // lea eax, [esp + param_base_offs + paramssize] + // lea eax, [ebp + param_base_offs + paramssize] // mov argptr, eax - IA32_Lea_Reg_DispRegMultImm32(&m_HookFunc, REG_EAX, REG_NOIDX, REG_ESP, NOSCALE, param_base_offs + GetParamsStackSize()); - IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, v_va_argptr, REG_EAX); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_base_offs + GetParamsStackSize() + SIZE_PTR); // +SIZE_PTR: last const char * is not in protoinfo + IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_va_argptr); + } + if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) + { + // vsnprintf + + // push valist, fmt param, maxsize, buffer + IA32_Push_Reg(&m_HookFunc, REG_EAX); + IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_base_offs + GetParamsStackSize()); // last given param (+4-4, see above) + IA32_Push_Imm32(&m_HookFunc, SourceHook::STRBUF_LEN - 1); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); + IA32_Push_Reg(&m_HookFunc, REG_ECX); + + // call + IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(&vsnprintf)); + IA32_Call_Reg(&m_HookFunc, REG_EAX); + + // Clean up (cdecl) + IA32_Add_Rm_Imm32(&m_HookFunc, REG_ESP, 0x10, MOD_REG); + + // Set trailing zero + IA32_Xor_Reg_Rm(&m_HookFunc, REG_EDX, REG_EDX, MOD_REG); + IA32_Mov_Rm8_Reg8_DispAuto(&m_HookFunc, REG_EBP, REG_EDX, v_va_buf + SourceHook::STRBUF_LEN - 1); } // Call constructors for ret vars if required @@ -1374,15 +1426,15 @@ namespace SourceHook // ********************** call pre hooks ********************** GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, - v_plugin_ret, v_place_for_memret, v_place_fbrr_base); + v_plugin_ret, v_place_for_memret, v_place_fbrr_base, v_va_buf); // ********************** call orig func ********************** GenerateCallOrig(v_status, v_pContext, param_base_offs, v_this, v_vfnptr_origentry, v_orig_ret, - v_override_ret, v_place_for_memret, v_place_fbrr_base); + v_override_ret, v_place_for_memret, v_place_fbrr_base, v_va_buf); // ********************** call post hooks ********************** GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, - v_plugin_ret, v_place_for_memret, v_place_fbrr_base); + v_plugin_ret, v_place_for_memret, v_place_fbrr_base, v_va_buf); // ********************** end context and return ********************** diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 8014694..71bbf54 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -221,11 +221,11 @@ namespace SourceHook // Call hooks void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, - int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base); + int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf); // Call orig void GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this, - int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base); + int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf); // Hook loop void CallSetupHookLoop(int v_orig_ret, int v_override_ret, diff --git a/sourcehook/sourcehook_hookmangen_x86.h b/sourcehook/sourcehook_hookmangen_x86.h index 81b40cd..4590ff0 100644 --- a/sourcehook/sourcehook_hookmangen_x86.h +++ b/sourcehook/sourcehook_hookmangen_x86.h @@ -943,6 +943,28 @@ namespace SourceHook jit->write_ubyte(ia32_modrm(mode, src, dest)); } + inline void IA32_Mov_Rm8_Reg8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) + { + jit->write_ubyte(IA32_MOV_RM8_REG8); + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest)); + jit->write_byte(disp); + } + + inline void IA32_Mov_Rm8_Reg8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + jit->write_ubyte(IA32_MOV_RM8_REG8); + jit->write_ubyte(ia32_modrm(MOD_DISP32, src, dest)); + jit->write_int32(disp); + } + + inline void IA32_Mov_Rm8_Reg8_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) + { + if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) + IA32_Mov_Rm8_Reg8_Disp8(jit, dest, src, static_cast(disp)); + else + IA32_Mov_Rm8_Reg8_Disp32(jit, dest, src, disp); + } + inline void IA32_Mov_RmESP_Reg(JitWriter *jit, jit_uint8_t src) { jit->write_ubyte(IA32_MOV_RM_REG); diff --git a/sourcehook/sourcehook_pibuilder.h b/sourcehook/sourcehook_pibuilder.h index 7c91738..6c2f592 100644 --- a/sourcehook/sourcehook_pibuilder.h +++ b/sourcehook/sourcehook_pibuilder.h @@ -23,7 +23,7 @@ namespace SourceHook CVector m_Params; CVector m_Params2; public: - CProtoInfoBuilder(ProtoInfo::CallConvention cc) + CProtoInfoBuilder(int cc) { memset(reinterpret_cast(&m_PI), 0, sizeof(ProtoInfo)); m_PI.convention = cc; diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index ccb3cdd..a391482 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -219,6 +219,15 @@ namespace } }; + template<> + struct Increment + { + static void Incr(std::string &what) + { + what += "!"; + } + }; + #include "testhookmangen.h" template @@ -412,6 +421,38 @@ namespace SourceHook::PassInfo::PassFlag_ByRef | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); + + // vafmt tests + THGM_MAKE_TEST0_vafmt_void(200); + THGM_SETUP_PI0(200); + + THGM_MAKE_TEST1_vafmt_void(201, char); + THGM_SETUP_PI1(201, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_vafmt_void(203, int); + THGM_SETUP_PI1(203, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST5_vafmt_void(206, char, short, int, float, double); + THGM_SETUP_PI5(206, + char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, + short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, + float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal, + double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal + ); + + THGM_MAKE_TEST2_vafmt_void(207, char&, double&); + THGM_SETUP_PI2(207, + char&, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByRef, + double&, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByRef + ); + + THGM_MAKE_TEST1_vafmt_void(208, POD<7>); + THGM_SETUP_PI1(208, POD<7>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_vafmt_void(210, POD<600> &); + THGM_SETUP_PI1(210, POD<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef) + MAKE_STATE(State_Hello_Func4_Called); MAKE_STATE(State_Hello_Func79_Called); @@ -915,6 +956,25 @@ bool TestHookManGen(std::string &error) // RefRet THGM_DO_TEST(111, ()); + // Vafmt + + THGM_DO_TEST_void(200, ("Hello %s%d%s", "BA", 1, "L!")); + + THGM_DO_TEST_void(201, (100, "Hello %s%d%s", "BA", 1, "L!")); + + THGM_DO_TEST_void(203, (0x1F000000, "Hello %s%d%s", "BA", 1, "L!")); + + THGM_DO_TEST_void(206, (100, 0x1f00, 0x1f000000, 0.5f, 5.5, "Hello %s%d%s", "BA", 1, "L!")); + + a = 5; + b = 233.33; + THGM_DO_TEST_void(207, (a, b, "Hello %s%d%s", "BA", 1, "L!")); + + pod7 = MakeRet< POD<7> >::Do(78); + THGM_DO_TEST_void(208, (pod7, "Hello %s%d%s", "BA", 1, "L!")); + + THGM_DO_TEST_void(210, (pod600, "Hello %s%d%s", "BA", 1, "L!")); + // Test for lange vtable indices Hello *pHello = new Hello; SourceHook::CProtoInfoBuilder helloPi(SourceHook::ProtoInfo::CallConv_ThisCall); diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index 1450eba..32c12d5 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -132,6 +132,20 @@ struct MakeRet< POD > }; // Stores parameter status +template +bool EqualToMyFmtString(T sth) +{ + return false; +} + +bool EqualToMyFmtString(std::string &sth) +{ + if (sth == "Hello %s%d%s") + sth = "Hello BA1L!"; + return true; +} + + template @@ -145,8 +159,9 @@ struct ParamState0 ; } - ParamState0() + ParamState0(...) { + } ParamState0 & operator() (int incrsteps) @@ -178,8 +193,11 @@ struct ParamState1 && m_1 == other.m_1 ; } - ParamState1(p1 a1) : m_1(a1) + ParamState1(p1 a1, ...) : m_1(a1) { + + EqualToMyFmtString(m_1); + } ParamState1 & operator() (int incrsteps) @@ -214,8 +232,13 @@ struct ParamState2 && m_2 == other.m_2 && m_2 == other.m_2 ; } - ParamState2(p1 a1, p2 a2) : m_1(a1), m_2(a2) + ParamState2(p1 a1, p2 a2, ...) : m_1(a1), m_2(a2) { + + EqualToMyFmtString(m_1); + + EqualToMyFmtString(m_2); + } ParamState2 & operator() (int incrsteps) @@ -253,8 +276,15 @@ struct ParamState3 && m_3 == other.m_3 && m_3 == other.m_3 && m_3 == other.m_3 ; } - ParamState3(p1 a1, p2 a2, p3 a3) : m_1(a1), m_2(a2), m_3(a3) + ParamState3(p1 a1, p2 a2, p3 a3, ...) : m_1(a1), m_2(a2), m_3(a3) { + + EqualToMyFmtString(m_1); + + EqualToMyFmtString(m_2); + + EqualToMyFmtString(m_3); + } ParamState3 & operator() (int incrsteps) @@ -295,8 +325,17 @@ struct ParamState4 && m_4 == other.m_4 && m_4 == other.m_4 && m_4 == other.m_4 && m_4 == other.m_4 ; } - ParamState4(p1 a1, p2 a2, p3 a3, p4 a4) : m_1(a1), m_2(a2), m_3(a3), m_4(a4) + ParamState4(p1 a1, p2 a2, p3 a3, p4 a4, ...) : m_1(a1), m_2(a2), m_3(a3), m_4(a4) { + + EqualToMyFmtString(m_1); + + EqualToMyFmtString(m_2); + + EqualToMyFmtString(m_3); + + EqualToMyFmtString(m_4); + } ParamState4 & operator() (int incrsteps) @@ -340,8 +379,19 @@ struct ParamState5 && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 ; } - ParamState5(p1 a1, p2 a2, p3 a3, p4 a4, p5 a5) : m_1(a1), m_2(a2), m_3(a3), m_4(a4), m_5(a5) + ParamState5(p1 a1, p2 a2, p3 a3, p4 a4, p5 a5, ...) : m_1(a1), m_2(a2), m_3(a3), m_4(a4), m_5(a5) { + + EqualToMyFmtString(m_1); + + EqualToMyFmtString(m_2); + + EqualToMyFmtString(m_3); + + EqualToMyFmtString(m_4); + + EqualToMyFmtString(m_5); + } ParamState5 & operator() (int incrsteps) @@ -388,8 +438,21 @@ struct ParamState6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 ; } - ParamState6(p1 a1, p2 a2, p3 a3, p4 a4, p5 a5, p6 a6) : m_1(a1), m_2(a2), m_3(a3), m_4(a4), m_5(a5), m_6(a6) + ParamState6(p1 a1, p2 a2, p3 a3, p4 a4, p5 a5, p6 a6, ...) : m_1(a1), m_2(a2), m_3(a3), m_4(a4), m_5(a5), m_6(a6) { + + EqualToMyFmtString(m_1); + + EqualToMyFmtString(m_2); + + EqualToMyFmtString(m_3); + + EqualToMyFmtString(m_4); + + EqualToMyFmtString(m_5); + + EqualToMyFmtString(m_6); + } ParamState6 & operator() (int incrsteps) @@ -622,6 +685,197 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); +#define THGM_MAKE_TEST0_vafmt_void(id) \ + struct TestClass##id; \ + typedef ParamState1<0, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(std::string(buf)))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ("%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ("%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ("%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ("%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); + + +#define THGM_MAKE_TEST0_vafmt(id, ret_type) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState0<0 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call() \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, ()); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) + + #define THGM_SETUP_PI0(id) \ void setuppi_##id() \ { \ @@ -812,6 +1066,197 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); +#define THGM_MAKE_TEST1_vafmt_void(id, param1) \ + struct TestClass##id; \ + typedef ParamState2<0, param1, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, std::string(buf)))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); + + +#define THGM_MAKE_TEST1_vafmt(id, ret_type, param1) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState1<0, param1 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) + + #define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ void setuppi_##id() \ { \ @@ -1009,6 +1454,197 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); +#define THGM_MAKE_TEST2_vafmt_void(id, param1, param2) \ + struct TestClass##id; \ + typedef ParamState3<0, param1, param2, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, std::string(buf)))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); + + +#define THGM_MAKE_TEST2_vafmt(id, ret_type, param1, param2) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState2<0, param1, param2 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) + + #define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ void setuppi_##id() \ { \ @@ -1213,6 +1849,197 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); +#define THGM_MAKE_TEST3_vafmt_void(id, param1, param2, param3) \ + struct TestClass##id; \ + typedef ParamState4<0, param1, param2, param3, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, param3 p3, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, std::string(buf)))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); + + +#define THGM_MAKE_TEST3_vafmt(id, ret_type, param1, param2, param3) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) + + #define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ void setuppi_##id() \ { \ @@ -1424,6 +2251,197 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); +#define THGM_MAKE_TEST4_vafmt_void(id, param1, param2, param3, param4) \ + struct TestClass##id; \ + typedef ParamState5<0, param1, param2, param3, param4, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, std::string(buf)))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); + + +#define THGM_MAKE_TEST4_vafmt(id, ret_type, param1, param2, param3, param4) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) + + #define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ void setuppi_##id() \ { \ @@ -1642,6 +2660,197 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); +#define THGM_MAKE_TEST5_vafmt_void(id, param1, param2, param3, param4, param5) \ + struct TestClass##id; \ + typedef ParamState6<0, param1, param2, param3, param4, param5, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, std::string(buf)))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); + + +#define THGM_MAKE_TEST5_vafmt(id, ret_type, param1, param2, param3, param4, param5) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) + + #define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ void setuppi_##id() \ { \ @@ -1867,6 +3076,197 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); +#define THGM_MAKE_TEST6_vafmt_void(id, param1, param2, param3, param4, param5, param6) \ + struct TestClass##id; \ + typedef ParamState7<0, param1, param2, param3, param4, param5, param6, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6, std::string(buf)))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); + + +#define THGM_MAKE_TEST6_vafmt(id, ret_type, param1, param2, param3, param4, param5, param6) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) + + #define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ void setuppi_##id() \ { \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 100ee2f..8b94fd3 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -132,6 +132,20 @@ struct MakeRet< POD > }; // Stores parameter status +template +bool EqualToMyFmtString(T sth) +{ + return false; +} + +bool EqualToMyFmtString(std::string &sth) +{ + if (sth == "Hello %s%d%s") + sth = "Hello BA1L!"; + return true; +} + + @[$1,0,$a: template @@ -145,8 +159,11 @@ struct ParamState$1 @[$2,1,$1: && m_$1 == other.m_$1@] ; } - ParamState$1(@[$2,1,$1|, :p$2 a$2@]) @[$1!=0::@] @[$2,1,$1|, :m_$2(a$2)@] + ParamState$1(@[$2,1,$1:p$2 a$2, @]...) @[$1!=0::@] @[$2,1,$1|, :m_$2(a$2)@] { + @[$2,1,$1: + EqualToMyFmtString(m_$2); + @] } ParamState$1 & operator() (int incrsteps) @@ -364,6 +381,197 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); +#define THGM_MAKE_TEST$1_vafmt_void(id@[$2,1,$1:, param$2@]) \ + struct TestClass##id; \ + typedef ParamState@($1+1)<0@[$2,1,$1:, param$2@], std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual void Func(@[$2,1,$1:param$2 p$2, @]const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1:p$2, @]std::string(buf)))); \ + g_Inside_LeafFunc = false; \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_IGNORED); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ + } \ + else \ + RETURN_META(MRES_SUPERCEDE); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); + + +#define THGM_MAKE_TEST$1_vafmt(id, ret_type@[$2,1,$1:, param$2@]) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate1 : public MyDelegate \ + { \ + virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + } \ + }; \ + struct Delegate2 : public MyDelegate \ + { \ + virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ + } \ + }; \ + struct Delegate3 : public MyDelegate \ + { \ + virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ + } \ + }; \ + struct Delegate4 : public MyDelegate \ + { \ + virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + } \ + else \ + RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ + }; \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) + + #define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ void setuppi_##id() \ { \ From 184232777a001d2eccf1817815ecef48bcf54f8a Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 18 Nov 2007 13:12:51 +0000 Subject: [PATCH 26/41] void vafmt works on msvc --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40565 --- sourcehook/sourcehook_hookmangen.cpp | 132 +++++++++++++++------------ 1 file changed, 72 insertions(+), 60 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index bc985c7..96d5430 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -20,6 +20,7 @@ #include "sourcehook_hookmangen_x86.h" #include "sh_memory.h" #include // we might need the address of vsnprintf +#include #if SH_COMP == SH_COMP_MSVC # define GCC_ONLY(x) @@ -895,20 +896,21 @@ namespace SourceHook // call eax // gcc: clean up - jit_int32_t gcc_clean_bytes = 0; + jit_int32_t caller_clean_bytes = 0; // gcc always, msvc never (hooks never have varargs!) // vafmt: push va_buf if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) { IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); IA32_Push_Reg(&m_HookFunc, REG_ECX); - gcc_clean_bytes += SIZE_PTR; + caller_clean_bytes += SIZE_PTR; } - gcc_clean_bytes += PushParams(base_param_offset, v_plugin_ret, v_place_for_memret, v_place_fbrr_base); + caller_clean_bytes += PushParams(base_param_offset, v_plugin_ret, v_place_for_memret, v_place_fbrr_base); IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - gcc_clean_bytes += PushMemRetPtr(v_plugin_ret, v_place_for_memret); + if (SH_COMP == SH_COMP_GCC) + IA32_Push_Reg(&m_HookFunc, REG_ECX); + caller_clean_bytes += PushMemRetPtr(v_plugin_ret, v_place_for_memret); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 2*SIZE_PTR); IA32_Call_Reg(&m_HookFunc, REG_EAX); @@ -917,12 +919,10 @@ namespace SourceHook SaveRetVal(v_plugin_ret, v_place_for_memret); - // cleanup -#if SH_COMP == SH_COMP_GCC - IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG); -#endif - - // params + thisptr + // cleanup (gcc only) + // params + thisptr + if (SH_COMP == SH_COMP_GCC) + IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, caller_clean_bytes + SIZE_PTR, MOD_REG); // process meta return: // prev_res = cur_res @@ -1014,7 +1014,7 @@ namespace SourceHook tmppos2 = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_Z, 0); m_HookFunc.start_count(counter2); - jit_int32_t gcc_clean_bytes = 0; + jit_int32_t caller_clean_bytes = 0; // gcc always, msvc when cdecl-like (varargs) // vafmt: push va_buf, then "%s" if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) @@ -1022,29 +1022,29 @@ namespace SourceHook IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); IA32_Push_Reg(&m_HookFunc, REG_ECX); IA32_Push_Imm32(&m_HookFunc, DownCastPtr("%s")); - gcc_clean_bytes += 2*SIZE_PTR; + caller_clean_bytes += 2*SIZE_PTR; } // push params - gcc_clean_bytes += PushParams(param_base_offs, v_orig_ret, v_place_for_memret, v_place_fbrr_base); + caller_clean_bytes += PushParams(param_base_offs, v_orig_ret, v_place_for_memret, v_place_fbrr_base); // thisptr IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); -#if SH_COMP == SH_COMP_GCC - // on gcc/mingw, this is the first parameter - IA32_Push_Reg(&m_HookFunc, REG_ECX); - // on msvc, simply leave it in ecx -#endif - gcc_clean_bytes += PushMemRetPtr(v_orig_ret, v_place_for_memret); + if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) + { + // on gcc/mingw or msvc with varargs, this is the first parameter + IA32_Push_Reg(&m_HookFunc, REG_ECX); + // on msvc without varargs, simply leave it in ecx + } + caller_clean_bytes += PushMemRetPtr(v_orig_ret, v_place_for_memret); // call IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_vfnptr_origentry); IA32_Call_Reg(&m_HookFunc, REG_EAX); // cleanup -#if SH_COMP == SH_COMP_GCC - IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, gcc_clean_bytes + SIZE_PTR, MOD_REG); -#endif + if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) + IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, caller_clean_bytes + SIZE_PTR, MOD_REG); DestroyParams(v_place_fbrr_base); @@ -1239,21 +1239,27 @@ namespace SourceHook IA32_Push_Reg(&m_HookFunc, REG_EBX); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EBP, REG_ESP, MOD_REG); - - // on msvc, save thisptr -#if SH_COMP == SH_COMP_MSVC - jit_int32_t v_this = -4; - IA32_Push_Reg(&m_HookFunc, REG_ECX); -#elif SH_COMP == SH_COMP_GCC - jit_int32_t v_this = 12; // first param -#endif - - ResetFrame( - (SH_COMP==SH_COMP_MSVC) ? -4 : 0 - ); // on msvc, start on offset -4 because there already is the thisptr variable + jit_int32_t v_this = 0; + jit_int32_t param_base_offs = 0; + if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) + { + // gcc or msvc with varargs: + v_this = 12; // first param + param_base_offs = 16; + ResetFrame(0); + } + else + { + // on msvc without varargs, save thisptr + v_this = -4; + param_base_offs = 12; + IA32_Push_Reg(&m_HookFunc, REG_ECX); + ResetFrame(-4); // start placing local vars on offset -4 + // because there already is the thisptr variable + } // ********************** stack frame ********************** - // MSVC + // MSVC without varargs // second param (gcc: first real param) ebp + 16 // first param (gcc: thisptr) ebp + 12 // ret address: ebp + 8 @@ -1292,28 +1298,25 @@ namespace SourceHook const jit_int8_t v_cur_res = AddVarToFrame(sizeof(META_RES)); const jit_int8_t v_iter = AddVarToFrame(SIZE_PTR); const jit_int8_t v_pContext = AddVarToFrame(SIZE_PTR); - -#if SH_COMP == SH_COMP_GCC - jit_int32_t param_base_offs = 16; -#elif SH_COMP == SH_COMP_MSVC - jit_int32_t param_base_offs = 12; -#endif // Memory return: first param is the address jit_int32_t v_memret_addr = 0; if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) { -#if SH_COMP == SH_COMP_GCC - // gcc: now: first param = mem ret addr - // second param = this pointer - // third param = actual first param - v_memret_addr = 12; - v_this += 4; - param_base_offs += SIZE_PTR; -#elif SH_COMP == SH_COMP_MSVC - v_memret_addr = param_base_offs; - param_base_offs += SIZE_PTR; -#endif + if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) + { + // gcc: now: first param = mem ret addr + // second param = this pointer + // third param = actual first param + v_memret_addr = 12; + v_this += 4; + param_base_offs += SIZE_PTR; + } + else + { + v_memret_addr = param_base_offs; + param_base_offs += SIZE_PTR; + } } jit_int32_t v_ret_ptr = 0; @@ -1494,14 +1497,23 @@ namespace SourceHook IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESP, REG_EBP, MOD_REG); IA32_Pop_Reg(&m_HookFunc, REG_EBX); IA32_Pop_Reg(&m_HookFunc, REG_EBP); - MSVC_ONLY(IA32_Return_Popstack(&m_HookFunc, GetParamsStackSize())); - // gcc: Remove 4 bytes from stack on memory return -#if SH_COMP == SH_COMP_GCC - if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - IA32_Return_Popstack(&m_HookFunc, SIZE_PTR); + + if (SH_COMP == SH_COMP_MSVC && !(m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) + { + // msvc without varargs: + // callee cleans the stack + IA32_Return_Popstack(&m_HookFunc, GetParamsStackSize()); + } else - IA32_Return(&m_HookFunc); -#endif + { + // gcc or msvc with varargs: caller cleans the stack + // exception: gcc removes the memret addr on memret: + if (SH_COMP == SH_COMP_GCC && (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)) + IA32_Return_Popstack(&m_HookFunc, SIZE_PTR); + else + IA32_Return(&m_HookFunc); + } + // Store pointer for later use // m_HookfuncVfnPtr is a pointer to a void* because SH expects a pointer From 14c51ca8d167043b877903ca06e6ba05fbd242bf Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 18 Nov 2007 15:08:03 +0000 Subject: [PATCH 27/41] Made testhookmangen easier for the compiler --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40566 --- sourcehook/test/msvc8/test.vcproj | 4 + sourcehook/test/testevents.h | 29 +- sourcehook/test/testhookmangen.cpp | 925 ++++++------ sourcehook/test/testhookmangen.h | 2110 +++------------------------- sourcehook/test/testhookmangen.hxx | 394 +----- 5 files changed, 759 insertions(+), 2703 deletions(-) diff --git a/sourcehook/test/msvc8/test.vcproj b/sourcehook/test/msvc8/test.vcproj index c8df00a..a0f1533 100644 --- a/sourcehook/test/msvc8/test.vcproj +++ b/sourcehook/test/msvc8/test.vcproj @@ -529,6 +529,10 @@ RelativePath="..\testevents.h" > + + diff --git a/sourcehook/test/testevents.h b/sourcehook/test/testevents.h index 24aa060..7a0175c 100644 --- a/sourcehook/test/testevents.h +++ b/sourcehook/test/testevents.h @@ -151,9 +151,9 @@ namespace p1_type m_Param1; \ name(p1_type param1) : m_Param1(param1) {} \ virtual bool IsEqual(State *other) { \ - name *other2 = dynamic_cast(other); \ - if (!other2) \ + if (MakeHash(GetName()) != MakeHash(other->GetName())) \ return false; \ + name *other2 = static_cast(other); \ return other2->m_Param1 == m_Param1;\ } \ virtual void Dump() { \ @@ -166,9 +166,9 @@ namespace p2_type m_Param2; \ name(p1_type param1, p2_type param2) : m_Param1(param1), m_Param2(param2) {} \ virtual bool IsEqual(State *other) { \ - name *other2 = dynamic_cast(other); \ - if (!other2) \ + if (MakeHash(GetName()) != MakeHash(other->GetName())) \ return false; \ + name *other2 = static_cast(other); \ return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2;\ } \ virtual void Dump() { \ @@ -182,9 +182,9 @@ namespace p3_type m_Param3; \ name(p1_type param1, p2_type param2, p3_type param3) : m_Param1(param1), m_Param2(param2), m_Param3(param3) {} \ virtual bool IsEqual(State *other) { \ - name *other2 = dynamic_cast(other); \ - if (!other2) \ + if (MakeHash(GetName()) != MakeHash(other->GetName())) \ return false; \ + name *other2 = static_cast(other); \ return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2 && other2->m_Param3 == m_Param3;\ } \ virtual void Dump() { \ @@ -192,6 +192,23 @@ namespace const char *GetName() { return #name; } \ } +#define MAKE_STATE_4(name, p1_type, p2_type, p3_type, p4_type) struct name : State { \ + p1_type m_Param1; \ + p2_type m_Param2; \ + p3_type m_Param3; \ + p4_type m_Param4; \ + name(p1_type param1, p2_type param2, p3_type param3, p4_type param4) : m_Param1(param1), m_Param2(param2), m_Param3(param3), m_Param4(param4) {} \ + virtual bool IsEqual(State *other) { \ + if (MakeHash(GetName()) != MakeHash(other->GetName())) \ + return false; \ + name *other2 = static_cast(other); \ + return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2 && other2->m_Param3 == m_Param3 && other2->m_Param4 == m_Param4;\ + } \ + virtual void Dump() { \ + std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << "; Param3=" << m_Param3 << "; Param4=" << m_Param4 << std::endl; } \ + const char *GetName() { return #name; } \ + } + #define CHECK_COND(c, err) if (!(c)) { error = err; return false; } #endif diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index a391482..4ac57a5 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -565,8 +565,488 @@ namespace ADD_STATE(State_Hello_Func79_PreHook); } }; + + bool Tests1(std::string &error) + { + THGM_DO_TEST_void(0, ()); + + THGM_DO_TEST_void(1, (100)); + + THGM_DO_TEST_void(2, (0x1F00)); + + THGM_DO_TEST_void(3, (0x1F000000)); + + THGM_DO_TEST_void(4, (0.5f)); + + THGM_DO_TEST_void(5, (5.5)); + + THGM_DO_TEST_void(6, (100, 0x1f00, 0x1f000000, 0.5f, 5.5)); + + return true; + } + + bool Tests2(std::string &error) + { + char a = 5; + double b = 233.33; + THGM_DO_TEST_void(7, (a, b)); + + POD<7> pod7 = MakeRet< POD<7> >::Do(78); + THGM_DO_TEST_void(8, (pod7)); + + POD<600> pod600 = MakeRet< POD<600> >::Do(34); + THGM_DO_TEST_void(9, (pod600)); + + THGM_DO_TEST_void(10, (pod600)); + + // Test11: Special: constructors/destructors + PtrBuf_Clear(); + Object<3> *obj3_real = new Object<3>(33); + Object<600> *obj600_real = new Object<600>(21); + + Object<3> & obj3 = *obj3_real; + Object<600> & obj600 = *obj600_real; + + CHECK_STATES((&g_States, + new State_ObjOCtor_Called(3), + new State_ObjOCtor_Called(600), + NULL), "Test11 Part0"); + + setuppi_11(); + SourceHook::HookManagerPubFunc myhookman11 = g_HMAGPtr->MakeHookMan(protoinfo_11, 0, 0); \ + CAutoReleaseHookMan arhm_11(myhookman11); \ + int hook1_11, hook2_11, hook3_11, hook4_11; + + TestClass11 *pTest11 = new TestClass11; + CAutoPtrDestruction apd11(pTest11); + + /* no hooks - no hooks */ + PtrBuf_Clear(); + pTest11->Func(obj3, obj600); + + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_ObjCCtor_Called(3), + new State_Func11(pTest11, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + NULL), "Test" "11" " Part1"); + g_Inside_LeafFunc = false; + + /* hook1 - no hooks */ + THGM_ADD_HOOK(11, 1); + + PtrBuf_Clear(); + pTest11->Func(obj3, obj600); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_ObjCCtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg_11(1, pTest11, 0, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Func11(pTest11, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjODtor_Called(3), + NULL), "Test" "11" " Part2"); + g_Inside_LeafFunc = false; + + THGM_REMOVE_HOOK(11, 1); + + /* hook1, hook2 - hook3, hook4 */ + THGM_ADD_HOOK(11, 1); + THGM_ADD_HOOK(11, 2); + THGM_ADD_HOOK(11, 3); + THGM_ADD_HOOK(11, 4); + PtrBuf_Clear(); + pTest11->Func(obj3, obj600); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_ObjCCtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg_11(1, pTest11, 0, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg_11(2, pTest11, 1, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg_11(3, pTest11, 2, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg_11(4, pTest11, 3, ParamState_m11 (obj3, obj600)), + new State_ObjODtor_Called(3), + + new State_ObjODtor_Called(3), + NULL), "Test" "11" " Part3"); + g_Inside_LeafFunc = false; + + /* hook1 - hook3, hook4 WITH RECALLS */ + THGM_REMOVE_HOOK(11, 2); + PtrBuf_Clear(); + TestClass11::ms_DoRecall = true; + pTest11->Func(obj3, obj600); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_ObjCCtor_Called(3), + + new State_ObjCCtor_Called(3), + new State_Deleg_11(1, pTest11, 0 /* first deleg ptr */, ParamState_m11 (obj3, obj600)), + + // recall ! + // second hookfunc -> new copy + new State_ObjCCtor_Called(3), + + // in second hookfunc now + // -> calls orig func + + new State_ObjCCtor_Called(3), + new State_Func11(pTest11, ParamState_m11 (obj3, obj600)(1)), + new State_ObjODtor_Called(3), + + // calls first posthook + new State_ObjCCtor_Called(3), + new State_Deleg_11(3, pTest11, 1 /* second deleg ptr */, ParamState_m11 (obj3, obj600)(1)), + + // recall! + // third hookfunc -> new copy + new State_ObjCCtor_Called(3), + + // calls second posthook + + new State_ObjCCtor_Called(3), + new State_Deleg_11(4, pTest11, 2 /* third deleg ptr */, ParamState_m11 (obj3, obj600)(2)), + + // recall! + // fourth hookfunc -> new copy + new State_ObjCCtor_Called(3), + + // has nothing to do though! + + // fourth hookfunc done -> ret + new State_ObjODtor_Called(3), + + // third hookfunc done -> ret + new State_ObjODtor_Called(3), + // ret from hookhandler which did the recall + new State_ObjODtor_Called(3), + + // second hookfunc done -> ret + new State_ObjODtor_Called(3), + // ret from hookhandler which did the recall + new State_ObjODtor_Called(3), + + // deleg1's instance + new State_ObjODtor_Called(3), + // first hookfunc done -> ret + new State_ObjODtor_Called(3), + NULL), "Test" "11" " Part4"); + g_Inside_LeafFunc = false; + + THGM_REMOVE_HOOK(11, 1); + THGM_REMOVE_HOOK(11, 3); + THGM_REMOVE_HOOK(11, 4); + + delete obj3_real; + delete obj600_real; + + CHECK_STATES((&g_States, + new State_ObjODtor_Called(3), + new State_ObjODtor_Called(600), + NULL), "Test11 Part100"); + + return true; + } + + bool Tests3(std::string &error) + { + THGM_DO_TEST(101, ()); + + THGM_DO_TEST(102, ()); + + THGM_DO_TEST(103, ()); + + THGM_DO_TEST(104, ()); + + THGM_DO_TEST(105, ()); + + // pod returns + THGM_DO_TEST(106, (5)); + THGM_DO_TEST(107, (5)); + THGM_DO_TEST(108, (5)); + THGM_DO_TEST(109, (5)); + + return true; + } + + bool Tests4(std::string &error) + { + // Test110: Special: constructors/destructors on return + PtrBuf_Clear(); + ObjRet13 *obj13_real = new ObjRet13; + ObjRet13 &obj13 = *obj13_real; + + CHECK_STATES((&g_States, + new State_ObjOCtor_Called(13), + NULL), "Test110 Part0"); + + setuppi_110(); + setupri_110(); + + SourceHook::HookManagerPubFunc myhookman110 = g_HMAGPtr->MakeHookMan(protoinfo_110, 0, 0); \ + CAutoReleaseHookMan arhm_110(myhookman110); \ + int hook1_110, hook2_110, hook3_110, hook4_110; + + TestClass110 *pTest110 = new TestClass110; + CAutoPtrDestruction apd110(pTest110); + + /* no hooks - no hooks */ + PtrBuf_Clear(); + obj13 = pTest110->Func(5); + + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + new State_Func110(pTest110, ParamState_m110 (5)), + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in our stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack + new State_ObjODtor_Called(13), // Func110: destruction of temporary object + NULL), "Test" "110" " Part1"); + g_Inside_LeafFunc = false; + + /* hook1 - no hooks */ + THGM_ADD_HOOK(110, 1); + + PtrBuf_Clear(); + obj13 = pTest110->Func(5); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + // HookFunc: construct orig_ret/override_ret/plugin_ret objects + new State_ObjOCtor_Called(13), + new State_ObjOCtor_Called(13), + new State_ObjOCtor_Called(13), + + // Calling delegate + new State_Deleg_110(1, pTest110, 0, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // Calling orig function Func110 + new State_Func110(pTest110, ParamState_m110 (5)), + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: orig_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // hookfunc is returning: + new State_ObjCCtor_Called(13), // copy to temp object in our stack + + // hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret + new State_ObjODtor_Called(13), + new State_ObjODtor_Called(13), + new State_ObjODtor_Called(13), + + // we are in our function: assign + new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack + new State_ObjODtor_Called(13), // Func110: destruction of temporary object + + NULL), "Test" "11" " Part2"); + + CHECK_COND(obj13 == 0, "Test" "11" " Part 2.1"); + g_Inside_LeafFunc = false; + + THGM_REMOVE_HOOK(110, 1); + + /* hook1, hook2 - hook3, hook4 */ + THGM_ADD_HOOK(110, 1); + THGM_ADD_HOOK(110, 2); + THGM_ADD_HOOK(110, 3); + THGM_ADD_HOOK(110, 4); + + PtrBuf_Clear(); + obj13 = pTest110->Func(5); + g_Inside_LeafFunc = true; + CHECK_STATES((&g_States, + // HookFunc: construct orig_ret/override_ret/plugin_ret objects + new State_ObjOCtor_Called(13), + new State_ObjOCtor_Called(13), + new State_ObjOCtor_Called(13), + + // Calling delegate1 + new State_Deleg_110(1, pTest110, 0, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + + // Calling delegate2 + new State_Deleg_110(2, pTest110, 1, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret + new State_ObjAssignOp_Called(13), + + // SUPERCEDE -> orig function is not called + // instead: orig_ret = override_ret + new State_ObjAssignOp_Called(13), + + // Calling delegate3 + new State_Deleg_110(3, pTest110, 2, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // Calling delegate4 + new State_Deleg_110(4, pTest110, 3, ParamState_m110 (5)), + + new State_ObjOCtor_Called(13), // MakeRet: Construction of x + new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // MakeRet: Destruction of x + + // back in hookfunc + new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack + new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack + + // hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret (yes really, we overwrite the old value!) + new State_ObjAssignOp_Called(13), + + // hookfunc is returning: + new State_ObjCCtor_Called(13), // copy to temp object in our stack + + // hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret + new State_ObjODtor_Called(13), + new State_ObjODtor_Called(13), + new State_ObjODtor_Called(13), + + // we are in our function: assign + new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack + new State_ObjODtor_Called(13), // Func110: destruction of temporary object + + NULL), "Test" "11" " Part3"); + + CHECK_COND(obj13 == 4, "Test" "11" " Part 3.1"); + g_Inside_LeafFunc = false; + + THGM_REMOVE_HOOK(110, 1); + THGM_REMOVE_HOOK(110, 2); + THGM_REMOVE_HOOK(110, 3); + THGM_REMOVE_HOOK(110, 4); + + delete obj13_real; + + CHECK_STATES((&g_States, + new State_ObjODtor_Called(13), + NULL), "Test110 Part100"); + + return true; + } + + bool Tests5(std::string &error) + { + // RefRet + THGM_DO_TEST(111, ()); + + // Vafmt + + THGM_DO_TEST_void(200, ("Hello %s%d%s", "BA", 1, "L!")); + + THGM_DO_TEST_void(201, (100, "Hello %s%d%s", "BA", 1, "L!")); + + THGM_DO_TEST_void(203, (0x1F000000, "Hello %s%d%s", "BA", 1, "L!")); + + THGM_DO_TEST_void(206, (100, 0x1f00, 0x1f000000, 0.5f, 5.5, "Hello %s%d%s", "BA", 1, "L!")); + + char a = 5; + double b = 233.33; + THGM_DO_TEST_void(207, (a, b, "Hello %s%d%s", "BA", 1, "L!")); + + POD<7> pod7 = MakeRet< POD<7> >::Do(78); + THGM_DO_TEST_void(208, (pod7, "Hello %s%d%s", "BA", 1, "L!")); + + POD<600> pod600 = MakeRet< POD<600> >::Do(34); + THGM_DO_TEST_void(210, (pod600, "Hello %s%d%s", "BA", 1, "L!")); + + // Test for lange vtable indices + Hello *pHello = new Hello; + SourceHook::CProtoInfoBuilder helloPi(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::HookManagerPubFunc helloHM_4 = g_HMAGPtr->MakeHookMan(helloPi, 0, 4); + SourceHook::HookManagerPubFunc helloHM_79 = g_HMAGPtr->MakeHookMan(helloPi, 0, 79); + + pHello->Func4(); + pHello->Func79(); + SH_CALL(pHello, &Hello::Func4)(); + SH_CALL(pHello, &Hello::Func79)(); + CHECK_STATES((&g_States, + new State_Hello_Func4_Called, + new State_Hello_Func79_Called, + new State_Hello_Func4_Called, + new State_Hello_Func79_Called, + NULL), "Test" "Hello" " Part1"); + + int helloHook4 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pHello), + 0, helloHM_4, new Hello_Func4_Deleg, false); + + int helloHook79 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pHello), + 0, helloHM_79, new Hello_Func79_Deleg, false); + + pHello->Func4(); + pHello->Func79(); + SH_CALL(pHello, &Hello::Func4)(); + SH_CALL(pHello, &Hello::Func79)(); + + CHECK_STATES((&g_States, + new State_Hello_Func4_PreHook, + new State_Hello_Func4_Called, + new State_Hello_Func79_PreHook, + new State_Hello_Func79_Called, + new State_Hello_Func4_Called, + new State_Hello_Func79_Called, + NULL), "Test" "Hello" " Part2"); + + g_SHPtr->RemoveHookByID(helloHook4); + g_SHPtr->RemoveHookByID(helloHook79); + + g_HMAGPtr->ReleaseHookMan(helloHM_4); + g_HMAGPtr->ReleaseHookMan(helloHM_79); + + return true; + } } + bool TestHookManGen(std::string &error) { GET_SHPTR(g_SHPtr); @@ -582,441 +1062,16 @@ bool TestHookManGen(std::string &error) new State_ObjOCtor_Called(111), NULL), "GlobCtors"); - THGM_DO_TEST_void(0, ()); - - THGM_DO_TEST_void(1, (100)); - - THGM_DO_TEST_void(2, (0x1F00)); - - THGM_DO_TEST_void(3, (0x1F000000)); - - THGM_DO_TEST_void(4, (0.5f)); - - THGM_DO_TEST_void(5, (5.5)); - - THGM_DO_TEST_void(6, (100, 0x1f00, 0x1f000000, 0.5f, 5.5)); - - char a = 5; - double b = 233.33; - THGM_DO_TEST_void(7, (a, b)); - - POD<7> pod7 = MakeRet< POD<7> >::Do(78); - THGM_DO_TEST_void(8, (pod7)); - - POD<600> pod600 = MakeRet< POD<600> >::Do(34); - THGM_DO_TEST_void(9, (pod600)); - - THGM_DO_TEST_void(10, (pod600)); - - // Test11: Special: constructors/destructors - PtrBuf_Clear(); - Object<3> obj3(33); - Object<600> obj600(21); - - CHECK_STATES((&g_States, - new State_ObjOCtor_Called(3), - new State_ObjOCtor_Called(600), - NULL), "Test11 Part0"); - - setuppi_11(); - SourceHook::HookManagerPubFunc myhookman11 = g_HMAGPtr->MakeHookMan(protoinfo_11, 0, 0); \ - CAutoReleaseHookMan arhm_11(myhookman11); \ - int hook1_11, hook2_11, hook3_11, hook4_11; - - TestClass11 *pTest11 = new TestClass11; - CAutoPtrDestruction apd11(pTest11); - - /* no hooks - no hooks */ - PtrBuf_Clear(); - pTest11->Func(obj3, obj600); - - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_ObjCCtor_Called(3), - new State_Func11(pTest11, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - NULL), "Test" "11" " Part1"); - g_Inside_LeafFunc = false; - - /* hook1 - no hooks */ - THGM_ADD_HOOK(11, 1); - - PtrBuf_Clear(); - pTest11->Func(obj3, obj600); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_ObjCCtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg1_11(pTest11, 0, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Func11(pTest11, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjODtor_Called(3), - NULL), "Test" "11" " Part2"); - g_Inside_LeafFunc = false; - - THGM_REMOVE_HOOK(11, 1); - - /* hook1, hook2 - hook3, hook4 */ - THGM_ADD_HOOK(11, 1); - THGM_ADD_HOOK(11, 2); - THGM_ADD_HOOK(11, 3); - THGM_ADD_HOOK(11, 4); - PtrBuf_Clear(); - pTest11->Func(obj3, obj600); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_ObjCCtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg1_11(pTest11, 0, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg2_11(pTest11, 1, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg3_11(pTest11, 2, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg4_11(pTest11, 3, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjODtor_Called(3), - NULL), "Test" "11" " Part3"); - g_Inside_LeafFunc = false; - - /* hook1 - hook3, hook4 WITH RECALLS */ - THGM_REMOVE_HOOK(11, 2); - PtrBuf_Clear(); - TestClass11::ms_DoRecall = true; - pTest11->Func(obj3, obj600); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_ObjCCtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg1_11(pTest11, 0 /* first deleg ptr */, ParamState_m11 (obj3, obj600)), - - // recall ! - // second hookfunc -> new copy - new State_ObjCCtor_Called(3), - - // in second hookfunc now - // -> calls orig func - - new State_ObjCCtor_Called(3), - new State_Func11(pTest11, ParamState_m11 (obj3, obj600)(1)), - new State_ObjODtor_Called(3), - - // calls first posthook - new State_ObjCCtor_Called(3), - new State_Deleg3_11(pTest11, 1 /* second deleg ptr */, ParamState_m11 (obj3, obj600)(1)), - - // recall! - // third hookfunc -> new copy - new State_ObjCCtor_Called(3), - - // calls second posthook - - new State_ObjCCtor_Called(3), - new State_Deleg4_11(pTest11, 2 /* third deleg ptr */, ParamState_m11 (obj3, obj600)(2)), - - // recall! - // fourth hookfunc -> new copy - new State_ObjCCtor_Called(3), - - // has nothing to do though! - - // fourth hookfunc done -> ret - new State_ObjODtor_Called(3), - - // third hookfunc done -> ret - new State_ObjODtor_Called(3), - // ret from hookhandler which did the recall - new State_ObjODtor_Called(3), - - // second hookfunc done -> ret - new State_ObjODtor_Called(3), - // ret from hookhandler which did the recall - new State_ObjODtor_Called(3), - - // deleg1's instance - new State_ObjODtor_Called(3), - // first hookfunc done -> ret - new State_ObjODtor_Called(3), - NULL), "Test" "11" " Part4"); - g_Inside_LeafFunc = false; - - THGM_REMOVE_HOOK(11, 1); - THGM_REMOVE_HOOK(11, 3); - THGM_REMOVE_HOOK(11, 4); - - THGM_DO_TEST(101, ()); - - THGM_DO_TEST(102, ()); - - THGM_DO_TEST(103, ()); - - THGM_DO_TEST(104, ()); - - THGM_DO_TEST(105, ()); - - // pod returns - THGM_DO_TEST(106, (5)); - THGM_DO_TEST(107, (5)); - THGM_DO_TEST(108, (5)); - THGM_DO_TEST(109, (5)); - - // Test110: Special: constructors/destructors on return - PtrBuf_Clear(); - ObjRet13 obj13; - - CHECK_STATES((&g_States, - new State_ObjOCtor_Called(13), - NULL), "Test110 Part0"); - - setuppi_110(); - setupri_110(); - - SourceHook::HookManagerPubFunc myhookman110 = g_HMAGPtr->MakeHookMan(protoinfo_110, 0, 0); \ - CAutoReleaseHookMan arhm_110(myhookman110); \ - int hook1_110, hook2_110, hook3_110, hook4_110; - - TestClass110 *pTest110 = new TestClass110; - CAutoPtrDestruction apd110(pTest110); - - /* no hooks - no hooks */ - PtrBuf_Clear(); - obj13 = pTest110->Func(5); - - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_Func110(pTest110, ParamState_m110 (5)), - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in our stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack - new State_ObjODtor_Called(13), // Func110: destruction of temporary object - NULL), "Test" "110" " Part1"); - g_Inside_LeafFunc = false; - - /* hook1 - no hooks */ - THGM_ADD_HOOK(110, 1); - - PtrBuf_Clear(); - obj13 = pTest110->Func(5); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - // HookFunc: construct orig_ret/override_ret/plugin_ret objects - new State_ObjOCtor_Called(13), - new State_ObjOCtor_Called(13), - new State_ObjOCtor_Called(13), - - // Calling delegate - new State_Deleg1_110(pTest110, 0, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // Calling orig function Func110 - new State_Func110(pTest110, ParamState_m110 (5)), - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: orig_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // hookfunc is returning: - new State_ObjCCtor_Called(13), // copy to temp object in our stack - - // hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret - new State_ObjODtor_Called(13), - new State_ObjODtor_Called(13), - new State_ObjODtor_Called(13), - - // we are in our function: assign - new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack - new State_ObjODtor_Called(13), // Func110: destruction of temporary object - - NULL), "Test" "11" " Part2"); - - CHECK_COND(obj13 == 0, "Test" "11" " Part 2.1"); - g_Inside_LeafFunc = false; - - THGM_REMOVE_HOOK(11, 1); - - /* hook1, hook2 - hook3, hook4 */ - THGM_ADD_HOOK(110, 1); - THGM_ADD_HOOK(110, 2); - THGM_ADD_HOOK(110, 3); - THGM_ADD_HOOK(110, 4); - - PtrBuf_Clear(); - obj13 = pTest110->Func(5); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - // HookFunc: construct orig_ret/override_ret/plugin_ret objects - new State_ObjOCtor_Called(13), - new State_ObjOCtor_Called(13), - new State_ObjOCtor_Called(13), - - // Calling delegate1 - new State_Deleg1_110(pTest110, 0, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - - // Calling delegate2 - new State_Deleg2_110(pTest110, 1, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret - new State_ObjAssignOp_Called(13), - - // SUPERCEDE -> orig function is not called - // instead: orig_ret = override_ret - new State_ObjAssignOp_Called(13), - - // Calling delegate3 - new State_Deleg3_110(pTest110, 2, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // Calling delegate4 - new State_Deleg4_110(pTest110, 3, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret (yes really, we overwrite the old value!) - new State_ObjAssignOp_Called(13), - - // hookfunc is returning: - new State_ObjCCtor_Called(13), // copy to temp object in our stack - - // hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret - new State_ObjODtor_Called(13), - new State_ObjODtor_Called(13), - new State_ObjODtor_Called(13), - - // we are in our function: assign - new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack - new State_ObjODtor_Called(13), // Func110: destruction of temporary object - - NULL), "Test" "11" " Part3"); - - CHECK_COND(obj13 == 4, "Test" "11" " Part 3.1"); - g_Inside_LeafFunc = false; - - THGM_REMOVE_HOOK(110, 1); - THGM_REMOVE_HOOK(110, 2); - THGM_REMOVE_HOOK(110, 3); - THGM_REMOVE_HOOK(110, 4); - - - // RefRet - THGM_DO_TEST(111, ()); - - // Vafmt - - THGM_DO_TEST_void(200, ("Hello %s%d%s", "BA", 1, "L!")); - - THGM_DO_TEST_void(201, (100, "Hello %s%d%s", "BA", 1, "L!")); - - THGM_DO_TEST_void(203, (0x1F000000, "Hello %s%d%s", "BA", 1, "L!")); - - THGM_DO_TEST_void(206, (100, 0x1f00, 0x1f000000, 0.5f, 5.5, "Hello %s%d%s", "BA", 1, "L!")); - - a = 5; - b = 233.33; - THGM_DO_TEST_void(207, (a, b, "Hello %s%d%s", "BA", 1, "L!")); - - pod7 = MakeRet< POD<7> >::Do(78); - THGM_DO_TEST_void(208, (pod7, "Hello %s%d%s", "BA", 1, "L!")); - - THGM_DO_TEST_void(210, (pod600, "Hello %s%d%s", "BA", 1, "L!")); - - // Test for lange vtable indices - Hello *pHello = new Hello; - SourceHook::CProtoInfoBuilder helloPi(SourceHook::ProtoInfo::CallConv_ThisCall); - SourceHook::HookManagerPubFunc helloHM_4 = g_HMAGPtr->MakeHookMan(helloPi, 0, 4); - SourceHook::HookManagerPubFunc helloHM_79 = g_HMAGPtr->MakeHookMan(helloPi, 0, 79); - - pHello->Func4(); - pHello->Func79(); - SH_CALL(pHello, &Hello::Func4)(); - SH_CALL(pHello, &Hello::Func79)(); - CHECK_STATES((&g_States, - new State_Hello_Func4_Called, - new State_Hello_Func79_Called, - new State_Hello_Func4_Called, - new State_Hello_Func79_Called, - NULL), "Test" "Hello" " Part1"); - - int helloHook4 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pHello), - 0, helloHM_4, new Hello_Func4_Deleg, false); - - int helloHook79 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pHello), - 0, helloHM_79, new Hello_Func79_Deleg, false); - - pHello->Func4(); - pHello->Func79(); - SH_CALL(pHello, &Hello::Func4)(); - SH_CALL(pHello, &Hello::Func79)(); - - CHECK_STATES((&g_States, - new State_Hello_Func4_PreHook, - new State_Hello_Func4_Called, - new State_Hello_Func79_PreHook, - new State_Hello_Func79_Called, - new State_Hello_Func4_Called, - new State_Hello_Func79_Called, - NULL), "Test" "Hello" " Part2"); - - g_SHPtr->RemoveHookByID(helloHook4); - g_SHPtr->RemoveHookByID(helloHook79); - - g_HMAGPtr->ReleaseHookMan(helloHM_4); - g_HMAGPtr->ReleaseHookMan(helloHM_79); + if (!Tests1(error)) + return false; + if (!Tests2(error)) + return false; + if (!Tests3(error)) + return false; + if (!Tests4(error)) + return false; + if (!Tests5(error)) + return false; // Shutdown now! // If we don't SH will auto-shutdown _after_ genc's destructor is called diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index 32c12d5..835532f 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -507,10 +507,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState0<0 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -523,70 +520,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call() \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ()); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, ()); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -598,10 +550,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, typedef ret_type RetType##id; \ typedef ParamState0<0 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -616,70 +565,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, return MakeRet< ret_type >::Do(0); \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual ret_type Call() \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, ()); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, ()); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -689,10 +593,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState1<0, std::string > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -713,169 +614,30 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(const char *buf) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ("%s!", buf)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, ("%s!", buf)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ("%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ("%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, ("%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST0_vafmt(id, ret_type) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState0<0 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate1 : public MyDelegate \ - { \ - virtual ret_type Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ - } \ - }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) - - #define THGM_SETUP_PI0(id) \ void setuppi_##id() \ { \ @@ -888,10 +650,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState1<0, param1 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -904,70 +663,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -979,10 +693,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, typedef ret_type RetType##id; \ typedef ParamState1<0, param1 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -997,70 +708,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, return MakeRet< ret_type >::Do(0); \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual ret_type Call(param1 p1) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1)); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -1070,10 +736,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState2<0, param1, std::string > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -1094,169 +757,30 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, const char *buf) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, "%s!", buf)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, "%s!", buf)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST1_vafmt(id, ret_type, param1) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState1<0, param1 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate1 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ - } \ - }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) - - #define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ void setuppi_##id() \ { \ @@ -1276,10 +800,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState2<0, param1, param2 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -1292,70 +813,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -1367,10 +843,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, typedef ret_type RetType##id; \ typedef ParamState2<0, param1, param2 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -1385,70 +858,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, return MakeRet< ret_type >::Do(0); \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual ret_type Call(param1 p1, param2 p2) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2)); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -1458,10 +886,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState3<0, param1, param2, std::string > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -1482,169 +907,30 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, const char *buf) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST2_vafmt(id, ret_type, param1, param2) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState2<0, param1, param2 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate1 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ - } \ - }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) - - #define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ void setuppi_##id() \ { \ @@ -1671,10 +957,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -1687,70 +970,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, param3 p3) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -1762,10 +1000,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, typedef ret_type RetType##id; \ typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -1780,70 +1015,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, return MakeRet< ret_type >::Do(0); \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3)); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -1853,10 +1043,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState4<0, param1, param2, param3, std::string > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -1877,169 +1064,30 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST3_vafmt(id, ret_type, param1, param2, param3) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate1 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ - } \ - }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) - - #define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ void setuppi_##id() \ { \ @@ -2073,10 +1121,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -2089,70 +1134,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -2164,10 +1164,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, typedef ret_type RetType##id; \ typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -2182,70 +1179,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, return MakeRet< ret_type >::Do(0); \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4)); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -2255,10 +1207,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState5<0, param1, param2, param3, param4, std::string > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -2279,169 +1228,30 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST4_vafmt(id, ret_type, param1, param2, param3, param4) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate1 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ - } \ - }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) - - #define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ void setuppi_##id() \ { \ @@ -2482,10 +1292,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -2498,70 +1305,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -2573,10 +1335,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, typedef ret_type RetType##id; \ typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -2591,70 +1350,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, return MakeRet< ret_type >::Do(0); \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -2664,10 +1378,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState6<0, param1, param2, param3, param4, param5, std::string > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -2688,169 +1399,30 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST5_vafmt(id, ret_type, param1, param2, param3, param4, param5) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate1 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ - } \ - }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) - - #define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ void setuppi_##id() \ { \ @@ -2898,10 +1470,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -2914,70 +1483,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -2989,10 +1513,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, typedef ret_type RetType##id; \ typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -3007,70 +1528,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, return MakeRet< ret_type >::Do(0); \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -3080,10 +1556,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, struct TestClass##id; \ typedef ParamState7<0, param1, param2, param3, param4, param5, param6, std::string > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -3104,169 +1577,30 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST6_vafmt(id, ret_type, param1, param2, param3, param4, param5, param6) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate1 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ - } \ - }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) - - #define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ void setuppi_##id() \ { \ @@ -3330,7 +1664,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, #define THGM_ADD_HOOK(id, num) \ CAT4(hook, num, _, id) = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pTest##id), \ - 0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate##num), num >= 3); + 0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate(num)), num >= 3); #define THGM_REMOVE_HOOK(id, num) \ g_SHPtr->RemoveHookByID(CAT4(hook, num, _, id)); @@ -3356,28 +1690,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, new State_Func##id(pTest##id, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part1"); \ - \ - /* hook1 - no hooks */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part2"); \ - THGM_REMOVE_HOOK(id, 1); \ - \ - /* no hooks - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part3"); \ - THGM_REMOVE_HOOK(id, 3); \ \ /* hook1 - hook3 */ \ PtrBuf_Clear(); \ @@ -3385,9 +1697,9 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, THGM_ADD_HOOK(id, 3); \ THGM_CALLS_void(id, call_params); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part4"); \ THGM_REMOVE_HOOK(id, 1); \ @@ -3400,26 +1712,19 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, THGM_ADD_HOOK(id, 3); \ THGM_CALLS_void(id, call_params); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part5"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 2); \ - THGM_REMOVE_HOOK(id, 3); \ /* hook1, hook2 - hook3, hook4 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 2); \ - THGM_ADD_HOOK(id, 3); \ THGM_ADD_HOOK(id, 4); \ THGM_CALLS_void(id, call_params); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ - new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part6"); \ \ @@ -3429,10 +1734,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, THGM_REMOVE_HOOK(id, 2); \ THGM_CALLS_void(id, call_params); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params(0)), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \ new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params(1)), \ - new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params(2)), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \ + new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \ /* sh_call one */ \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part7"); \ @@ -3474,28 +1779,6 @@ T* ComparableRef(T& x) new State_Func##id(pTest##id, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part1"); \ - \ - /* hook1 - no hooks */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_CALLS(id, call_params, 0, 0, "Part2"); \ - CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part2"); \ - THGM_REMOVE_HOOK(id, 1); \ - \ - /* no hooks - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS(id, call_params, 0, 0, "Part3"); \ - CHECK_STATES((&g_States, \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part3"); \ - THGM_REMOVE_HOOK(id, 3); \ \ /* hook1 - hook3 */ \ PtrBuf_Clear(); \ @@ -3503,9 +1786,9 @@ T* ComparableRef(T& x) THGM_ADD_HOOK(id, 3); \ THGM_CALLS(id, call_params, 0, 0, "Part4"); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part4"); \ THGM_REMOVE_HOOK(id, 1); \ @@ -3518,26 +1801,19 @@ T* ComparableRef(T& x) THGM_ADD_HOOK(id, 3); \ THGM_CALLS(id, call_params, 2, 0, "Part5"); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part5"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 2); \ - THGM_REMOVE_HOOK(id, 3); \ /* hook1, hook2 - hook3, hook4 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 2); \ - THGM_ADD_HOOK(id, 3); \ THGM_ADD_HOOK(id, 4); \ THGM_CALLS(id, call_params, 4, 0, "Part6"); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ - new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part6"); \ \ @@ -3547,10 +1823,10 @@ T* ComparableRef(T& x) THGM_REMOVE_HOOK(id, 2); \ THGM_CALLS(id, call_params, 4, 0, "Part7"); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params(0)), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \ new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params(1)), \ - new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params(2)), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \ + new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \ /* sh_call one */ \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part7"); \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 8b94fd3..7941ef5 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -203,10 +203,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] struct TestClass##id; \ typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -219,70 +216,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS(MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -294,10 +246,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] typedef ret_type RetType##id; \ typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -312,70 +261,25 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] return MakeRet< ret_type >::Do(0); \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ } \ else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ @@ -385,10 +289,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] struct TestClass##id; \ typedef ParamState@($1+1)<0@[$2,1,$1:, param$2@], std::string > ParamState_m##id; \ MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ \ struct TestClass##id \ { \ @@ -409,169 +310,30 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] g_Inside_LeafFunc = false; \ } \ \ - struct Delegate1 : public MyDelegate \ + struct Delegate : public MyDelegate \ { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ { \ g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ g_Inside_LeafFunc = false; \ if (ms_DoRecall) \ { \ @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ + RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ } \ else \ - RETURN_META(MRES_IGNORED); \ + RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ } \ }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_IGNORED); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS(MRES_IGNORED, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ - } \ - else \ - RETURN_META(MRES_SUPERCEDE); \ - }; \ - }; \ }; \ \ bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST$1_vafmt(id, ret_type@[$2,1,$1:, param$2@]) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg1_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg2_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg3_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - MAKE_STATE_3(State_Deleg4_##id, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate1 : public MyDelegate \ - { \ - virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg1_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(1), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(1)); \ - } \ - }; \ - struct Delegate2 : public MyDelegate \ - { \ - virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg2_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(2)); \ - } \ - }; \ - struct Delegate3 : public MyDelegate \ - { \ - virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg3_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet< ret_type >::Do(3), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META_VALUE(MRES_IGNORED, MakeRet< ret_type >::Do(3)); \ - } \ - }; \ - struct Delegate4 : public MyDelegate \ - { \ - virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg4_##id(META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet< ret_type >::Do(4)); \ - }; \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall) - - #define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ void setuppi_##id() \ { \ @@ -600,7 +362,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] #define THGM_ADD_HOOK(id, num) \ CAT4(hook, num, _, id) = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pTest##id), \ - 0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate##num), num >= 3); + 0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate(num)), num >= 3); #define THGM_REMOVE_HOOK(id, num) \ g_SHPtr->RemoveHookByID(CAT4(hook, num, _, id)); @@ -626,28 +388,6 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] new State_Func##id(pTest##id, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part1"); \ - \ - /* hook1 - no hooks */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part2"); \ - THGM_REMOVE_HOOK(id, 1); \ - \ - /* no hooks - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part3"); \ - THGM_REMOVE_HOOK(id, 3); \ \ /* hook1 - hook3 */ \ PtrBuf_Clear(); \ @@ -655,9 +395,9 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] THGM_ADD_HOOK(id, 3); \ THGM_CALLS_void(id, call_params); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part4"); \ THGM_REMOVE_HOOK(id, 1); \ @@ -670,26 +410,19 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] THGM_ADD_HOOK(id, 3); \ THGM_CALLS_void(id, call_params); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part5"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 2); \ - THGM_REMOVE_HOOK(id, 3); \ /* hook1, hook2 - hook3, hook4 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 2); \ - THGM_ADD_HOOK(id, 3); \ THGM_ADD_HOOK(id, 4); \ THGM_CALLS_void(id, call_params); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ - new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part6"); \ \ @@ -699,10 +432,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] THGM_REMOVE_HOOK(id, 2); \ THGM_CALLS_void(id, call_params); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params(0)), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \ new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params(1)), \ - new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params(2)), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \ + new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \ /* sh_call one */ \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part7"); \ @@ -744,28 +477,6 @@ T* ComparableRef(T& x) new State_Func##id(pTest##id, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part1"); \ - \ - /* hook1 - no hooks */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_CALLS(id, call_params, 0, 0, "Part2"); \ - CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part2"); \ - THGM_REMOVE_HOOK(id, 1); \ - \ - /* no hooks - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS(id, call_params, 0, 0, "Part3"); \ - CHECK_STATES((&g_States, \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part3"); \ - THGM_REMOVE_HOOK(id, 3); \ \ /* hook1 - hook3 */ \ PtrBuf_Clear(); \ @@ -773,9 +484,9 @@ T* ComparableRef(T& x) THGM_ADD_HOOK(id, 3); \ THGM_CALLS(id, call_params, 0, 0, "Part4"); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part4"); \ THGM_REMOVE_HOOK(id, 1); \ @@ -788,26 +499,19 @@ T* ComparableRef(T& x) THGM_ADD_HOOK(id, 3); \ THGM_CALLS(id, call_params, 2, 0, "Part5"); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part5"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 2); \ - THGM_REMOVE_HOOK(id, 3); \ /* hook1, hook2 - hook3, hook4 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 2); \ - THGM_ADD_HOOK(id, 3); \ THGM_ADD_HOOK(id, 4); \ THGM_CALLS(id, call_params, 4, 0, "Part6"); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg2_##id(pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params), \ - new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ + new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ + new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part6"); \ \ @@ -817,10 +521,10 @@ T* ComparableRef(T& x) THGM_REMOVE_HOOK(id, 2); \ THGM_CALLS(id, call_params, 4, 0, "Part7"); \ CHECK_STATES((&g_States, \ - new State_Deleg1_##id(pTest##id, 0, ParamState_m##id call_params(0)), \ + new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \ new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ - new State_Deleg3_##id(pTest##id, 2, ParamState_m##id call_params(1)), \ - new State_Deleg4_##id(pTest##id, 3, ParamState_m##id call_params(2)), \ + new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \ + new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \ /* sh_call one */ \ new State_Func##id(pTest##id, ParamState_m##id call_params), \ NULL), "Test" #id " Part7"); \ From 84a87208ac15e72ca7b1b8492531a106bc53aa25 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Mon, 19 Nov 2007 13:39:44 +0000 Subject: [PATCH 28/41] Added test for an void (int, double, int) function (in case doubles are aligned on an 8-byte boundary and we don't know about it) Added tests for vafmt functions with non-void return types (basic, float, object) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40567 --- sourcehook/test/testhookmangen.cpp | 34 +++ sourcehook/test/testhookmangen.h | 357 +++++++++++++++++++++++++++++ sourcehook/test/testhookmangen.hxx | 51 +++++ 3 files changed, 442 insertions(+) diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 4ac57a5..2cc8953 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -422,6 +422,12 @@ namespace SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); + THGM_MAKE_TEST3_void(150, int, double, int); + THGM_SETUP_PI3(150, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, + double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + // vafmt tests THGM_MAKE_TEST0_vafmt_void(200); THGM_SETUP_PI0(200); @@ -453,6 +459,25 @@ namespace THGM_MAKE_TEST1_vafmt_void(210, POD<600> &); THGM_SETUP_PI1(210, POD<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef) + THGM_MAKE_TEST1_vafmt(211, int, int); + THGM_SETUP_PI1(211, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal + ); + THGM_SETUP_RI(211, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_vafmt(212, double, int); + THGM_SETUP_PI1(212, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal + ); + THGM_SETUP_RI(212, float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); + + THGM_MAKE_TEST1_vafmt(213, PodRet8, int); + THGM_SETUP_PI1(213, + int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal + ); + THGM_SETUP_RI(213, PodRet8, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + + MAKE_STATE(State_Hello_Func4_Called); MAKE_STATE(State_Hello_Func79_Called); @@ -971,6 +996,9 @@ namespace new State_ObjODtor_Called(13), NULL), "Test110 Part100"); + + THGM_DO_TEST_void(150, (5, 5.5, 6)); + return true; } @@ -999,6 +1027,12 @@ namespace POD<600> pod600 = MakeRet< POD<600> >::Do(34); THGM_DO_TEST_void(210, (pod600, "Hello %s%d%s", "BA", 1, "L!")); + + THGM_DO_TEST(211, (5, "Hello %s%d%s", "BA", 1, "L!")); + THGM_DO_TEST(212, (5, "Hello %s%d%s", "BA", 1, "L!")); + THGM_DO_TEST(213, (5, "Hello %s%d%s", "BA", 1, "L!")); + + // Test for lange vtable indices Hello *pHello = new Hello; SourceHook::CProtoInfoBuilder helloPi(SourceHook::ProtoInfo::CallConv_ThisCall); diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index 835532f..d0faad5 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -638,6 +638,57 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); +#define THGM_MAKE_TEST0_vafmt(id, ret_type) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState1<0, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(std::string(buf)))); \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate : public MyDelegate \ + { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ + virtual ret_type Call(const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, ("%s!", buf)); \ + } \ + else \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ + } \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + #define THGM_SETUP_PI0(id) \ void setuppi_##id() \ { \ @@ -781,6 +832,57 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); +#define THGM_MAKE_TEST1_vafmt(id, ret_type, param1) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState2<0, param1, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, std::string(buf)))); \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate : public MyDelegate \ + { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ + virtual ret_type Call(param1 p1, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, "%s!", buf)); \ + } \ + else \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ + } \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + #define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ void setuppi_##id() \ { \ @@ -931,6 +1033,57 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); +#define THGM_MAKE_TEST2_vafmt(id, ret_type, param1, param2) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState3<0, param1, param2, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, std::string(buf)))); \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate : public MyDelegate \ + { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ + virtual ret_type Call(param1 p1, param2 p2, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, "%s!", buf)); \ + } \ + else \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ + } \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + #define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ void setuppi_##id() \ { \ @@ -1088,6 +1241,57 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); +#define THGM_MAKE_TEST3_vafmt(id, ret_type, param1, param2, param3) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState4<0, param1, param2, param3, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, std::string(buf)))); \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate : public MyDelegate \ + { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ + } \ + else \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ + } \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + #define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ void setuppi_##id() \ { \ @@ -1252,6 +1456,57 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); +#define THGM_MAKE_TEST4_vafmt(id, ret_type, param1, param2, param3, param4) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState5<0, param1, param2, param3, param4, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, std::string(buf)))); \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate : public MyDelegate \ + { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ + } \ + else \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ + } \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + #define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ void setuppi_##id() \ { \ @@ -1423,6 +1678,57 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); +#define THGM_MAKE_TEST5_vafmt(id, ret_type, param1, param2, param3, param4, param5) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState6<0, param1, param2, param3, param4, param5, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, std::string(buf)))); \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate : public MyDelegate \ + { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ + } \ + else \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ + } \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + #define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ void setuppi_##id() \ { \ @@ -1601,6 +1907,57 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); +#define THGM_MAKE_TEST6_vafmt(id, ret_type, param1, param2, param3, param4, param5, param6) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState7<0, param1, param2, param3, param4, param5, param6, std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6, std::string(buf)))); \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate : public MyDelegate \ + { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ + virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ + } \ + else \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ + } \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + #define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ void setuppi_##id() \ { \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index 7941ef5..cf6bd79 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -334,6 +334,57 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] bool TestClass##id::ms_DoRecall = false; \ SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); +#define THGM_MAKE_TEST$1_vafmt(id, ret_type@[$2,1,$1:, param$2@]) \ + struct TestClass##id; \ + typedef ret_type RetType##id; \ + typedef ParamState@($1+1)<0@[$2,1,$1:, param$2@], std::string > ParamState_m##id; \ + MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ + MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ + \ + struct TestClass##id \ + { \ + static bool ms_DoRecall; \ + \ + virtual ret_type Func(@[$2,1,$1:param$2 p$2, @]const char *fmt, ...) \ + { \ + g_Inside_LeafFunc = true; \ + \ + char buf[9999]; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(buf, 9998, fmt, ap); \ + buf[9998] = 0; \ + va_end(ap); \ + \ + ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1:p$2, @]std::string(buf)))); \ + \ + return MakeRet< ret_type >::Do(0); \ + } \ + \ + struct Delegate : public MyDelegate \ + { \ + int m_DelegNumber; \ + Delegate(int num) : m_DelegNumber(num) { } \ + \ + virtual ret_type Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ + { \ + g_Inside_LeafFunc = true; \ + ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ + g_Inside_LeafFunc = false; \ + if (ms_DoRecall) \ + { \ + @[$2,1,$1:Increment::type>::Incr(p$2);@] \ + RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ + } \ + else \ + RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ + } \ + }; \ + }; \ + \ + bool TestClass##id::ms_DoRecall = false; \ + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + #define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ void setuppi_##id() \ { \ From 524e0f16295b32276e41edc5844a3b06c9518c60 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Mon, 19 Nov 2007 14:36:42 +0000 Subject: [PATCH 29/41] Fixed vafmt/nonvoid test vafmt/nonvoid now works on msvc --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40568 --- sourcehook/sourcehook_hookmangen.cpp | 61 +++++++++++++++++++++------- sourcehook/test/testhookmangen.cpp | 2 +- sourcehook/test/testhookmangen.h | 14 +++---- sourcehook/test/testhookmangen.hxx | 2 +- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 96d5430..02683be 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -207,12 +207,6 @@ namespace SourceHook acc += GetStackSize(m_Proto.GetParam(i)); } - // Memory return: address is first param - if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - acc += SIZE_PTR; - - // :TODO: cdecl: THIS POINTER AS FIRST PARAM!!! - return acc; } @@ -1030,13 +1024,28 @@ namespace SourceHook // thisptr IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); - if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) + if (SH_COMP == SH_COMP_GCC) { - // on gcc/mingw or msvc with varargs, this is the first parameter + // on gcc/mingw, this is the first parameter IA32_Push_Reg(&m_HookFunc, REG_ECX); // on msvc without varargs, simply leave it in ecx + + // actually, if we're returning in memory, this pointer is the second param + // and the memret pointer is the real first parameter + caller_clean_bytes += PushMemRetPtr(v_orig_ret, v_place_for_memret); + } + else + { + // On msvc, if we're returning in memory, the memret pointer is the first parameter + caller_clean_bytes += PushMemRetPtr(v_orig_ret, v_place_for_memret); + + // actually, with varargs, the this pointer is the first param and the memret ptr + // is the second one + if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) + { + IA32_Push_Reg(&m_HookFunc, REG_ECX); + } } - caller_clean_bytes += PushMemRetPtr(v_orig_ret, v_place_for_memret); // call IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_vfnptr_origentry); @@ -1239,6 +1248,9 @@ namespace SourceHook IA32_Push_Reg(&m_HookFunc, REG_EBX); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EBP, REG_ESP, MOD_REG); + if ((m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) && (m_Proto.GetRet().type == PassInfo::PassType_Object)) + IA32_Int3(&m_HookFunc); + jit_int32_t v_this = 0; jit_int32_t param_base_offs = 0; if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) @@ -1303,7 +1315,7 @@ namespace SourceHook jit_int32_t v_memret_addr = 0; if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) { - if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) + if (SH_COMP == SH_COMP_GCC) { // gcc: now: first param = mem ret addr // second param = this pointer @@ -1312,10 +1324,25 @@ namespace SourceHook v_this += 4; param_base_offs += SIZE_PTR; } - else + else // MSVC { - v_memret_addr = param_base_offs; - param_base_offs += SIZE_PTR; + if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) + { + // varargs -> cdecl + // msvc: now: + // first param = this pointer + // second param = mem ret addr + // third param = actual first param + + // params_base_offs is already updated to point to after the this pointer + v_memret_addr = param_base_offs; + param_base_offs += SIZE_PTR; + } + else + { + v_memret_addr = param_base_offs; + param_base_offs += SIZE_PTR; + } } } @@ -1502,7 +1529,13 @@ namespace SourceHook { // msvc without varargs: // callee cleans the stack - IA32_Return_Popstack(&m_HookFunc, GetParamsStackSize()); + + short cleansize = GetParamsStackSize(); + // Memory return: address is first param + if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) + cleansize += SIZE_PTR; + + IA32_Return_Popstack(&m_HookFunc, cleansize); } else { diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 2cc8953..14e4e52 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -469,7 +469,7 @@ namespace THGM_SETUP_PI1(212, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal ); - THGM_SETUP_RI(212, float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); + THGM_SETUP_RI(212, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); THGM_MAKE_TEST1_vafmt(213, PodRet8, int); THGM_SETUP_PI1(213, diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h index d0faad5..736894b 100644 --- a/sourcehook/test/testhookmangen.h +++ b/sourcehook/test/testhookmangen.h @@ -687,7 +687,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); #define THGM_SETUP_PI0(id) \ void setuppi_##id() \ @@ -881,7 +881,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); #define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ void setuppi_##id() \ @@ -1082,7 +1082,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); #define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ void setuppi_##id() \ @@ -1290,7 +1290,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); #define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ void setuppi_##id() \ @@ -1505,7 +1505,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); #define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ void setuppi_##id() \ @@ -1727,7 +1727,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); #define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ void setuppi_##id() \ @@ -1956,7 +1956,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, }; \ \ bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); #define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ void setuppi_##id() \ diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx index cf6bd79..8833eee 100644 --- a/sourcehook/test/testhookmangen.hxx +++ b/sourcehook/test/testhookmangen.hxx @@ -383,7 +383,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@] }; \ \ bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); + SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); #define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ void setuppi_##id() \ From 149638416d6ac0c266c645b4084e8f44394081bf Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Mon, 19 Nov 2007 14:41:31 +0000 Subject: [PATCH 30/41] Removed forgotten debug code --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40569 --- sourcehook/sourcehook_hookmangen.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 02683be..080b34b 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -1248,9 +1248,6 @@ namespace SourceHook IA32_Push_Reg(&m_HookFunc, REG_EBX); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EBP, REG_ESP, MOD_REG); - if ((m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) && (m_Proto.GetRet().type == PassInfo::PassType_Object)) - IA32_Int3(&m_HookFunc); - jit_int32_t v_this = 0; jit_int32_t param_base_offs = 0; if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) From 07d38f007bfc04935ce24545d0f18f04759064d0 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 23 Nov 2007 15:08:44 +0000 Subject: [PATCH 31/41] Fixed problems with object with dtor params on gcc --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40570 --- sourcehook/test/testhookmangen.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 14e4e52..6dd5205 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -30,6 +30,7 @@ namespace SourceHook::List g_PtrHash; bool g_Inside_LeafFunc = false; // inside a hook or a func + bool g_Silent_CtorDtor = false; // inside a hook or a func // POD / Object types @@ -74,32 +75,32 @@ namespace Object(char initch) { memset(reinterpret_cast(x), initch, MYSIZE); - if (!g_Inside_LeafFunc) + if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) ADD_STATE(State_ObjOCtor_Called(MYSIZE)); } Object() { - if (!g_Inside_LeafFunc) + if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) ADD_STATE(State_ObjOCtor_Called(MYSIZE)); } Object(const Object & other) { memcpy(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE); - if (!g_Inside_LeafFunc) + if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) ADD_STATE(State_ObjCCtor_Called(MYSIZE)); } ~Object() { - if (!g_Inside_LeafFunc) + if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) ADD_STATE(State_ObjODtor_Called(MYSIZE)); } Object & operator = (const Object &other) { - if (!g_Inside_LeafFunc) + if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) ADD_STATE(State_ObjAssignOp_Called(MYSIZE)); memcpy(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE); @@ -477,6 +478,11 @@ namespace ); THGM_SETUP_RI(213, PodRet8, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); + THGM_MAKE_TEST1_vafmt_void(214, Object<133>); + THGM_SETUP_PI1(214, Object<133>, SourceHook::PassInfo::PassType_Object, + SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | + SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); + MAKE_STATE(State_Hello_Func4_Called); MAKE_STATE(State_Hello_Func79_Called); @@ -1032,8 +1038,14 @@ namespace THGM_DO_TEST(212, (5, "Hello %s%d%s", "BA", 1, "L!")); THGM_DO_TEST(213, (5, "Hello %s%d%s", "BA", 1, "L!")); + // Silence Object's ctors/dtors: we only want a forced byref param + g_Silent_CtorDtor = true; + Object<133> *myobj133 = new Object<133>; + THGM_DO_TEST_void(214, (*myobj133, "Hello %s%d%s", "BA", 1, "L!")); + delete myobj133; + g_Silent_CtorDtor = false; - // Test for lange vtable indices + // Test for high vtable indices Hello *pHello = new Hello; SourceHook::CProtoInfoBuilder helloPi(SourceHook::ProtoInfo::CallConv_ThisCall); SourceHook::HookManagerPubFunc helloHM_4 = g_HMAGPtr->MakeHookMan(helloPi, 0, 4); From a0cbabed06bd3dd227682f89329bdbb4d89f8551 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 23 Nov 2007 15:09:36 +0000 Subject: [PATCH 32/41] Fixed problems with object params on gcc when object has a destructor (forcedbyref) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40571 --- sourcehook/sourcehook_hookmangen.cpp | 44 +++++++++++++++------------- sourcehook/sourcehook_hookmangen.h | 7 +++-- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 080b34b..a3f4449 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -126,21 +126,25 @@ namespace SourceHook jit_int32_t GenContext::GetRealSize(const IntPassInfo &info) { - if (info.flags & PassInfo::PassFlag_ByRef) + if (info.flags & (PassInfo::PassFlag_ByRef | PassFlag_ForcedByRef)) { return SIZE_PTR; } return static_cast(info.size); } + jit_int32_t GenContext::AlignSize(jit_int32_t x, jit_int32_t boundary) + { + if (x % boundary != 0) + x = (x & ~(boundary-1)) + boundary; + return x; + } + // Computes size on the stack - jit_int32_t GenContext::GetStackSize(const IntPassInfo &info) + jit_int32_t GenContext::GetParamStackSize(const IntPassInfo &info) { // Align up to 4 byte boundaries - jit_int32_t rs = GetRealSize(info); - if (rs % 4 != 0) - rs = (rs & ~(3)) + 4; - return rs; + return AlignSize(GetRealSize(info), 4); } jit_int8_t GenContext::NextRegEBX_ECX_EDX() @@ -199,12 +203,12 @@ namespace SourceHook IA32_Pop_Reg(&m_HookFunc, REG_EDI); } - short GenContext::GetParamsStackSize() + short GenContext::GetParamsTotalStackSize() { short acc = 0; for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) { - acc += GetStackSize(m_Proto.GetParam(i)); + acc += GetParamStackSize(m_Proto.GetParam(i)); } return acc; @@ -216,7 +220,7 @@ namespace SourceHook for (int i = 0; i < p; ++i) { if (m_Proto.GetParam(i).flags & PassFlag_ForcedByRef) - off += GetStackSize(m_Proto.GetParam(i)); + off += AlignSize(m_Proto.GetParam(i).size, 4); } return off; } @@ -318,7 +322,7 @@ namespace SourceHook { // make room on the stack // sub esp, - IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, GetStackSize(pi), MOD_REG); + IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, GetParamStackSize(pi), MOD_REG); } // if there is a copy constructor.. @@ -404,14 +408,14 @@ namespace SourceHook jit_int32_t cur_offset = param_base_offset; for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) { - cur_offset += GetStackSize(m_Proto.GetParam(i)); + cur_offset += GetParamStackSize(m_Proto.GetParam(i)); } // push parameters in reverse order for (int i = m_Proto.GetNumOfParams() - 1; i >= 0; --i) { const IntPassInfo &pi = m_Proto.GetParam(i); - cur_offset -= GetStackSize(pi); + cur_offset -= GetParamStackSize(pi); if (pi.flags & PassInfo::PassFlag_ByVal) { switch (pi.type) @@ -1351,15 +1355,15 @@ namespace SourceHook if (m_Proto.GetRet().size != 0) { v_ret_ptr = AddVarToFrame(SIZE_PTR); - v_orig_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet())); - v_override_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet())); - v_plugin_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet())); + v_orig_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet())); + v_override_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet())); + v_plugin_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet())); } jit_int32_t v_place_for_memret = 0; if (MemRetWithTempObj()) { - v_place_for_memret = AddVarToFrame(GetStackSize(m_Proto.GetRet())); + v_place_for_memret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet())); } jit_int32_t v_place_fbrr_base = 0; @@ -1393,7 +1397,7 @@ namespace SourceHook // lea eax, [ebp + param_base_offs + paramssize] // mov argptr, eax - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_base_offs + GetParamsStackSize() + SIZE_PTR); // +SIZE_PTR: last const char * is not in protoinfo + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_base_offs + GetParamsTotalStackSize() + SIZE_PTR); // +SIZE_PTR: last const char * is not in protoinfo IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_va_argptr); } if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) @@ -1402,7 +1406,7 @@ namespace SourceHook // push valist, fmt param, maxsize, buffer IA32_Push_Reg(&m_HookFunc, REG_EAX); - IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_base_offs + GetParamsStackSize()); // last given param (+4-4, see above) + IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_base_offs + GetParamsTotalStackSize()); // last given param (+4-4, see above) IA32_Push_Imm32(&m_HookFunc, SourceHook::STRBUF_LEN - 1); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); IA32_Push_Reg(&m_HookFunc, REG_ECX); @@ -1482,7 +1486,7 @@ namespace SourceHook IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); } - cur_param_pos += GetStackSize(pi); + cur_param_pos += GetParamStackSize(pi); } DoReturn(v_ret_ptr, v_memret_addr); @@ -1527,7 +1531,7 @@ namespace SourceHook // msvc without varargs: // callee cleans the stack - short cleansize = GetParamsStackSize(); + short cleansize = GetParamsTotalStackSize(); // Memory return: address is first param if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) cleansize += SIZE_PTR; diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 71bbf54..ad3b9a1 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -181,9 +181,10 @@ namespace SourceHook jit_int8_t NextRegEBX_ECX_EDX(); // size info - jit_int32_t GetRealSize(const IntPassInfo &info); - jit_int32_t GetStackSize(const IntPassInfo &info); - short GetParamsStackSize(); // sum(GetStackSize(param[i]), 0 <= i < numOfParams) + jit_int32_t GetRealSize(const IntPassInfo &info); // checks for reference + jit_int32_t AlignSize(jit_int32_t x, jit_int32_t boundary); // align a size + jit_int32_t GetParamStackSize(const IntPassInfo &info); // get the size of a param in the param stack + short GetParamsTotalStackSize(); // sum(GetParamStackSize(param[i]), 0 <= i < numOfParams) // Helpers void BitwiseCopy_Setup(); From 12cb5ea79a9e99c7352401d9cb2776985c21dbc9 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 23 Nov 2007 15:26:00 +0000 Subject: [PATCH 33/41] Fixed wrong this pointer on destruction of forcedbyref params (this ptr was eip!) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40572 --- sourcehook/sourcehook_hookmangen.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index a3f4449..4e61f59 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -390,9 +390,12 @@ namespace SourceHook if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ODtor) && (pi.flags & PassInfo::PassFlag_ByVal) && (pi.flags & PassFlag_ForcedByRef)) { + // Actually, this is only for GCC (see line above: ForcedByRef) IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, fbrr_base + GetForcedByRefParamOffset(i)); + IA32_Push_Reg(&m_HookFunc, REG_ECX); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); IA32_Call_Reg(&m_HookFunc, REG_EAX); + IA32_Pop_Reg(&m_HookFunc, REG_ECX); } } } From 8cb55b818b421ca5107eefee367162ba438b2332 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sat, 24 Nov 2007 16:53:27 +0000 Subject: [PATCH 34/41] 16-byte stack alignment on external calls --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40574 --- sourcehook/sourcehook_hookmangen.cpp | 164 ++++++++++++++++++++++--- sourcehook/sourcehook_hookmangen.h | 11 ++ sourcehook/sourcehook_hookmangen_x86.h | 8 ++ sourcehook/test/msvc7/test.vcproj | 3 + 4 files changed, 171 insertions(+), 15 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 4e61f59..4faff52 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -203,6 +203,53 @@ namespace SourceHook IA32_Pop_Reg(&m_HookFunc, REG_EDI); } + jit_int32_t GenContext::AlignStackBeforeCall(int paramsize, int flags) + { + paramsize += + GCC_ONLY( ((flags & AlignStack_GCC_ThisOnStack)!=0 ? SIZE_PTR : 0) + ) + MSVC_ONLY( ((flags & AlignStack_MSVC_ThisOnStack)!=0 ? SIZE_PTR : 0) + ) + ((flags & AlignStack_MemRet)!=0 ? SIZE_PTR : 0); + + // At the beginning of the hookfunc, the stack is aligned to a 16 bytes boundary. + // Then, m_BytesPushedAfterInitialAlignment were pushed (can also be 0). + + // After this function is called, paramsize bytes will be pushed onto the stack + // After that, the alignment has to be a 16 bytes boundary again. + + + // How many bytes we would subtract if the alignment was alright now: + int subtractFromEsp = 16 - (paramsize % 16); + if (subtractFromEsp == 16) + subtractFromEsp = 0; + + // But: there might be bytes pushed alreay! + subtractFromEsp -= m_BytesPushedAfterInitialAlignment; + + // For example: paramsize was 0 and m_BytesPushedAfterInitialAlignment was 4. + // we then have to push another 12 bytes to reach 16 bytes alignment again. + + if (subtractFromEsp < 0) + subtractFromEsp = 16 - ((-subtractFromEsp) % 16); + + IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, subtractFromEsp, MOD_REG); + + return subtractFromEsp; + } + + void GenContext::AlignStackAfterCall(jit_int32_t numofbytes) + { + IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, numofbytes, MOD_REG); + } + + void GenContext::CheckAlignmentBeforeCall() + { +#if 0 + IA32_Test_Rm_Imm32(&m_HookFunc, REG_ESP, 15, MOD_REG); + IA32_Jump_Cond_Imm8(&m_HookFunc, CC_Z, 1); + IA32_Int3(&m_HookFunc); +#endif + } + short GenContext::GetParamsTotalStackSize() { short acc = 0; @@ -220,7 +267,7 @@ namespace SourceHook for (int i = 0; i < p; ++i) { if (m_Proto.GetParam(i).flags & PassFlag_ForcedByRef) - off += AlignSize(m_Proto.GetParam(i).size, 4); + off += AlignSize(static_cast(m_Proto.GetParam(i).size), 4); } return off; } @@ -328,31 +375,35 @@ namespace SourceHook // if there is a copy constructor.. if (pi.pCopyCtor) { - // save eax - // push src addr - // this= target addr = forcedbyref ? ebp+place_fbrr : esp+12 - // call copy constructor - // restore eax - + // :TODO: alignment here? + // can't use normal alignment methods + // because an unknown number of bytes has been pushed already (the other params) IA32_Push_Reg(&m_HookFunc, REG_EAX); - + + // compute dest addr to ECX + // = forcedbyref ? ebp+place_fbrr : esp+12 if (pi.flags & PassFlag_ForcedByRef) IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, place_fbrr); else IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_ECX, REG_NOIDX, REG_ESP, NOSCALE, 4); + // compute src addr to EAX IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_offset); + + // push params (gcc: also this) IA32_Push_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); + + // call IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EDX, DownCastPtr(pi.pCopyCtor)); IA32_Call_Reg(&m_HookFunc, REG_EDX); - GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); + + // restore eax IA32_Pop_Reg(&m_HookFunc, REG_EAX); } else { // bitwise copy - BitwiseCopy_Setup(); @@ -379,7 +430,7 @@ namespace SourceHook return SIZE_PTR; } - return DownCastSize(pi.size); + return GetParamStackSize(pi); } void GenContext::DestroyParams(jit_int32_t fbrr_base) @@ -391,11 +442,15 @@ namespace SourceHook (pi.flags & PassInfo::PassFlag_ByVal) && (pi.flags & PassFlag_ForcedByRef)) { // Actually, this is only for GCC (see line above: ForcedByRef) + jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, fbrr_base + GetForcedByRefParamOffset(i)); IA32_Push_Reg(&m_HookFunc, REG_ECX); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); IA32_Pop_Reg(&m_HookFunc, REG_ECX); + + AlignStackAfterCall(tmpAlign); } } } @@ -436,7 +491,7 @@ namespace SourceHook } else if (pi.flags & PassInfo::PassFlag_ByRef) { - PushRef(cur_offset, pi); + ret = PushRef(cur_offset, pi); } else { @@ -501,14 +556,19 @@ namespace SourceHook // call it // gcc: clean up + jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR, AlignStack_GCC_ThisOnStack); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_place_for_memret); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_where); IA32_Push_Reg(&m_HookFunc, REG_EDX); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); + + AlignStackAfterCall(tmpAlign); } else { @@ -531,11 +591,16 @@ namespace SourceHook //call it //gcc: clean up + jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_place_for_memret); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); + + AlignStackAfterCall(tmpAlign); } } else @@ -636,7 +701,7 @@ namespace SourceHook tmppos = IA32_Jump_Cond_Imm8(&m_HookFunc, CC_NGE, 0); m_HookFunc.start_count(counter); - // eax = pContext->GetOverrideRetPtr() + // eax = pContext->GetOverrideRetPtr() no alignment needs // ECX = pContext // gcc: push ecx // eax = [ecx] @@ -672,6 +737,8 @@ namespace SourceHook // call it // gcc: clean up + jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR, AlignStack_GCC_ThisOnStack); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_plugin_ret); IA32_Push_Reg(&m_HookFunc, REG_EDX); #if SH_COMP == SH_COMP_MSVC @@ -681,8 +748,11 @@ namespace SourceHook #endif IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); + + AlignStackAfterCall(tmpAlign); } else { @@ -817,6 +887,8 @@ namespace SourceHook // call it // gcc: clean up + jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR, AlignStack_GCC_ThisOnStack); + IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_ECX, MOD_REG); IA32_Push_Reg(&m_HookFunc, REG_EDX); @@ -827,8 +899,11 @@ namespace SourceHook #endif IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pCopyCtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); + + AlignStackAfterCall(tmpAlign); } else { @@ -898,6 +973,12 @@ namespace SourceHook // gcc: clean up jit_int32_t caller_clean_bytes = 0; // gcc always, msvc never (hooks never have varargs!) + + jit_int32_t alignBytes = AlignStackBeforeCall( + GetParamsTotalStackSize() + ((m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt)!=0 ? SIZE_PTR : 0), + AlignStack_GCC_ThisOnStack | ((m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) == 0 ? 0 : AlignStack_MemRet) + ); + // vafmt: push va_buf if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) { @@ -914,8 +995,11 @@ namespace SourceHook caller_clean_bytes += PushMemRetPtr(v_plugin_ret, v_place_for_memret); IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 2*SIZE_PTR); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); + AlignStackAfterCall(alignBytes); + DestroyParams(v_place_fbrr_base); SaveRetVal(v_plugin_ret, v_place_for_memret); @@ -956,7 +1040,7 @@ namespace SourceHook // jump back to loop begin tmppos2 = IA32_Jump_Imm32(&m_HookFunc, 0); m_HookFunc.end_count(loop_begin_counter); - m_HookFunc.rewrite(tmppos2, -static_cast(loop_begin_counter)); + m_HookFunc.rewrite(tmppos2, static_cast(-loop_begin_counter)); m_HookFunc.end_count(counter); m_HookFunc.rewrite(tmppos, static_cast(counter)); @@ -1016,7 +1100,14 @@ namespace SourceHook m_HookFunc.start_count(counter2); jit_int32_t caller_clean_bytes = 0; // gcc always, msvc when cdecl-like (varargs) - + + jit_int32_t alignBytes = AlignStackBeforeCall( + GetParamsTotalStackSize() + ((m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt)!=0 ? 2*SIZE_PTR : 0), + AlignStack_GCC_ThisOnStack | + ((m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) == 0 ? 0 : AlignStack_MemRet) | + ((m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) == 0 ? 0 : AlignStack_MSVC_ThisOnStack) + ); + // vafmt: push va_buf, then "%s" if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) { @@ -1056,8 +1147,11 @@ namespace SourceHook // call IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_vfnptr_origentry); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); + AlignStackAfterCall(alignBytes); + // cleanup if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, caller_clean_bytes + SIZE_PTR, MOD_REG); @@ -1099,14 +1193,19 @@ namespace SourceHook // call it // gcc: clean up + jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR, AlignStack_GCC_ThisOnStack); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_override_ret); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); IA32_Push_Reg(&m_HookFunc, REG_EDX); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG)); + + AlignStackAfterCall(tmpAlign); } else { @@ -1390,6 +1489,10 @@ namespace SourceHook IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, ComputeVarsSize(), MOD_REG); + // Initial stack alignment + IA32_And_Rm_Imm32(&m_HookFunc, REG_ESP, MOD_REG, -16); + m_BytesPushedAfterInitialAlignment = 0; + // init status localvar IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_status); @@ -1407,6 +1510,8 @@ namespace SourceHook { // vsnprintf + jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR*3 + sizeof(size_t), AlignStack_GCC_ThisOnStack); + // push valist, fmt param, maxsize, buffer IA32_Push_Reg(&m_HookFunc, REG_EAX); IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_base_offs + GetParamsTotalStackSize()); // last given param (+4-4, see above) @@ -1416,11 +1521,14 @@ namespace SourceHook // call IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(&vsnprintf)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); // Clean up (cdecl) IA32_Add_Rm_Imm32(&m_HookFunc, REG_ESP, 0x10, MOD_REG); + AlignStackAfterCall(tmpAlign); + // Set trailing zero IA32_Xor_Reg_Rm(&m_HookFunc, REG_EDX, REG_EDX, MOD_REG); IA32_Mov_Rm8_Reg8_DispAuto(&m_HookFunc, REG_EBP, REG_EDX, v_va_buf + SourceHook::STRBUF_LEN - 1); @@ -1430,10 +1538,13 @@ namespace SourceHook if((m_Proto.GetRet().flags & PassInfo::PassFlag_ByVal) && m_Proto.GetRet().pNormalCtor) { + jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); + // orig_reg IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); @@ -1441,6 +1552,7 @@ namespace SourceHook IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); @@ -1448,9 +1560,12 @@ namespace SourceHook IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); + AlignStackAfterCall(tmpAlign); + // _don't_ call a constructor for v_place_for_memret ! } @@ -1477,6 +1592,9 @@ namespace SourceHook CallEndContext(v_pContext); // Call destructors of byval object params which have a destructor + + jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); + jit_int32_t cur_param_pos = param_base_offs; for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) { @@ -1487,11 +1605,16 @@ namespace SourceHook { IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, cur_param_pos); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); + GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); } cur_param_pos += GetParamStackSize(pi); } + AlignStackAfterCall(tmpAlign); + DoReturn(v_ret_ptr, v_memret_addr); // Call destructors of orig_ret/ ... @@ -1502,26 +1625,37 @@ namespace SourceHook IA32_Push_Reg(&m_HookFunc, REG_EAX); IA32_Push_Reg(&m_HookFunc, REG_EDX); + m_BytesPushedAfterInitialAlignment += 8; + + jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); + IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); + CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); + AlignStackAfterCall(tmpAlign); + IA32_Pop_Reg(&m_HookFunc, REG_EDX); IA32_Pop_Reg(&m_HookFunc, REG_EAX); + + m_BytesPushedAfterInitialAlignment -= 8; } // epilogue diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index ad3b9a1..028e5b6 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -180,6 +180,17 @@ namespace SourceHook int m_RegCounter; jit_int8_t NextRegEBX_ECX_EDX(); + int m_BytesPushedAfterInitialAlignment; + enum AlignStackFlags + { + AlignStack_GCC_ThisOnStack = 1, + AlignStack_MSVC_ThisOnStack = 2, + AlignStack_MemRet = 4 + }; + jit_int32_t AlignStackBeforeCall(int paramsize, int flags); + void AlignStackAfterCall(jit_int32_t numofbytes); + void CheckAlignmentBeforeCall(); + // size info jit_int32_t GetRealSize(const IntPassInfo &info); // checks for reference jit_int32_t AlignSize(jit_int32_t x, jit_int32_t boundary); // align a size diff --git a/sourcehook/sourcehook_hookmangen_x86.h b/sourcehook/sourcehook_hookmangen_x86.h index 4590ff0..6d268ed 100644 --- a/sourcehook/sourcehook_hookmangen_x86.h +++ b/sourcehook/sourcehook_hookmangen_x86.h @@ -111,6 +111,7 @@ #define IA32_CMPSB 0xA6 // no extra encoding #define IA32_TEST_RM_REG8 0x84 // encoding is /r #define IA32_TEST_RM_REG 0x85 // encoding is /r +#define IA32_TEST_RM_IMM32 0xF7 // encoding is /0 #define IA32_JCC_IMM 0x70 // encoding is +cc #define IA32_JCC_IMM32_1 0x0F // opcode part 1 #define IA32_JCC_IMM32_2 0x80 // encoding is +cc @@ -1477,6 +1478,13 @@ namespace SourceHook jit->write_ubyte(ia32_modrm(mode, reg2, reg1)); } + inline void IA32_Test_Rm_Imm32(JitWriter *jit, jit_uint8_t operand1, jit_int32_t imm_operand, jit_uint8_t mode) + { + jit->write_ubyte(IA32_TEST_RM_IMM32); + jit->write_ubyte(ia32_modrm(mode, 0, operand1)); + jit->write_int32(imm_operand); + } + inline void IA32_Cmp_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) { jit->write_ubyte(IA32_CMP_RM_REG); diff --git a/sourcehook/test/msvc7/test.vcproj b/sourcehook/test/msvc7/test.vcproj index 561eb34..6d9b638 100644 --- a/sourcehook/test/msvc7/test.vcproj +++ b/sourcehook/test/msvc7/test.vcproj @@ -363,6 +363,9 @@ + + From 26ed1c3f0ca5e46037c2c506b456ca959ebf5d8a Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sat, 24 Nov 2007 23:02:35 +0000 Subject: [PATCH 35/41] GCC fixes --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40575 --- sourcehook/sourcehook_hookmangen.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 4faff52..2df158a 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -378,6 +378,8 @@ namespace SourceHook // :TODO: alignment here? // can't use normal alignment methods // because an unknown number of bytes has been pushed already (the other params) + + // save eax IA32_Push_Reg(&m_HookFunc, REG_EAX); // compute dest addr to ECX @@ -398,6 +400,11 @@ namespace SourceHook IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EDX, DownCastPtr(pi.pCopyCtor)); IA32_Call_Reg(&m_HookFunc, REG_EDX); + // gcc: pop this ptr off the stack + GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); + // pop other params off the stack + IA32_Pop_Reg(&m_HookFunc, REG_EAX); + // restore eax IA32_Pop_Reg(&m_HookFunc, REG_EAX); } @@ -1883,7 +1890,7 @@ namespace SourceHook for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) { IntPassInfo &pi = m_Proto.GetParam(i); - if (pi.type == PassInfo::PassType_Object && + if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ByVal) && (pi.flags & PassInfo::PassFlag_ODtor)) { pi.flags |= PassFlag_ForcedByRef; From a4e70c3c997fe4787bc29d78790dcb26501192e9 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 25 Nov 2007 00:05:02 +0000 Subject: [PATCH 36/41] Fixes: alignment, stack cleanup, memory --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40576 --- sourcehook/sh_memory.h | 2 +- sourcehook/sourcehook_hookmangen.cpp | 24 +++++++++++------------- sourcehook/sourcehook_hookmangen.h | 4 ++++ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/sourcehook/sh_memory.h b/sourcehook/sh_memory.h index 11e4633..14fc240 100644 --- a/sourcehook/sh_memory.h +++ b/sourcehook/sh_memory.h @@ -41,7 +41,7 @@ namespace LinuxSignal // We need to align addr down to pagesize on linux // We assume PAGESIZE is a power of two # define SH_LALIGN(x) (void*)((intptr_t)(x) & ~(PAGESIZE-1)) -# define SH_LALDIF(x) ((intptr_t)(x) & (PAGESIZE-1)) +# define SH_LALDIF(x) ((intptr_t)(x) % PAGESIZE) # else # error Unsupported OS/Compiler # endif diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 2df158a..73c5b1f 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -243,11 +243,11 @@ namespace SourceHook void GenContext::CheckAlignmentBeforeCall() { -#if 0 +//#if 0 IA32_Test_Rm_Imm32(&m_HookFunc, REG_ESP, 15, MOD_REG); IA32_Jump_Cond_Imm8(&m_HookFunc, CC_Z, 1); IA32_Int3(&m_HookFunc); -#endif +//#endif } short GenContext::GetParamsTotalStackSize() @@ -400,10 +400,8 @@ namespace SourceHook IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EDX, DownCastPtr(pi.pCopyCtor)); IA32_Call_Reg(&m_HookFunc, REG_EDX); - // gcc: pop this ptr off the stack - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - // pop other params off the stack - IA32_Pop_Reg(&m_HookFunc, REG_EAX); + // gcc: clean up stack + GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); // restore eax IA32_Pop_Reg(&m_HookFunc, REG_EAX); @@ -573,7 +571,7 @@ namespace SourceHook IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); CheckAlignmentBeforeCall(); IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); + GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); AlignStackAfterCall(tmpAlign); } @@ -1006,16 +1004,16 @@ namespace SourceHook IA32_Call_Reg(&m_HookFunc, REG_EAX); AlignStackAfterCall(alignBytes); - - DestroyParams(v_place_fbrr_base); - - SaveRetVal(v_plugin_ret, v_place_for_memret); - + // cleanup (gcc only) // params + thisptr if (SH_COMP == SH_COMP_GCC) IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, caller_clean_bytes + SIZE_PTR, MOD_REG); + DestroyParams(v_place_fbrr_base); + + SaveRetVal(v_plugin_ret, v_place_for_memret); + // process meta return: // prev_res = cur_res // if (cur_res > status) status = cur_res; @@ -1517,7 +1515,7 @@ namespace SourceHook { // vsnprintf - jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR*3 + sizeof(size_t), AlignStack_GCC_ThisOnStack); + jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR*3 + sizeof(size_t), 0); // push valist, fmt param, maxsize, buffer IA32_Push_Reg(&m_HookFunc, REG_EAX); diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h index 028e5b6..148c9ab 100644 --- a/sourcehook/sourcehook_hookmangen.h +++ b/sourcehook/sourcehook_hookmangen.h @@ -89,7 +89,11 @@ namespace SourceHook memset((void*)newBuf, 0xCC, m_AllocatedSize); // :TODO: remove this ! memcpy((void*)newBuf, (const void*)m_pData, m_Size); if (m_pData) + { + ms_Allocator.SetRE(reinterpret_cast(m_pData)); + ms_Allocator.SetRW(newBuf); ms_Allocator.Free(reinterpret_cast(m_pData)); + } m_pData = newBuf; } memcpy((void*)(m_pData + m_Size), (const void*)data, size); From d3c3737355acd0c01e55c497ab8988aa8e8acc74 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 25 Nov 2007 00:06:47 +0000 Subject: [PATCH 37/41] Disabled debug code --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40577 --- sourcehook/sourcehook_hookmangen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 73c5b1f..e69dae5 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -243,11 +243,11 @@ namespace SourceHook void GenContext::CheckAlignmentBeforeCall() { -//#if 0 +#if 0 IA32_Test_Rm_Imm32(&m_HookFunc, REG_ESP, 15, MOD_REG); IA32_Jump_Cond_Imm8(&m_HookFunc, CC_Z, 1); IA32_Int3(&m_HookFunc); -//#endif +#endif } short GenContext::GetParamsTotalStackSize() From f307e854587e9805a92538ca50d2d76bb36bfe65 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 25 Nov 2007 00:12:56 +0000 Subject: [PATCH 38/41] Only emit alignment code if it is necessary (no sub esp, 0) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40578 --- sourcehook/sourcehook_hookmangen.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index e69dae5..2d99e85 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -231,14 +231,16 @@ namespace SourceHook if (subtractFromEsp < 0) subtractFromEsp = 16 - ((-subtractFromEsp) % 16); - IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, subtractFromEsp, MOD_REG); + if (subtractFromEsp != 0) + IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, subtractFromEsp, MOD_REG); return subtractFromEsp; } void GenContext::AlignStackAfterCall(jit_int32_t numofbytes) { - IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, numofbytes, MOD_REG); + if (numofbytes != 0) + IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, numofbytes, MOD_REG); } void GenContext::CheckAlignmentBeforeCall() From c45df0a90b33e2cab183576908cb2aed2a2fbefd Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 25 Nov 2007 01:20:00 +0000 Subject: [PATCH 39/41] Made CPageAlloc return aligned pointers if required --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40579 --- sourcehook/sh_pagealloc.h | 61 ++++++++++++++++++---------- sourcehook/sourcehook_hookmangen.cpp | 2 +- sourcehook/test/testhookmangen.cpp | 25 ++++++++++++ 3 files changed, 65 insertions(+), 23 deletions(-) diff --git a/sourcehook/sh_pagealloc.h b/sourcehook/sh_pagealloc.h index 49fd734..ee155e5 100644 --- a/sourcehook/sh_pagealloc.h +++ b/sourcehook/sh_pagealloc.h @@ -46,14 +46,37 @@ namespace SourceHook }; typedef List AUList; - struct AllocatedRegion { void *startPtr; size_t size; bool isolated; // may contain only one AU + size_t minAlignment; AUList allocUnits; + void CheckGap(size_t gap_begin, size_t gap_end, size_t reqsize, + size_t &smallestgap_pos, size_t &smallestgap_size, size_t &outAlignBytes) + { + size_t gapsize = gap_end - gap_begin; + // How many bytes do we actually need here? + // = requested size + alignment bytes + size_t neededSize = reqsize; + size_t alignBytes = minAlignment - ((reinterpret_cast(startPtr) + gap_begin) % minAlignment); + + alignBytes %= minAlignment; + neededSize += alignBytes; + + if (gap_end - gap_begin >= neededSize) + { + if (gap_end - gap_begin < smallestgap_size) + { + smallestgap_size = gap_end - gap_begin; + smallestgap_pos = gap_begin; + outAlignBytes = alignBytes; + } + } + } + bool TryAlloc(size_t reqsize, void * &outAddr) { // Check for isolated @@ -64,33 +87,20 @@ namespace SourceHook size_t lastend = 0; size_t smallestgap_pos = size + 1; size_t smallestgap_size = size + 1; + size_t alignmentbytes = 0; for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) { - if (iter->begin_offset - lastend >= reqsize) - { - if (iter->begin_offset - lastend < smallestgap_size) - { - smallestgap_size = iter->begin_offset - lastend; - smallestgap_pos = lastend; - } - } + CheckGap(lastend, iter->begin_offset, reqsize, smallestgap_pos, smallestgap_size, alignmentbytes); lastend = iter->begin_offset + iter->size; } - if (size - lastend >= reqsize) - { - if (size - lastend < smallestgap_size) - { - smallestgap_size = size - lastend; - smallestgap_pos = lastend; - } - } + CheckGap(lastend, size, reqsize, smallestgap_pos, smallestgap_size, alignmentbytes); if (smallestgap_pos < size) { - outAddr = reinterpret_cast(reinterpret_cast(startPtr) + smallestgap_pos); - allocUnits.push_sorted( AllocationUnit(smallestgap_pos, reqsize) ); + outAddr = reinterpret_cast(reinterpret_cast(startPtr) + smallestgap_pos + alignmentbytes); + allocUnits.push_sorted( AllocationUnit(smallestgap_pos, reqsize + alignmentbytes) ); return true; } else @@ -104,11 +114,16 @@ namespace SourceHook if (addr < startPtr || addr >= reinterpret_cast(reinterpret_cast(startPtr) + size)) return false; - size_t offs = reinterpret_cast(addr) - reinterpret_cast(startPtr); + intptr_t start = reinterpret_cast(startPtr); for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) { - if (iter->begin_offset == offs) + size_t AUBegin = start + iter->begin_offset; + void *alignedAUBegin = reinterpret_cast( + AUBegin + ((minAlignment - AUBegin % minAlignment) % minAlignment) + ); + + if (addr == alignedAUBegin) { allocUnits.erase(iter); return true; @@ -135,6 +150,7 @@ namespace SourceHook typedef List ARList; + size_t m_MinAlignment; size_t m_PageSize; ARList m_Regions; @@ -143,6 +159,7 @@ namespace SourceHook AllocatedRegion newRegion; newRegion.startPtr = 0; newRegion.isolated = isolated; + newRegion.minAlignment = m_MinAlignment; // Compute real size -> align up to m_PageSize boundary @@ -190,7 +207,7 @@ namespace SourceHook } public: - CPageAlloc() + CPageAlloc(size_t minAlignment = 1 /* power of 2 */ ) : m_MinAlignment(minAlignment) { #ifdef __linux__ m_PageSize = sysconf(_SC_PAGESIZE); diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp index 2d99e85..69c10c1 100644 --- a/sourcehook/sourcehook_hookmangen.cpp +++ b/sourcehook/sourcehook_hookmangen.cpp @@ -36,7 +36,7 @@ namespace SourceHook { namespace Impl { - CPageAlloc GenBuffer::ms_Allocator; + CPageAlloc GenBuffer::ms_Allocator(16); template jit_int32_t DownCastPtr(T ptr) diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp index 6dd5205..06cd501 100644 --- a/sourcehook/test/testhookmangen.cpp +++ b/sourcehook/test/testhookmangen.cpp @@ -1200,5 +1200,30 @@ bool TestCPageAlloc(std::string &error) memset((void*)test4[2], 0, ps / 4); + // alignement tests + CPageAlloc alloc1(1); + CPageAlloc alloc4(4); + CPageAlloc alloc16(16); + + void *last1 = alloc1.Alloc(1); + void *last4 = alloc4.Alloc(4); + void *last16 = alloc16.Alloc(16); + void *cur; + for (int i = 0; i < 20; ++i) + { + cur = alloc1.Alloc(1); + CHECK_COND(reinterpret_cast(cur) == reinterpret_cast(last1) + 1, "Part 4.1"); + last1 = cur; + + cur = alloc4.Alloc(1); + CHECK_COND(reinterpret_cast(cur) == reinterpret_cast(last4) + 4, "Part 4.2"); + last4 = cur; + + cur = alloc16.Alloc(1); + CHECK_COND(reinterpret_cast(cur) == reinterpret_cast(last16) + 16, "Part 4.3"); + last16 = cur; + } + + alloc16.Free(alloc16.Alloc(1)); return true; } From 1aa8c8572dbd5408aaa03f14f4118e7847f13311 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sun, 25 Nov 2007 01:22:41 +0000 Subject: [PATCH 40/41] I'm tired :) --HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40580 --- sourcehook/sh_pagealloc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sourcehook/sh_pagealloc.h b/sourcehook/sh_pagealloc.h index ee155e5..afabc3d 100644 --- a/sourcehook/sh_pagealloc.h +++ b/sourcehook/sh_pagealloc.h @@ -66,11 +66,11 @@ namespace SourceHook alignBytes %= minAlignment; neededSize += alignBytes; - if (gap_end - gap_begin >= neededSize) + if (gapsize >= neededSize) { - if (gap_end - gap_begin < smallestgap_size) + if (gapsize < smallestgap_size) { - smallestgap_size = gap_end - gap_begin; + smallestgap_size = gapsize; smallestgap_pos = gap_begin; outAlignBytes = alignBytes; } From 1556c94c280ea42dbdd26e0b9ee290d8d72f9075 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Sun, 24 Aug 2008 04:01:36 +0000 Subject: [PATCH 41/41] Removed hookman_autogen branch (was merged into trunk a long time ago) --HG-- branch : hookman_autogen --- installer/Attach.cfg | 38 - installer/Attach.dpr | 85 - installer/Attach.exe | Bin 360960 -> 0 bytes installer/HL2Launch.cfg | 38 - installer/HL2Launch.dpr | 189 - installer/HL2Launch.exe | Bin 43008 -> 0 bytes installer/MMS_Installer.cfg | 38 - installer/MMS_Installer.dpr | 72 - installer/MMS_Installer.exe | Bin 637952 -> 0 bytes installer/MMS_Installer.res | Bin 171456 -> 0 bytes installer/UnitFunctions.pas | 126 - installer/UnitInstall.pas | 560 - installer/UnitPackSystem.pas | 222 - installer/UnitSelectModPath.dfm | Bin 1148 -> 0 bytes installer/UnitSelectModPath.pas | 26 - installer/UnitfrmMain.dfm | 11577 ---------------- installer/UnitfrmMain.pas | 804 -- installer/UnitfrmProxy.dfm | Bin 1584 -> 0 bytes installer/UnitfrmProxy.pas | 72 - installer/del.bat | 15 - installer/files/Readme.txt | 8 - installer/install.bmp | Bin 154542 -> 0 bytes installer/upx.exe | Bin 126464 -> 0 bytes modules.versions | 9 - sample_mm/Makefile.ep2 | 67 - sample_mm/engine_wrappers.h | 44 - sample_mm/msvc8/sample_mm.sln | 26 - sample_mm/msvc8/sample_mm.vcproj | 367 - sample_mm/sample_mm.cpp | 329 - sample_mm/sample_mm.h | 78 - sourcehook/FastDelegate.h | 3259 ----- sourcehook/generate/FastDelegate.h | 3259 ----- sourcehook/generate/FastDelegate.hxx | 1054 -- sourcehook/generate/generate | 7 - sourcehook/generate/generate.bat | 10 - sourcehook/generate/sh_memfuncinfo.h | 796 -- sourcehook/generate/sh_memfuncinfo.hxx | 332 - sourcehook/generate/shworker.bin | Bin 50608 -> 0 bytes sourcehook/generate/shworker.exe | Bin 352256 -> 0 bytes sourcehook/generate/shworker/Makefile | 13 - sourcehook/generate/shworker/fd_hopter.cpp | 370 - .../generate/shworker/msvc7/shworker.vcproj | 137 - .../generate/shworker/msvc8/shworker.vcproj | 208 - sourcehook/generate/shworker/shworker.cpp | 767 - sourcehook/generate/sourcehook.h | 6043 -------- sourcehook/generate/sourcehook.hxx | 1377 -- sourcehook/sh_list.h | 321 - sourcehook/sh_memfuncinfo.h | 796 -- sourcehook/sh_memory.h | 190 - sourcehook/sh_pagealloc.h | 288 - sourcehook/sh_stack.h | 232 - sourcehook/sh_string.h | 401 - sourcehook/sh_tinyhash.h | 534 - sourcehook/sh_vector.h | 519 - sourcehook/sourcehook.cpp | 1093 -- sourcehook/sourcehook.h | 6043 -------- sourcehook/sourcehook_hookmangen.cpp | 2030 --- sourcehook/sourcehook_hookmangen.h | 299 - sourcehook/sourcehook_hookmangen_x86.h | 1611 --- sourcehook/sourcehook_impl.h | 340 - sourcehook/sourcehook_impl_chook.h | 106 - sourcehook/sourcehook_impl_chookidman.h | 81 - sourcehook/sourcehook_impl_chookmaninfo.h | 199 - sourcehook/sourcehook_impl_ciface.h | 81 - sourcehook/sourcehook_impl_cproto.h | 141 - sourcehook/sourcehook_impl_cvfnptr.h | 117 - sourcehook/sourcehook_pibuilder.h | 109 - sourcehook/test/Makefile | 63 - sourcehook/test/generate.bat | 6 - sourcehook/test/main.cpp | 125 - sourcehook/test/msvc7/test.vcproj | 417 - sourcehook/test/msvc8/test.vcproj | 574 - sourcehook/test/sourcehook_test.h | 49 - sourcehook/test/test1.cpp | 750 - sourcehook/test/test2.cpp | 176 - sourcehook/test/test3.cpp | 245 - sourcehook/test/test4.cpp | 315 - sourcehook/test/testbail.cpp | 115 - sourcehook/test/testbail.h | 39 - sourcehook/test/testbail2.cpp | 36 - sourcehook/test/testevents.h | 214 - sourcehook/test/testhookmangen.cpp | 1229 -- sourcehook/test/testhookmangen.h | 2192 --- sourcehook/test/testhookmangen.hxx | 584 - sourcehook/test/testlist.cpp | 282 - sourcehook/test/testmanual.cpp | 364 - sourcehook/test/testmulti.cpp | 106 - sourcehook/test/testrecall.cpp | 231 - sourcehook/test/testreentr.cpp | 599 - sourcehook/test/testref.cpp | 227 - sourcehook/test/testrefret.cpp | 205 - sourcehook/test/testvphooks.cpp | 260 - sourcemm/IPluginManager.h | 159 - sourcemm/ISmmAPI.h | 405 - sourcemm/ISmmPlugin.h | 505 - sourcemm/ISmmPluginExt.h | 109 - sourcemm/LICENSE.txt | 29 - sourcemm/Makefile.ep1 | 78 - sourcemm/Makefile.ep2 | 78 - sourcemm/changelog.txt | 157 - sourcemm/episode1/console.cpp | 169 - sourcemm/episode1/console.h | 51 - sourcemm/episode1/convar_smm.h | 523 - sourcemm/episode1/msvc8/sourcemm.sln | 20 - sourcemm/episode1/msvc8/sourcemm.vcproj | 343 - sourcemm/episode1/provider_ep1.cpp | 602 - sourcemm/episode1/provider_ep1.h | 82 - sourcemm/episode1/vsp_listener.cpp | 138 - sourcemm/episode1/vsp_listener.h | 64 - sourcemm/episode2/console.cpp | 55 - sourcemm/episode2/console.h | 55 - sourcemm/episode2/msvc8/sourcemm.sln | 20 - sourcemm/episode2/msvc8/sourcemm.vcproj | 338 - sourcemm/episode2/provider_ep2.cpp | 570 - sourcemm/episode2/provider_ep2.h | 90 - sourcemm/episode2/vsp_listener.cpp | 141 - sourcemm/episode2/vsp_listener.h | 73 - sourcemm/metamod.cpp | 1272 -- sourcemm/metamod.h | 108 - sourcemm/metamod_console.cpp | 747 - sourcemm/metamod_console.h | 36 - sourcemm/metamod_oslink.cpp | 101 - sourcemm/metamod_oslink.h | 111 - sourcemm/metamod_plugins.cpp | 832 -- sourcemm/metamod_plugins.h | 170 - sourcemm/metamod_provider.h | 302 - sourcemm/metamod_util.cpp | 425 - sourcemm/metamod_util.h | 98 - sourcemm/svn_version.h | 13 - sourcemm/svn_version.tpl | 13 - sourcemm/version.rc | 101 - stub_mm/Makefile.ep2 | 68 - stub_mm/msvc8/stub_mm.sln | 20 - stub_mm/msvc8/stub_mm.vcproj | 207 - stub_mm/stub_mm.cpp | 104 - stub_mm/stub_mm.h | 47 - update_tool/Makefile | 68 - update_tool/README.txt | 90 - update_tool/api_link.asm | 138 - update_tool/msvc8/update_tool.sln | 20 - update_tool/msvc8/update_tool.vcproj | 203 - update_tool/sourcemm_update_tool.vdf | 6 - update_tool/sourcemm_updater.conf | 9 - update_tool/update_tool.cpp | 366 - 144 files changed, 67885 deletions(-) delete mode 100644 installer/Attach.cfg delete mode 100644 installer/Attach.dpr delete mode 100644 installer/Attach.exe delete mode 100644 installer/HL2Launch.cfg delete mode 100644 installer/HL2Launch.dpr delete mode 100644 installer/HL2Launch.exe delete mode 100644 installer/MMS_Installer.cfg delete mode 100644 installer/MMS_Installer.dpr delete mode 100644 installer/MMS_Installer.exe delete mode 100644 installer/MMS_Installer.res delete mode 100644 installer/UnitFunctions.pas delete mode 100644 installer/UnitInstall.pas delete mode 100644 installer/UnitPackSystem.pas delete mode 100644 installer/UnitSelectModPath.dfm delete mode 100644 installer/UnitSelectModPath.pas delete mode 100644 installer/UnitfrmMain.dfm delete mode 100644 installer/UnitfrmMain.pas delete mode 100644 installer/UnitfrmProxy.dfm delete mode 100644 installer/UnitfrmProxy.pas delete mode 100644 installer/del.bat delete mode 100644 installer/files/Readme.txt delete mode 100644 installer/install.bmp delete mode 100644 installer/upx.exe delete mode 100644 modules.versions delete mode 100644 sample_mm/Makefile.ep2 delete mode 100644 sample_mm/engine_wrappers.h delete mode 100644 sample_mm/msvc8/sample_mm.sln delete mode 100644 sample_mm/msvc8/sample_mm.vcproj delete mode 100644 sample_mm/sample_mm.cpp delete mode 100644 sample_mm/sample_mm.h delete mode 100644 sourcehook/FastDelegate.h delete mode 100644 sourcehook/generate/FastDelegate.h delete mode 100644 sourcehook/generate/FastDelegate.hxx delete mode 100755 sourcehook/generate/generate delete mode 100644 sourcehook/generate/generate.bat delete mode 100644 sourcehook/generate/sh_memfuncinfo.h delete mode 100644 sourcehook/generate/sh_memfuncinfo.hxx delete mode 100755 sourcehook/generate/shworker.bin delete mode 100644 sourcehook/generate/shworker.exe delete mode 100644 sourcehook/generate/shworker/Makefile delete mode 100644 sourcehook/generate/shworker/fd_hopter.cpp delete mode 100644 sourcehook/generate/shworker/msvc7/shworker.vcproj delete mode 100644 sourcehook/generate/shworker/msvc8/shworker.vcproj delete mode 100644 sourcehook/generate/shworker/shworker.cpp delete mode 100644 sourcehook/generate/sourcehook.h delete mode 100755 sourcehook/generate/sourcehook.hxx delete mode 100644 sourcehook/sh_list.h delete mode 100644 sourcehook/sh_memfuncinfo.h delete mode 100644 sourcehook/sh_memory.h delete mode 100644 sourcehook/sh_pagealloc.h delete mode 100644 sourcehook/sh_stack.h delete mode 100755 sourcehook/sh_string.h delete mode 100644 sourcehook/sh_tinyhash.h delete mode 100755 sourcehook/sh_vector.h delete mode 100644 sourcehook/sourcehook.cpp delete mode 100644 sourcehook/sourcehook.h delete mode 100644 sourcehook/sourcehook_hookmangen.cpp delete mode 100644 sourcehook/sourcehook_hookmangen.h delete mode 100644 sourcehook/sourcehook_hookmangen_x86.h delete mode 100644 sourcehook/sourcehook_impl.h delete mode 100644 sourcehook/sourcehook_impl_chook.h delete mode 100644 sourcehook/sourcehook_impl_chookidman.h delete mode 100644 sourcehook/sourcehook_impl_chookmaninfo.h delete mode 100644 sourcehook/sourcehook_impl_ciface.h delete mode 100644 sourcehook/sourcehook_impl_cproto.h delete mode 100644 sourcehook/sourcehook_impl_cvfnptr.h delete mode 100644 sourcehook/sourcehook_pibuilder.h delete mode 100644 sourcehook/test/Makefile delete mode 100644 sourcehook/test/generate.bat delete mode 100644 sourcehook/test/main.cpp delete mode 100644 sourcehook/test/msvc7/test.vcproj delete mode 100644 sourcehook/test/msvc8/test.vcproj delete mode 100644 sourcehook/test/sourcehook_test.h delete mode 100644 sourcehook/test/test1.cpp delete mode 100644 sourcehook/test/test2.cpp delete mode 100644 sourcehook/test/test3.cpp delete mode 100644 sourcehook/test/test4.cpp delete mode 100644 sourcehook/test/testbail.cpp delete mode 100644 sourcehook/test/testbail.h delete mode 100644 sourcehook/test/testbail2.cpp delete mode 100644 sourcehook/test/testevents.h delete mode 100644 sourcehook/test/testhookmangen.cpp delete mode 100644 sourcehook/test/testhookmangen.h delete mode 100644 sourcehook/test/testhookmangen.hxx delete mode 100644 sourcehook/test/testlist.cpp delete mode 100644 sourcehook/test/testmanual.cpp delete mode 100644 sourcehook/test/testmulti.cpp delete mode 100644 sourcehook/test/testrecall.cpp delete mode 100644 sourcehook/test/testreentr.cpp delete mode 100644 sourcehook/test/testref.cpp delete mode 100644 sourcehook/test/testrefret.cpp delete mode 100644 sourcehook/test/testvphooks.cpp delete mode 100644 sourcemm/IPluginManager.h delete mode 100644 sourcemm/ISmmAPI.h delete mode 100644 sourcemm/ISmmPlugin.h delete mode 100644 sourcemm/ISmmPluginExt.h delete mode 100644 sourcemm/LICENSE.txt delete mode 100644 sourcemm/Makefile.ep1 delete mode 100644 sourcemm/Makefile.ep2 delete mode 100644 sourcemm/changelog.txt delete mode 100644 sourcemm/episode1/console.cpp delete mode 100644 sourcemm/episode1/console.h delete mode 100644 sourcemm/episode1/convar_smm.h delete mode 100644 sourcemm/episode1/msvc8/sourcemm.sln delete mode 100644 sourcemm/episode1/msvc8/sourcemm.vcproj delete mode 100644 sourcemm/episode1/provider_ep1.cpp delete mode 100644 sourcemm/episode1/provider_ep1.h delete mode 100644 sourcemm/episode1/vsp_listener.cpp delete mode 100644 sourcemm/episode1/vsp_listener.h delete mode 100644 sourcemm/episode2/console.cpp delete mode 100644 sourcemm/episode2/console.h delete mode 100644 sourcemm/episode2/msvc8/sourcemm.sln delete mode 100644 sourcemm/episode2/msvc8/sourcemm.vcproj delete mode 100644 sourcemm/episode2/provider_ep2.cpp delete mode 100644 sourcemm/episode2/provider_ep2.h delete mode 100644 sourcemm/episode2/vsp_listener.cpp delete mode 100644 sourcemm/episode2/vsp_listener.h delete mode 100644 sourcemm/metamod.cpp delete mode 100644 sourcemm/metamod.h delete mode 100644 sourcemm/metamod_console.cpp delete mode 100644 sourcemm/metamod_console.h delete mode 100644 sourcemm/metamod_oslink.cpp delete mode 100644 sourcemm/metamod_oslink.h delete mode 100644 sourcemm/metamod_plugins.cpp delete mode 100644 sourcemm/metamod_plugins.h delete mode 100644 sourcemm/metamod_provider.h delete mode 100644 sourcemm/metamod_util.cpp delete mode 100644 sourcemm/metamod_util.h delete mode 100644 sourcemm/svn_version.h delete mode 100644 sourcemm/svn_version.tpl delete mode 100755 sourcemm/version.rc delete mode 100644 stub_mm/Makefile.ep2 delete mode 100644 stub_mm/msvc8/stub_mm.sln delete mode 100644 stub_mm/msvc8/stub_mm.vcproj delete mode 100644 stub_mm/stub_mm.cpp delete mode 100644 stub_mm/stub_mm.h delete mode 100644 update_tool/Makefile delete mode 100644 update_tool/README.txt delete mode 100644 update_tool/api_link.asm delete mode 100644 update_tool/msvc8/update_tool.sln delete mode 100644 update_tool/msvc8/update_tool.vcproj delete mode 100644 update_tool/sourcemm_update_tool.vdf delete mode 100644 update_tool/sourcemm_updater.conf delete mode 100644 update_tool/update_tool.cpp diff --git a/installer/Attach.cfg b/installer/Attach.cfg deleted file mode 100644 index 6c57635..0000000 --- a/installer/Attach.cfg +++ /dev/null @@ -1,38 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --LE"c:\program files\borland\delphi7\Projects\Bpl" --LN"c:\program files\borland\delphi7\Projects\Bpl" --w-UNSAFE_TYPE --w-UNSAFE_CODE --w-UNSAFE_CAST diff --git a/installer/Attach.dpr b/installer/Attach.dpr deleted file mode 100644 index eb258b4..0000000 --- a/installer/Attach.dpr +++ /dev/null @@ -1,85 +0,0 @@ -program Attach; - -{$APPTYPE CONSOLE} - -uses - SysUtils, Classes, UnitPackSystem; - -var eStream: TMemoryStream; - eFiles: TStringList; - Version: String; -begin - WriteLn('// File attacher for the MM:S installer'); - WriteLn('// by Basic-Master'); - WriteLn(''); - WriteLn('// Looking up files...'); - { Check files } - if FileExists(ExtractFilePath(ParamStr(0)) + 'files\hl2launch.exe') then - WriteLn('// Found files\hl2launch.exe') - else begin - WriteLn('// Error: Couldn''t find files\hl2launch.exe!'); - ReadLn; - exit; - end; - if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server.dll.source') then - WriteLn('// Found files\server.dll.source') - else begin - WriteLn('// Error: Couldn''t find files\server.dll.source!'); - ReadLn; - exit; - end; - if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so.source') then - WriteLn('// Found files\server_i486.so.source') - else begin - WriteLn('// Error: Couldn''t find files\server_i486.so.source!'); - ReadLn; - exit; - end; - if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server.dll.orangebox') then - WriteLn('// Found files\server.dll.orangebox') - else begin - WriteLn('// Error: Couldn''t find files\server.dll.orangebox!'); - ReadLn; - exit; - end; - if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so.orangebox') then - WriteLn('// Found files\server_i486.so.orangebox') - else begin - WriteLn('// Error: Couldn''t find files\server_i486.so.orangebox!'); - ReadLn; - exit; - end; - if FileExists(ExtractFilePath(ParamStr(0)) + 'MMS_Installer.exe') then - WriteLn('// Found MMS_Installer.exe') - else begin - WriteLn('// Error: Couldn''t find MMS_Installer.exe!'); - ReadLn; - exit; - end; - { Get version number } - WriteLn('// Please enter the version number:'); - ReadLn(Version); - if (Trim(Version) = '') then begin - WriteLn('// Error: Invalid version number!'); - ReadLn; - exit; - end; - { Compress files } - WriteLn('// Compressing files...'); - eFiles := TStringList.Create; - eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\hl2launch.exe'); - eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server.dll.source'); - eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so.source'); - eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server.dll.orangebox'); - eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so.orangebox'); - eStream := TMemoryStream.Create; - CompressFiles(eFiles, ExtractFilePath(ParamStr(0)) + 'temp.zip'); - eStream.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'temp.zip'); - WriteLn('// Attaching output to MMS_Installer.exe...'); - AttachToFile(ExtractFilePath(ParamStr(0)) + 'MMS_Installer.exe', eStream, Version); - DeleteFile(ExtractFilePath(ParamStr(0)) + 'temp.zip'); - eStream.Free; - eFiles.Free; - WriteLn('// Done.'); - ReadLn; -end. diff --git a/installer/Attach.exe b/installer/Attach.exe deleted file mode 100644 index e28edcbb6b6445c9f63233a7b2465b00e38ec4b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360960 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 =M#|m=bBGLjuO;a-%BM!lWTH4ePkH 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�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 z zYun+#jp%h^pU8%!Oza^B9GMt+lr+R@v{kh)D$#qF8}*!2 z+AnJPq8V0K?y)Mo@KJJRYkKEZe%xSKs3d~0ZkqY0=8y4JURm8jF@8~rdK_lDCp5&h zRc6+UZ^3KrNn1X&l4G#l9>DVbY9}vLoWL26jm;R4_VQ#3qTcYA`NoJRXZ6R;y? zG`Bf7KDmfadq~$I%NnC>b)E($1N8HLd_u`mFc>@t#|CL7dUua5 zEuGr`*);vjSuV(DWZX2|iuO`RZ zAkH1p(BXn3->9ny3|kB9BnP@HKLro)ZWIGqmLOjs@XS#AT|sY{kndCY7+yx-(Kt(s zg;F|>zHA%8wz&Y5L>ZXjhaZi|X~nZ_KBQRjm`5Fnl-aT~9IFWphwW1yT79UZ3wWIl z2Xm*?%x+5kx20B91UG*Gs?<(J^@AL-_ck-O;i9VR=z_gyY$V=wBhLrKpXVyaHvK|* zL|>KWpH(zFeW=QiKbJFKzT5*QrQ^%?@C=OE^Q?Xm#Ijw)A3N6HF?hflV zb!({oLVL0N@+{2))RwvGA?H*2cz%{L%0um`+fixfrd;DU`NTE>=WD6vSI9;=327ca z49o4T$vN?(ijg0UeN*W-CRL+~pH~MWQMg5f-L{9I>`c(4Rj=fKldfTdV19TBv3Lnp z@bR`iFsw5om_Yb;FrmO-hpzkQ%Bhz|7j6$CbawFUQnzb+H2*MuQR@>{{*`<1=;SZ# z>C?3_G@fm)ZLR{tcJ|7~RVa(X=M~rV)n7A8<&VNjPsT_5A39oVl~uESZp!YY)C4Pn zcxFRSs(EhJWv-_*yQ*EvVEXK|a9HwKPhFhQ!Kv+-YA#W&(dNp^2m3sUu#O-1=Y=L>7R|CQdW|^3>_kYZa&__FY_dg@s6^&k zFEijn_*hT-&l@P!;_1-ycNh~=MhSg2ki7$X z^v0;sNve|_W={39mG~6b7B$|~xK1@m=XgGQNKdI2f2IX;%TqL$U)>KQW3oi~R_`Ov z-;CW}a8ZovrQRJNlRiq^v(hZog@FA1qBle8pBUCr|26WBvMacWe$ zVPH8h@bB!O%vOR-d12m&FYma|L*q{~K064~wJ;UVR>A2_w^rYeU8lH2Znha{vX2J7 z-%q$L|N36D7Qc|i&1~bdp)Gb@Mk$t47Zql)9Q_&JY(J*0k!tk!@sqQ2aL8lx37`xkNd;L>6-$X6aLg10owVvSbCb{+)!ZFVEuzW z*5q`f>j#Kd>Tnr<1QRA_kcRkrleyKdWgOa#o@TTOTW`W945>E+AqP>q5PEBIBfBd|96S4+nZ|Fl7j<@ASXUq ztp~PMyXAi7zsFU9s=F8US$1dQ&unh0m|fvCdzMs@?- zQ-pJJLYT4beCmFuhE4bi=Q>aD_-o^~LSEOjWP7cIYhT2r zBjTSp-fGMF(q|}A=^Lno5K~mN;+Gs2n>@mkX_Ci`_v7EX8{D?*X#S(yn8nI~MCUJQ zhKF~a8B;uOYk8wuJc6cF=XJ^gj8kUY#kJkKXp*=j)yuSpMm=B{e!;l`b|>s|zqobx z4@y0Lnq!NT%PD~I;Z&`Z#o|`0C2BstFCD`fLKdX6%LV|@JO4iU9=Z3_i1tM-2AcCd zt=%7+C?0`%P*ff8;iN9!gb&sN1SOgT3Sl5()nQeg*~lu-%B2Vxa_sm65ZM;H9&pmb znnE&{)RO$!V!^y}{+fhGs_-qzVQqB?taf+Qrsk#Z=c}LL@y{)~K(ojgOZISIoh+}m zB&`SMUnH#ug8G9>?s@qYG0;oqJLWnG^f|6JY`cQf(w_GR;hovd1Ql!AnwPo)NeQaj zV|>;XYe=aRz0{iLx^s1nij3MR-tfz_71m8!1IY=zb$JJJ8???c1JBh1wx2e54hkMm zYo+iAe2J>bCZQDu|3qEb4`B!^YzgPteJ-0}Q}#3;2rfnL=xFTh$KFa;|2)E_!J!DE zaxFi>>4j|_cMomFXtqf)hiXK4WpUBY&Q8QMPf~N|Tz!m(P~=4d!2WM=~j0_&-e#WHKhq6x(fj*6iUNvL$6r$ACq*ya>K;@b%=V>QonpK&?Ndwx zkG&4(JQ~PWkRQ$~D1_$NMmV22qp9}EVw>C$NY9^98Mv z3Pv>xjagMs@A_Mi06szANNMMTKa^R5?Gv))TYy5hDbp%}tjonM2Ed`{R}C8!sM)63 zy3bdN$}d_RzT37&M8rh6i^_MEvPQAj{&ksV0Ecb_xxgZRo#pE;GLYpBJ|rITVe$Nj zwyFNjk36_VD~pFcM1S9+C?7fa&29ck8IGWbyZlwh zzv-@sE4Nn#x;_%*ew&lS%CKq{Ryyd9TCu9TAO2yCV?4cTAsJ2msg41a}zqcB@qA&?h3Ryg%qSmVoTm!dfIc=QQy#3?}ERHC(k=X9#oP1x&iR#%$y=R zc6y5Z!DWu@yH8e#W9p$+H2xB}ZRiEuook%u^;Drs)S*9W}%pLb_yV-*ubo;lzx|oQ)ec*KG>^Fz^SzBqpUwYopH% zcdDK^Z5ln5rB3-yh>}!|y?K%$^RwnII+B>-6cmhjdi2>~v8S8_=tSU1VgDn40q0 zxX4Plly=Iqcy&&^kFs;z*%))R6**w03c!^)YkXN0K>c(C-yXA#-sFw-7` zU_k5|#aG&(U0S`v;7;`bDJEzim6gjS`P)1-0H;8P5B;^?ASHBV+@PN0F4 z)V(0GcX$_4fGe3F0lR>uLbQUBiMFpGrjeP>Idpy-x#*beU4FFqTy9Fh5`3R#@p~nQ z0OeYF2_VVk7rGqd2Hj7=qT;x?6H|*6B}ak#j=%gxBj?0cw(z+BpiXHI58{xw3e+(; z(~0Ta5y}Ev-i7;|p<~mWgizS8E}B#R(6%au@jELUc{{-w`5ksX_SYBivAIarAXgO~FVbpBK0=#Ak zcgVPOIj%6mfa;e{KgaOCq{!~R)N z>wS;yv;o3=QH_#CHWO-umj@R(WN_mvIRjKI-hk_jtN|=R@*qC)QMM*W+lh8ziztW! z{_Ec6f=d$Du~HY7E%p|)os7e+;vTov7j2$PQ!%CdIe-{jw(G@a{h`Kr|Ly7dDgXAT zqrfSk7O;8m5*L^|7K%VS-gg78{};aNH0v_YeD0s+bRVmAf*O+s$YraiUf@^6V-GY6O}V&SIQZdCsiP2o)OnTMN<-L# z*RVB_y0G+AOm<<31z`zIz11roy{OqQ$>*_(a9xjZ_|%g@4uwvox2Ob-fVcEzvsfOx zEpS=cT$U9ux)ZamWom+gcAmCx6EDqbq0%v-H5U`R4r$b46{DY>UyJwJ@_4A2){vGR zR`l*0kw7;ioNC5;-e=Xv$qMXonQ=#A(_bcK?A!7A@|)#=hF-0cN0)39E-uW&scxIk z$UY7uTz-Bvf#Z6VK}1o+xflmbuRhOa65a3$L*cK|n|7D(s}=_* z0MFWRq~ajdQ}?fXeA&(gO^pIj@NUJQ>57YN6_7GA8*GdftZ~_>4cI z47a2k9O9TANkRZY1-+3QQGEqma}z=dp3?4!|1%y+bR2B3ek2zE4X+sx;H_x3shXbo zMpazLd|jxQX~EW4N2ttzw||jJb07HcdaK$?#wch1QjC#{Y*zZ&_wC=1Ip{V{7QtfX zVZ&0@a=pV?Ky*Yc7o&@8!Lxj8i&!`rRnOfa=7#)TN;cr(HJf5s$VbeIBq$Ta%Py0U zTF&EP1dRheS)@qtl2^3znHrhgG17bPq;O;V;d`G!(X%xzH~ds}73Pq-935WRZ#mwK zRK5Q$>e3{pYw_D=?2H220hUnvKALwqQ^wI{K!SOPD}~ofmIk&ca;}xR7m@>iCC5t` zz@tNY7V$HgDkPVS2ya)p2k8*HvFL^f-X0~Cgr6h?vxXPZ_`7n z+=XYglRHfRF?Md&wHpqgsEe8q0SDPJvo-I$!(|@VfjHDZ{!jo;v=nkGRc*rbE$UgI zV>A5X0fq4%|E&M*ZxJ+{_oYOKN=;;aR`aDo27~uoMV~a#fD9>dE0(nvgxi9TyXt&G zpNI(n39o3U8#ex83dO`@#zSKhJgKUC>?q~HZk%dbH;NB5q3%4e+tr#4Q&bk%(=AzV za%OwAWcv&q7-Fa|Fk|EbGt7-Q?c9Bb*^U&0*+GM-yT@Q)8(HEd#&tx4cI;L+A$F+Z z76Zu&HP_MN_6fVn()<~mM_J+);GtUK`H-iCFCIe!5!WYjJa$;1n8w}U*S1w^#kksS zd0W}7-A1kOy66CjTFEykJv&#gvwTr6Vm3bdY>#mBi#*#WjM;pB=sgG5yqnX_7M{cV z)ieMP;v2b|44dsXdaID&1r*T+j@`2doiM8e2`Jk9%!rvrb>jC*WkOd@>}Aj>(* zYZ+rAxnrW4Tf*Hc&SN^OG+8*R*n<%P1@eW-GgB!%5Y}c@-LVjW= zSN=fzQVW{V+mTStJ3%J&h5!Yo_@FcCvgsca9sIC0^tAvq}&C&aAaPSu^PFU%_E$qoUoc z;<7B%01IiMGdg}mm5cZpfKA;&usV#-nTHYgptf#sXq6gUbzA*iWcjl`nkGp~gSh)l z`(6hVlL#fqY`W-bLkpC>7qxwKk3Tno;$E<)*WYPjWi?;Fk_AjZ(}B!*iL5BjF%f2h zPy=z)*OcXDXmX4o3M%?VaEt?^fAyNxd`6=ZaBOWB>}t>~v@znFK{X^HX4dOL1T+w* z8L?&nZPB(1w~MW_h=r~+;eUmH@)iE?XClB|6$18vaKv2$;NsaBDq)}@>>jkKAsM>SUKM8<)EKrD0iCN${uFs-?}sha3?Gvq zOM$k8t<7uFQ8Ft(VRLo!Yr)4=o2#10?!T&2UVdlbUE7$K>J}QlvjkJt}rX5 zu6b%tyq&JfxUSn>9T61%tj(nj?qM$nZM^zFV2011mX^9^n%1+f#j17;)Tdz-*HB+) z_u$!ASamI>y`~eIY#Vt9%QM5HR-WtLe-Lr}TlU<&E*NCLqpAE^awNTXz9*#g@!>re z(^=UZ2~QVDyX2P(g_m_kc6vT8g>Cj%WehezH3uROi)ENQ6`9bJ0x@V^!G?~{Hkb!A0WhjsE48o9?mqyS{yxOmzMtSbkd@UvZ zwbNqsm_5^xo*XeF!$5lbH{NfO1xLD1O1q!em~otw>yN{lPjCsV@`Mgf+|H_otMs|{ z?7HhEo6Xpd@6E>&vT)*CN0fCJlNlr?b7RSmF+6-}eHb8Qf|=yh+mCmqNs)Uhf-N?6F^}Lcs?e`9 z(kP4#V-5c^aZDO{-r5V~lsu~$OCz?2wJVd-6}!9T&$OqvNxo{LquOknT3ROXcD?fM zb)I#N?Z`1wqrCfJc(m$8Rdsc&Z7*Hkz0~S3JW*OvAscE~Ew?&;wxEEqregP% z(Njfc2>h#d&tM#eGjei-|1&w7GnQNWwB?@F2kXMLjgzFpT*wpp;A^lDot}>#T&1k} zYQuqw(Xj+bf(>akE)$QuY+HcN)Vd)})Pd7cRvQe7C)D+Ms>irpG%<$~4!QF_C&4LE z@{f%@I3JxRb%qoi4U6R=+1VX+CWU=HZg0b-1USz7H;X$tAc-`oWao8davK?| zsUwh<^ZV@Mun7#N^oc!qnKa=gaZMe-Btoi%(Zp*Vfsu-T*e<9+$g#0&f1t zDK08DEYc3(9}BTo8Y8J5Q!Ry;TBKfx%#p~=Qc%B6Y#rC<34w|8T|WiZ7E^i2Nu$Wr zct6LA=F7nd!slOo!!eWmFXNOC(Y^6P#eR}HP}Q=q`T=*N3$0uO_a6g%WVoc2j~tRY zmjbsfcAFFsZvvpG#26|(p&8q)g zE-*^ctJ*{9sIT#IflSd<;_$hub<7!7K^k^I+>>Mx!azr0M*QsuX0T8gVu`!0NgRiW zM)29`7aVd+5uA1gl`D_NWSsH39)Ym_2|<`?t7M$s8nEzF>VkSo(0A3$8N8BFG7 z{wV`XTc{6%=y==8g?0!!i&zo!{LqYn|H6uE0_9%G9B`8YgMuT{mDnH{i78v0*pv{H zWG~ndb%Cg-r=3N*o;UbeaVG@;5#i@UC`=30$inVK`6kP z6#uCqQV@jOKQKOuQx;5c(78$n36een1$YO-x>iBJFhM>6oMk7Npe*SLgdI|)tw7-a zF{UA0z}}_KrLN1_P}u)O`iD53|B3VuaXNmk9naAz2N!-8>g*k|wqe{*1Q!y50;53~ zAogayBJk^mCRHP22M{R^#SRw|J+x4fu!7`FS?3|`h*DX;Ym(?oT~goeoJr34+(Cu9 zF5tA_1lX?alESj{4-CW(N5If0mO8@a#7Vm1AgU2j6EOSS2NMzg<5cEaGUj0Z7_M48 z=+jaMrbV1IEDoA8x;zp7p16tG|8E6u-|#f~LBu6aCFbC_W_5KPz|3y8eI60ufdR#! za{h;Y1y&!TFb`p{vy-?D-u?D>5A3*64xh0kDG_nq!){v;y^rBZMl=4`g_t_wK4jbB z(KL9Q4^BHg`58e@&;UaFUp?Y}VzID2KUr1*ZJk(+A+=x*&$z-rEU?1G(Kv)>LLrWD zQNUqrsR9FR0gc&393HdjyQw&*!>d0?lgpyy99CoJQ4@Q!p!I(>*0uHZ%z0`bwrqP1 z;{193@GciU&|Sy%VdnW{!7K6inVDSc^V6t(YSUuzdC2$5Pst79)(if$+!6b-ev)~QZwD{U!Ci=t@xcU5#5%(TNl znSTAg6Zd!SdGDQj?tSOn_ue^Zy3ke^O<)i{1BOAYFnCfi_HV)T-Q=Zn zq7eN4&a`~@C`a&rPo-KM4fn)K*Y%P%fFHjih2Ls}9`90t)fu%4?#3_Vo{XB#qK>1! ztv`(CqWz~NUW<_>XI#gT=Ai^m7bPrA<)q7}Yo?>S{4@kxD?p;c=7fa<`2)@OiyJzT zsY_hyPqf+cM<*_bi-PbA&LhES2|TY(14c~f{tQI*=zb1LgrEBXB@E@8l{g-EBNNGc zTH*yraWKy%(O7|u5MEUWK~LVeU5M^Z01D1#U*&73x$Z{iy3QEKa&jA>L47*?za8(# z!f^TmmeGfU$1ZateFcoK0{6$~9eEzt#vTSv(lO=tqXkE&7x2fsuJiuXYWX`6+V*L< zgqo>lHaV;Z4AE5Y4U*iYiv}v6Ct@bQ-g~R{2ke+2YA(B{EEWZrz!$K^AvkbXEN^Ug zbJE~{=U@1*Nbo;DfBk!~&o>eXEIaeupw5@>th8J(00rp}LN)Y~pISJT67HcY?E$y>~ zV}~3kbr&qE-#kudh~Woge78kN_$RYmRJZTjuPY(3sg^=eVIi=qF%+qGT@}J4Ch@>wLJB&Ep*2U&3((6+?kibbi>e z4a9p1+;wdwrI=$Eu56v#RF3;x3{lQgynG&9)|Uo(Uwtl zNyd%m;0~xQB6rKix7%?KAD@a&2(6bwQ?JKDzuLHr9-JO6P74KYUpI?WQo|K{P`4}fXU-i(Hmmzd@4RHv98Ob zlE1JL#gRay6HXa##G?SgMTX6%(pQNMi##fO{{_nQ5*$p_e&&Aze72OhsQ$MufGMMT zl+9yl*WsZu8qXq{tNa!_(Oav$uTv_hjJnh5M~EIbcG)*>=ze+J>ryogtSVJre-|@H zZNQSM;6`VkG2y7K;hX9;aG$aztiqj|$#ZB3e>LD$O@3qc3<<=J*J^4@aanb#09Z7- z{EgDBLZJ88tt6L7uo^tHmwgTqMDkoX#Ux-T-eBjDQkivA7+8=}!Cts5Pz693vX?ob z@_}Rw0%~;|{D(6{n2Oo8f51UP6$IGOzTel~O%(+q1u2K*C(rR}Zer#N9wn0!Jneiie&e$J!*lu>DJi(>#~GeuD4=a ze)BcMi4s8yUpT^M13)U}R8F1LWlS6?`3{{fe5dO4Lt6Bs;h-}QDJe}KhP@tA&cY}m z;sY0WsRGiH{0(*6A(YHfl5^Ji81V{9_9!Lu$#D0%(WIQ7&z1;su8Ce$J>BsjwgXI| zx!+muEZsJ_n8AU5C4;Mjxu+jK#Mi@hlEDkyBij+J?}1-NZF+%=_rE;GnzqCJZ?scM zcMvn30&~1M+je#leD(b{fb5{UbbKe8miCY8cfmb$V@}7Ebx~!yi-G3tZsnMaIjVAR zE^t5Q-BqK~Kdg}VfZ;yVIo22s!z6~ zVfxBA@Ih^GPIu933yU8b0TPC&+gxTv3^sVU1h_v;^(kybHNyf0yv6xYOOs9SO? z)xpIs&Cxgf`8>6uSKQlTtAYd{>+ivab$$qs8UBQi>h0#)_9karb|&z7@*Vn8a&3B& zlt19-mDVL*sD36aQr_d{8Y0Sk>cXyi@Ohe;6@K-MQg6th);H9I@jiG!^Q*|SZ0SHzbU*Gn^xZ>F3Z0WeSU;jy{CqL*{zjT8OZ0k8FIx?fy7@&Z;X><&*RR`5kul@JFdvhyEw| zvN5XMmm6N<6(1~da69t)iCZVHdG4NmbnjsQr%#o;xdYlxt5%^wlpvq-E1n*K{&zPi zjh7rQ6|YAyi}9eNJIu_Eh~aAg-F@w@M@aQS%NyQP9+F6VotBg&9P6%!&ZOuORz)bU z|9$;BKh_;hcqmpVWKlo#ga0R5kFWyEHwopP-ByV09T&|Vlc%wcms;QdFliKx-l9)^ zGcmE=KR7UaSl=J1^wFe`G@5e8^^HkDQ{1v=!*g)LGwHlsp;81&)7HIP6fgB&%*imr zK>)3!ksG0fl}9VLywJ#fe>iO+5%P!lC<>6|-w|aLRW$W^_ekzBEmb91{@oIb#t{#x z@iA=!L!Bdhj4Ve{Kg!39j_XqOjPU>{(gY*d8aG!|&WTLx_-i_~ z@$R=@Sf`zmPud0zkQ`^|?66Qh;V(HNVv|%dTsI(HWI%Gu+=SKrx@BEgAK=Eq$8^sL zo)G|p#bdn`GDdhME#c`Gg?yOLM!9aO+iKTI|Gt#&$pGd>2aB-bna{)U~zaUX?L-uVlcuUx%WQd)Msyr#D97Pr3PcH`X+zKwNu zb@%lCac^*F_|eGd<0nt2XI{LVotuBP@aFB>`v2a&57yW_`0(-5*Kgl{{I#>Y_xC?x zApksfI}`>FlT4}&OA_1E+Gae&c}GE<}=Peez9C8^i;zq5EubD94y zvWWQLk-itniza<;2txcj`6BSaK}@%(@4sQYlEbC2)oSC0!q>z4S(#5a6UZvMf)a{YD?!nTty z0_oF>kKl{Auaw-c#ut${Y+Cl1#>X1Q{d@n@XxQTy$@6?{KKsK`@gDaTFSNNK2-C$j z@Eh?P!^+$9{0{ni8@9h9d3)9%VISBHiT~sZswHDA`D}R-{$(-=|H&og^(ygNxYdu< zdjFHFG4(;`!`{2DtVpBt?*wqBe0~|ct-dmicivw%vHBkAwm#f|8J%LE;7x3Vhz+4I z+c_C~RW5I6D(5D4J+=({!=%BY?@cf^gVKvdqNj4IMIK}EyYpD(PWcFn(GOVt(mkxD z?&AT`G=SlP$Lcr|GX0&Ev0=UX{Gp9_Y#aT8^o$puu{Xeu@%KU8aA0bQuc{9}Ku3^x z{%I>|7}**p|78yaQ-@<@l>ajnQ<_g0n=kEb-qq@6FfWYi9i9U7 zF6HA@eJ;@6**_A-ET3B1)&(7t6Tc&rCb?v1LnnNb*Kx4Htyo4=Byf_-PBt8cZh4#p z?tHJ~uq0Mp{LVQ^oFq28<-+_yii|^yq^TDfFQg}!l zi5_B@qy8l@Gn0SyFTn@_y+=V7?bF%w! z2yF1*Le-8lECq17vFR${_>&t+^uZT{#Nmdi$vo{m)0+Z`!bKyL+xbQ$m}k2U^We8i zfFuRiR1 zNdDLs(DtBiVtl36D#mFI^IEvVbcH$yAImgfhx||Tm{pf%jDL}S7OXnHsx8n;j?q8cDiAQ)*;KhAM zk|fpkpK$U0A=ylwXYtx2+-VP^4s{`JVAj6HJ6=bmAE6{gc%0;DILmAm>Lxip(yq+k zci3^%COz}UCFxBVF&9V-BBd3zoI8V@_Sm=C43Z=94q2IIvdlfsT!f?bbeTt<-}#yoW}EZm_D5SDz5YtdJ}2ytzaQ}#ZvBtXaP4JRPMEUP zU(Z_j3}1fdF^9eW^IslvbEuZjuy$o8hetcUkMS9rKJytW7W?FRl75cz8S3Ac@}x=4 z_3ZKx<;gZa!&cSGh`DXf!=U`qdzgwvpo~e)wDLmY0tiuQh35G%M@_uP*h#&{H0v$p* z&9NPTqtTL|_hAcIW%>`+rh5+xvL;ZiXgLuVcjoT%;JpY_(kuPp3z{DjXHKrUEfQ{# zvKuhzF?C_z>;9n8(@5a5ccjM@dV1#$kWNZC%|4_>->59j&~~8tS{sS?&*Twyx=zcJ ztp1EI5CVTZ9YdeWh+&6X*PS{Be|6{qAtf>)ZD=hd;c)kzmtM?C)f4AU4_*9IS{Q-0&NtC9I8MAWDqOTZ`#i#;XUu)8pnfj$yEuip zCKVRpI03>yMa6h~CV;qv*-12V@bQaXfz)yDspz7+JC&MiHpi-EG2k+Lzdo&8o%mOTi6knJ+ z&eVpkrSnu%{{SwChe`0Ygp`4ZA^sap0E;4mI~nC%Q6VXaBp|{UA`2B4CY(3ba)jfs zW*;-7H%H5W0Zz|53g$$~|15GP@G>O4V2&MDH$$g1geA-V8kL_ISH0TvewxI4o-jMn zqqMoX+1<*mEGaB@N$0d@WQ)mn&NnkOD-bs?B1jRMWfbe|;*jvky2t}SA0{9GfZ&2* zwty7R{Z-~IIY^O)u!b-cIvu28aahb2IDLK%#B*zTs~XSJd5E%%Y`Uy@!!dBMER2f$ z<_6aWiHaegkg|C5>A6NuaaEhOh+@vel~qq=Ja3!0hbZms^5`xY>#sZ_*SMT?x2(srH;q~x8`0Ho-R}d!b%@zYgipV ze@6r%jc`!Zjao^Y8R-|@`b7nl@b+(LI-p4e-{!2PrEpk05Gf5{Sb&6pG!TZLBnYvD z)sA~c zi&Fd7`f>S=NrAN>GAC#7(48)soPt!fYdx18$OFJ=V2(}XcWgLYWfpgeA@m)LC|*c?&R3{G~Un>xs?27M`$_ z!y-jvlmE#jGv5tx!*j9|cVC>t!pKtyUo#~yj|rpH9}keepT(j#E5nzZh5?VR7u7kN z-5Zo6*E2ak$Q!zy7Va)C#QS6!>$-Jv%TfJo?(%qLv+n&avunYXWXD46hLTTwJK&L+ zgxoOp)9Re#&qi*|R@( zvb!>8r?A0XqgMZLBypH+(Nc{ynutifI%|5^73BFg~8KLSdn9rmOb4#q3I2e=!xAusyRdJ=i_0k9cYha3W zd$nuN29D>*q%vEorM!qbf$J!b{U4~A@=S}f*6*5^to@(QB7EzBtJoK_VNTUIQY{P* zD;XE2>gY;#W@ZwjOManfUPiULQ7yVR!oyHu>ee(a@2Nrixd$xk8$hSAPOGUEQv$g; z^5TI`s=uFPr&AsF24I{J*wXbKOSZha+ey?h?(C-d1muQUZ@w@d(UGv#<&cT1>e(Iz zzJ94*<<-io|9;Lh5cV=w6NWrlNHs19 z+{`r75OeZoJ-DP)GYo_WcA^G+e~@7;?vL=Lx=S(1PF{PLxYkMoHB!3EGW*7Y5=Ix6 zk*QdkXrexT(@A%dThqn4?{u}W&g(1@Hs!?48c+4brjlK}@(aBJS2xvwtGcN29+4?0 ziHQg7M~o#8WUuE;;nMiT1FV_pk0~dk)+;4`GYgNM0yPi>(mW{w(#o$bN7d_so6VbhElh^ zM!fu4(uW9LIY!1gl?Cn0FE4p^Zye@iSxD4^x26M2M0KFQy1IBdFEt^s>GECOaO(mT z`4^t|%zFn&s021fwhfN5vZHRDX5rBJv=IlX}&Qn1^W=!Rm&oGqY5a z&*rRiDuHIKq1YSW^}yy<;N{cSo`ILWu&H_72uWY&Ce2uI;;h#@fuhkaWJ&bC7iS+M z`ZY>`qvT|yZtVz_(5VblPe4_gZikr~21?AnD}>Je;try3z7AmEaLL{vkBBuoXwpe~YXP`KPc)H9H|8Q{F) z0TS@7=n9deK?HFY(oP7gimsgr1z!c4ue$;uXRDXOAnLjV*@0}zRbh%LAzSLwVj~W@ z1|Dx2EnRjeP*ybp-IglO3)(SX96`uQvNgdH>(+dnIX7V;4Ke#YnC$W1kh()ASb+R)!jJN=_k9-cq2}@You7%#lv-dZ0lo^ z7CIcPi7q>K?`%?ZnJp-@9J^G6oV&fXWo<~uc@aTXPn2`n@rpOq7p&Qv z(2y@@EEntpg;5ioL*)tvHjT!DF|!hCM2MrAs*qxxBu&$0&c{iV!kk_3tNdi4;Amjk z<^czt1=oN<%D7{Y=wdL$1#(K-6!KEdIn-t!03Sdji(Xw!--7p#0kWOC>vyI0!MxQD zNVk4+=N$Op^g4a_`N3=Wue5_bvvM1v$-%bV!D@f!yWh%(e}PScgwTMA2C}=crydd+Sl_AJE`_l^IAiL*PP3Oo*bWARoQFJ|6R&JYc zpz&TS{VW{*?{VO@($P+|iNK%0{phpN<+^%B;Q%K!tzV^EV(>G5#!i7O^7CWZyeK{Rzm(E3?%sCVs!6}x-mQQr zZznKZ-Np&NxE#pZD*|IeG9h)+jHUU#QIfb9dCzrJ1eZkpA;qcu1C&NTYDv`3t0#q-7FLO$jk}z6 zL&rkD$XrR<*btf3PSH_Nu<&!Zb8V4g?s|*zcV80KQN@L5;zHI^sHxfBAi=Y~8>qM> z>&xCv+VwL@<~S(0`f_r=ymBEws&O56A)^mJNRc;CbSctT+^-={ge=!;yV?hO>>Cht z2fSRvT<12=#c*7n)>B**G4!GCA(tLk5%{C-i=(cT(HhsK@)(K>#dTC#sx*XA`xSQL!^9@QFTh!AeJVUZK#&ktc*D_Rdbo#FtigCEbbBcCG^pn1KPUJoC4xX_1 zl~Q$VG;2q*yXx5YQLrEA^j4VbD=>4>fa1DL;apjSK6Eu9+wR5;#*BTgFSoQNGrNCh z%eqo*L7^4n;}y!O6z$C~-|0i8Di05Du6df;MCqS{OK1yZsYa~mT-vbwzKVjCNNEca z8|$95$@-{}ao+_^$Xa!wDG#r_)6UYbk<;adl1)^wYE)3Fd@ZE*PKa?Gkq7+5#Rb@q9U(L(tImp@uNNB}p z*RLOV=c!psZ(hHy6!~6F)bqW`uHuscfbv}`S5#B))^M>!pr&BmdI4QF)}m0Lo0r7gz*<_y;uAIf@YG2?mt2FvMwO9=Ra1YseUZc+XjyD!xEqEj zDC>_-kd^)-O__!mv}M7O?4-gXvRoo_oShB5_j?{?aeFXlab}TnaiCpZZ$gj!=o*)- zXnCCkTU*$c;9PG!d|V^k-fB*b!e*2(qi_0ft_;%~2AEPVBnqKNzmHHuUfUzTZui<= z(lL+7`nE?=DBUnPB}{ZAACODnM6)SSV=pRiucX=MuU@4aCRO*U8^xkbFy!?^RSaPt z5N33+)qWg&O;D)waYr6F9i43sLUNQ&;LR}Pltmdf+tVSMVe-Qut@4gc{*9Sngs!YRIsk(XNRc2e)LbD;Nud43&dD>(LVZ)xPzA z02`b4tF}=xXxl}e6K;}LwZ^V(F!^uQpSz5{bF*-f^5y%JPEnrc)HQI?Qvlwx;;&J zdu=yC)Ij$vnl{{sO3u|p!Smk# z{t9|y+b=gA{lV|!{SNibTqmePQ6GuI(Uud0F88)KsoX`O;h=8L?)v5#o@K}xtHDJK zVugTwPg1Fd^$_PuQY#uNgf39V6AV#sXKI!}WbJ{RKID)OEQngvf)uSOL?cb}tcon1 zwLxbEJWPzhG!8A>-uWI0SXGIDJct+T-w}0Gj|7FAoo(}USbM?@f-xs^WCJqgV!hxo zfh1JtPICa8bs>R6V39*ni9+*GFf=d>?8}9&le*FB_J?%!9r`POkNM8(c0{n+XE%XZ4v}IVkC2PQMe2|D zaICw{us5q;3(UpmSSJ!03$|thm+wVoGFb+p3syT5cd_OP-hsb>GYT6+OP4i4UNs>m zeP87JLc`s~&J5)=1}kTpo!m$32*8CFra!S6#3S#6g+-Ap6Yc8PId5l^3DHDdkPgCy z7MwEA0^(u``rHeDMllpJXR$cNK`z~Z>{MFuY#};{$|Twhu^FLJ=k);_1=UfR($!>U zLOv>2C&oaAz2Ka+`eflxYDl=4vepHXzJ~1lGQ{byR^v%8e|b_pwS85(h5kTMl{gS{ z7ahJFpOj9L7r4u6+j!l-tQSEn4<|5)&9cbZ@8spg3ke5zY%z~KuSg4Tgt_ELDD=G5 zZy{cW>}bCO6+NHrUhqq}79dg|)^nLH<_F%KzKkn{#gPq5=h*m|KGtXTQ(FQKbU90d z=Y`-et*z`d113_0pwgn-?DxP$ud)zcVL;5R(}1sxF|#R0OxWn#<@nQ?0oM?r z7WnwD*k~K=P^g9UtWL}~oA{u73AM7&P(@BqVS?g|mzU>49nMfcC*M7$81L$SGJh;7wt_XcR&h!c-@=%3R}=LVZYO?N-JggqT|M&HH82J( zXCL`7@2hUxg0(Q~W4nlMk9r4omfbK+rrWB!Bd1T@VzBH*<9Y%Fu({$9jENhpM-B=E z-G9VwvpqX@#3;;u>^yqX(EWBTh&C7MycC@MQkxYg?b`rDG8%~&T54W0LsOc3Zbry4 z^&Dhk1kk{d?`aMjEmN|JzAWZ9Al_ynYzBVnN*%r8P1vrZA&2o1fXkb>gloB{rwr%R zBq^+%c5oyB^cn56PRW0!B&Z?oMfS@E39(r-IC-VdBg{_8?DcqQai)NStBk^ED9mOc z=VueqJF}h!4Tlm>!!zhDH#MkwB>;?`H1^Z-@ae1}oZLG253Hg%Y4(nST1Wh!FYc_C zN!mgD9K#HOjF@3W&18g+OH*iArMBFsVf zC{Fi~5El_Q7k5=D&O+$>`YJlro3mDix8;@1Y1Tv? zTtqUhfxytBc3K~Y-PNC5Fl!Z3G~Bz26k%LlVLbFmR>_66ck%HZ4Z(TEy4nm;aBnd|9SM6bof1#rLW`lkTBQ&V zODCH)0WAc9my=PwT}#^@VO^X~I+x2-kQ6Q0XND?}k^!bqt-hCMykVm>?vTYCNZb6$ z%vyRB(&~LY4VPiGtYsF8Xt@l7M}W+#;dl>?^aD6l+5FrW#$ivKmw6A8WGl(Qg?S7> z#&C&dcR-v{mllKMy1ZKpc>Ez%$M09xOISBIxhZXliF z<@;G)@}~7z#v@UnDqeBjwW5vexKuqYX=AnKy_#+%0XL8a>KcWqR?<$mYbzRtO*RTq zx1bl|CR}c>=y^qp#%Zj8hYd`rZMtSQg){XU52FV}1%rk>GD9)AbWpF#fvF8h9rTBz z)=`ypWfOz-8?_(ke#by=13ETt13+ zn!QKUowOaKK7hhV`g8U$+X-rHm z5Gx?ahbAb(3b$G4k`#p#J$;E{U9$`QHnb><%QUPb%A%WNR;_FI0O1fHquX98EUD^3 zvCedBX%P%dQc<_WdSu{~BLH!noO5%_ZvwS8AQ5NI3H2~v!?|3Tuba4MpNKAj_DX@ z-z@ZnhU9Q}huJTtHgnCy-EGVA$QDx2n4zek6o!!f06|>AjaC&NQE6_UnrLo_>hD6# zDjpQwe>oyN<|1AbjmY9yxe2}vA(tTUi^3h;-#ESfP$ibaR4B}-bBi^zVB)JorJB%i zzvtpGxG2b*Y9k`@1cMBZab()83H4F@%td8{sWOXCY?bEXB^-|WU#h@iE&K|GBH)s( zY)WN;m1SuYQ=_@nL89L80k@Jw9kTcxh9(M^v}TjT9?=~#31%-NU%h6lYb z@SdBMMthSYH114&J3(XUgm-ij?Y()#c}Fz$0P<0!da}cDB`ZVe%jvs}!2XZ3<0lbx$ad&2XxC=H%9Y`B|CEl20y+gC`$>P z4KcX4P^)EjMoeHoA}7Jo|Bz{$?a?3Y3np)$MpPo=&Slk{RPmS$y!@tzY2c<18iS>^ zTh&^4;FNSEv<<#!R8DiX+8$v>hopUl7f~~a-?AN}^^Di$`i?q&kuZ#? z#Xh|m8m0FW;~t+?UZ~K8v{(~zhWfp{v+TtTyd2da-74Ia7*CiGGHV>&@@0c1ufYB8 z%l0A;&SdSg)hnvgfzle@2*I>mBy_}tkw_;@706=&20Xe{NYS@1 zytf_CEA6?^o+S-1VtzKE#!s=l2b!T?R#(E8VctFi7u&)OJfE(p z(lg*pYj>4d)wugH=U2Gm${^ovhmsIY*CxzQu_VW-2E=EQ4t(o^*^3ZA?uD!&yuSik{jH1zb3x2r z=7{^51AQfgVyyJ@*8YB$w{m>Jh3BMl^N0Qv8J#SuLcCi#fgK-vrl)ar6D1vA@|14V z?;yh~IAD#OJ+l#dVUWX3ASL|Fhh9hs9d+-J%TI{z*Y2oE7hs|l9f}+l**R{LsfyEe zctJakVrBc=kQ`?l_2~#{+NQ&XDFIcUloQXaZIy`bIj)geSRkxuHzB&*8Z+BxNHud; z#|v-}xLFfHWNFzfnXGEx?Y4u8W*J#8(ox-^&o3tYIZK&1DN4_C`K;1|@-ZAXy9>w} zs2%Bln~9+GyIRC>u{1d$%|db2F>S!fTh_d$&+m|-xMKk0r1(x{tziq-Pa1{N#4F36 zaq=4RyU9?;?hE)mT6426^{X4A_rsm72VpVgDe**aXI4UaZ)-fTA~K87Qnl<;uzI9h zQMFEGWYNhbIU17r`!f&^8SY-I5Sp&Sh$@nN1=tTc*$C%Xze9TO+F11td@9k3#|F!` zLRHU%SNW`ZHDS+~Gp4y~!e=~3V`8yB5*1CckRD~&Ob>CQUWHKlTMU}z5!5*N`vSIY zEz5_Qd#`hW%Vr)mA0NR|$r)eDFE+&!q6dJu#^|Ob5&J_dw^+G!$)(ItL?21=&qqJw zXk+-BgL!^g!qP8C=(+thhBb6w096%Wi>I$RIvvpvvDbJwsq2S9mVdWd9$L-o!-^Hs zt9nO%_xT>K5;s#F;c3_ehqTmyXX5Fm9ErOtv86sSk0hW!;Tn-5->Ditqbefx57H2d zV%ID>en_NGy>D~x!ux8Yz3<)exnrSV!B*n8$ADVaGPXkn;E4nTAY*3LKq!U>wfzus?RWWpfgpAuA?=M`xB z--8OO`+Rq5|Bsv(4__7+{6PZj8Et)YXelaUVnIxhY*D+hFH zfxE%rnVt2AVi|5Ys`*2j2OQHTdgTa`W&@x77Jfx>kYw-bkbgt-c~|Cv`~_e5A;jkg zw`vi$IvfaJwIGH=EQlw)Tt$&>=*~1%mOYXiJSD*|t1qknvcr09Q4$vdBYI*srZaQlBC3c9;WvJVW#DB)V$HYDIs>R_?U7dBw zJt7`r8f8GPuMJ+jEizUyX*GZD)cc$Obspf&>?@y_ImI^I|BYaqZ;4)1zf z_I!s$TCua5E;ZC4GUw<=4dvIoqg32A=uUEl|UXkUjK;0(#0Cf>2`Flygq zx+uQ(weHpl)i6bMl1N^l;Y!J*XyK80;%JddDa;244Dlvkr@8a;opVNDs$T1%cuKKv%ut0lRpQTLO1ZH1&I^5cTE*S>C9N16nlPuJHnq>U=viE&zIV zeVI;i@R7oE!M60zEJ zjXy{C-+GK4eWBqGS9&@b?%nlfa8#_V-pTK?5>jm6gChNs9%>ZDzS}gj212NAK_y2T zGyh=$_EBGMUqb(kJ6R%^Ct&^@7PY>@{Zn2#HLf+u(I7I!JF>|BuDCkj1bHj4%JLmO z(vF&y?kHF!za4S*mJ{smpGB!~EEMz<^?%>#d>4yw>^}FQ0kS2UkFuv(j;X1Vq!=RL ze9<_Ixt6Q-4`!RpGe(1hS(V==#Jn+vi?}n3D$TXKX1EzClywH%`AnEISU1GeFWxzL z7Uq{Flcsp8X+$xVo-XjXPPpwRHu&7oOn$_uC|+Ugnmt<-YF?V6BPQ0jId?`vZBRNk zML4*}?e>9Q^r$TKpC)J(%3-w7un3x;<#cK^wC@4>ZVI%04Ye4H@`l=E^m|@%HivT^ zn))o_$L_S7`tV)}%@Aat&PBAAb?WUN7VZoYIsC9K9Yd8VdC=DN7b1oJeT@XpYMDb0{*4SZFUzt7^^^@Or05@}!9}Fhz+21+|9a9cGz$+^rsLO4uWT zQD?%6a6|f&DvFkH(o>ck3yBoGGgBcE+|F`lxw9C_$3wob544oTq}xND^=&ycg7n;o zy0~^xT$EfD>wrx1fiKR<61cgSm=O7y(H(VR6-!SVlya*!Ixpf(~4*z0{eBFMUZHJ z)XlhG=$2g1er)I<16+}3HWZ{`nJ}>MQyCXu7A4Y<_BnF6?~wC5Hh{%IB>@lB6ulPd zEIV9oyFvjyDgP=2n@d1@s~okzYh&1T3SlGrT~9bOA@mC6o={z*az}0Y;Q)NdP)Bd# z%QAsdq0g$y89n5q_1-S>{?wl_GKun}4uxRYO zAs*RYlaCWop;{L;y|`*SCXvDpt}*A8MAG5C@0OM#T_W9iZ)+?*9JwL#04H}QNQN*Z zav8dn(0smM@{E@lS~$DkG3a5xLO|4*ip{N;?0`vZ{q{uj^V+AElVlte(_e^xcWZXd z&t6&46PmYM%i;*PPV<7s#yH+qxu#i#H1m1Ei}N<9Uu9u7ehwq(&|kI~q`;zVY=Eqf zY!X_wB0V_MIjlk~DJq*6+)(fHz9y_GSSd>}GB`~>Wg>)DIfMf<#s_o3tNK}{Vp`|_ z1azOikpB@LH$0i*I#2MmPGlYWbiCX&UXDz@9%X1HF)GTwt`L|s8lvnvxsZXe3)Jfv zk93RuhK`@{=_g5Z8_75XlK=90bKJA@%=NBaH1<`(kKa>oUxS=qw7#IJ z-|i9zt>BQ)#(BH5GbAcw3IcCh?R%k_3T_@Wti`x6^kj;pQV{9nP?qaB0@JTpcTQDO zM&gjG%G0X^nBZiMYSGw&`Ak1%wgF6{7$OEN0Ja&9}!%*9UC%JGxt zc?O1K`ctPtNjH}jC-#i74ETlChCODYFGMLHZN;#@%~!nApxlzUFNU;APWWrF|67O# zfgM@BAHIwj)4LQRV`mx7AS81T$=VX)$`@WZoD31|lP!Z2{I1%WES|hS@DmK(@?x0a2BU><+Wz@ezfV%mEAPc?@pR8*4Cy}1QCt9L5>5VaccIiRG{P#ZJqIbQ z28DX@E&EjqrVjy_z-9cQ0L48I3m00ul+63wzP*3!ZglYfdczqzto=?G*7$QMJ|2sKQ<@*jjf=j@cfb?(5H+Z%zh$BMZ6qP%sivH@R4>@ zX?wf_H_2c~D}e-(I^Bx7B=W7-)}1!st=M;tu;TZE66M;v=p%O&X~j9b{F3P@?P7ZJ z$OP(Mp05dg1lcP+<5id0o$q<}?9PdEGFcwcmD(?sP2z?|6y!?7Ts}2E_h)`jxD>{Y z9=dAM1C|Oc`#(iz9uLL;$MIRm4r0f-E7!W$m8D`)tb27?gsmKl3Z<+{Ryo$aj&g)u z_qvzJQQty`qe92G=+tRZ(P`DUtgik1{O0d@eC9Kc`OJLgeY~Ep6Z#{b+pCn0JYwv0 z-X{{v#o?u94<1gme6*QhG~48)V8ch{%=~CjkV(Szq?w-IUa>L8euRwur={L*TVT2a92UfLO(srSw2*i&aeq~i2*TJF9#=4L#Ti(aqeYBa}{ zx}f<=mG$BBAJ54(Q#3FCm$BLTqGpVT-M^>{X0C*n6>_g$V%PZ<6wa;kM+de_)^=pZ zKiJ+RMVCsEh( z&Txg>hSgIL$-O9Pvpd6Ueo9OwmRTK#Wqsv6L$_~v-)8v}MiP8olx5{M>E^UQkCKXtaNL^zrZ`BW{YyNtCBDicX`J(d*DPkQa;hP9Czd!pJ~v zn7fB9ToYXJGO;hO61a%E`YkjLtEh1BtnhEG>MnhhZs7F;uMKgS#hC6TF-Oi)MzQL#D3XB zuTnk}QGbRGR|TR_Fl1w63t8JcL7V<&3hNOkMB7$YXY+Q*Y!koyYxIdt_8u!=!3<>K z=}Xv7hn)OEAieGF4tsvVbGv`+`4N%~*@kAahsg)bBUq4!+ZInxK}QBrK-q#&yteLu zwoYyz$`fvpOTqbg3y4C!aHgaZq1`;J3f4ki&}QqC=+l!A^SzMA`9zsIZs;PyY?NBKcv z#!uNDUQG#ni6wUadNX|}4j)HD5}*j@11D(1Gxm?{y+-pNHVOF)<@5{Fho^8&fRT)3g=XQEmb%o zgy>m)hcnpp^gK!$Eiof&=E~+3QEnmiRCQq$v!u=`IdKVJ&YL>bRdl+8e5wfZ=Q(6(YiP)RGj>=GNt?Jhk_FFZd~islZ81`)iVa&V&ZGM&>)uA1u8P8Eb!F6^um z?5^#nr0(U?-9O>~#8tFG2W#+0>n=jaTaB{-=2$yjnSBG&C}90eNtQl!r@IhVD1TWY zfKlYqtr1T@(B!@|Of{uzurPZYxQT|4BF`+|5{jTT3rO%MdB@(6o+vWd4{tOD~*WjQ*e8k{T(C~Ns2=nWRhjkuDPI`hKUbERkxj@cCD` zXRqEMj67i_3WPVV(|d0aT5rEV?mVX56OH_KB;`*4_5%?zNh^D@%=j&wo1XdsKSM%R zm=EWne_np+6Npj-FYq0&Db244-81meJN)_C^{E2UPw2{9`0hO8-}h0&^S@R?rE8Bo zAfsF#h^JQ}7p?~Cswfp{b#+bagfP;R{noosc-Q@l;-O5kyE@*C=`*&T|ReS`wMt#%K+V1lg4K7{lhDM|>^z7dmp<*2p1|EqG z7}ecf|6D}1t4K6=!k&P$z5MFPY85i{(?9Ra86`AvW!xRJZ+j&zvc7RqnH<8|?RKBt?SqCn7eMgWTrwkHhbqX{W+&EGf=xRe1{Yzv;g~PW6$9=M)|sW4;&Nw zl5l%Zp=9aUsK%|`bG6GMQak9y_#uPc>akz0z56GJz6*s>kpCcK%H90MkyoUjqE1&) zKi>H0fS^&Kb9a`kilPy({Ntd?(P!3ll6n@3rQ^j(ko@f^l}o}cWYRUvO=+|1HY07X&4$8Xr9MjtEePu$M@2k%KpR!NQQi1bTkDVueFN`msNl-G z!z2Hq1|O#?Li~`tP1Tr8=tV@HbNK7OFW&{`jZZ+cFP}eu_U!3xEVT3Zlflp!b?p=u z6i9T&ClxX$mUDO`i_qNkOI2thaZYAw$c#F;n3kNp3Hw@rY)S%u4H9#j7XL%NrN93V zbv=ipWxi6diKT9Nhh^}_`0aes5@CJzKP#w@^Y4~dI%fob@6~exf`-&X79%y^{238% zXeF4P$nW{~8};+wf}%~~Rx>0U^^`ARfES@WB%!~*x?t=l{&Nreh}n_^+otT$!uJ=N zVCd!90u%eB>hXWSd|O`r@6Pb4ykmp|tP24qL3o_a?A9 za1*kMe?Z$|He$s1KdXxGjmQeT^ibYwgX9cq_|{QFNr;sewB8UV;~9@G>DeL(EJP$1 zCyOnXRw#dBZ|UAZ#9;E-G)9Q2m$c*o@q~nW-@$Izcd~Ewv#C-%r|6GPj*dp#FS_p# zt@imtj-J~fvn_idyKMoGh3|gIaOWXt^X_P9Q_x|ufwsih-XvLPols|$4-^j%f>-%A zYLOSd1iyXTcES$trwIZB7vCUCKqvw0@8|fC#clWR3-tGg0(O&wLQ*{r3UR@tJ=hS> zU_3oEbO?w_Jbi+~Nc3=M7d-+B4oCKc?Mns%5#$#hO^7;--+ut29biB~(J{D#vEQx< z@e|Q0koUn8Nty@J;co&WDT(eH`2QV8Fc%+ z?x|dyUgpJ>)S+b7sY|CXKn~@U9hp^dRt*OIf4hc~iEB*u(v?5Uf<5S{TrL!y=bSm= zky(!eBccg5ydxL(%58z%bK8(pV48BdQ^fZvY$u%IJC_bX3DUBHk;>NYhCZE=Oytax z!kKdJ%cx9P04knCYpY&B8r83fbu&Y#K&$g=W2o;y-fF(xXiUqUKw9=;9P zR^7%Aft0(||5i~9D_90KQ;>1ZQ(EmqNGM7bn%6$T*RhQo1hht;Le(5xO%=Lv-`389 z4^vf=xOZM)u$G|8!>iZLLKp-O4+*AK8%T;+ZB`_w_R?1DE83V#o_@~zv(H+B#=cT!1Rr1jl`5=^K~_ZLbxwFhy$ zz!jFHa`n$Hc@sKevvcdZt^^M@eI4q7ZF=p_JN`pRByWD`7Ujw#IyXLmn_wK-sqetK zNlMQ%;pOff-%F-%^t|Er4tX%Q4E(2fO2A}aj@mVZ>>m0~CkpyH;KSD^Qtrgx`LX|w z5=%dYn|zO!os|W#OABzo#Hg$c%H>3H%7MXa(P#xXs)*M{?6^#z{Pv>%sqFj*s_Q0H z_goEZy>J;`iTio?pR^12ppt>+A;G!3VCI`6()%wwFp>T*oc~}M;y%8HPfZc>o+mZk zBQ-qz3O|>IQ^CTyX%STaf^c!}=O|9@1|Rr) z=Wp@xp^=fnIJ+&%?k9BOO3wBE16{+vNIHKm%f7(DabqsO_X>2?h1K(0vbW_(wu=LH zU11wIBjSx;85p?I*V`PP>8Xs*s88GRVum&8*V5WzPj6|fJ`7(G3vUAK(F$Ir6n5Kk zldq1Z&U#krMrHDJA9$2vnar!@Z9%Xnc#sAbg`gF}zX;h14UXGKi8a0^`cbsbAlI*}}pX@Csmk zonT&~Y2pOAECfN3$$CwbR}n@(&B4+1-axIBKlVx=&3i~W+VK`N>h693QiJAd8ce%2fHe;OL%sQM>&!kyi~G!7c;pFUUHH!xa8If%ok0lu>criV?+dRqm0g}8n-R^lv(JMZ zI{>QJg1gIzj7X+rCKi7|t)JO6{TF{<7 zLbv-;QK57=ebFSel7RXEQQ}j%3DXi~fQn!SQ_I$wDY3xd3uymO@)j(y1&Oh`S>6WL4r= z6#`3a#sDp&4KmK*P2XVmQwuIK3t>k!$XaD-&Cn@gY+7F7R<>Y9G$_cUxE7onFYF-{ zQ~WEhUeBceCGgHe$J-&5oDpLFNY_%gI2Bv=y+W*dF3UsK(bta) z{{qe!M67=St-klr=7vY(jTHOVSN4M7m25$3@oz_zW#?ze_Ut?J;Mu+@s{Oh5W5z=?I|+`d z1>UyX?gkqkx&V_ee&g2v3%5^AF_&fme;i6Ue-Ap@dyClhruzbHFq0w(yvPpf7kTv2 zJW0btQ`{X9*S|yBFzfy@l#c3L(q72V%S!;WLxTGiHFZ#3EnHLI1QoPU8oRn6e(zsV zD!2rl@9l+74@|XR8zl@)WDie6ynF4dQR7hB-R_+GaLHp{&D5&TWIO~U```S82Hp~P zg{oShHsDF99$?~8BQK+DWU^N7@(+;rTHbQc;q=V(n1Ho18y-+v7(hNCB_lTv$~fdI zzy6)Pm~<)2?+28@%1L&YsU`q$gDAf(K0?v?#L4Uv-bR$DNP_%^A76lY?f!%WX?dz_ zg1(##I>ARST;4sdj{#Ue!cdBF33M50a%jSlwc#?p#~=q8$KMk#myd0d*`XZgOq7p~ zl~4$il~g_fXtRyZe@EzeSJqqWo6l3 zlkG*pMyXBmyEFeT$*y#tZEkM6b}q>UQ)nz45)A!kD<4?g)eBX|5RGI^T9svLto((q zUjliP-KWl!o+;S2*22cB(IynaP8sw4So!9bkTsvLENrPaE6nVzMM<_StoTJfG=X=o zJS-pdRN2d-kh^L(USZ(jv;i1?aj4iu66Fb>-W?OrwS@VD2DaV%oH@qRin=ISVwSAq zl(oOu;7^PV{RHIZK}m4i>J4q(vgP-dp;9K|OQpu{*hwQOrTYEe6$))f`!f7?`ZKZw z`kQIHAY)1}d+VNvL7*Lu5W;ZV!eXFZ(F|@RQ}PexWW@ z1YUt9-)QXr~+SY9VoEoXt0@e|fL|G3EFSTZc?nskZz$!g`N* zsy2Nh3L(PT&-iGyM8P?dZ8t)ga7_FenB#B(alGhVJt8>!kQBz40sRX)IrLYgxb(EN zz|$y3VL9aV>o3TzY=*e)y-;gsH`Lw*cU`==_xxo@EV@PtAWlqW-sPU2{00?27TGNI zp(oHQP{(xNVPC}=!Ah?-zF5U&*REZ1nwE+y$Tv%z%x*m`*X_Q(+c&Y6yN4!r`9?W7#T_`cxo%-|9*P< z$6juY6-C+^@44mT2K_)EP+&TXU*oRi($iRVfgIu(7pR-06tkj z+-PE>>A(Nr!F@aBrDbdpgZ4&nK9r7_tI9}A2Zbn^JEK$~+docew`0(pt7&L>%k{UP zYvDAM#LOM5?3vi^M>bX0-|1?4=$o97K~?IbrQ9FX`~LPt!3>if;Q{{{x@}XJ?r2%J z)>Z+=5F8d?zy7~`I90Na7-52zLs6tvgRVE{$i_6UGPCe#10#aT)gC6w(n+5li?jB6 z6mP78tdT0zhbHk0ut`pYi9mS@&t46V4qKqtlQucIa8_A{ZXTX;!o`P#|Bq~|apvfu zm)44n#a**hw5_Dy5g(}qm1#|dQ6G6rnj_om|M(sBHg8`)|J6wq2LuwdiJxD4qCSD9I;snp&lWzytY?n}PMaMZ?(wb|=s*0r|BpUjM_c>U z@1veHh4DCff9`g?vyInO+>nK(E+!wP_|O;@<{W54%T3{hB-)M$yssl0b?VhmdL3o5Cx6n?Mb9tx_EqyVCFq&{hm#!UMk`aGCI9!>pOZ1X&o10t=m|vIzYmeYIu3tZ_j>DxG@0ilv zLGxdg7@Oj@KhVWoLX$OeP$;4_v$(Z=8qu=wT7zn8JGc^Vxo+M0r{AZ>0TLl_A(LnH z_4K%s5)ylm)#vGEYm8kZ*=XplD~Uc}C+Q?>y!!q7ljNy@+HbRA!w~P6FjZAvj^yF) zE}S(PRw6Zo1|zz6zol;{xLD(B3(pq9M7ra^u%)~^Dq7f}EF9;9oMX~t+ z-m-iUPhncY**K4eUyK4nS})2nq`WA$#`%`u_bOEGi1dh8kbsKHeQ{>p21Z zA``McMhmv1z&6en5&=`sV7}C2Qmwpp#(U4ZT49_YOFz<)CW<2EA4rIBR3|0WL|T4M zl=pMNj>KLo)xbV>P!RYHR_RP}aUd=!2{74gkaDIJuB-z|b$l?$`YldqI0ue4_L3Se zzzyfYvHC7*U3(z_zsXhg@R@Run3oTZq^5!cM~{MV&)#C4!rhj}_*LxRCmpJ>>19dD zR)XKWm&pMKv;kTPefwy-o}@rtvoSjHp=)=w(@)V8oSb~9&dz`U=Fke=I(j-GD+{o= zRUp2B7t*j=@LfG9yfHwky$4Jx9{@b}A<*GG2D%kbfPU3eU|2l`1WC&mjL=xU%BLi4 z&LbR`wyx?;5%@I$HrL#OYX?DO9XYXr_vZJ&U|}ve7$48_4-5p}D6myN7+;Tbb8&fx z+jhIF6v1y+#lYl8{=uq}iwZixmp{q=@hS>#^rz)9@uqiezqjqcP^ZJ&wz~`r=MRy zJK1@MGTspWe(h(c8rSKxYL-9F9(wZ$;gWY?k5@Kf_2Cx(FRSY#*wpHIX)YmKc_ z54^dDzR6zP^EB2W)vhpMW7}K4aE~n>Yhh5m*3z!(7Uc6897J8OllB~kh{)C9+}RlZ$X+yg%zU( z3dn-tvROU6u4%z!)lJB%b$y$SZD(jm?=Jt?RXer&j^`JRPrQ8xUvRo0T=nX7uB{Dm zwMBbJqLYKF-!Q*0Hr3g8koSdj6!M1^_!ROH!C;P{{nWnYq0|X7;;%cNIS z@mjBU1yt`pwrFb6Otfyd?64wYaRghEu={hkW$0D9LoZ{~`J&CEmUT?w68z6s-bFa( z<%?V7ZwL;)bmM$XtP{GZ4!fy$EXCd_n1g(rCazy`u#0<&%;6ge##544KV#I(Y%9m9 zmCXbRjMjT56T5?8=k)GzBt9NqWqL)rt;4}Pt)(QRWS2Gcn$GTDZ_ZhmO8g2!A|e1Y zCkLEpyEtBRKkBKPLI-uC?&ZS$b&FOW9-|%YQ|mj>=dj%iyE(#lc0KmJLiqgB1&1cn zy2efO=*?ZQ_7?ORM<;3#dw)>^+}e8Sf`vAI{0ruD*T$9MyZf!%*0q>5OcS3cz9;`e zN@>2e*FeIlqEuPgeoq!|H-~Z6SXD(Onds|kKB_-ANfMPMKaz*BL~}EPq*E$INQw-oeQ~&cbc&77Od}Hf_vZ%mHXblMfYy}W|LK1DtX?v z)7j}LBlUvEJNu(Wi;N|VZCo14UB}p#sO%^u2{fW8BAR zkN~et_7)etBZb^LZ$Zaxv(=W13y@J=&c7K%+K;HI=b^?s`4$Di9{>(^4ns)6KL!8y|0v9EjKW}cD&u2 zo_c;5wd$LeiX|+)o02pnc@jHt=6sk)X)(-V(K`Kz=GAp-0VoA9Z+Wlsc!-9jo z{UqnS#a(G3g@{FeI2KNMk8P8Wjq59IgZZKF9lRWE>kePnaQ&adB@ z1U}nz+06W0FZ-QHXwe0)TaEmuEMYy`H+f=@6%_YYhQXHnx1^9KTJqd6o(=^v)}hS^ z!A`@9%sLIu6zA^n>|@EP(yB<9gUEYZTKtFjxme2V+f7iE^q(c7SAqUSVxyqmd{8!s zP6x@$5ogEly!&=1R#f$pH`_d~?R3q2*`)mw+`%>NOH53GeH0)~I9;!ytGD@~}2U3)=x%h|dm zB^JJF^8Xa{YJB}_iJXVmZszK=lJISmiUGS(T`>&wU~Tggh58-z;x%@$XqKUo*2i?S zrdjG9mQPFb=g6>bW-+kgxHiV*-tq<{e1R34W84lK>NPKbx2FGf zMiAB0dunA;QljrOA;`msz{9yA<2M6_QA2v7e=S|>l?C@RxfOQ{9ux_h{spQ+Q1z-# zIF2Zw8*y4KA7TC%xJ`9wplVTwv)tqg>VqYjJSN!rYWrc62{>R=V#Sk^x5q=5;IqtN z?Z#CpZ@OsLm;GU;A_N}!!P>CLKl}i2O|1pQn#Z8JsK^3;|14~%-%7E&4h!&2^NVYN zx<9=1^vtAp;Et)x-uGmr2klzEamNl@4gY$mU1WJ!*f_LXCiHkl1~_!?ra&t0WSkmz z0b9#mzL8|Z1kE4eR)Qvf5k29J#*lfiKC>~qh*%F8z|9q*%Ff8Q-RFH`Zv7&FqhQ0D z=V@Bj<193cr)k6Mb!{6Vpv0zi9juCP?6LF|6;VgU>ExaC` z2Y4a|g2-gIwH{;SWPfIhz=tTN)RSrTQElU1Ybxn%EhGLZ)-%NjSkdO$mntz==O* z(s$DKu#cV^FS?!^m-UGwgeP>S6NhIEgc^Px;GVS@`?AImBxi z)PB6P!J2IEPW@#~_0uvK<}+%cRL`#`)5+a~K(Sb)lN`5^J5fEQ%3BaLemr&c?-JY$ zV_Ssqs_V^l`=w%oEy0M33nj>I35%VE-6|s%#)A(sTE4(*<8t?!XfSoF-ILD6F}#V3 zFd7$DWD8ryX2=vFIhNj`y!$#wrq)fjejY;OcyIBqO_OEuq_U^1TlFfjvpI#h{XgAz zT3$r95QAs+�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%0Agb|;amcDG<@jNxg0~=K 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 SOA{rEoD}HA|H^-6;Qs&$uk8T< diff --git a/installer/HL2Launch.cfg b/installer/HL2Launch.cfg deleted file mode 100644 index 662b86f..0000000 --- a/installer/HL2Launch.cfg +++ /dev/null @@ -1,38 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --LE"c:\programme\borland\delphi7\Projects\Bpl" --LN"c:\programme\borland\delphi7\Projects\Bpl" --w-UNSAFE_TYPE --w-UNSAFE_CODE --w-UNSAFE_CAST diff --git a/installer/HL2Launch.dpr b/installer/HL2Launch.dpr deleted file mode 100644 index 7eacc19..0000000 --- a/installer/HL2Launch.dpr +++ /dev/null @@ -1,189 +0,0 @@ -program HL2Launch; - -{$APPTYPE CONSOLE} - -uses - SysUtils, - ShellApi, - Windows, - Classes; - -procedure LaunchFile(eFile, eStartDir, eParams: String); -var eStartInfo: TStartupInfo; - eProcInfo: TProcessInformation; -begin - FillChar(eStartInfo, SizeOf(TStartupInfo), 0); - with eStartInfo do begin - cb := SizeOf(eStartInfo); - dwFlags := STARTF_USESHOWWINDOW; - end; - - if (CreateProcess(nil, PChar(eFile + #32 + eParams), nil, nil, False, NORMAL_PRIORITY_CLASS, nil, PChar(eStartDir), eStartInfo, eProcInfo)) then begin - try - WaitForSingleObject(eProcInfo.hProcess, INFINITE); - finally - CloseHandle(eProcInfo.hProcess); - CloseHandle(eProcInfo.hThread); - end; - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2); - Write(' Done.' + #13#10); - end - else begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12); - Write(' Couldn''t start hl2.exe!' + #13#10); - end; -end; - -function GetFileSize(eFile: String): Int64; -var eFindHandle: THandle; - eFindData: TWIN32FINDDATA; -begin - Result := 0; - if not FileExists(eFile) then exit; - eFindHandle := FindFirstFile(PChar(eFile), eFindData); - if eFindHandle = INVALID_HANDLE_VALUE then exit; - Result := (eFindData.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + eFindData.nFileSizeLow; - FindClose(eFindHandle); -end; - -var eStream: TFileStream; - ePath, eParams: String; - eModDir: String; - eSearchRec: TSearchRec; - eStr: TStringList; - i: integer; - CheckSuccessful: Boolean; - StartTime: Cardinal; -begin - ePath := ExtractFilePath(ParamStr(0)); - for i := 1 to ParamCount do - eParams := eParams + #32 + ParamStr(i); - Delete(eParams, 1, 1); - if Pos('console', LowerCase(eParams)) = 0 then - eParams := eParams + ' -console'; - eStream := nil; - eModDir := ''; - - SetConsoleTitle('HL2 Launcher'); - Sleep(200); // wait a few ms until the launch program is closed - - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2); - WriteLn(' _ _ _ ____ _ _ '); - WriteLn('| | | | | |___ \ | | __ _ _ _ _ __ ___| |__ ___ _ __ '); - WriteLn('| |_| | | __) | | | / _` | | | | ''_ \ / __| ''_ \ / _ \ ''__|'); - WriteLn('| _ | |___ / __/ | |__| (_| | |_| | | | | (__| | | | __/ | '); - WriteLn('|_| |_|_____|_____| |_____\__,_|\__,_|_| |_|\___|_| |_|\___|_| '); - WriteLn(' for listen servers using Metamod:Source'); - WriteLn(''); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); - { Check files } - WriteLn('Checking files...'); - if not FileExists(ePath + 'hl2.exe') then begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12); - WriteLn('Error: hl2.exe is missing! Maybe wrong directory? If not, start your HL2 Mod again via Steam and try again.'); - ReadLn; - exit; - end; - if not FileExists(Copy(ePath, 1, Pos('\steamapps\', LowerCase(ePath))) + 'steam.exe') then begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12); - WriteLn('Error: Cannot find steam.exe! Make sure this application is located in your listen server''s directory.'); - ReadLn; - exit; - end; - { Verify GameInfo.txt ... } - Write('Verifying GameInfo.txt...'); - if (FindFirst(ePath + '*.*', faDirectory, eSearchRec) = 0) then begin - repeat - if (FileExists(ePath + eSearchRec.Name + '\GameInfo.txt')) then begin - eModDir := eSearchRec.Name; - break; - end; - until (FindNext(eSearchRec) <> 0); - end; - FindClose(eSearchRec.FindHandle); - if eModDir = '' then begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12); - WriteLn(''); - WriteLn('Error: Couldn''t find GameInfo.txt!'); - ReadLn; - exit; - end - else begin - if Pos('game', LowerCase(eParams)) = 0 then // a small test which isn't worth a notice - eParams := '-game ' + eSearchRec.Name + #32 + eParams; - - eStr := TStringList.Create; - eStr.LoadFromFile(ePath + eModDir + '\GameInfo.txt'); - if Pos('|gameinfo_path|addons/metamod/bin', LowerCase(eStr.Text)) = 0 then begin - CheckSuccessful := False; - for i := 0 to eStr.Count -1 do begin - if Pos('searchpaths', LowerCase(Trim(eStr[i]))) = 1 then begin - if i+3 >= eStr.Count then - break; - eStr.Insert(i+2, ' GameBin |gameinfo_path|addons/metamod/bin'); - CheckSuccessful := True; - break; - end; - end; - - if CheckSuccessful then begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2); - SetFileAttributes(PChar(ePath + eModDir + '\GameInfo.txt'), 0); - eStr.SaveToFile(ePath + eModDir + '\GameInfo.txt'); - SetFileAttributes(PChar(ePath + eModDir + '\GameInfo.txt'), faReadOnly); - Write(' Registered MM:S sucessfully' + #13#10); - end - else begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4); - Write(' Unexpected EOF, your GameInfo.txt seems to be corrupt' + #13#10); - end; - end - else begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2); - Write(' Done' + #13#10); - end; - eStr.Free; - end; - { ... and set it to write-protected } - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); - Write('Setting GameInfo.txt to write-protected...'); - try - eStream := TFileStream.Create(ePath + eModDir + '\GameInfo.txt', fmShareDenyWrite); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2); - Write(' Done.' + #13#10); - except - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14); - WriteLn(''); - WriteLn('Warning: Couldn''t set GameInfo.txt to write-protected!'); - eStream := nil; - end; - { Launch Steam if not opened } - ShellExecute(0, 'open', PChar(Copy(ePath, 1, Pos('\steamapps\', LowerCase(ePath))) + 'steam.exe'), nil, PChar(Copy(ePath, 1, Pos('\steamapps\', LowerCase(ePath)))), SW_SHOW); - { Launch game } - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); - Write('Starting HL2...'); - StartTime := GetTickCount; - LaunchFile(ePath + 'hl2.exe', Copy(ePath, 1, Pos('Steam', ePath)+5), eParams); - if (GetTickCount - StartTime < 10000) then begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14); - WriteLn('Important: If you experience any problems starting HL2 using this program, please start it once via Steam and try again.'); - ReadLn; - end; - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); - { Free GameInfo.txt } - Write('Removing read-only again from GameInfo.txt...'); - if Assigned(eStream) then begin - eStream.Free; - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2); - Write(' Done' + #13#10); - end - else begin - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4); - Write(' Skipped' + #13#10); - end; - { End message } - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); - WriteLn(''); - WriteLn('Thanks for using Metamod:Source! Visit http://www.sourcemm.net/'); - Sleep(2500); -end. diff --git a/installer/HL2Launch.exe b/installer/HL2Launch.exe deleted file mode 100644 index b5c9c39a6597ee3d0f32c5dde26f148201441d94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43008 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

55V$X_SxwbIGd;j5TO>d^rSiV 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 diff --git a/installer/MMS_Installer.cfg b/installer/MMS_Installer.cfg deleted file mode 100644 index 6c57635..0000000 --- a/installer/MMS_Installer.cfg +++ /dev/null @@ -1,38 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --LE"c:\program files\borland\delphi7\Projects\Bpl" --LN"c:\program files\borland\delphi7\Projects\Bpl" --w-UNSAFE_TYPE --w-UNSAFE_CODE --w-UNSAFE_CAST diff --git a/installer/MMS_Installer.dpr b/installer/MMS_Installer.dpr deleted file mode 100644 index 09273ac..0000000 --- a/installer/MMS_Installer.dpr +++ /dev/null @@ -1,72 +0,0 @@ -program MMS_Installer; - -{ - - Metamod:Source installer is published under the zlib/libpng license, as well - as Metamod:Source itself. You can find a copy of it below. - - --------- - - zLib/libpng License - - Copyright (c) 2007, Metamod:Source Development Team - - This software is provided 'as-is', without any express or implied warranty. - In no event will the authors be held liable for any damages arising from the - use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it freely, - subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software in a - product, an acknowledgment in the product documentation would be appreciated - but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source distribution. - - --------- - - Used components: - - - Indy 9 (www.indyproject.org) - - FlatStyle Components (www.torry.net) - - FlatPack Component Pack (www.torry.net) - - JVCL Lib Pack 3.0 (jvcl.sourceforge.net) - - Half-Life 2 Icons by Vasili "vaksa" Vorotnikov, Thanks! - Visit www.vaksa.net for further information - -} - -uses - Forms, - UnitfrmMain in 'UnitfrmMain.pas' {frmMain}, - UnitFunctions in 'UnitFunctions.pas', - UnitfrmProxy in 'UnitfrmProxy.pas' {frmProxy}, - UnitInstall in 'UnitInstall.pas', - UnitSelectModPath in 'UnitSelectModPath.pas' {frmSelectModPath}, - UnitPackSystem in 'UnitPackSystem.pas'; - -{$R *.res} - -begin - Application.Initialize; - Application.Title := 'Metamod:Source Installer'; - Application.CreateForm(TfrmMain, frmMain); - UnitfrmMain.VERSION := GetVersion; - frmMain.lblWelcome.Caption := 'Welcome to the Metamod:Source ' + VERSION + ' Setup Wizard'; - frmMain.lblInfo1.Caption := 'This wizard will guide you through the installation of Metamod:Source ' + VERSION + '.'; - frmMain.lblSubTitle1.Caption := 'Please review the following license terms before installing Metamod:Source ' + VERSION + '.'; - frmMain.lblSelectModInfo.Caption := 'Please select the mod Metamod:Source ' + VERSION + ' shall be installed to.'; - frmMain.lblTitle3.Caption := 'Installing Metamod:Source ' + VERSION + ' via FTP'; - frmMain.lblTitle5.Caption := 'Installing Metamod:Source ' + VERSION; - frmMain.lblSubTitle5.Caption := 'Please wait while Metamod:Source ' + VERSION + ' is being installed.'; - Application.CreateForm(TfrmProxy, frmProxy); - Application.CreateForm(TfrmSelectModPath, frmSelectModPath); - Application.Run; -end. diff --git a/installer/MMS_Installer.exe b/installer/MMS_Installer.exe deleted file mode 100644 index 93ad18c1cf4102f881c7f0ad0443f19cd66f6d8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 637952 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[v7A0aVo6d3yqj8MHxh}hY=9K-cL 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%0D%8!5Su}yjYGa_o&HB3Kb{FXs= z=PBon+h+gOP#4-`ZZm|0x0N>%=3~4kIpoz;JIb-a(HS`<_3ZD{p7#L49uGYV+`lV9 zQjTODM@_If>aPlBDsu;w)q){ggqEi~We6uN1ez<1RPL5Pzf_-G=35|=mJ@3}7Q!t9 z{(AD+@tx@BZA+y^*(wh0BBVmU&2a?iT3A_tFygg<4xeL85q-F?zz=v#-VI7k4_ zlM%2IK3VrvbWaX&xQ6(>hi{Wy* z|HrvodK^j4KmUJP{I$NvZ#JIkKE4GwB_ylE{Qsfup-Fk?uKvGm@1yzucJ|&vUkLsr z!4z~YoDtUtbPu1=X${(@rpH`>Qo!J^s4)Zt2_;W(OffK_y-Ej;M-cWZumDL=e6J)U zB~g3TS7|hPub9A4u}XUt3a2JS+bcQ3x+4GYVTd;s{eKTSf%*R)L>9^Z|2@Q<#ohkj zL&8gPpA-12j}*;6X(jwpqquZHxJ=-s4=Lvlk%Js4!FzwDn8}7{$uTZnT?v)LQIF(x z&@ah{IYr*F^zRdm;NCnJ7pnPl7<4!%7WUr(2w`|wPd9Y<(#kAyc2?4IEMl$(N(02J9f0yLF&LP2vo0xUEe@eeE}{}G?;b@tgS z`>UIMS5=>x=&{%yqr1_YkDl^Ru=*mfiR(4m+}K*XCDX3!%Q*Dn%Vl-625Q#kz~lk` z!SeSNPjQ#5AtyRqWYK_gtT=hlBE(hmZC{vqApnnw63ZlMSWLjAwiUVe#CM|d7_bsi zg_rp!8K)s~zs0imA|gB0yRG=v(cO{VM^~pub*}A)q4<3c{K+Oy z7KzV5q@50w5k5g`Ai$NqyJ2}~Fv~fsqi_j4LM_W3meKWM=ydaP%8%zl$Z}$X7=>h* z+b`Y?xY(k&IOap^er*v&XD|X~;14L!AXlFq1DA&A1EPUK^;~=4f&h6Ohc#g3G!5Wj zkQN1w&;U~zs5h?-&}LSO;3=--ZlVO1WkwS&46t0xDn861Zn0%;k*wPHD$ZpTlEHBx z54m?WK_c8T4E7Gl&YM)Y!|m9%_-{6d^T+gA!$9(B(OGT((@c27=pbFEh>!+ z*NQ#I6z?%_!t5_i^ubNm=|t%de7^M^5fbG1I|?aO;xEy;9vi|S*k30eV{E%zFXThc zccBmVCSH(P*O!)-#vlB>4z#?S9C0xZ2=ZIL7Aq*IF7v&WNoh_gX>GeTk+LALJbbID zMRV*1oO?bb@;WVX8`A{yxmk{=ySMpCHK=Ty{Eb#y6IemwaU7<9U93gy;&ZrY*fHCxYFVEBW4 zJSzUCj-AV1~%RJRXG`&-Or$6N; zAhs9&2m;6jWPbjeUygjR8{8*x7FL~I_f!{wY^Ti*1&lVp<%xzaUslz;QJB7|URTKXT*PDvg+Wx9j?lZp(o5gGHF3 z{ZJ0kOM@tTTP~%jpEjbJx^`=d%pemR_P7|Nl|@8x-lC3ws+_~H2f#_^_)i(r}j2b&B zJq?>vt9;miS)Lttd)WOz*BMpt0supGCNeaIdp+RF=OuB*51!YgOV*Tt<*s|z@a-l^ zhJs#k68xa}*^7it(N=`0YxrTzolsDuqCZY5(Gu63t}8-8h?+y9wWSh8OJ-XduTVP^ zKik*JzzBx0a!bjZ=SS_I+!WzcKaM>f4dcl*mc9f`1W!OkI8}9%eXzNbq5Y75H(Cid zcgCsc_EdvMGgZL3!MBZ=QyH2{X#%aPeQHTqKvv3y_kU!*PadHUtq;$_H^KFp*M~3d zymp)_sP(1Z2-!P%xML}y`mJ?yVZO*MpmA1ms*5e7@By8+h0zQnnHD#_2Y&Bk@AyU!U|QO`>Z`Cxq?{* zTv<>WO?uVKn_DS8Uns?{m+`?n!#y7Fu82!>O!@sx<~=xT=#B<14GR`HV6vA^ur>gI z4P7My4I`T>)yzbN_>6sb%(sdw1jmHr9;e09SJ1I0*cuvNNRX5G5|xu@BD4qj;_E6o z*=x|x7cA(ek2ec4cP};Gu&#)WQmu=N&FbRh7x};UfDT%;B{<*Cd8fSxfAmzhq9XQ0g?JAg&H3`n zIQ=t&AP~!eIrg-QorN>xK-SmfpVn)=%2}-cP-%XOgQPuypPoar1%w1WQ^ZYpJH~7;5`=}kBK-V2hVpL`SRlmW~vEq(8NnN*BLaB@A>#WmnR3gUA@^FrT_m)P5eagPvNS( zD64x%4OmFAqg3O{nCwMfnjt9<>zyK@BK%U+=@J=+74pQHbX5!G#MAzC=6W_a%e~f2 z)AV@EM3}q`)#DdXgEqiHW0c6^Yhpmh8Rn>4Guy`3(;Fm7udmV-Ar~7QKwlw`xb^jV zU5NVE{a484rQyYMqts6>XHZlhUtSm31_g*OV zcs|kPkXllc8!%Hq9~Ps;r@p-p=-Qbhzn#Z6Vj)-N#FDlOf3xvuHm&TrS?bT zF&1R;W=i3tZ)bEcMU3gMSHK++8q*&QAYxSVur13x)eB-1wMyrrLQTBoj1bDLZ7#!s zW*g&ItiI~C4d;bq_~o7!Rj+fdQ7p@29ts&Kczz3MEbylj#+8WfQXR*vU#IM{H}w3~ zY;HL~fci{<+vitnj=F~Xe#Lwr(wLm|HmI>1nWy$&)=8#seHV!-bsv^){Z4c1-Hm4L zxaXOqZKp$=@{v@4H#8jl0*h{MrhOWaKN(*{(>jm7Hb5pxHfo7c-z}4EAB{Q#2G81k z5aS(Da@y(NVIj;FcFKYV$Be{?!rIzUv->*^_R|E#5zh0|2zk%b+gEh`dYakg@xDZFrP?rMRnCOE-O+%Z1l zRkoG$5>#E*{RR{W9(o|F#|(tBj9m2sGM;Wda%yQJ<^%Q~$x0N(TvJ2;FrQv2e12=- zY7ME~&osvhHSeiVFH-BMcBF!LL93lwJkYrOAcx8-quWa?!;Ft1mzQWBEN+~grl(!>rxUO$f2^74VcO>&z(>_72VAQvs7*UUMLeh{^hI^F%X(zg04e=+#g-EFZTNJ?5 zuIy*shx_S=W*q;KjKcgWjDEFD%y8?<#;b`Z4>exK2}1MP8x06m z(xr{UJ;lOl!7o2oEbE2A3tH&%5jjr=K?~8C>!(11SK0;}I6Q_hc!GPfTHE1?f4Uwb zMWZ*>Nd8pCXn&u|unJrK8_RdkmyI}ww2eOSkfepI%*Y8IxSZa#;g266y}4>0&D1#S z2|SnFnjt7m{lZD0o(;T4yZ^@RvCSbTUq3T)M|{4kfs-Y8cAeR}hg&*-Mz#C-8&~(X zVw?6`LG%a{MoyksKITBK;gSWb5-`>J9+C3f^N6*P(&5)EsWfpt%eDYDlBdyq#7&@% zfu4s@k*IY|a2Q9^IBZ;~NX%5M`ARFyr9|ApG~s7AmeT0LPmk_NhUyekKP1j+%pEK3 z+Du&rbC1w{Ny~vc*|ZA}J3t@hC&!$xqFxyn1h`OeBV6`bpVV^-q%5N$28Gows!Dr= zu#}bZ!?3J<7RzUzhrF$UTv*%<2<5O9wiHj>?AN_mRLdm08BJQ)MfELK2t(0(G;8y@ zSM}yTYamjqe#^{+-p>9?@%hQfz;m0v%ky0u!r$=VI6Mia{V;Q?Sm0{6%VJMdufD4- zQ%GfJAp>-3yR#qPemZD)P1Mu)YR&C;CZhQ{RfXVdVzSr0T@x;jBAX=)!1Kou0S-u; zd|1F+hWAd`I3VyoYry0tJ9#)j6AUYUk=Z~>FDTO03O)C)b9ve3+C~nQ8aM86NB*X~ zf=>=1PT|b94k($^djyu{hytx$-#mQ&DeAAhBFA;OVvY1?BJNbnX3%b-8MFw&*^f>@ z9RiQQ06+|rt7rv0vh3V!eQ4;O)!n9Paa`S=J5up48Id3+Y8fULw7teON9a57q~H)0 zrOL-5Jb%6mu+rB{*@%R)ECMUbN*2pASN#B?5%6)7}oqAmnd{D&nI5lthWWQ2DX zUPpA0J?=^~tzv0pej2_R*T zkzwm}6i1tB*TMe9sq90blH>+sz4%Rv1YdwQBm2N+MXUnjTXxmZPwh>s@23jsH?_Z~ zYtp~dU|Fj)wy*kA`!s!zQv(UHZC8caixIVGXjG=&+fbF_>EV3zHC;4(O-5DpN4AJ_ z*ujmAB76G{FQ)JTtFRU2fYOo)gHa~r<&<>FP`cB;TmXr>sT5-?z$jB>$+WwQdtCyg zZvDD_sZX))yP8>t7H~#-@CkYvU@~);r=peeGxWleI@BGF|6_5NGG;O^0llaJx=XuN z+{SnV5^AnyD5JS=Zv@TP7-Hy`SHndQ(7^kFvnRq9yX^bi$i7E)GGiNHCRg7SP}I|o z9inHD4%nuYkoUEr^+F3z`0b(_O;E4cdrmxfl^3Y>Lg29qT#H=YHICdb$3p+rhk%DU zqvX2N%4pv!U-}_svB77tfZAe?4odI`@Ddme08J3+!!;HLIPidq_lvkdz8ic%HYN8#RVRBaVf-{HBI^B$R`pBSzBI3o) zqKahvoJ)_C%I()t2VZ_V%m}Rs8@owpQ8+T!?KcKxziBXdhgbhw?w`e;n*w>rpR;vBN%joOk9I;`t>e^;H}4k=nQ1#VZR;v+O0Pr?!itFwCO z8YH81O)Jn{EZs?ZSug+7*f_S!q6~i+2KUF+KhyayHm{-6WA&EtK3E?i=c3}X9OaXm zbC{G~UKd$Z=f9pC((U|ZDd~}1UyNECB&6}|5a*r&G*!9Y;Es&ZS6F+N+2QQs*g!?d zqUBlwDnSZzViF6JKtiAx%0`jfR_X7xWd~@HrxB@jJ=1`s=K2a40E~Bq$NkA_S`$?V zaI?Zl4W}m{8$d&jkRoST&CcLC3|4#aLH&%9f9V56LgqnzI1j`HaX`l8x5{(Dk1PO7 z0|h4Q&jh<)5fs-O7u)nMdb-8-v^;2QIBmM#brJZBldhsR8!m#mRZ01P_wl#xXM4Em z0Q*soK#`9C@r}?Ir9g=aW*j+2{-?IC_S8{rS_55H#8ONvj!Mq5aWRagq({y*3l-Dq z_B+c1^J+vo4_(ec7QtXGvuBVb@Za3J>T+R#ggGWoAl1k5k(3qgb=V~%gFT4p0R}M^ zY+;W!_3nCj4Yb2rb^&Ek=iMI(B*K?{BK$(*aV5%DrUw0luE2<;9ziLDWPXJLGCN;X z6Xh%=rG4z`!ecaODj;2N-K$gILQLYdf20&s_L+&(c=Bt#b<&)Di6Bc}<#A_gq_UOY zN8uUCS`@TnE1s(hDDK+BuUT6uDu_=N(=F2`Fy zhUvaxL(!CxthgsHP8TXe!+0PB(DYMEG2NOkuB^UPW>J8A%AKRWOHc4iNCI>}PE^ao zY|XlX4R}u^E88>hw~p#X6xG(XhY$X}ZE-`ZzIbTF4QV7bNc5U0@ugVo7~oR%IUwQDV<3TIy(1$8_xlmZIHuYBuHh42Nyi2ksVW4-JV6`rV0+ zZsW{M&yOLz*gW~r^+=Tt+}~-A#S!V;Y~c9b-f5w;?XD*za2)CT9Y8o!{QUE^>t|Y% z`Ug-?eFinbK#r7@2dGEso=qd*%ojXV7MB0w>GDZ-B6uKn>21K)&wc5b|t4=IsFUAiy0Td(dz= zO_IbWr(m=4GRBmPGs-N-P{n1Bj2m9+ttV`EXfJ|pAp(XU-!l2ai_?03C1Jfh8Kdc!@>*ZtJ4h@g)K&5j z%0_cv&uwqcko|9b@ z4pl+Fe@E;{10U2l)LP*~?+eFAk_vzFj7F$CKFVnW|&V64E%23lcJ_i@imrM&$W z=}QTeS$*?k{lL1(B&lwd#nIBo_J0(Fae^+fgTnx{UQFfDdAvo9Hz`Zq{<auXay$W(Q9INaVP-iNQfRFgXWdC>~y- z;}IrtpSkpE$eSWrXifLtNmb7V2G7e@ur=;eZSI_vCq{;SdIlFr6?V0gwDYj%&tY&) zVWP2=5LZh|2l~X`Ets9Xne*}zS5(az0m!oc^!*gI%mM#r&zT z8WJMQ8#m6B-%X@3mC5N+?g#cb04MPh@C?odkL;Y09KBKV#VWY5He^LX*g_T%$@r=Q z+4uRijIOW+chPpmc^$II-FI?4%9MEmbU;$PgI_Uy_P6FdA{ENd*8V9K1WZu~QbZD@ zf~Pg8>Yq$zh~i$z1W#y7@%?G_y21#6pSa`Z->g8O;>70|h;qUlac}!Z>qocJ-{sy1 zCSA|I2}a<7k4+FaU_rd3G91oWbTw{<)O2kBn>Pzo@pEM_FWO7h>uy9MawAVUdmzx5 z$K$OK>tMWdo_&ZJBE-i&Lh$h;?bENyCvAlrUmYzyE)mug0X{;Py}!ry5!2H8Ofyd=K6b=R zjYJceoM(E*^198HyR|)VdoB@AIvMpagMG!JKC){cXF#2UBmc#%%#5MY( zfU1|}s6~{*dvW8rE>DW*an1&%@bY=ne>_KZW`Im~dOkO~sGXl(w;KVQpM1S<3d?|Z}M{7&W) zL-M@rxR+N3VIFT+2>)kSv*)0GgLfpW%5O^&{3lMM0>=Y;V?RN7PisaNo3dT%iSNp3r7@e|y_Q6(r(z$cl%GY^6d6XJphZ&? za#~|k-CzWU=XJDph%3!d(T`>OmM8nI^`;b!B5us8%#6g<1%0!AC-H+Q1O-}=%40jwKf5VxL`os9c5XHt({h7Q;eF9rZV98>EqP`f5GGdfyBD7;1@!o zTD}foLM0-@``NxLih|vkM*2(9==8$Py0QRqutT;Kg%?~pGNWZ74X)1JdPni(w)Jl= zi{kDGyZ>AUGyHFx#N1e>CHm^T-(dYwu++m2is=EuIgAupx>DtCnk-M=Kh7m(H_ zTeqD?ZsUu10pPSm#cO9XJxcWE1dBf0Z>|x?+@cxeMP?8~mlY}ScvA9otL%mm_Jh}f z0*Um)D1W_`%W0@qo-gPFctyO~Jdm2yG4NLXuAT%6`iGI+P6mS5VlIMg5y9g>2^4uj zEx0^g#X^E>Sf;FAww3%HjGG&nuDUXT5Ht|79<{J^c7iSh*Y=tQ;lHrPIC% z|JPUy83Go-VR{t;hiVo4cNcQ~JZ&6VmiEqouHlWeBNmcv=smJc7kaGQj4G$2ZD2sd zsx#l}+<>D2j)1|8edZ*tb4#zX5)FG7Y7`6lc6jx-ydvP=gTkHfeiD`D-=7;F#wAcW zYjqrK^+tkJRSHVJB!O-3$)3BQo{BKBA`z|$F5OrTSuHS2sH@Ht?U!R1C>L!4dqg)0 zkZON}@3j^r>M&|-FE@9B{7GEmGW*V?2xSNNfNAMJ3ZJSgoZh{F9KG5~5R1(eeaThk zt{%Np(K4(jvq=m8m|+BfYGls>P4=HS>g6M$I<#-qF>x*Oyh6*<9|8j|U`3u)>_3b?o0__`h+5=u{R9lb6w|n6sJP2rxc8^l>=WlC6Rc~F3J9K#wqgs4Zj;dd z%7X~9o?>-p4fC~^2}*)zeJ z&+QAKspPJ^s2%gpVM*Z4nBV{siC<$DAGEp8u}p-ws1J8@d0nNy1X8xgcj*1w)&Rr& zI^Wf0K))-&V0LR;6(H~C%~YXuMb8Sx=Uh2{_((P>z3f7Kf3 z6|)P=->+*8OrFPn7rO@@=7hjx)V|$*(MK|fje^AzrioZxDUWB~dD2C&a^&=pmd9#< z`N`XGilB`+icJFIO-Tcm|LE)1v5rl?QTt8R(#DZS?$#V}CGlYTbze6H2#i4F`a3@g zF_p064VmY4=DmR%c|2-h{g0yaex&;Uqxju>a&hfzlXY#G7Z=y;8rkC-*>cH6C0+ZP z-J~cgO5_uDMNw49Ohb}Xl2s{03(foW{ptPw175G!`~5txa~{VSlav1#vPNLobW^Qp z1>g6CjJ)fRdMGt5wJnu%WllxJ`zT)`B!yq!)3r*LR^qqQ7{)ynB>N0w%4aITt~hr{6g;2SCHN8&u|Stu^{@zJc{E| z;gZT89A$lS4I|5!IoU$QMZpXEOt_oC78K>dxO}x0&5A3W(XmJ9+E)+?s=B3f$7eD7 z_(O0FT>VE1vfSj=1%5AOL&8c%{pSQIDG%rn(ChZqRqqepks`l034w4JnL?;m7>c|B zbDPe@@;f%t47p-l+FCUrQa4{<2&)2h_9lk=V14ls({46SHeglHp6^-6=DGQ`GCjnG z4k9wqt&IZ(eTE2$afy_j&cOW#0*|Kwg-cY`Ox;t}b2hv`u4C>)K?p?5XMzjUO0-TNCCAAmS^0GPoyR0S3SHN?3Q zCVo<=4u<$vR1Cbm)(SWxFVJPFaw%Jp)cq^fjrJy{a_Vvf?>WXAcIvPD5M1w0-*;0H z7ROwS3TZ{~)wf$JfqH-_AR{x@B?KnzfZ22KBa90SE+wQz@qr-FRv7>XyhZvKz;BRl z0H@`B+l8#QIFCU4(o4kA@TV(=r?@U|*L%@)@v$*K72q+@aiBkNuF1y3a5B;+(eR*e z=bz7bQHb5s)iP5WI0n9lx9|J*r*$IvplQ-Bd-2%R56U17{7G%5!sQm@ym77!VmoW88A1P!g*XN|VrEUT+pai%8ULE%#-)}U*PnsMOCNcAbm;L`-z${3B>bNtp*MGDE$qc|U9)4MsOCCuO&A^8R4f7_;p=JP z)z2d}nt>V_VtCVEIPt!01@7LZ{B$jX%eR%5_sKTBqLgEVgud+NTir{;ZEa=Gn7?Pl z^V|+3j{KG1yd4BQ$z`j;e7lPH@HrzyC{=y`P8&s-Xm&am|139#wCPe(f8d|+jt~R~ zfk7}3(jEkaf)F4SNFLw_KnpN{jbk83tN^Jr+I^J`|1>ihNhz`ub$FJ+o?CI3gSfxE~0o1hMbB#Rq7K zGpb=5)4?Xpkeb9ZQ850pdZ-Qzz%m+priCDc(a5bvV~ujlrO}ZIusq{h!&ZOej_?tN zLqb=|Pvh65h;rPxbD=UV)Bn`9#P_S-xIgZVZuq$v@2P#TdZ4z|iDm-Be_RBx0Y0+&5Aco~vcj9$-nbu~g}(-tjEY`)@K2Ki{ivBEe-Lf--MslzO|0z(vvD;b*%Z#+ovxOqR zq*YajAodDjN1X|`O>hWsn4s8>)Go~1Rhui4_nGnoO^>x#797R+IkQKING%NN75#)9 zOL%m~N}2eT30a?9hk&RWMNdr z1{dYC9Si=0;gzzZ+{#hZ3OkNgJO1sC!^OrwCX9}!C#3(=aY>Q!atTYtRNBRCXQ!#f z=BIhJM{}+@g{2Lui(caaq_MOH`>Z_xaqdC+>LyEE>-53C9g7c%U16Mb$Zo$c1bj@O z0}D?R$-4r`L}G2ajxX+rbj0mOCrzuWKjkRz)5a*&$K%@uAKj()(Xn*&V8d90J>H%? z6Te0SdZP<>4&I}N)g7DnJO6U_e_+`#;xXQ_3Cexm${-BinA*iwtGx+atxmOr0*AYd zSpzQ#^5M()$_v*H{*^4q?tc~{2MuOjWG~mCZ>&ux?l%NQ1OJHELFM-;pLr(^E{DV! z_-pkZie}LzvO{w(L*_>9kMe90>PHd%e!WqtL_fWIp@92_3f3JLT8sgr;U$zgU4>{o zfCzMFY0b$$B>}~NyYawtOf4yriNlAI-^}95Tp$Dp)Cldi+y((ffVvSNo$_2jPELM0 zm_(n+ zxAI$|^)K*Wfto<~>>c18&>hGf*c~l_K|;UUAAzC3RIvLO8T@rss4*vv-9IQC5Z<4! zE;#pJZ~WbPwLjKR{_Y$BJ;H9`?crO(pX>g;*7v)Fox+>x9inB=4A&9S$Ka+xEsg%h zZVy)pd_%vems&NMkmCcS3dT#r_?n=lGwwA}uvLETvz;x%I*T}`9)!ybd3|Qz#x21^ z825J8d3eI3!vXObk4yj6o`AFS8vS1zR;%Aht80Wc#NUiP)6&sHstpK>z_{YuBF<0^iI1+PLX!X}Ou8lpZd(QH8fUEF&MMcN8 z(7ptieLUDD=&gL6_+{91ZyW&8Sy+6W_u?q~Zpu7eq2pfAVgs^U6oa!TuTdahcK(Ub zyL;ILYbu--AKyzxNEk!pFd$09Z7n#&l+@I@F|xH`8v?8yWjt`8)xGJ=)WIbp))dsv zTfsFz?&9o%$fd!Jg%_oW&T3=;A)q@!yZ}aqVz1>Sb=~X4DWA+#?zR6u{qWuE5X@kD zT|aLCR@)c9WRLxO^x2 ztOkVqVG~~2@a5ndQGe|E#y#Xf$9CAl4D5k6v^?2ct!@s|UWM{Ttg@iT#Ni5VK{n<- zK`=}qDu$YE@VMTJN~A|UMcF3wfb;5YS{USkbb(3AoTLN534G5sz97$I`r?l~TXo3` zaCm&p{FUVh+k-8HUuK4s!V|r9gaWAi^gu56>e+FX*F+<#D_4xrUaXn=UIT!#qrnvM zKJ^;U07$cEa(pV!23GIpiunS|tF^SD?ek-q!j!>k5If{fANQRC+sC#a`V#C#yiC-gXaKZd@{a?LXdC$Z#)Qr zctT>RgN9?kHHb9$1_VZMz=^QKPQw1;*$6>l7F_SK9vRjpQT-NcC^2?ao{ym!wMgj- zfngc@VX|*XOz?F!Sw}qD5DTVRsxZFG#eHwT2xw3WA*7PVoQFD$c+i^Im&dd zmV)XC3PcYb5XxqtXc;>)C(*-mm$atSY}EjJqF;gUHj+Fhp8_Xm2iL0EqB5x?Pqv&u$SK+UoZO*oBxz{?xXkaaJ2WM!D?s*Jra?n zF8=#B9Gy=GteXI!Dsg};qttyoeV$!~aW8C>@kF^!S{w=9;vqauo0?u6& zyY14yO)$4TUoRqKcd97OHmIP7{xOvY% zZMYgE?wA2%a|f)?_h+BZJ8B_;*hTmiePaJ{aTxnt+|X(5R=g`*4JzB0E9#5#D`EJ$ zGlj;ULa>Ip4ogHrtl@9TcVB5?AlTz2n}fbthTKLU7BR zBw+4z&#~b>J-to@Z8YY(*4T9nfj}aS?Yxo66pFHP$%E@!>grlAY@%q}%$RCP`+Q$% z1ZCJu{sqtmj2@arqxyupX_4H=TxMM|vuO0iUWh~DOS8$>G0+XM%%kK~2W_oXX{*H- zz-2omIMpf)sm0kK-Mq$Rr2b9sIO8emZFj2%w3i>l+#!c98O0`0!$nCv;qsCRL9%qk zSpc+o2O)CI>lx8qN5~H_ZdxtF*)gh@i40U-Y8(2NtT}EcX_Kg3_4A0d?*|Pa9R-IH zRq`ya4WVL}OWrkoI$h`U#pHWQOOnk?^f%%8J_iua*xNn6`i%Pde#aTENZ^V3@zv|3 zQv?-mstxd}mX&Om z@ov~f-F-t;An&j8Uzcf|&=Q)$&P;O`oZn7HhLw(PJh@qR5*BKSWY*y!wAg8>*}d>X zWt4=A${rZkPT75>rzz7Cb*--Ct5>b%jQpZgo1mzP`f7r~0UG5UVRV&Q3bNY$@fOH! zBEvym@24(S&-YUy+xeL_&hbDk#rK^)MZA{8Foo zcu>%d(N~a7JKEnMJ(SD6+tFd~Y-#ERq47101&5J7&-+AHdV*pnR4wmv*&rmn&jztU zoxtqBM&Pwy0wJ93K|srE`zkPa_x_6;CQAe!;HQuA*Xlx??$wdt z!to!rW~=Pzv!d1P5gDJm2VUPYb_Nfty~<-HD62LpQZ*7W>;FKn64O7G{5DUA&1=nvVFfGb3E$7TDE`W)1o8^BBa zI%m=3tCt3blLoSlCzU6{2o4`%TYTqf*5ACp9kg~AxW(ce93(GmkO1la>V1L+pNidWxlzs#M?4QqE& zx=u`kaw1F_w+4>WmI7&AcQW7DchJ@}Q~|jbX>G_*vO)>>vkP{)s4rFWnfku@&p%(m z++r`}P5yVn0f!*zJXcxG=V~iC+4w?-?d3x94*r)wTxnF>H^TmP=*SilN83fn%*nM( z(D}5>b$*w39Wlo>su}+2;x_tZ?-Tu;j%r;epLztD9WZ$q1?Z~ZUxY91q1oOvhR$lr zHt2spbZ>A&AJr6 zyy~R%2fMq>UhoB;5JnDSQyLpKxIzl3t^a-fvf}Qcc^gf~XYRGt3LK}gz5mRyES7o0 zER8dsU3x=aMM&gE7yuN;RdQ{m>J>bFAy-&N*-3d81w+(vb;b)C*#!K>1k+oN*T z%HH;tk!d{@xCDfo`Laj8b`NIv=_~q_5rOC1uz4*Pn1Wq{^{zeMK5%;M35Ty{^`_1o zF=KWSHF&Pa;da5s{^%i0EDA9qeaY*ReJh{~Z}f+@#Aea%87ae@pzx7G~MyzlNN#0$9{`Y0mS?p zC%@o#L^82(yT4bv-Wzx47CB54KBLPzB3bWO;RoGRb%bb`M4r_))~}}rp^JGGJ=QHN zOA7$hM*b1M{;4hjVq!j zp)v+rWa~cAZ*xCLs>>%4`dCZPGmc{2x>*r^Eg>dfLspE?CNeIuqWw75pXq;fUA^1Rl&}xz}uP@WSA9C_T7kU^W54(i8dQ!j#=wnE`}utxqE>5^y(I?jK%nl$=<#g5 zS5)@?&S~p)%DeC8K$G@aPqm5TwaZ@e3L3KrWL}nx+66Z0OdLi{dMoO$nHq{xXENwz zM3(_wBc{~FYhR5rG8r!!UfwaYsmUkyvn0mv}NW|lD25Ge_WU7I!#K)1u607}gY zf=+>&>S(PgW@(0A)m0WaZ6W z*J52rrpTlfxaNPuv50+$i#}qNUIQSVLd0(B$1!$vAucX9Gb+5H&;FBt0DQvEv372r z8S5HSj8eB>dLV;Qm36&$Zz&??lgp;&Os>Z2_`UTo7x{oOd_j)$Llw2O9V*vWLX9y~ z;VjUVyl`@9)kA-gLoTcSOd9h`L6d#hsty)zH;9rpb9U5JI{fWy-+jY{=b^b-)CkS| zRTUH5 zQ}Cbz9qh;mh*TQZPxf_X%1nCkr?Brox_-^pfr^ReLy}F2LzY}75YYs}ite-I&MV#UxK(ca>b_VPaw@rzXP5BfX)l7h>xH8Jb3%}W=;qhk3Wl3#@~;)5%I7>u zNep2@lI&l=(=$r_8DW;w)t)eaNi8TKk9g$v?Y3Ad68taXdoZ})E+cq~ttB5R zQW8{Qbz$7x%hbfUhOq&g{R7;Q9Usx-#Vl`703UljzF_t(^#YQbr!1vqSr?A)#jjF{MKQ7zyn#4n9Mp6LVANus&^7|)#m%`UA)UWM_C zjE@-mQd|9?TA&7ktl;jUbxyIs+Q?jv{1E~LGG9R9JhqONSBMvYM8MIH4i6xJ52>ODd3qBa8?(rew z;3@MfHH_ulH{cR*lfRb+xC;EPl9MEY#TP%&8I+OtJ$5@!U>p4}NVNLz&KF;En28<2 z=aGIK3iOWNsL$YB02KXpRMx493Hxt!TL@)TA5ZwRS2@TKc1ZhY0cfxFp}*QqF5`+i z@+~J<=!^tou@%S&hszCwCf*z9b&VG}@1$vQi?Wv+pZ*=rsML6T4+%4-H70(K1r+H+ z;jMhdu21)#dljuJlH`ZFMRn=`d;I3(*Xwv6fI^alp4kjZ zuzHrur(5_bT@hnJ7U`#fX0q{J&%HjFAMkUE!WBuhphfeKiGG7B*8xY(Ch+!|$ZQvH zZcuiF_fa6Lp~KgDX=faX4r6{DI~?AvNbwSxiiRB`dr*Mte!x5-g($_z+(u%XcIx~EFUpP(KCMK z8tLPtGU8!T3f%KOSnXh@phitE+eQ?=S4M7{~U-BtE|RUJIuml3UCl~XX(Jnj^ywvI4(|f zouUrcczZ9N>WCWryLC0Ne;%X1n|d5k@S6FBa8b)*Ez&O;k`H(}bjCWu|3Ldp-;C_- zgYjMC;96(?2eHs=91brhZj`LY<>5=yFhhI zl2+SH@Z0L30Gal*&Y+8Km=BZ)vQA{()Luj6oxX&0D|PWHO#K=;()y@Ato4>D{t%Q` z5nFWTSRwsplz-rmfwFJmoJRF~gcyA!&wn zXYzuKdELIEKnqQm43}lS(fa8mJX2B^)mw8Q=Jj#5&gm}t{TVvXE|gne8fNhkN>Q%r z-*=FaDnss&A3pQ`&PO{ols#nU3xxam2iyzv3d%j>O=7`908ws-z6n?;?jdkf+|J&`0lRUA&_&8O z#%S50U7{Z9ysWmbzwq!!b};$Ns}-cLV}gNbzD>xIWGX%;lG0cTO&Go`)=O_XiBfg& z-2z;tCEdd1zB);)Q^?6lIYzZ%5kDSRc}8P8D#Xb1D%c6Oim&@TL{1@w69?L}M_)8L ziVk^i>knFP)HSJbWhQps&0;kbi&Jib?i%fceecQ*cFoEJ9eR7UtUTQpzKoWuIBhdhn^MH(MdT@UDu6 z@<3n4PMQn-$Z7WQ)n~L@$$Jm%%Kp zM@XCUVv`pde`XaPiC6B8@ZM6{t^eZ>a}_CBp>SFrp=5*@tWdC&Ft920YC0hVjUhfL zn`dQm(7EGrfTWHe!Q@3H3-fK$;IC`Zg=!fdF`hIuTp{ptzMOXaAg>@a5W^oTG>~N* zsQJxuVzQvtTvu4`(UzbWuvA~>7a#FAXphf~?F(NhE@9739g!9lC-s~4b98j(X#B~9 zXG(<>q?W*07rm}@&C!(!XUIVs#`=9}3U0GqZ2Ms(Y5c5!JQun~i>hD%@v% zyT5yuKOS8jt%|E$)QoFJ*1htUj_DD-yw&c&(B(13XrDV+xuUzmz*7E2hI~+&q-Wgn>OT&P;jafAAJBbh zE})orF9luC<1WiNva66PPe(*kb{|wox=RGOuUeW{*AX?n3u;bxYh=HW(AbSrA;g)+ z*4=TalSvslP%&=ZolD#E+V7Bf{D#)3x3(+XGP*azCX%Qcdt4VJvox>mx$(+;`qwst zB3Cpa=L3{a4{!T5xVtJJ0Qg}StVf8sjk93gYk#>7NyB{=V|fdIyP0={>!sIM7pN-6 zV-l}|imBr0iw>Y!ZxNiB_CS?OPKhbM5iuXY-D+Y3dl51_F0oQ_OM#QwH6I2e?A~pp zk_^Pt!t(Y--_R1q7z&x>4EglZrHce+FzRK9uHfvlLoe0P)>^j=%{~>zLHbh>vzmj% zN6MYS<)2sg-y1y%t0*zaxt2k&OGbVoV&d; zryXb+_4Jc_7h_oVIX`xB-fj&qn?dc`?>=0tN%o;#ABw8S(CjOd?`wDvNH&^)Umgm2 zqNXz%>GmWOzu_paF<^FFspjQ=o?weZx(`)XO+sC~- zmxcZ);TkGC!eP2z28D|(_|l4y+P;H+&@9#{xMV+#N;0_FHxx*RyKAbHU8%LoNhAW;)lr4al_Jy60U{200NboDg zxmo^&O4M01?6{m=NKDdwK}~Ggxa>$B2xywg=M{WHw^`PSljK3bdlXErgD@zSz*~fh zCL=vlA{YKchHn4Uv;1#&f$jZGMB{|g6d{)Z$x+IP~UxMxP0uDoCY6WphxNNoP5jgyx8Ef4v)HhYLw#i|J z@rWmHSbVX~nSKsEY<-auR68Z+_dfcBg}W^?^CHO})Sxxtle$HTNgRNMB>bqH2+jt9`cpz#*Kc`#pgI{#HwU}l^OrEGY{Xb z-2QT?1mL9TxJ%`9z-B6ihp$mOQE1+^Y0hM~7a=7A3`Y7Yu(|;O-%h!X1|S_-8C9;M zEX$~u88H36->0KqXW;SYuD3~k7KgSpm`?jO9V5MT%Eixb%4rFtOS=*mTu#rAN7@kG8kTN3!i#KJao1*8(&iuF`sg~H`f;ulu zx4XMY)?|D=_wa7hO}h!!T*XEG^F@1M-(Soqm6h1bxvk3w#Vh-ehxCtL=M4EO5Vm-3 zDary#7S$31`PQ&MmLg_oJ1r^B0Smz6zmg#w{{>oucM%wyBG=sd&2O=+X1a`dlp` zm7^vG%4wMlKiaG2XIyqRFAjJqm#}v%6+1g4p5S+$?S~RKlr69e z@nk58aY94#fRG|hjuf+eRAl&B!K23h^aDqGj9h08ZWa1BhB+Y$HowM&iPW2aMxF^$ z&S86KWD1w}pzl#?$>mIFr6LsYxN)s4>N*RC(o zi~O(yAE|si@IilE>(o$*81`qym)nQ1QK8_V(Ry8ADq>4PZ}W2KtrP=re|z>r^((|; zPe`-<5Rau+U7cKSKfFl!imvkidC&g)++@F)&s7IW#rfBY?L;AGUrBCJ|L;vl?}Mh@ z#4{NFusBO1Z7ujNqJD!pjf`g_+M6-GH!mz%NqFnBdylYiP}-Kb&tl#O?4c(&+_83F zTm^fl8k(` zZ%XyeDk-4M9x`yz-8R1J*sIwKa*SEbWUNMy@-!!rYk0Y4A^0*)wDPDe)6_ik?2HTL zwH;v-KW2K`UCc6L*f-?Rm{$+C<_6mc)ienvLE;s zGjhszg;wS(04;1nvc*#00#Lb%r=J&lc`r*(2s{%MC?zh2#&QZCrsOjg4=>4Va z#EDJ_|B2>76c7VM08QJ`r$G=$0J)gMlX&cD0y@OE92z>l9x2V~Hk0!4ME8>PHf8w= z24C|nOjTU!b-Osp!1e~lrR2S6t=it}xia~g6%VpixCHr zk+xgCQ#8e!o(Qa`1MZx=f97~Dou-8`jW6~)BCIM6Qt)ziW$Xr&RvOQNwtyIdY2wrg zdyA_$lOSwtq3wYcj1>K5Sh<^J@X)&)_UGTq{9wXsXSxJ)iBI)Be7+0Z?$jRRgnw(T zUtV&FGp9MEd4KnjrJDDut-dgqJbHWdl~R`Gu*KeCljR#PlR7l*c$)Tex~nK3<*C^# z+4f60z6Rx>+*e+Q5uJ-A>#+>R zDw-#qHgq3i>ZUz2bHN(`shm4mz7q<=9Lsh?P1lI3{tL}ovMQyQ%kF~mED_PVe^$(* zjx7AxJF{j@3$tyx@0kQv`Vtl^d37l|xR8-x4X8AHXzM`iWJ+9qaD)(tt3I{gmm_G6nU^hxVQ9!dkcT70(+@|I)d?%Z-d+GrBa<5s4+1n7VlgMq9j`Zh zZz)B^0UEl)M#*O(Tq%||OFg0F~ag%>!Ug5V%WU|4t^N$L>a`ir|_nab5B;&ze( z$yicDlgR{Tnzo$om)iUGscOIat${;!XI}3#b9A}4d?hk=wR${v#{9A4cGnu0JdH2a z4ujgANxu2=06MzEc12+pziLOCuzQTGIRa}P5$G{!6|Yj1`E*SwMort4`AJQRtGfI# z8o+KCvz)Aqx@iol5D)_fiTsgqV{Jkg^WMpT31p6R;yIOlieV({N%1L43LGbx9xbiDfa(f(@V+Ac>AcW>ZI7I0Boh>i08 zw~}7K4JMDA(N7So3kzG09v>7nx0T^|Gf;ap?YtuoiSiP83dS8g`|rdI@UsNX%{ilw z$M2DJDVFilP|yIv%Q{vSx>I}iqyf~{BJtN_^@FU%jN(g7s&g|m1a^8Gx@#pmIB7c` z4m_WJZ#urfY5b6`h%WFSf)=~{x5G=R8P;U=A|&HuYPwiyvGJB6Nv#2EK(aV)W^2Og;f9>_ zpMzo0T6^jrO3TE|loK{+73QunjP1v4fBS$T;0>6Q)NV@Nc{Qe|%ZGeLvoFqJ5-W;g zNb}s!-VxxLR6?V&9LY)>Q`R8zM5AX(=MR*;LXHgUh&_vo`1la?H3Ya@{rFiu#TR(j zL%58^(i12DMA`XeA6dlgKXE%y&3gN?tJkKZhh9|nQO4XiarFM9NTO?&E-yhw=LEf{ z`3`!*@r6VB2nzdEVdDPu^XDqLQ@fxDCIaOas29aBcw$^hlA{PxO)Q;d<6A*kV~a0? z{g-7B63(DHOrZUjvM^A}C1Ym`NX)=QY!yQJ#T5MMi#yZ(9*X95nS61T({EllUCiOW zNTp@M4fb>MK0b%174n13!osgWIw@Q=dJx?xWLF-_#X(nb@3yLhrB@0q);nhd7B0iC z6TOU5MA&5%-MQg%h69$bcBsPk!(A^i-ei6g;}>+3ZPM$Kk~;Zwkzss#;_)qp6ywN zzAa?xelXeG&dn~VI_*8}gJbUZ1nfTK;`z`z7oLsTr`?3IBv;cT5%}PX1QdBTFX^RRn$p8;@Q7ysA8W`Uv>*wM6?2KzuU*J zr|Z+upnPz)_eB?2u@{85pdjGTpCbLm1gLe{lJo}g=XwUHn~L_O=Y4jY;zS&=u~^YX z?iUXH9Unl(;m^EY$T4Dai?s^9msrD5i^9+THq$$O&D$}u>(VKAM*Ty4R!uf39p@w3 z7#G#mOMTA$nECDyehtq|=)WyGIxvBGt4pez$_aDUDZjN5bKYRn-p}Hvc&Q*rtndD^ z=rD|-hOIzC^sx%30LBMAl;6JoG7WBbl4C*8yI{{uzJRSqc(+u`$6xoRzD z`D(-M>Mbt<{ycP=%dwE(o>|*O)tpuEjnp=bL8lk@+dDE}75m0zN#6$8N6Ovh^3t0s z=F18Q@tLv=uBEtPpl>gZyd8`!uJSF4C)Ey&MD3F)ie_yuI;u=4B=2K7K2;Wh$M?C;(i%;MPJ5ajlBH2NpG@-bkscrWVzY*BTWb z&@4fv1Bf?j;+IOMXJn>B#ERfT~B>Qcgw$B>&(|XAIbhsd+$ z7?!!z@*Ic;&E4}QcWd$Q3R(te0?r)+aeRZ&kT(b!ftskPf86~}_!kl1D$vo?;O%t?gIS(;`C=e}p}eaQ;08T0)QO03%`6jR+J zQCG}KFr1P~T9!b$au0`n2=2qDq}3K3jOGcLQV2VKV^=dEg_b^b}v_=JFh>QI(2rvXTlmnstkEpmevpmM!UK zb*bMR#8FzjA*G1@i|!$yvB((APiHx?<0W2kqF^Y~z@K64sbcag$N1`pVG#G;W%=^e zJe#3Hq8>p|R){Vf8P5cA3Num-ZK3jy0U!UJUS>p-a_@0tSS!*gzlZf>y|WpK){n=X zr8k-$MRxAvrgi`E;Jn}sVh{GQ#W2!u!y$J(Rc4A?2bG^*Yb?l_n6Fg-_p3(ZJsB0Qng-d~IFct7PY{_eXKC@Lqa~Q2A{8-7vTKB)LTR z6WlA<+O`^3=qEtKj+ry*`15@$>qncc6X{^*1JYootN8=`ITbzsQ_%;_X*5+DgI{)H zAB`ajil{N`{qwA@(IMwg-JyMorJ$qzQ2<8ZOZ>Q)=deVX{lbE3?e7*d+pv}Ag*{J) zy;1y4`R>Yc168#v9Jzck|0p7TqZ}5_xVnR-5vpiF2CcZ&y4_7%9_U-&c&XIa)*e zlFnpFd+zt_g4&mPr7!|FH2d5BAV3yMg_z3HrDcAE-KxpPUl43*DY9~@bXjW7j#fKF ztNKN$u!xjR3R*@F zNP%eO&iK^#o(RR*wj3;KfsBS>7@<9{i$}rpp#aWzz=Nj+;TwaEu(}AVYreM=0}i7Z z;cWO6ZVC1e%`T8K?p9NQ9i#xuE!W0uvZOVbm{yGL+OfoyNP|@%VZ~R{4Y9X_0(~m7 zV(AOnN6LRvW)pO|*(b}KZi-xb&NR)&wCm$5dqBG{v0K>0{HcOg9XvfwAQjnq$;wq_ zvEF~L%`a$2r>uX$$=8PhlHuQQ@IyN(32E3av(jYEdZVBX&14O_ms%qQf=eXy%JtK~ zJ6cj@pNn@-0z)bC*`A*&>+uNecZ{>yckxyh#ri8vVv z_16i1&HMs6M3vLAdG}$>pNd_g=Il{-k!v|x&V6K6Ek z;WC^GQT4z??zolU+GJSz2`3F%8PqW(((+~CRoP-O94cd2`G6HOjDxuNRD9HX&t+EOEHK3Hr_5MasbhL6Yx}mOK=lnCX!l;f-Vp8nl4#guI&}@*biQ*V2g4X4aB0ck;Y*eNf5aSEe=Orym7n9k`}N zHJjzMRlK~iBU6jsC@bTFyY%*sNrht3NeN{Yd56)MN}rL-Z9V{h;oJSHh)`HI-djNc zi#lsVtI?=TBY%~7aNmKT!U{g%qiyki4%T3<{Xk+==Ybw=eB!WdO5`rjAcG0@4Tt5rKBKlz>Nl~pJjb%#&7oBd>f4AX3IroblT4SQh zXgYyG@;tAu7HOYF-4GXX@J1@gEcdQLcP5@x5>WYcOhi}^V;$wTAgeB%l(pbbiu>|t zhQ@~4A|q$jU=lmDT30z0wqFkG<>&kzd~E=ZCUnd!qTYrRj(qd)0D|J^vbtPXO z*m3mvfzABGyJ$Z`AWy$rI6ErIehgJ$HDCF`U!jRSrFgXDqcqIlgrUnMtx|mz_O08O z$&L4W<-6F|78NQ#K72XZ^_Be}#fGxWf3dg!5PxeEBb>HV^(X?(&Ta=E9xHFyN)FEj zpDwSCbB(HHD$)yxMMiN1Q>5TSp(Q6V(1VLkDPs0&OZA@R%V@1#Buh>F0=@tRAg4l85yZaG9pnbqEabZUq8P;KYxE7kN4y8 zd4FE7=hG${$y^DHcY0TJA(UKAyMTDxqHU&>)`il_PglVWF5Vu2B*@L>9}7FNeSiTUKLB7Zu@f2RgEu9Z7!cCbi?_T;c5L+3Tp%F& zUU)7-Tv;e4t4JN2wOgttV25?Ps^fh-{H6+}s!`j-*LYy)Y=*MbM<3i48D7{3lncS`=@}iJw}Tiz8v!116m}d z$ziw^U=L&yWkudBq6+a3dvf_!P3LDTl;$S?836N>M`fOZqap-ST_VqjCc8}K!m2N zrx}mrj|z2%=M{1f55}%B$OHQ<@VID=&8a8FET(Nf+fazld2fQ{5=EBame^2#W;_;t zQ&K4N9S2F7ZPEtf3;D)-6TTl_HL|_6yvf6QNUgC|koWI7($?GvWrTbI zNAS)CCmD56SqY*>`LQotgY1^9^Dyd|Cq^FFCA)lm%iK(v64zH)tBp&y|a-kM}7 z2Ye_D85zBByE5ZVcQx@rqM5&3`Z?pwAf(JmlG3Ylj_#;0>6*GafTBQ25(Qn+;dUAY ziGaYh6G&6=973;mw34f3`-|>8tVsQrbJM*E^c!ybv3t;+o@r&C`p2PRxd^D;h=~PH z1NwNp`LuCeX5Nfo{;|WuI&38U`}i5GVM)Z!CQ4F-mM(K{J~+2j73IB^L~L;!<Grn-vYRvN_v5%=>8c9{%;JW^9ZEk3b!t5#!wOZl-#R7=Dv7Ahw1Di66tE^Q*)< z33>6cSf?brd#bH93UqX&4&tjj_nlXHC6*?-c9UiXFcy2I_s0rfV<4wBK{)i(=;XA>t$m!6mE$V-Sk4j z(&zKs&!mrX3*VQ=O-u$<9P7-d1s!d4X!wdR1dsHO!n6*{rzjhlQ2#8ih@oDd5SB1> z@id7F)bffbn7SK&pUe`LxPy)tY2umr61Ie=(fv+=i8uDotCxDuOtVQkMPcem>4WSi zX4R7B;qswvT(^1prjJR@@u^EqZJH*%WG|l!n68lfPsRR-#ey|Tvd%wuejNvO?6o>M z^Q@BGY${(lB@N<^qa!s!lw>g;0%Vqqnak@E84M0RN5wf$ zC29k|x>=j;ZRoK;yzE9GkF0`!+$L(m}ELJ^$jZNTqa5Ni(KgE#W#)`bykd;{!V8gtFst z%tAxW;OI4_hx`04zQ@r`FV4^M5XUsMeeKXRe*F2c{w?3feo3red^PpFZ#ysCtfkrp z1~?aNsmw&YD+r))Dv1(0>Dbb{pFCF64Y%;`)}^}(ufz9$5T(T&$x3E+K15a(@c6)8 zfqs5+o5)bC^R1Rs_14UQSsJ*OXgjbD93BR(Z+Y%zKG6C}TJv@AT`@DHNlE38=cLU4 zM7q|rVWZlq{>?Dez&J!`T?C(?9g!B+;J(SpO0op+9$?`^{x1nNbAvlm1rpT9@U zBGR&w+Fp$yWQ9#l3L(h_01I8@uLj*~#wkCgy__6Lw;*?A%pbJqOdgWOOkycL9F2Z%;7V7Z??osb^ z9#^jF?U&WwejtrEnqo|5vQCIu6N(N8VF22y0IlWTqU5>5Dh3s(BIc3Im>~k&vAfMe zLoCCZ@XBea7l8QgZ)%^{Ks4;u*#;_C&ZcnI{~PRbz{d!H)uv)7ly4R$NtPiHP3OyS z$NI2w9ehKU8$zg&kQH|67h>RAQ~!S_lm0U(NmQ^%X8H2>&po0MU|+LU|D#{G2}w^y z0eN&s5-eMR-U`A_+DU9lQ3tg4NRJ8W37<}dVrRB!o~zs~xkCnBIh|cC> zA<{Q>L&R(ChV)Fuu&d6p1I= zs%&p7&+oimA-bLC+gw_nd3;#As}}htBSGX@U#RrghR40)ly{_}H0A3G+ODMhdZ>$F z!__(nJUwZhbRTXw8%R~le)0I`RCYjz&d)p2%0Rm&oHyC)4*V)#$ZmYg-pa6+OLvGz zX+w8bvUUUttR#KC5Z^p4{CEt?1H3ge^`i0lRhw%MC)uo1*<9<%*B*dXm-i$>G$JWS z3Fwq~uQKA}=wu?vPX<$`9#oXQjGmCgHU+wUADW)vSYDK7Ze$Cu7OrG&<&&QBnwPW0 zm@9yJTl+(sovh~t9N8wyWe*^BxwUHV=+YO%%Ui72T)w{eU?s&YN~%hF_po9iS>l** z@DYNwPkV`N|Hb~KJfvpBBbZb4R1M%*oqC)!@@k1l2fij3LU6w&A9iE9KL}a34bZ;ORY|T>RT!{JB9rP=lE$7Ce@__=#1eGezr?dKFtj!tgq}C zhX0eHTr$eE$f}+JzfpL4L^s%6xnaS=CTLU~)_hQ_19c(m_zsOT{JK|bLYLST3p{~< zT%NG{!_I@KJ!Ma;95w9P@0zzoG)vrkmM>4$V|xb~MmhPMWuJY0!}u4MwrXmPj9TJ3 za~EGSG+$WjxidX&$$dVTUSsZU%Ir`VlzyiA?{r{3$>>Ko`@RY&56(Vg{`6bC9va=C z%M(1txi zJSS1Ycgj9)twS^``U;r$x<^o|C6nEzQpecRLRM?lC2!VN0=A=qFfNJ^rlaFYN!&=3 zDEfBFT|LE1SWTJ++fTmN5@VBVV~-l9O61}NWYvR8ufw93#kE*afCuK^E4{1JQ$BU{ zfpSF84v;0q!-f7m|BQySh1?YYy7Qp31}R?!{}M|_AhxZ2GsB(IL{4$o`h`nuLBL*D zZ>XcpcBXi&^_W6|ufig)yI&9k+#4@>oeaoY@Q?pkie#p!biCNVq@%?=Y~L)@yg6i6COdPKq%G+P`>oTE zKIJIz3`5M#nKZ@PT^D<3Vsp9&q8{>#@VV3f2F=hdhCVzwLIKz<3xgZRzlEC&Nw}K% zig>xJ$$mY1hB~01Oe2CWnm*LO?eHh=kN?`Hw7s#=8kr0>t{A*Vjv2@i8#srKF;b1U z5O%JTSW%E+Bi}9zv;CsKrphsNxYif=UF$T?3c8lw_9d_hzmafH;5?Z(F(2|@62hSa z?+zIx08YJiv1hCJ>ALp}-L$%MY1%CQy`< z+Gof~D+aE9S`***raElOYsG>`PmZ{cjBwAVUyldhKwfzPd6!0>7q|T2Y>dSt&=6^x zkKO`7$NFoYY<7_r`gC5PjfEp`R?X61te|X#tf*Kksj}f~SZOLeG8(AyECv1i<;A)h zyOitpq}lps=C7YW>lK`J<@vw?Q!PIOM7fCJy&Mj+XucUL0@TLjoG1_DcC1`DRnUcN zICR4&>p>V)^@OF_%1w0izE(WMOYOv-2v+qs#6NvX0STk5d!JhD$4YEUa=42E$N7+; z&y;3se7^^}|Fi1>m`MiWXJaPwSP*_s+?CtK&(*-^0Oa;2AbM>&0PImwu7(yg5SlHN zRSRzAr>Z7_%#!>@ZN>3xA5IG6`8O$K{Um$@UT~5SSfxAP)M#>Y%}yL@)69lpbj=$+ z6mZq=aldr*Yrf8JSJaP}{Bt=P&t52&LXcUadV&oIIgy<6+$z@a_m$G}s~N(0G=FBD znz_RZ|F_EVq7l9dXN&L?CFi-v$fq|M&U*_PtEEPxRx`@PnXXucCgof!kViT-ezoAlV>;|~vs-$_HC@c{OgsMddVbI}yhc6D-g zMcHW6LKB-Jw3YK=N69A#c-mtRpicm5AlLxqZ9oO-GfQmvA`78ZI6fHCx^pi`3&v>B zy>kSpp>2hnJ3r_e>MSD`YRa8lv#{LMn21+29;%_~+r9q+RX8H~LJWB$0H~|Ywl+2Ml;)mx( z(!j$;|FKX>DHDSV3)vZnu?v;{=jk*+m8*V?wW+aP^Pc!&fux0Qx#H8<+3Y0k@kBtLQ% z^1dPLLp=>@su0`c@EM~l8pLAHzg8E8Nc|K-e|Y90s9UJ#vy$)F2sNFN?rFea2Wjg! z+I`K_3C4rp-Q1_ZvFZEH+5pj(W3};QZKAB;UM9Ybs20B-yu<{4@V*N0J_i?m-kYn$ z#{bnSxK0Hg;XnDu@Cu{{?%7-H#EU=*pt_!jzBsG8*yAo}XCCV*1+8)mXnj13@l;ID z?*Yk$o}9ApmBfVgA_B>{IbG*q;F~)kSem)L_m3kT&r+d3^Kgl6{<3r-Ffyv&?rt8z z)D@A6BqaKWtjZw*<`l+N0~;>4}EuH&TYs0 zg0*DiBLo9hDyl#V$L7kq;~%n(N@#dodfx3k{_jRH1zaN7kX^Pwye!T)!d`R4aHHxY z^Oar&2;N0h73lKm;aq^#*hzIzA=ogq&#W^+#9?edYD2i-LnimwC4?y9$)RgOe+5^R zBtmwzo*F%)Y+gjn;Qo7M$^5EEid&pR!XFFV@|ggD6CE=pzM=f6%n<8!!=W{)BUh#lTgqrzf@Y|IYkG!%^dV%-Km0<7yis|Uz!!yXu{`;` zDBYw{Ws}!ULmQS%JG8)&jo4F&fMV`=)twwXyV;xhif}7$)sG~^E3QPQ6@mucBb4L| z-hhCj?#6JuvaIEPR#k+VbA!KSjDd}eOl47`PO}C}LA$u8uJ@vYHvUKFKGP|FszjZS z_NBB|=C$nBBPsLr8|OVc^|aTl+cEVdQu+=4V5w3u%{kHPHmMZ_rTuszG+Nm}rOK;K z@m*Von)jV;EnW-lo0)cly8MAW4)d-RgKnC$j+?9ZT3TvZWD~LmbO&mVWcQC^r&ez1 z%uL#-8>s|Fo85hVdJg(rp*fP+=y+Wq6OyWsq!Pi?|MF&*1VD`a4d`;ac0;o5N+mBB z;ZQxC7(?ZhXc(Rl*`00&ZbdFr$iw7Lnb5y)uj*WR@Z~skx@_+l<;qKp0Ci78x-Q0X z%0=fnwLSRFXag#&u=|B@FOOVq`%ra(w(~CXnXat0Wi6kDY3=-7_6?R>0_r7s<%>sd zp3qoMpAAz;4ui?V{w`3Sz@mBI`l0i1;w{mOYv@W+rPtl>T8PShSds5-mF8ESZHNDn z@!^8@sE#l+dbIY=W)Vcty#<^R%jvB1teLmAu&Jppz_mQ^nAR7o$8}|THe8rK9%jcoHlHhCB=$7NI?#LDXtd%4d2$PZ zST{o5E^xTgJ-mXL{BArswe)y?Z027s#(4N5hQDz0SPz77$tGQ@eV!J$m!}d@0>2OJ zpigw|JnAd$?CqoU#lEb#!f?!f)C7@qIJQmNUn(r@Yn!m??Nx1iFfsIeq}TnsyQ>3FZ=O$;@)xK=r;x~csFIqhLgyxI zq<^mnz3JYO*v;4ski+mvTOqo##roiLr%3{ijwq>>KIF23pup*s7&SF?!t#x;eK9!K zKB;~D%aco~IF}_JR~pbA1_|$Y1~L8g8*IjY7$K~1(^Xfe z#ZB7cxCTEEsJCLS36$vRqoAX2ps`N9lepe1aptJ^E|fc{UP90Z`9HAe3M2cVbg#+ zRQ|AT7pqqIb@N&cSU50@Rb51mz`p#?6L=j`bfv>pW{ezrog=-jOc5*CEwr5)dIti+ z-c~^_QYPLyt}K04crJv%m<^l351tM6u?fBJ;xWUKE+FcuH`%}Y5t&E2THp6YmF1G% zIrqCzw{*kb+8JhPqh{u2*q{_YQ*?T`gl}=c+nP#`Vh*F8 zeluE|seD;-kyNR*D3v!p(S~J$tK#H?CEdzVDir+MSpkS{at^A3(5rqp4p3}-sp1blRCni`&JWbJ+u zRg7v7SR%ZIi(VjoP9qLKg5Az>ImdsXBu6gx3Z$h-@B^ z6(_akCuR()2d@h0aSpWgdFBSf5>9}I|3<=t1X5KuF+tc2a+%ke?f%8->#uK0>+#k_ zKA2AEX|xjF6dvTwTy%DK@j>(gfDPshqJGtv7lWra?*kj1C67sCz4C=a70h+1|0=$5l>({vbS}$!#^elUk4Xfkx@4Ac7c8p}eH)Cl#;>eK;b6zas&`k4ooqfAZ?q z0v<+_l4wVq?7j_DDnBhBd`!lE0kR*I(?l&$kRu~?%_5MnDb66wLz)Tq`g*X6dm>=t z3t96e7t<&;gZ{(uNQU>9Zx2T?w$~R7brb=|%5t$veB)9YCx^AQ*^r`{j6pl1`NIpd zj#uEQv1G6lHf=oC`gc8+2N`sayq6P?UOO0Hm~Z)bg66QFE5jc7dsZhgK{(yj`<9-Wl&!-ONs8;tSl?@u zomIfXk1$8ZLJn;V`!V12x=ySMm<;UZ`R*wR=fP(Aw~&Raka(Zm%DSOYaO@FAeM5cC z2j^-21@o}|LYz}cvNwoNs6w~(G?-T?y5CYTll&#EbHpNjL0>BDd>tX#3E-BZrL8Vf z&uMy`%+qHH#4kmP0*%BvHfZJd-YYrS8w{FN#*GF7Iq*PP)K8hec_)(cl4ILgsKB?n zB0vLZRzt#;W=(Vi_SR=?j=+bo@jRYWunUqifUYi;IQzsD4DI1SciD~ahY=ph*6B%s zsi8>~#f@G@?9_06>uEsZQ5BCQ>!Ht*RTSgXxz2KNdVLs~Q3yRwF{lT&$|X3BoSG^JLfWIUkj&(iV|IbF^YpzBT3D0BrC|h{Z@QEHxF875hQphO#h%lp2hW9`X&L{3+ zFVlLYmDkKxrlZRuHoCa-R4-uF2mJ$jcZqCePPIt=*QA!|#6E@Lql+4u2gl2LxV{%j z`pRUBX7P(^yI{CxFW@${C6CM%8V6M-p(s-*cLtRRt=-17S~Pil*DCpU9s@3W%`KO{&&>_SYw-6GLq9mD?h;db!7T8x@N?~p{-E6~^O zqvD%5t?|{dJYC}Z;y$z}s@+GT_{XIULYCpC=vbxUbZNM6JmxOyOqSD}3)E)wkh_Nt zO6BqDlCkKW#A8u~XN1K@fn(tS_aB0>==Dw5V8W>|)xD<+DjPpT5!H-fmIz-#Y;c|u zvY0pCI)n-ipO69E)qQF~mToJtX!a-fr3(%_nQmHR=r*!a6z@q?v_S!#P?JLEzlZV8 zikIChQyScqn)$scabs6>ep29VF!Wv+Aj&0ycQDY)4vC(gl*%2D7UrwHuw7su<)^+p zpKpy3Y;n)7CW}UE2m!R$?2jq%i3tED{viW#0(I5i1&^QrYOSC$l=-k zzviL+V9dpiwplse2flnz1+n~y@yR-|Y!K34_A1##vBBe;2;|P%vUi^ChI>}4{h;C> zp%C6u;CTxKK+o8vd*^e=gFCWLB?7Jw0lKa|dQSRz41G zk37nLOw$*?-Ri!ega~{4=JldhBibSe518<4MpU)^HA}crQovR$K7G9E?KcfO)eh(3% zd@DuGR`+l7V(uy8{NKc{^h@|3IX%y}=$Jnn(Iej5`q4UsK2=>;(V4M2( zGZC&Gt#ITRpe}%~9eiEDjeFADo`D{<8>*b9@h2P|vuL|t+^Z3KP zmuc!e#@Ys8V>y*q@D2Uk?Q|c3#v9H7bBXP`pmys#5B0KLNVW-&cEz%Y_5A^TFx$gq zx)XEwdi06u)T-&%YzPPV#0(-Pu>B9YPmP4rBFSlG2}jr{m$gN0ss$(a1C^i89)Moh zi(Iz{zVq1w3i}1ZnbB zOyWhNC1=wnap;rIG*Fh6D%IY2EXt%qSYNZ`;699Ygp1;<{BA+iWm_lCoC9>8pF1;E z>$W1zPCfO>tZ4gvwLWiNEMx~)&i&IeA|)3rT>ouQ457XvVKXzC)k&~8y{>e6C6=7$ zFjU*fY7@8cwMf1%U&zJ_-dk)0;89`~cF@urJ?t5IDySXuD9w_rKJg@7*kN4YoKQ{k z;ii)X6B@2$OihxSxqjFyyfrOg=%%t&1$YD+kH_ul@?_6HBtCcO0b;KDs*pnR*>r|8 z*Euk&ZdZc5tWS%NC`b<0+I_&&ExC_+r?Tnht=OJf_vFf`9Hb3=JMyrEf%&pio<-QE zf*TMd!+-#rD)t~9s?$90Pi?~Xt$?ym`5u6C-FFSei3bX~c#>OO86$&JEBn{$-q(!N z5~E9-qH4P?MkCrmqAn2;-R_SE^;P6rPTAsyp5CAL6Xyx_iGyan!exWio_d5;TFdR; z`l5skv$Up3Q%9{WZEpwj53iVRX<4>5uy=(}3}m7!2wrF@ndcu|oen2+o8OBkX==7F zI&4O2A0?utH8SwL;58$>r?rEH@<$W}kXNuf$|u!#@2`isZ$J8ann{s@AC2^Qpy%M|i)sVoB-#AhU8I(J1yGqU&sK29_m(OP!a2SXuTkyIftv060e6n`k>3<^8k-o&sV2DrDF?uQdDh9&w3wraK|nqKsdRAD%4nLm*MXIoF_7>Q zyseR<`=|I|KlbX4C1;R-gYQok1eUys{t?eCdOQ-p_)Ykw%9aOR3^C^BWjiAWDnG!b zsb@Re6|agkBl>=YhAGvTT%u`~g47L*?B0U8jh%;$J@vx?D^u_mGnmLJz@scK8%%AA z%)XQVu8Jc$u4Nm&?U#sh8UectS4y{RKVo|kKg}$1!zHG0M$F>X=i-jML#_hBjMx_% zj}K90JcB8Mij6^tNC9`b`0c6LE83%y>J4;kK*{VgmkMX%v{)+1)KR$1XAx&ntKNt& ztLj&BP(G=;5{FC<9AA0$9mQJKh}PsIPTLH1FJ3IUxAxVl$I-YQHy}}PdgUlu=-Ct2Ah=rb#lIp*V8!@cfYeYx%7_zuM*&uLpl^sv|e z9HrNoKY6znvaRPqP-c!kcC|eaY*OSJJQ9LEd4e8mD_-PE7LRhx8JH1DyWb2*^qOYG z<)t!7N>vVw;7yMm$*(Kx!ts1O{DpBD`#*TgcONZoQk7B>&=V5sd~t!)p^@KPfy}*H zEewMcdQvZ4`PuG8js-QyU5@F0`}^O=1G**eof{v$+B1kNEvx>J+|0^F6rUbq9ca#a zl3tI3c_Cond@k0hbWeT~Jn^CI^VwPays`&|h`8`%bgmg42)&qtoE<}B7VPn5UjR`u zEHRhfc|>{W9K%+kT(GR0jj^2d0Q$^N*vd$hGJNrP8$ZKsP|9+qn>*LM08G_+&VCj9 zWXp?m)`c_w%!=IC7=UuPVDqPz2-w-3aoA>{`xJEKGkk+cz1vk6`;#y8 z6*S)7=z!Hxvb$9!nFhWOvIhdI%MdV8S!N)oe-NL~TrUv3x z<+~LNZrCS2zcIBa3*N?|yavp?B4uCKT9|^y14Hgm2!aocG~#{ITLNjpw?8EYtRR1_ zfx%n_egbzP>Fm1YdfkbI?D3?#;&BI{@hyk#_3f{n>CiF~2=qCt2D85(g@CP%Bu|DY z3fp0Kiw(nu&TJX;)CN}x8X)QNb8Sq8(S>bgV2ntPTeLtIK;vq}-z;9MHdL#W@)9$v z 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ℑ#%f;eG=IHuR_OSVnf za7CHlw)RrjyU-#NUv{50tGsHry>KMr$t7l%x9lmo-I%uor;js88izUlhY|+Ty3Zv+I=cFwnCk)r}@uSpo?1(ewrq0)n-_={e4pzP8u)8Pg(= z$%||}c!RZ9Cp1viCigwRcVhsc_N($|3+`DS7ScLsIdr|vh!@}n#zkseOX&s!NkH6y zH{^%}`OBrrwMzoI$!z%cKOvGi#lUhI%<;wxctV5>WJ%Whrd+%A(;QGhY|z(3{8HQj zWZDEM{W9OTORv28ACd1@k-}Be$!MMpkO+&F6o|%Hw-PgTyO3|+oZOF41?K-sihO}g zumaU=0!Ib~86u{P5t0iW9{1JTpI_QJOlKNzG@)m^y|+^sxH=(*ijlMGKTRloT~>aT zvuS8PnrLP=P`Vi<%TCLk+{-VCQ)s}xJOJ`)M({ZHm;yY@vMp_UEe89qejUv_|bxPu6RBK$NPXs=^3W;<+rP<_}nf4*R3{b(UEZv z)0Y{8y5FG*)PD@x)l+&KPsM4WzYz{>bQ$th9y~Zzms_9Ix|n@bdZ|?<}XvPT*Lpq4h4PEjl87DNB!VT zFeXHVgzX{B1riJ{%-BI{OZy2JkTySOnw)M^zwSu#vTx&hml=g+u0rSY)^z%X`u-?Q zTcm{TEjXF-Yd(p=O;yV}SNkYrE=}Er#(>u(o-l6_eqZbn_6i4-8OpbZ@(05}bL3$V zb@4`8g8J_b*dcg_-9&qD6^dn`#%HVowji_w1*7x1Cbt>yNluD zSQ)z*+t(MRunJ;9Q{O9q`BQ&$4|_OiZyI9HjnB^BJ|{ZN!l)N?D04qwTHW4H9|4>= z^qR`}l89e7pIUzSuLeOps=VlsEQR7sExy*#@sc|T96hDJ;qh13+PNBX=qN3hZT_jv zcqjjwh>9U@uHdw%yRp1JUzCEG-|I4hkHq!Q*u3@Zt3%~(B+kdPfA{pLc4YcZ`TwN4 zO?GP+4Q{4-Lxr?&D&52bqXBCF{fx>66m>zBHU`eZ=_?OJcwiCM4`g)I21C0g^K=$% z^5_6fX!+qchleQMV%AZkpgh5y2B}hT!fgw|s!m`d28Pga(im#=m6@zA`T5LS6{{=? z>~JmGoUPuv1 z3#rxuiZ#+@9}?l62B?gaVBzK_>J64T zY`J-J3UE4AM!kL{!)T_zymYA=gGT)vs0BIp+ir&&aGIQf-yp)=fn^!C8eQLT^>_Jo zUh!;4frYEq=9@5WjdzZk1*Fz8#4?JN&%Q^&D4=h(0#X{b9=^9IHv!LHsX*ml@bDM6 z%hrlvt2F{PuzAAP=?`qU{4PX8hO}L(W&|~bF8A?(W_0PWEweUZOjS3+_`4fA<&N1M zdy|noU)=+WPTyZhP5u19(tmtv9krQl%AOT6J13|M&c26M9{)xFzd* zsGSX|9)mY8L%V$mV1kUOPUIWHDbzt{S#;O+69C&5`d;BaFA?M*XnPn>N$`2dmIv94PQw8l`f3o zmikZPen!sJ06`PnHGV^i5vFe>#ob?3Zv@Q2u6ivZ{v5Iu;3)Aopj8 z^?7Us^LpI=DU4(FJGwpIa%|$*q71OxDEie}$iNH?>T_XwOF53|6G7Q*xpXUQQG39p zR^&{b+-)9Nr%c`6o}|0<<;aHZ@9l-Fmd6+4b#<}=WkzIfTBo>|l?T$`fI`aB9!fJ6 zSZB%gaJW>%F_QVP6Z(!bmfZT=8GQp5PpT^AU9rxaog?}!|mD@6W(YUwC8^>;B!N!joi| zwL?8T%}9#< z(Fp10GZ+W-?WtcIZW8=yYlbA5d1F2_+=8BMW4%Xts;qTKZH2h?l<^yWnSb6SST+dz z_Fc5J?pupHUgJ!1E9%7Jg+p&XkQ)$Dabih5z3W7+v+dJY83&^WH`TQ;AUpWJ0mxh4 z*A&g0QlmgJ`^Oryo=qXFPk;1$KzK;i7uFv01+fj2_TK4OOrw%{U!>9z{73gWX+-S` zUXeT-p_FyKn|pxwo5ltXy2Dm{jDeC_BS9NL1g>T_AIE~CltH$J*I;-O9^Ge6m&LKO zjXukO##(1RFzX?yjcEi z6-qSALcJFtC8~c!;4SR8IxsWv@k&FZL)A7kDNCb5-PwYzZSb)CRu9M>VFjQoA9sgu zrZ&|y3%0N@P=xHz{?2fbg9?+?^DTr~%F=qQ56R9!WF(5h>Yv3zc?wrQBy&-b6xtTF z11pr&+mNIYADL}JbTJw1U#zl~Wm2GI5YN>Ntd%IcNXUJxN5ApE2?;16U7C+x#^6(U za`yDlwA_d#FYqqaH6!Z-5=G-X7KEyAWRb-N&u3Oil-Rq5dKf(YERH@ns!B7><)(ba zwFo&kP-^IO`3J7{(=MiGc*a)LHXVc>yR_yW7P;X?mmr?polXu)hLd2Eu=AeUBv`jf{Ly={7Ux_C%+8igbYhY8_l@c+O4`A7hv;S~2$A z+gMllj8WDZ7lMUHbcoYj_|0`!pz8?Tqz!vi@ECT^#98**>rgxu+;J_9EM?{XSDpA6 zRu#a1JBMA3y~r97{gUs@?hjrv<_p_pSqLO_?S*L%bE`0~@r9wtU)x4kqJeo8~WIM-+ed<>~! z&skl{g>Oj(;7T3wh>-8n0%F!Bo$S-s1MC))3{e7gU6}+AvCP-1Us^)c!tO4};D_|f zSj}UQUP7(6;;J$~yVE;yr%7FY<$hUiTJ0S11O=_?wAx`StAHrjZ`7?qZ+#jfYjH{_lYviea(T zQ`bOmUl=$R{_pnQAVzm-CB#xEagcvdOw&(Nkza4i{9#*rlfA)5{v{O8dT#Q)o`?PB ze7PBAe!$RaZ+u}l_SuRv9bF`MVlN+;K5{o;K5*7p3w#8P!FzD~l|1Q{FqolDZjv(Z z=JF@+7-br9GAriS1RvVM1qKcT<0RiN2IK@|VfFeWTtIt)KWcH%2M=Mmv+;HNMLV*_ z476M4AISY#W0k{PVvg-RGff7pWz{OYehyamS^r-2b7^Cz1!?%%)&To-{`{anvk@`P zkh)5*dK(DnPSc%LN6m~cd)SCI3sC>`fgE!qJ)J~6o9}46dGPQ!lcrZ!F|K#9 z1rK#%AM)1;)AX&JsJK^7`3j#LxHS(r777#BF}CovYOhulTz{Nr1LkUUf2uH5#N;wb z4ydq0h{v+l^7RHE+&xcLIOO4q{TBNa3>GlH^bljj6f~ns>>jg{j6}2`a1lG#&w`KH zhKi-0fk`_V(j(SSIJ`RYghLd%%u9%C*S2aXUW|6}0|GM8rTtOF#$k<>p9NAyJrDfD z$FgRhI|KakEiYA+69N;MNs~50gjOEh${y;{*qNSP(7b*%t$UEngrLg~J=aj5pYv`n}dOV-I>3g-- z7=-A;S(YO3ZlStDsiL>*g4%V}ONna^Dk0aESsX>6pmygUIeMMRp2){{0Xf3y6umb?=$#Ky8~g)($Z&3 zpFR)5Vvee6T@$q~eQ_c?$iF2v-H5?pU2j#*;LiLJgr8QVE0zH{PfwKa&Gx{#|FmF@UW)c1cFqz90~Tnz(g_Z4 z38wDyFe1@OfiI!sLXKe9d&Z^_V~B~$J1NhHIG7ID3d@R`S$^41X)V01Hyjtot2oBh zhXejAE^$IQuMY}mIgOI)-oRZ$wnq^hU=RYiAB$@pqiUc!`|#*6bb zp0Q2C+#%{b`R4bUz3$*{G$}}04~52keH6+X6o$tl`@zuk82e#%ZPL&T* zZf9l=Upa;}RD2D;mj3U?#xs>XP66=(4~=<|@DIB_h+7_ju;11CX})_E$ct&0?rFuTQS;@`x?M#Zc4ZjJ`ODT~WJ>jo-L1HniAZ&u8M z6cR!IlN3uy6DW#ixIr`Jgp+B@I+HbQmL47@25L(34(;W) zeD~c>gcI5#m_yAG6Z-Vgm?B>B!B$S+RT`aS{Ejrfb^hFy(6zfe>g^y_4I^$ooT~rg zj<$t$aX)!&XCSM`w4}pk{xq315*a$HF&L3)^n_oQ%*{@NwkaJ1RAG3&l)`lWK$1=`cwG)X09jD63A@(&d1@*$`DrD^@@^2)obC(PHh~76bF#}0 zYVqxg;1?T`FCo~4IcwgP3u)nNgRiqhQ$ByDf^|w)_(kBc=uf=r1Ld+B-*I|r#(jQ$ z_r9LPRyavIIaJH9t5ECKF)k)!wAL%0H{ve(dkS#DljLQkp5AXcHzMYYtRd@Z

MNJ1&rJf$Jb=8fKMpoJnOZ4texyeeW-j-K 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

$Lruc$AwnPFK|4nuaZm#Cun3At%8djC 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

>Jp-<0 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

    iSEi@7TPRPDST6;k%@geks-j4Ea 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 0) then begin - eOld := eNew - eOld; - //eOld := eOld *2; // this is only used for faster updates... - Result := 'Metamod:Source - Uploading with ' + FloatToStr(RoundTo(eOld / 1024, -2)) + ' kb/s'; - end; -end; - -function GetAllFiles(Mask: String; Attr: Integer; Recursive: Boolean; ShowDirs: Boolean; ShowPath: Boolean = True): TStringList; -var eSearch: TSearchRec; -begin - Result := TStringList.Create; - - // Find all files - if FindFirst(Mask, Attr, eSearch) = 0 then - begin - repeat - if eSearch.Name[1] <> '.' then begin - if ShowPath then begin - if ((eSearch.Attr and Attr) = eSearch.Attr) and ((eSearch.Attr and faDirectory) <> eSearch.Attr) then - Result.Add(ExtractFilePath(Mask) + eSearch.Name) - else if (ShowDirs) and ((eSearch.Attr and faDirectory) = eSearch.Attr) then - Result.Add(ExtractFilePath(Mask) + eSearch.Name); - end - else begin - if ((eSearch.Attr and Attr) = eSearch.Attr) and ((eSearch.Attr and faDirectory) <> eSearch.Attr) then - Result.Add(eSearch.Name) - else if (ShowDirs) and ((eSearch.Attr and faDirectory) = eSearch.Attr) then - Result.Add(eSearch.Name); - end; - - if ((eSearch.Attr and faDirectory) = eSearch.Attr) and (Recursive) then begin - with GetAllFiles(ExtractFilePath(Mask) + eSearch.Name + '\' + ExtractFileName(Mask), Attr, True, ShowDirs, ShowPath) do begin - Result.Text := Result.Text + Text; - Free; - end; - end; - end; - until FindNext(eSearch) <> 0; - end; -end; - -function GetAllDirs: TStringList; -var eList: TStringList; - i: integer; -begin - eList := TStringList.Create; - frmMain.IdFTP.List(eList); - frmMain.IdFTP.DirectoryListing.LoadList(eList); - eList.Clear; - for i := 0 to frmMain.IdFTP.DirectoryListing.Count -1 do begin - if frmMain.IdFTP.DirectoryListing.Items[i].ItemType = ditDirectory then - eList.Add(frmMain.IdFTP.DirectoryListing.Items[i].FileName); - end; - Result := eList; -end; - -{ This is another possibility I coded because I couldn't find another bug... - -function GetAllDirs: TStringList; -var eList: TStringList; - i, eStart: integer; -begin - eList := TStringList.Create; - frmMain.IdFTP.List(eList, '', True); - eStart := 0; - - - // +----------------------------------------------------------------+ - // | drwxr-xr-x 5 web3 ftponly 2048 Jun 25 19:43 files | - // | drwxr-xr-x 2 web3 ftponly 2048 Jun 25 19:57 html | - // | drwxr-xr-x 3 root root 2048 Jun 20 05:03 log | - // | drwxrwxrwx 2 web3 ftponly 2048 Jun 19 2004 phptmp | - // +----------------------------------------------------------------+ - - - // at first remove all non-directories from the list - for i := eList.Count -1 downto 0 do begin - if Pos('d', eList[i]) <> 1 then - eList.Delete(i); - end; - // then we have to find the position where ALL filenames start... - for i := 0 to eList.Count -1 do begin - if (eStart = 0) and (Pos(':', eList[i]) <> 0) then - eStart := Pos(':', eList[i]); - end; - - if eStart = 0 then - eList.Clear - else begin - // find the position - for i := 0 to eList.Count -1 do begin - if Pos(':', eList[i]) <> 0 then begin - while (eStart <> Length(eList[i])) and (eList[i][eStart] <> #32) do - Inc(eStart, 1); - end; - end; - // remove the detail stuff... - for i := 0 to eList.Count -1 do - eList[i] := Copy(eList[i], eStart +1, Length(eList[i])); - end; - - Result := eList; -end; } - -end. - - diff --git a/installer/UnitInstall.pas b/installer/UnitInstall.pas deleted file mode 100644 index 95622ba..0000000 --- a/installer/UnitInstall.pas +++ /dev/null @@ -1,560 +0,0 @@ -unit UnitInstall; - -interface - -uses SysUtils, Classes, Windows, Graphics, Forms, ShellAPI, Controls, Messages, - TlHelp32, IdFTPCommon, ComCtrls; - -type TOS = (osWindows, osLinux); - -procedure AddStatus(Text: String; Color: TColor; ShowTime: Boolean = True); -procedure AddDone(Additional: String = ''); -procedure AddSkipped; -procedure AddNotFound; -procedure DownloadFile(eFile: String; eDestination: String); - -procedure BasicInstallation(ePath: String; SteamInstall, ListenInstall: Boolean; OS: TOS; const Source: Boolean); -procedure InstallDedicated(eModPath: String; const UseSteam, Source: Boolean); -procedure InstallListen(ePath: String; const Source: Boolean); -procedure InstallCustom(ePath: String; eOS: TOS; const Source: Boolean); -procedure InstallFTP(OS: TOS; const Source: Boolean); - -var StartTime: TDateTime; - SteamPath: String; - StandaloneServer: String; - Cancel: Boolean = False; - -implementation - -uses UnitfrmMain, UnitfrmProxy, UnitFunctions, UnitPackSystem; - -// useful stuff - -function InstallTime: String; -begin - Result := Copy(FormatDateTime('HH:MM:SS', Now - StartTime), 4, 5); -end; - -procedure AddStatus(Text: String; Color: TColor; ShowTime: Boolean = True); -begin - frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text); - if ShowTime then begin - frmMain.rtfDetails.SelAttributes.Color := clBlack; - if frmMain.rtfDetails.Text = '' then - frmMain.rtfDetails.SelText := '[' + InstallTime + '] ' - else - frmMain.rtfDetails.SelText := #13#10 + '[' + InstallTime + '] '; - frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text); - end - else - frmMain.rtfDetails.SelText := #13#10; - - frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text); - frmMain.rtfDetails.SelAttributes.Color := Color; - frmMain.rtfDetails.SelText := Text; - frmMain.rtfDetails.Perform(WM_VSCROLL, SB_BOTTOM, 0); - - frmMain.Repaint; - Application.ProcessMessages; -end; - -procedure AddDone(Additional: String = ''); -begin - frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text); - frmMain.rtfDetails.SelAttributes.Color := clGreen; - if Additional = '' then - frmMain.rtfDetails.SelText := ' Done.' - else - frmMain.rtfDetails.SelText := ' Done, ' + Additional + '.'; - frmMain.rtfDetails.Perform(WM_VSCROLL, SB_BOTTOM, 0); - - frmMain.Repaint; - Application.ProcessMessages; -end; - -procedure AddSkipped; -begin - frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text); - frmMain.rtfDetails.SelAttributes.Color := $004080FF; // orange - frmMain.rtfDetails.SelText := ' Skipped.'; - frmMain.rtfDetails.Perform(WM_VSCROLL, SB_BOTTOM, 0); - - frmMain.Repaint; - Application.ProcessMessages; -end; - -procedure AddNotFound; -begin - frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text); - frmMain.rtfDetails.SelAttributes.Color := clRed; - frmMain.rtfDetails.SelText := ' Not found.'; - frmMain.rtfDetails.Perform(WM_VSCROLL, SB_BOTTOM, 0); - - frmMain.Repaint; - Application.ProcessMessages; -end; - -procedure FileCopy(Source, Destination: String; CopyConfig: Boolean; AddStatus: Boolean = True); -begin - if (not CopyConfig) and (Pos('config', Source) <> 0) then begin - if AddStatus then - AddSkipped; - exit; - end; - - if not FileExists(Source) then begin - if AddStatus then - AddNotFound; - exit; - end; - - try - if FileExists(Destination) then - DeleteFile(PChar(Destination)); - CopyFile(PChar(Source), PChar(Destination), False); - except - Application.ProcessMessages; - end; - - if AddStatus then - AddDone; -end; - -procedure DownloadFile(eFile: String; eDestination: String); -var TransferType: TIdFTPTransferType; -begin - // There's only one file to download and it's ASCII :] - TransferType := ftASCII; - if frmMain.IdFTP.TransferType <> TransferType then - frmMain.IdFTP.TransferType := TransferType; - // download the file - frmMain.IdFTP.Get(eFile, eDestination, True); -end; - -procedure UploadFile(eFile: String; eDestination: String; CopyConfig: Boolean = True); -var TransferType: TIdFTPTransferType; -begin - if (Pos('config', eFile) > 0) and (not CopyConfig) then begin - AddSkipped; - exit; - end; - - eDestination := StringReplace(eDestination, '\', '/', [rfReplaceAll]); - - // the same as in DownloadFile() - TransferType := ftBinary; - if ExtractFileExt(LowerCase(eFile)) = '.txt' then TransferType := ftASCII; - if frmMain.IdFTP.TransferType <> TransferType then - frmMain.IdFTP.TransferType := TransferType; - // upload the file - frmMain.IdFTP.Put(eFile, eDestination); - AddDone; -end; - -procedure FTPMakeDir(eDir: String); -begin - eDir := StringReplace(eDir, '\', '/', [rfReplaceAll]); - try - frmMain.IdFTP.MakeDir(eDir); - except - Application.ProcessMessages; - end; -end; - -function FSize(eFile: String): Cardinal; -var eRec: TSearchRec; -begin - if FindFirst(eFile, faAnyFile, eRec) = 0 then - Result := eRec.Size - else - Result := 0; -end; - -// stuff for killing processes - -function GetProcessID(sProcName: String): Integer; -var - hProcSnap: THandle; - pe32: TProcessEntry32; -begin - result := -1; - hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0); - if hProcSnap = INVALID_HANDLE_VALUE then - exit; - - pe32.dwSize := SizeOf(ProcessEntry32); - if Process32First(hProcSnap, pe32) = true then begin - while Process32Next(hProcSnap, pe32) = true do begin - if pos(sProcName, pe32.szExeFile) <> 0then - result := pe32.th32ProcessID; - end; - end; - CloseHandle(hProcSnap); -end; - -procedure KillProcess(dwProcID: DWORD); -var - hProcess : Cardinal; - dw : DWORD; -begin - hProcess := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, dwProcID); - TerminateProcess(hProcess, 0); - dw := WaitForSingleObject(hProcess, 5000); - case dw of - WAIT_TIMEOUT: begin - CloseHandle(hProcess); - exit; - end; - WAIT_FAILED: begin - RaiseLastOSError; - CloseHandle(hProcess); - exit; - end; - end; - CloseHandle(hProcess); -end; - -// Installation here - -{ Basic Installation } - -procedure BasicInstallation(ePath: String; SteamInstall, ListenInstall: Boolean; OS: TOS; const Source: Boolean); -var eStr: TStringList; - i: integer; - CopyConfig: Boolean; - eFound: Boolean; -begin - frmMain.ggeAll.MaxValue := 8; - frmMain.ggeAll.Progress := 0; - frmMain.ggeItem.MaxValue := 1; - frmMain.ggeItem.Progress := 0; - - {if (GetProcessID('Steam.exe') <> -1) and (SteamInstall) then begin - if MessageBox(frmMain.Handle, 'Steam is still running. It is necersarry to shut it down before you install Metamod:Source. Shut it down now?', PChar(frmMain.Caption), MB_ICONQUESTION + MB_YESNO) = mrYes then begin - AddStatus('Shutting down Steam...', clBlack, False); - if GetProcessID('Steam.exe') = -1 then - AddDone - else - KillProcess(GetProcessID('Steam.exe')); - - while GetProcessID('Steam.exe') <> -1 do begin // sure is sure... - Sleep(50); - Application.ProcessMessages; - end; - AddDone; - end - else begin - Application.Terminate; - exit; - end; - end;} - frmMain.ggeAll.Progress := 1; - frmMain.ggeItem.Progress := 1; - { Unpack } - frmMain.ggeItem.Progress := 0; - AddStatus('Unpacking files...', clBlack); - if not Unpack(Source) then begin - AddStatus('No files attached!', clRed); - Screen.Cursor := crDefault; - exit; - end; - AddDone; - frmMain.ggeAll.Progress := 2; - frmMain.ggeItem.Progress := 1; - { Check for installation / Create directories } - CopyConfig := True; - AddStatus('Creating directories...', clBlack); - if DirectoryExists(ePath + 'addons\metamod\bin') then begin - case MessageBox(frmMain.Handle, 'A Metamod:Source installation was already detected. If you choose to reinstall, your configuration files will be erased. Click Yes to continue, No to Upgrade, or Cancel to abort the install.', PChar(frmMain.Caption), MB_ICONQUESTION + MB_YESNOCANCEL) of - mrNo: CopyConfig := False; - mrCancel: begin - Application.Terminate; - exit; - end; - end; - AddSkipped; - end - else begin - frmMain.ggeItem.Progress := 0; - ForceDirectories(ePath + 'addons\metamod\bin'); - AddDone; - end; - frmMain.ggeItem.Progress := 1; - frmMain.ggeAll.Progress := 3; - - { gameinfo.txt } - if not FileExists(ePath + 'gameinfo.txt') then begin - if MessageBox(frmMain.Handle, 'The file "gameinfo.txt" couldn''t be found. Continue installation?', PChar(frmMain.Caption), MB_ICONQUESTION + MB_YESNO) = mrNo then begin - AddStatus('Installation canceled by user!', clRed, False); - Screen.Cursor := crDefault; - Cancel := True; - exit; - end; - end - else begin - eStr := TStringList.Create; - { Metaplugins.ini } - frmMain.ggeItem.Progress := 0; - AddStatus('Creating metaplugins.ini...', clBlack); - if CopyConfig then begin - eStr.SaveToFile(ePath + 'addons\metamod\metaplugins.ini'); - AddDone; - end - else - AddSkipped; - frmMain.ggeItem.Progress := 1; - frmMain.ggeAll.Progress := 4; - { Gameinfo.txt } - frmMain.ggeItem.Progress := 0; - eFound := False; - AddStatus('Editing gameinfo.txt...', clBlack); - eStr.LoadFromFile(ePath + 'gameinfo.txt'); - for i := 0 to eStr.Count -1 do begin - if Trim(LowerCase(eStr[i])) = 'gamebin |gameinfo_path|addons/metamod/bin' then begin - eFound := True; - break; - end; - end; - - if not eFound then begin - for i := 0 to eStr.Count -1 do begin - if Trim(eStr[i]) = 'SearchPaths' then begin - eStr.Insert(i +2, ' GameBin |gameinfo_path|addons/metamod/bin'); - break; - end; - end; - SetFileAttributes(PChar(ePath + 'gameinfo.txt'), 0); - eStr.SaveToFile(ePath + 'gameinfo.txt'); - SetFileAttributes(PChar(ePath + 'gameinfo.txt'), faReadOnly); // important for listen servers - AddDone; - end - else - AddSkipped; - eStr.Free; - frmMain.ggeItem.Progress := 1; - frmMain.ggeAll.Progress := 5; - end; - { Copy files } - frmMain.ggeItem.Progress := 0; - AddStatus('Copying server.dll...', clBlack); - CopyFile(PChar(ExtractFilePath(ParamStr(0)) + 'server.dll'), PChar(ePath + 'addons\metamod\bin\server.dll'), False); - AddDone; - frmMain.ggeItem.Progress := 1; - frmMain.ggeAll.Progress := 6; - if ListenInstall then begin - ePath := ExtractFilePath(Copy(ePath, 1, Length(ePath)-1)); - AddStatus('Copying hl2launch.exe...', clBlack); - CopyFile(PChar(ExtractFilePath(ParamStr(0)) + 'hl2launch.exe'), PChar(ePath + 'hl2launch.exe'), False); - AddDone; - end; - { Remove files } - frmMain.ggeItem.Progress := 0; - AddStatus('Removing temporary files...', clBlack); - DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'hl2launch.exe')); - DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'server.dll')); - DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'server_i486.so')); - AddDone; - frmMain.ggeItem.Progress := 1; - frmMain.ggeAll.Progress := 8; - { Finish } - AddStatus('', clBlack, False); - AddStatus('Finished installation!', clBlack, False); - frmMain.cmdNext.Enabled := True; - frmMain.cmdCancel.Hide; - Screen.Cursor := crDefault; - - if ListenInstall then - MessageBox(frmMain.Handle, PChar('The Source launcher "hl2launch.exe" has been copied to ' + ePath + '. You can use it to start your game with Metamod:Source enabled.'), PChar(Application.Title), MB_ICONINFORMATION); -end; - -{ Dedicated Server } - -procedure InstallDedicated(eModPath: String; const UseSteam, Source: Boolean); -begin - StartTime := Now; - Screen.Cursor := crHourGlass; - AddStatus('Starting Metamod:Source installation on dedicated server...', clBlack, False); - BasicInstallation(eModPath, UseSteam, False, osWindows, Source); -end; - -{ Listen Server } - -procedure InstallListen(ePath: String; const Source: Boolean); -begin - StartTime := Now; - Screen.Cursor := crHourGlass; - AddStatus('Starting Metamod:Source installation on the listen server...', clBlack); - BasicInstallation(ePath, True, True, osWindows, Source); -end; - -{ Custom mod } - -procedure InstallCustom(ePath: String; eOS: TOS; const Source: Boolean); -begin - StartTime := Now; - Screen.Cursor := crHourGlass; - AddStatus('Starting Metamod:Source installation...', clBlack); - BasicInstallation(ePath, False, False, eOS, Source); -end; - -{ FTP } - -procedure InstallFTP(OS: TOS; const Source: Boolean); -function DoReconnect: Boolean; -begin - Result := False; - if MessageBox(frmMain.Handle, 'You have been disconnected due to an error. Try to reconnect?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then begin - try - frmMain.IdFTP.Connect; - Result := True; - except - MessageBox(frmMain.Handle, 'Failed to reconnect. Installation aborted.', PChar(Application.Title), MB_ICONSTOP); - end; - end; -end; - -label CreateAgain; -label UploadAgain; -var eStr: TStringList; - i: integer; - CopyConfig, eFound: Boolean; -begin - frmMain.cmdCancel.Show; - frmMain.cmdNext.Hide; - Screen.Cursor := crHourGlass; - - frmMain.ggeAll.MaxValue := 6; - frmMain.ggeAll.Progress := 0; - frmMain.ggeItem.MaxValue := 1; - frmMain.ggeItem.Progress := 0; - - { Unpack } - frmMain.ggeItem.Progress := 0; - AddStatus('Unpacking files...', clBlack); - if not Unpack(Source) then begin - AddStatus('No files attached!', clRed); - Screen.Cursor := crDefault; - exit; - end; - AddDone; - frmMain.ggeAll.Progress := 2; - frmMain.ggeItem.Progress := 1; - { Check for installation } - AddStatus('Editing gameinfo.txt...', clBlack); - eStr := TStringList.Create; - DownloadFile('gameinfo.txt', ExtractFilePath(ParamStr(0)) + 'gameinfo.txt'); - eStr.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'gameinfo.txt'); - - CopyConfig := True; - eFound := False; - for i := 0 to eStr.Count -1 do begin - if Trim(LowerCase(eStr[i])) = 'gamebin |gameinfo_path|addons/metamod/bin' then begin - eFound := True; - case MessageBox(frmMain.Handle, 'A Metamod:Source installation was already detected. If you choose to reinstall, your configuration files will be erased. Click Yes to continue, No to Upgrade, or Cancel to abort the install.', PChar(frmMain.Caption), MB_ICONQUESTION + MB_YESNOCANCEL) of - mrNo: CopyConfig := False; - mrCancel: begin - Application.Terminate; - eStr.Free; - exit; - end; - end; - break; - end; - end; - - if not eFound then begin - for i := 0 to eStr.Count -1 do begin - if Trim(eStr[i]) = 'SearchPaths' then begin - eStr.Insert(i +2, ' GameBin |gameinfo_path|addons/metamod/bin'); - AddDone; - break; - end; - end; - eStr.SaveToFile(ExtractFilePath(ParamStr(0)) + 'gameinfo.txt'); - UploadFile(ExtractFilePath(ParamStr(0)) + 'gameinfo.txt', 'gameinfo.txt'); - try - AddStatus('Trying to set gameinfo.txt to read-only...', clBlack); - frmMain.IdFTP.Site('CHMOD 744 gameinfo.txt'); - AddDone; - except - AddStatus('Warning: CHMOD not supported.', clMaroon); - end; - DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'gameinfo.txt')); - end - else - AddSkipped; - frmMain.ggeAll.Progress := 3; - frmMain.ggeItem.Progress := 1; - - { Create directories } - frmMain.ggeItem.Progress := 0; - frmMain.ggeItem.MaxValue := 3; - AddStatus('Creating directories...', clBlack); - if not eFound then begin - FTPMakeDir('addons'); - frmMain.IdFTP.ChangeDir('addons'); - frmMain.ggeItem.Progress := 1; - FTPMakeDir('metamod'); - frmMain.IdFTP.ChangeDir('metamod'); - frmMain.ggeItem.Progress := 2; - FTPMakeDir('bin'); - frmMain.ggeItem.Progress := 3; - AddDone; - end - else - AddSkipped; - frmMain.ggeAll.Progress := 4; - frmMain.ggeItem.Progress := 3; - { Upload metaplugins.ini } - frmMain.ggeAll.Progress := 4; - frmMain.ggeItem.MaxValue := 1; - frmMain.ggeItem.Progress := 0; - AddStatus('Uploading metaplugins.ini...', clBlack); - if CopyConfig then begin - eStr.Clear; - eStr.SaveToFile(ExtractFilePath(ParamStr(0)) + 'metaplugins.ini'); - UploadFile(ExtractFilePath(ParamStr(0)) + 'metaplugins.ini', 'metaplugins.ini'); - DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'metaplugins.ini')); - end - else - AddSkipped; - frmMain.ggeAll.Progress := 5; - frmMain.ggeItem.Progress := 1; - { Upload server.dll / server_i486.so } - frmMain.tmrSpeed.Enabled := True; - frmMain.ggeItem.Progress := 0; - frmMain.IdFTP.ChangeDir('bin'); - if OS = osWindows then begin - AddStatus('Uploading server.dll...', clBlack); - frmMain.ggeItem.MaxValue := FSize(ExtractFilePath(ParamStr(0)) + 'server.dll'); - UploadFile(ExtractFilePath(ParamStr(0)) + 'server.dll', 'server.dll'); - end - else begin - AddStatus('Uploading server_i486.so...', clBlack); - frmMain.ggeItem.MaxValue := FSize(ExtractFilePath(ParamStr(0)) + 'server_i486.so'); - UploadFile(ExtractFilePath(ParamStr(0)) + 'server_i486.so', 'server_i486.so'); - end; - { Remove created files } - AddStatus('Removing temporary files...', clBlack); - DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'hl2launch.exe')); - DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'server.dll')); - DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'server_i486.so')); - AddDone; - { End } - frmMain.IdFTP.Disconnect; - frmMain.ggeAll.Progress := frmMain.ggeAll.MaxValue; - frmMain.ggeItem.Progress := frmMain.ggeItem.MaxValue; - AddStatus('', clBlack, False); - AddStatus('Finished installation!', clBlack, False); - frmMain.tmrSpeed.Enabled := False; - eStr.Free; - - Screen.Cursor := crDefault; - frmMain.cmdNext.Enabled := True; - frmMain.cmdCancel.Hide; - frmMain.cmdNext.Show; - frmMain.tmrSpeed.Enabled := False; - frmMain.Caption := Application.Title; -end; - -end. diff --git a/installer/UnitPackSystem.pas b/installer/UnitPackSystem.pas deleted file mode 100644 index db98ca9..0000000 --- a/installer/UnitPackSystem.pas +++ /dev/null @@ -1,222 +0,0 @@ -unit UnitPackSystem; - -interface - -uses SysUtils, Classes, Zlib; - -procedure CompressFiles(Files: TStrings; const Filename: String); -function DecompressStream(Stream: TMemoryStream; DestDirectory: String; const Source: Boolean): Boolean; -function AttachToFile(const AFileName: string; MemoryStream: TMemoryStream; Version: String): Boolean; -function LoadFromFile(const AFileName: string; MemoryStream: TMemoryStream): Boolean; -function Unpack(const Source: Boolean): Boolean; -function GetVersion: String; - -implementation - -uses UnitfrmMain; - -procedure CompressFiles(Files : TStrings; const Filename : String); -var - infile, outfile, tmpFile : TFileStream; - compr : TCompressionStream; - i,l : Integer; - s : String; - -begin - if Files.Count > 0 then - begin - outFile := TFileStream.Create(Filename,fmCreate); - try - { the number of files } - l := Files.Count; - outfile.Write(l,SizeOf(l)); - for i := 0 to Files.Count-1 do - begin - infile := TFileStream.Create(Files[i],fmOpenRead); - try - { the original filename } - s := ExtractFilename(Files[i]); - l := Length(s); - outfile.Write(l,SizeOf(l)); - outfile.Write(s[1],l); - { the original filesize } - l := infile.Size; - outfile.Write(l,SizeOf(l)); - { compress and store the file temporary} - tmpFile := TFileStream.Create('tmp',fmCreate); - compr := TCompressionStream.Create(clMax,tmpfile); - try - compr.CopyFrom(infile,l); - finally - compr.Free; - tmpFile.Free; - end; - { append the compressed file to the destination file } - tmpFile := TFileStream.Create('tmp',fmOpenRead); - try - l := tmpFile.Size; - outfile.WriteBuffer(l, SizeOf(l)); - outfile.CopyFrom(tmpFile,0); - finally - tmpFile.Free; - end; - finally - infile.Free; - end; - end; - finally - outfile.Free; - end; - DeleteFile('tmp'); - end; -end; - -function DecompressStream(Stream : TMemoryStream; DestDirectory : String; const Source: Boolean): Boolean; -var - dest,s : String; - decompr : TDecompressionStream; - outfile : TFilestream; - i,l,lr,c : Integer; -begin - // IncludeTrailingPathDelimiter (D6/D7 only) - dest := IncludeTrailingPathDelimiter(DestDirectory); - - Result := False; - try - { number of files } - Stream.Read(c,SizeOf(c)); - for i := 1 to c do begin - { read filename } - Stream.Read(l,SizeOf(l)); - SetLength(s,l); - Stream.Read(s[1],l); - Stream.Read(l,SizeOf(l)); - Stream.Read(lr,SizeOf(lr)); - { check if this is the right file } - if (s = 'hl2launch.exe') or ((Pos('.source', s) <> 0) and (Source)) or ((Pos('.orangebox', s) <> 0) and (not Source)) then begin - { remove extension and read filesize } - if (s <> 'hl2launch.exe') then - s := ChangeFileExt(s, ''); - { decompress the files and store it } - s := dest+s; //include the path - outfile := TFileStream.Create(s,fmCreate); - decompr := TDecompressionStream.Create(Stream); - try - outfile.CopyFrom(decompr,l); - finally - outfile.Free; - decompr.Free; - end; - end - else - Stream.Position := Stream.Position + lr; - end; - finally - Result := True; - end; -end; - -function AttachToFile(const AFileName: string; MemoryStream: TMemoryStream; Version: String): Boolean; -var - aStream: TFileStream; - iSize: Integer; -begin - Result := False; - if not FileExists(AFileName) then - Exit; - - try - aStream := TFileStream.Create(AFileName, fmOpenWrite or fmShareDenyWrite); - MemoryStream.Seek(0, soFromBeginning); - // seek to end of File - // ans Ende der Datei Seeken - aStream.Seek(0, soFromEnd); - // copy data from MemoryStream - // Daten vom MemoryStream kopieren - aStream.CopyFrom(MemoryStream, 0); - // save Stream-Size - // die Streamgröße speichern - iSize := MemoryStream.Size + SizeOf(Integer); - aStream.Write(iSize, SizeOf(iSize)); - // save version number+length - iSize := aStream.Position; - aStream.Write(Version[1], Length(Version)); - aStream.Write(iSize, SizeOf(iSize)); - finally - aStream.Free; - end; - Result := True; -end; - -function LoadFromFile(const AFileName: string; MemoryStream: TMemoryStream): Boolean; -var - aStream: TMemoryStream; - iSize: Integer; - EndPos: Integer; -begin - Result := False; - if not FileExists(AFileName) then - Exit; - - try - aStream := TMemoryStream.Create; - aStream.LoadFromFile(AFileName); - // drop version part - aStream.Seek(-SizeOf(Integer), soFromEnd); - aStream.Read(EndPos, SizeOf(Integer)); - aStream.SetSize(EndPos); - // seek to position where Stream-Size is saved - // zur Position seeken wo Streamgröße gespeichert - aStream.Seek(-SizeOf(Integer), soFromEnd); - aStream.Read(iSize, SizeOf(iSize)); - if iSize > aStream.Size then - begin - aStream.Free; - Exit; - end; - // seek to position where data is saved - // zur Position seeken an der die Daten abgelegt sind - aStream.Seek(-iSize, soFromEnd); - MemoryStream.SetSize(iSize - SizeOf(Integer)); - MemoryStream.CopyFrom(aStream, iSize - SizeOf(iSize)); - MemoryStream.Seek(0, soFromBeginning); - finally - aStream.Free; - end; - Result := True; -end; - -{ Unpack function } - -function Unpack(const Source: Boolean): Boolean; -var eStream: TMemoryStream; -begin - eStream := TMemoryStream.Create; - try - // Get ZIP - LoadFromFile(ParamStr(0), eStream); - DecompressStream(eStream, ExtractFilePath(ParamStr(0)), Source); // Unpack files - - Result := True; - except - Result := False; - end; - eStream.Free; -end; - -function GetVersion: String; -var FileStream: TFileStream; - EndPos, Size: Integer; - Version: String; -begin - FileStream := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyWrite); - FileStream.Seek(-SizeOf(Integer), soFromEnd); - FileStream.Read(EndPos, SizeOf(EndPos)); - FileStream.Position := EndPos; - Size := FileStream.Size - EndPos - SizeOf(Integer); - SetString(Result, nil, Size); - FileStream.Read(Pointer(Result)^, Size); // YAMS - FileStream.Free; -end; - -end. diff --git a/installer/UnitSelectModPath.dfm b/installer/UnitSelectModPath.dfm deleted file mode 100644 index 436262ce6c27b2c60427026c017b384104e95075..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1148 zcmc&z%Z}496m^nL9!;kdA+bP08a6D^u!U8dHnf@!i5d^H1UI>D!nk(jxb5_B=115e zu|fO;OFm%44se{#qe!gT<@(z9JnqTwCc@$5G#QKs0X~iTaTgEKafdVz!f|-~5YNOS z0Sc)+lv?p0eQfP&o$rnLRLw`| zvoU@j47-zLfSYw!ziFlPykHsMV7QdNZqz8|wWq7MWC6B~NzNCfeyCads2$NP5I`hE zl@`~Hd0ABSo%WI^sQ_Ss;tb+2E-rzVF^CaMbMr&9g4%%`A{)nq0ri%Q_Mt51Oj~6( zDyPiGK`rqb**op8jb;zlK%#0LL#K4aX1pF~?+v`V z8E78fy8bMtK$PpH-sI7iuf)-UXLnn8g-{zOIZ%p~x_1R^T2ie0H%q#Y^LR)6#|@74 z)bOL}N3~A8T|()5T!x$~-%8Y&a4v06%#{8M$(QZ35;V$aLFQ0;es?AL1ZD!t+_gt6 zQ?8ni{Fn&!p*Qb#CRH$0DAJ2Mhn}0{d{Yf}?>mE#k3&jiZzUyX2k9b2!G`Oa|jNgb}n*Ds$?OQVH6U6qhEzJ33RJblvV8>UNNmvy)uU&k@YiAq;nH-?Jk zxMI53s~^?(_8PaFv7SdKdwTCQnZEkv2%SK=qS7?>1$s(gKv)X2-c9%~jsHuSU9-EB LW9-RMSw?>V>;-uw diff --git a/installer/UnitSelectModPath.pas b/installer/UnitSelectModPath.pas deleted file mode 100644 index 368d478..0000000 --- a/installer/UnitSelectModPath.pas +++ /dev/null @@ -1,26 +0,0 @@ -unit UnitSelectModPath; - -interface - -uses - SysUtils, Windows, Messages, Classes, Graphics, Controls, - StdCtrls, ExtCtrls, Forms, FileCtrl, ComCtrls, ShellCtrls, - TFlatComboBoxUnit, TFlatButtonUnit; - -type - TfrmSelectModPath = class(TForm) - pnlDesign: TPanel; - lblInfo: TLabel; - trvDirectory: TShellTreeView; - cmdOK: TFlatButton; - cmdCancel: TFlatButton; - end; - -var - frmSelectModPath: TfrmSelectModPath; - -implementation - -{$R *.DFM} - -end. diff --git a/installer/UnitfrmMain.dfm b/installer/UnitfrmMain.dfm deleted file mode 100644 index 14b183c..0000000 --- a/installer/UnitfrmMain.dfm +++ /dev/null @@ -1,11577 +0,0 @@ -object frmMain: TfrmMain - Left = 333 - Top = 271 - BorderIcons = [biSystemMenu, biMinimize] - BorderStyle = bsSingle - Caption = 'Metamod:Source Installer' - ClientHeight = 355 - ClientWidth = 527 - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - Icon.Data = { - 000001000C003030000001000800A80E0000C60000002020000001000800A808 - 00006E0F00001818000001000800C80600001618000010100000010008006805 - 0000DE1E0000808000000100200028080100462400006060000001002000A894 - 00006E2C010048480000010020008854000016C1010040400000010020002842 - 00009E1502003030000001002000A8250000C65702002020000001002000A810 - 00006E7D0200181800000100200088090000168E020010100000010020006804 - 00009E9702002800000030000000600000000100080000000000000900000000 - 0000000000000001000000010000000000003535360031393E003B3B3B00403E - 3E001D3642001E3C4C002A3B4400323B4100264150002C465400274C5F003E52 - 5D00214C62003A5A6B00205A7700205D7C00365E73002B627F00454343004846 - 46004647490048474800464A4D004A4848004C4A4A004D4D4D00504E4E004F4F - 50004F5050004351590053535300585656005457590055585800595858005C5B - 5B00595D5D005E5D5D00605F5F00595F600045616F005C6364005E696B004364 - 7500496A7B00596B72005B737B00636363006463630060656500666464006167 - 6B00636B6C006C6B6B00706E6E00606C70006370720068747600627479006979 - 7C007170700074737300767575007877770070777900797979007C7B7B007D7C - 7C0019668E0015699300336680002D6F91002C72970029729800337699003D7D - 9D001674A400327CA200476E820042728A005A79850051778B00567D8D005B7E - 8B00637D8500697D8200717C82001380B7002182B3002A82B000398CB7003E95 - BD005F8493006D8287006681890071808500788284007C888E00638C9B00688E - 9A0069919E0079959F00438CAE00488DAB00548CA300588FA600518FA9004B90 - AE005B91A6005594AF005993AA00408EB2004C93B2004C97B9004699BE004D99 - BA005496B100559AB7005E99B000539EBD00599DB800648FA6006397AA007098 - A8006A9CB300729EB50075A6BC007EA9BA001287C3001A8BC500118CCA00188E - CA000D95DB000D98DF001495D6001995D3001E98D5001195D800159ADD001C9B - DB00298EC2002596CD002A95CA003395C3003895C0003D9AC500329ACB00399B - CB002196D000239AD6002B9BD200239BD900319DD00024A0DF002CA1DC0032A0 - D70030A2DD000D9BE3000D9EE800119CE2001A9DE0000DA2EE001EA2E50013A4 - ED0019A5ED001DA8EF001AA7F0001CA8F00022A2E4002BA6E50021A7EB0028A7 - E80023A9ED002BABED0031A6E10034A9E50039ABE50033ACEA0039AEEA0037B0 - EE003CB2EE0024ABF0002BAEF00031AFF00033B1F1003CB4F100429AC3004C9E - C200529FC70070BADD0040B0E9004CB6EC0041B6F10047B8F2004CBAF30053BD - F3005BBEF10062BEED005BC0F40068C1EE007AC0E4007ACAEF0067C4F50069C5 - F50074C7F20078C7F00077CBF60078CBF5008281810086868600888787008B8A - 8A0086979D0090909100979B9F0099989800959DA2008FA0A60093A4AC0080AB - BE009AAEB500A5A4A400A3ADAD00AEBABA0084AFC60093B5C7009EB7C2009DBB - CA00A7BBC500AABCC30093C1D50099C2D700B1C3CA00A6C9DA00B1CAD40084CD - F1008ACFF20087D1F7008AD0F30094D5F6009ED7F5009ED8F60095D6F800A7D2 - E600B4DBED00A3DAF600ABDDF700A4DCF800AFE0F800BFE5F600B2E1F900BBE4 - F900CBE6F300CCE8F500C0E6FA00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - D13F3F3F42D10000000000000000000000000000000000000000000000000000 - 00000000000000000000000042231814141413141418181B3100000000000000 - 0000000000000000000000000000000000000000000000000000311814141414 - 141414141414141414141F420000000000000000000000000000000000000000 - 00000000000000003F14141414181F2A2F5154542F2B2218181414141F000000 - 00000000000000000000000000000000000000000000001F1314141F3969BB9C - 9CB0AFAFAF9D9471511F181414143F0000000000000000000000000000000000 - 000000000000181814183B729DAFB2B5B5B5B5C1B5B5B3B09D94531F18141331 - 000000000000000000000000000000000000000000181814236F9BAFAEB4B5B5 - B5B5B5B5B5B5B5B5B4B2AF912B18161323000000000000000000000000000000 - 000000001818182BBB9AAAAEB4B9B9B9B9B9B9B9B5B9BAB9B5B9B2AF96511818 - 183100000000000000000000000000000000002018182B929AACB7B7B7B7B7B7 - B8B8B8B8B7B9B7B9B9B8B7B7AF9A531818183F00000000000000000000000000 - 00003F14142ABBA1ABB6B6B6B6B6B6B6B6B6B7B7B7B7B7AFAFB7B7B7B69A962F - 18161800000000000000000000000000000018141F6E8BA3A84A2C2D2D8FB6B6 - B6B6A8A8B6B6B650214F5BACB6ACA38F2A161423000000000000000000000000 - 00311814558CA0A7A38804181F29A3A8A7A8A8A8B6A7A11F1F201F21508DA3A3 - 671818180000000000000000000000000014142292A0A4A7A2A710131B185AA7 - A7A7A7A7A2A74B1F1B1B1B1B1812A8A4872F1814230000000000000000000000 - 4218145F8A9FA4A2A7A28B0218180CA4A2A2A2A2A7A20C19160301130484A7A4 - A07018181800000000000000000000001F141F7286A2A2A2A2A2A24504181449 - A2A4A2A2A25916191410460506A4A2A486882A18183F00000000000000000000 - 14142A9B86A2A2A2A2A2A286071314178AA2A2A2A21116140383A2A285A2A2A2 - A28553181418000000000000000000001414568A9FA2A2A2A2A2A2A24D041314 - 47A2A2A28B1616140BA2A2A2A2A2A2A2A28670181818D10000000000000000D1 - 18186385A2A2A2A2A2A2A2A2A20913141684A7A24A1614044DA2A2A2A2A2A2A2 - A286901F14182300000000000000003F14186E86A2A2A2A2A2A2A2A2A2580114 - 160EA2A20C14140886A2A2A2A2A2A2A2A29F8F2216141800000000000000003F - 13187586A2A2A2A2A2A2A2A2A2A20D131414598413141310A2A2A2A2A2A2A2A2 - A29F952318141431000000000000003718187586A2A2A2A2A2A2A2A2A2A28401 - 13181E4814140481A2A2A2A2A2A2A2A2A29F952816141418000000000000003F - 13187785A2A2A2A2A2A2A2A2A2A2A21013181F181B180AA2A2A2A2A2A2A2A2A2 - A29F8F22141414143F000000000000D418186385A2A2A2A2A2A2A2A2A7A8B79A - 1723232723204EB6A8A2A2A2A2A2A2A2A286911F141414141B00000000000000 - 1418568786A2A2A2A2A2A7B7B8B9B9B94C2731313122B0B9B9B8A8A2A2A2A2A2 - A28667181614141414D300000000000014182A999FA2A2A2A2A7B8BABAC1C1C1 - B52B37373752C1B5C1B5BAB6A2A2A2A2A2855416141414141423000000000000 - 1F141D7586A2A2A2A2C1C3C3C3C3C3C3C37A403F37BDC3C3C3C4C3C3A8A2A2A2 - 9F952A14141414141414000000000000D118185E8B86A2A2B8C7C7C7C7C7C7C7 - C762D1D157C5C7C7C7C7C7C7C3A2A2A2866C1818141414141414330000000000 - 00141422BC86A2A2C1CCCCCCCCCCCCCCBED4D4D47ECCCCCCCCCCCCCCCCA7A286 - 893B141818181B18181418000000000000401414568986A2C7CFCFCFCFE1DBD9 - D9D8D8D6C9CFCFCFCFCFCFCFCFA7A2866B181D7D7F7F7F7F5616184000000000 - 000018141F7B869FC1EEEEEEEEE2DEDEDEDEDEDBEEEEEEEEEEEEEEEECFA28690 - 2A1618BEEE807C7C3B16141F000000000000DF1314237886A3EEF3F3F3E4DEDE - DEDEDEE8F3F3F3F3F3F3F3F3C286963B1318182ECA7F23141414141400000000 - 00000037131832BC86B4F8F8F8EAE6E6E6E6E5F6F8F8F8F8F8F8F8CDA0965518 - 181618185DEE661B1414141433000000000000001F16182A798AB0F2FBFBFBFB - FBFBFBFBFBFBFBFBFBF9CC8B8F3B181414141414187DED60181414141F000000 - 000000000018181822659B8BC6F9FFFFFFFFFFFFFFFFFFFCECB0877135181814 - 14141414181FE7F4311814141B0000000000000000001F141418397B9B8AB0CC - EDF2F6F6F3CAC08C8973551F141414141414181F1F1735FBD518141420000000 - 0000000000000034141814183564789389878B87879B736D3C1D181414141414 - 14141DF5DD182AFADA181414420000000000000000000000E018181814181C23 - 3A3C56563A2A1F181818131414141414141418E3FEDDEBFE4114141B00000000 - 00000000000000000000D1181814181818181414141414181418181414141414 - 1416181FDBE9E661181814000000000000000000000000000000000000371814 - 1414141414141414141414141414141414141418181818181823000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFF - FFFFFFFF0000FFFFFFFFFFFF0000FFFFC0FFFFFF0000FFFC001FFFFF0000FFF0 - 0003FFFF0000FFC00001FFFF0000FF8000007FFF0000FF0000003FFF0000FE00 - 00001FFF0000FC0000000FFF0000F800000007FF0000F000000007FF0000F000 - 000003FF0000E000000003FF0000E000000001FF0000C000000001FF0000C000 - 000000FF0000C000000000FF0000C0000000007F000080000000007F00008000 - 0000007F000080000000003F000080000000003F000080000000001F00008000 - 0000001F0000C0000000000F0000C0000000000F0000C0000000000F0000C000 - 000000070000E000000000070000E000000000030000F000000000030000F000 - 000000030000F800000000010000FC00000000010000FE00000000010000FF00 - 000000010000FF80000000010000FFC0000000030000FFF0000000070000FFFE - 0000000F0000FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFF - FFFFFFFF0000FFFFFFFFFFFF0000280000002000000040000000010008000000 - 00000004000000000000000000000001000000010000000000003E3D3D003042 - 4C0034444D003D464B002A495A00384B55002C51650024536C003C5968003B5B - 6D0034637B004240400045434300474545004846460046484900454B4F004A48 - 48004C4A4A004C4B4C004D4D4D00504E4E004D4E50004F50500041515B004555 - 5E005050500054525200535455005654540055595900555B5D00565C5E005A59 - 59005D5B5B00595C5D005F5E5E00605F5F00505B6000565F6100585F62005C61 - 61005A6064005261680056676D005C65690057696F005B686B005C6A6E004068 - 7D004E6A790052687100586B71005C6D7100596F7700526D780051717E006261 - 610064636300666464006B6A6A006C6B6B006E6D6D006C75780069767C007170 - 70007473730075747400787777007E7E7E00176288001F678D001D6E98001670 - 9E003B6E890029769E00397D9F001874A3001678AA00247AA700357DA2003C7F - A1004D758700497588005B7B8600507B8E00457A9500647E8900757F82001385 - BF001F88BE002981AE003E82A2003989AF003D88AE002183B500358CB6003C8D - B3003A95BF004D839A004D849C005F82910056879B0051879E005A879E006788 - 9700688997004083A1004583A0004C87A0004D88A3004888A5004488A800468C - AC00498DAB00508EA9004892B5004093B9007699A60071A1B6001E91CB001192 - D4001297DB001698D900199ADA001A9BDD001E9EDE002491C8002999CF002E99 - CE003D97C1003798C6003A98C4003399C900369AC900379BCC003A9AC8002498 - D400239CD700269CD6002E9DD2002B9DD500239EDD0026A1DF0033A2DA000D9A - E2000D9BE4000D9DE6000D9EE900129AE000179DE200149FE600189EE1000EA2 - EE001FA2E50014A1E90010A2EE0012A4EF0015A5EE001CA4EA0019A6EE0019A7 - F0001BA8F00027A6E60029A3E1002BA4E2002BA8E70025A8EB0026ABEF002EAE - EF0033A6E00031A8E40034ABE7003CACE60037AEEB0032AFEF0035AFED003AAF - EA0039B0ED003DB3EE0022AAF00024ABF00027ACF0002AADF0002DAEF10030B0 - F10035B1F10038B2F1003DB4F000439AC300429FCB0040A2D10040A3D40069AD - D00062B0D8007EBAD5004DB0E30049B1E60045B8F20049B9F3004FBAF10058BF - F30059BFF4005EC1F4006DC2ED007DCAEE0074CAF5007FCAF0007CCDF5008281 - 810085848400879396008B94940088969E0096959500989797008F9FA80087AB - BA0088ABBE0099ACB4009EAFB6009BB0BC00A5A4A400A6B3BA00A6B4BA0080B3 - CD0091B9CD00A4BFCC00ADCBD800B1CCD800B9CFD80081CCF2008AD1F60097D4 - F4009FD9F800A3CDE100A1D6F100A1D9F500ADDEF700A0DAF800B5E2F9000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 3F1E161616162244000000000000000000000000000000000000000000001E12 - 12161216160F121212220000000000000000000000000000000000003A12161F - 5675BFC1C1BE7038161612440000000000000000000000000000001E121E7091 - ADB1B4B4B4B4B2AD8439160F3A000000000000000000000000001E123488A7B1 - BBBBBBBBBBBCBBBCB1A57116163A00000000000000000000003A162D8EA8B7B7 - B7B7B7B7BBB9B9BBB7B1A461160F4600000000000000000000121F82A0804D52 - A5B6B6B6B6B6A5395FA5A89B6D16120000000000000000001E1672989F990416 - 4BA2A2A2A2A3511E1B1E327F7E34123F0000000000000000122E7C9F9D9F490F - 16799F9F9F9F1A16010F069F9F61121600000000000000440F70939D9D9D9502 - 0F0A9D9D9D5B120F4A474A9F957B280FD20000000000001E1684959D9D9D9D4F - 0C0F609D9D0B0F039D9D9D9D9D93540F1E000000000000121E8B9D9D9D9D9A9D - 050F199593100F489D9D9D9D9D935D120F0000000000000F2A7C9D9D9A9A9A9D - 5A010F4C5012017A9D9D9A9A9A9A5E0F122200000000000F2A7C9D9D9D9A9A9A - 9A080F11090F079D9D9A9A9A9A955E0F161600000000000F1F8B9D9D9A9A9A9D - 9F8B161F221E5C9F9D9A9A9A9A945D0F0F0F3F000000001E1684959D9A9AA3BB - BBBB573A3D29B1BBB99D9A9A9A94540F0F0F1600000000441268939D9AA3C8C8 - C8C8C5444469C8C8C8C89D9D9A7A28100F0F12D200000000122A7E9A9DCACCCC - CCCCC2D2D2C3CCCCCCCCBD9A9561160F12120F1E00000000221674939FCFCFCF - E2DBD9D7D6CFCFCFCFCFCA9D7B2D276A6A6A2A1000000000000F1F8893D1E9E9 - DEDFDFDFE3E9E9E9E9E9C89264102CCE77581F0F3A00000000D50F318EB4EEF0 - E4E1E1E1EDF0F0F0F0E99871150F1066C41E11121200000000002E102A84AEEE - F1F1F1F1F1F1F1F1E88F6E150F0F0F0F78DA160F120000000000002E161D688E - C5D0EEEFEFEACDAB633716120F0F16151DEC40121200000000000000D40F121F - 5574638884766537160F0F0F0F0F41E61FE55912160000000000000000003A0F - 0F0F1616160F12121212120F0F0F16DCE7DC1B12000000000000000000000000 - D83F1E0F0F1212120F120F0F0F0F0F0F16163D00000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFF - FFFFFFC03FFFFF000FFFFC0003FFF80001FFF00000FFE000007FE000007FC000 - 003FC000003F8000001F8000001F8000001F8000000F8000000F800000078000 - 000780000003C0000003C0000003E0000001E0000001F0000001F8000001FC00 - 0001FF000003FFC00007FFFFFFFFFFFFFFFFFFFFFFFF28000000180000003000 - 0000010008000000000040020000000000000000000000010000000100000000 - 00003E41430039424800384851002C5B73002B5C7600345E7300464444004846 - 460045494C004A4848004C4A4A004E4D4D00454B50004D51530041525C004656 - 5F004F595D005151510054535300535455005554540058565600525859005559 - 5A00525B5E00545A5C00525C5F005B5A5A005C5B5B00595E5F005E5D5D00605F - 5F0043576200455862004F5F6800535B6000525D6100585F62004D616A005061 - 67005461670059606300596264005262690056676D00516872004F707E006065 - 670061676A006A6969006E6D6D00706F6F006972760064747D00727171007473 - 73001D6F9A002164860033658000226A900029779F003E7894001478AC00436B - 8100466F82004A7183004C74850048758A004D7A8E005D7C8B0042779300497A - 90004F7F9400467F9900497F9800607C8B001682B9003882A8002686B800348B - B500398EB5003D8EB400318CB9006E8089004583A0004A87A2004789A800428B - AD00438EB0004590B5005499BC00729FB20075A3BB001386C1001D8AC1001192 - D4001694D5001E95D1001799DB00129ADF001D9AD9001F9FDF002D95CA003296 - C6002FA0DA0037A1D6003CA1D30031A2DB0039A6DC000F9AE0000D9CE6000D9E - E900109AE0000DA0EB000DA2EE0018A1E70010A0E90011A3EE0011A4EF0014A4 - EE001CA8EF001EA9F00022A1E10027A5E5002DA7E50023A7EA002EABEB002EAC - EC0036AAE50035AFEE0039ADE80022AAF00026ACF00029ADF0002CAEF00036B2 - F10038B3F1003FB5F20042A0CC0049A9D7006AA7C70076B2CD007AB1C80046AE - E30054B3E30056B5E5005BB8E70045B7F10046B8F2004DBAF30062C2F40066C4 - F4007FCEF60081818100868686008A8989009897970099989800989C9E009E9D - 9E009CA0A3008BA5B000A2AEAE00A7B1B600B2B1B1008DB9CC00A9BDC500A2BF - CD0085C0DE009FCDE50080CBF20086CEF20091D4F6009CD7F6009CD8F800B8E3 - F900B9E4FA000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000331F1F1F370000000000 - 00000000000000000000009C0C08122528190C08120000000000000000000000 - 0000200C2E5A6D8183816B55190833000000000000000000001F0C557D828889 - 898989826C420C320000000000000000370C5284858686868686827F867C4408 - 9B000000000000000C4B74621040797A85794E25476766270C00000000000033 - 19657676050C4F767676220A080676500A9B00000000000C4470737360011070 - 765F08053F5E7671190C00000000000851737373733A083D733B084D73737370 - 400C00000000000C68737373736E020D60090373737373733E081F0000000008 - 6873737373733908220C3C73737373703E080800000000085173737376867F23 - 201F69847673736E410A08340000000C456E737A9595955B374C949589767371 - 2508080C00000037196673969797975D9B8D9797978873500C080C089B000000 - 08496E9799A9A1A0A0ABAB99999463284C8F5C2512000000A30C5983AFAAA4A4 - A8AFAFAFAD7B420C0E8E26080800000000360C5690AEB1B1B1B1B1996B2F0808 - 0828A612089C00000000540C28598C9293928B4B190808083530A23508000000 - 0000000016080C262B190C080808080831A7A71220000000000000000000A5A0 - 9D9D9D9D9D9D9D9D9DA0A0A50000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FFFFFF00FF07FF00F801FF00F0007F00E0003F00C0001F00C0001F008000 - 0F0080000F0080000F008000070080000700800003008000030080000100C000 - 0100C0000100E0000000F0000100FC000100FF000300FFFFFF00FFFFFF002800 - 0000100000002000000001000800000000000001000000000000000000000001 - 000000010000000000003D525D00315467002E5F79004345470048464600434A - 4E004A4949004D4D4E00514F4F004F5050004D5357004A585E004C585E005152 - 52005253540053545500555758005E5D5D00475C67004A5A6200525D62004F60 - 67004B606B0058686F00436677004D6671004A6774004B68760042667800466C - 7E00496A7900486D7D0069686800647077007171710031698600306B8A003B7C - 9B003C7C9A00187FB4002F7CA3002B7DA700437085004372880047758B004777 - 8E005E7D8C001E87BC002D8AB8002D8CBB005B8094006B899600718793007A9A - A80078A4BB001386C2001C8CC6001196DA003B97C5003295C800359BCF002199 - D500249EDC002E9FD8002AA0DB0037A0D40031A2DC000F9DE600139BE0000DA0 - EA000EA2EE0014A3EB0015A5EF0027AAEC003CADE60036AFEC0027ACF00029AD - F0002CAEF00035B1F1003AB3F0003DB5F1004E9BC10058AAD20071B8DD0040B5 - F10069C5F500818080008B8A8A008D8D8D00808E95008599A40097A9B100A6AC - AF00A9AEAF00AEB5B500A3B2BA00B4B4B40097CFEB0083CBF0008DD0F20090D4 - F70095D6F70095D6F800ABDEF800AFDFF8000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000058580000 - 000000000000000000580A1B2E2E17085900000000000000211C424C51514C3B - 14230000000000591F3F3C4A4D4E3D43410C00000000000F3E48012948491708 - 293209000000001E46462806453904383A440C00000062264647470225240346 - 47461D1200006226464747390A0B304747461D050000001F4649525233225650 - 47460B08210000113E5257555C3757574F3215180F0000601F4B68615E636868 - 410C2F3408590000351B54656A6A64530C0508360F230000005F0F1B2E2B1408 - 05055B5D11000000000000000000000000000000000000000000000000000000 - 000000000000FFFF0000FCFF0000E01F0000C00F0000800F0000800700008007 - 00000003000000030000800100008001000080000000C0000000E0010000FFFF - 0000FFFF00002800000080000000000100000100200000000000000801000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000007F7F - 7F017F7F7F017F7F7F017F7F7F017F7F7F017F7F7F017F7F7F017F7F7F017F7F - 7F01000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000100000002000000040000000500000007000000080000000A0000 - 000C0000000D0000000D0000000E0000000E0000000E0000000D0000000D0000 - 000C0000000A0000000800000007000000050000000300000002000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000100000003000000050000 - 00090000000C0000001000000014000000180000001C0000001F000000230000 - 0025000000270000002800000028000000280000002800000028000000270000 - 0025000000220000001F0000001C00000017000000130000000F0000000B0000 - 0007000000040000000200000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000100000003000000070000000C00000012000000180000 - 001F000000250000002C00000032000000370000003B0000003E000000410000 - 0043000000450000004500000046000000460000004600000045000000450000 - 0043000000410000003E0000003B00000036000000310000002B000000240000 - 001D00000016000000100000000A000000060000000300000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0003000000070000000C000000130000001B000000250000002E000000360000 - 003D00000043000000480000004B0000004E0000005100000052000000540000 - 0055000000550000005500000056000000560000005600000055000000550000 - 00540000005400000052000000500000004E0000004B00000047000000420000 - 003B000000340000002B0000002200000019000000110000000A000000050000 - 0001000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000001211110100000004000000090000 - 00100000001A00000025000000300000003A00000042000000490000004E0000 - 005203030357161616761F1E1E91242323A9343333BE3D3C3CD0403E3ED84543 - 43EA454343EA454343EA454343EA454343EA454343EA454343EA403E3ED83C3A - 3ACD323131BB232222A71E1D1D8C141414720000005700000056000000540000 - 00510000004C0000004700000040000000370000002C00000020000000160000 - 000E000000070000000300000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000012111101000000040000000A000000130000001F0000 - 002B00000037000000410000004A000000500908085E1F1E1E902D2C2CB54240 - 40E0484646FC494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF474545F73F3D3DD5292828AC1A1A - 1A820505055D00000056000000530000004E000000470000003E000000330000 - 00260000001A0000001000000008000000030000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000012111101000000040000000A00000014000000210000002F0000003B0000 - 00460000004E0F0F0F69262525A5403E3ED7494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF474545F7393737C8201F1F940707076000000055000000510000004B0000 - 0043000000370000002A0000001B000000100000000700000002000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00030000000800000012000000200000002F0000003D0000004805050555201F - 1F94403E3ED7494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF474545F7343232C01817177D000000570000 - 00540000004E0000004400000038000000290000001A0000000E000000061211 - 1101000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000012111101000000050000 - 000F0000001C0000002C0000003B000000480B0B0B612E2D2DB2474545F44947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF413F3FE02221 - 21970302025A000000540000004E000000440000003600000026000000160000 - 000B000000031211110100000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000300000009000000160000 - 002600000037000000460D0D0D65353333BF484646FA494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF454444EF262525A10505055C000000540000004C00000041000000310000 - 001F000000100000000712111101000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000002F3F3F01000000050000000E0000001D0000002F0000 - 0040090909572F2E2EB3484646FA494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF4A4848FF4A48 - 48FF4A4949FF4A4949FF4A4949FF4A4949FF4A4848FF4A4848FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF444242E7212020940000005700000052000000490000 - 003A00000028000000170000000A000000030000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000002F3F3F0100000007000000130000002400000037000000472524 - 2497474545F4494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4A4949FF4C4B4BFF4F4F4FFF515353FF555757FF585C5CFF5B6060FF5D63 - 63FF5F6565FF606767FF606767FF5F6565FF5E6363FF5C6060FF585C5CFF5558 - 58FF525353FF4F4F4FFF4C4C4CFF4B4949FF494848FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF3F3D3DDB12121277000000550000 - 004E00000042000000300000001D0000000E000000052F3F3F01000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000020000000A000000170000002A0000003E111111673F3D3DD94947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4A4949FF4D4C4CFF515252FF585B - 5BFF5F6565FF677070FF707B7BFF778787FF7D9293FF7D999EFF7B9EA7FF76A1 - ADFF72A2B1FF70A2B3FF70A2B3FF70A1B2FF73A0AEFF779EA9FF7B9AA0FF7B92 - 95FF78898AFF717E7EFF697272FF616767FF595C5CFF525353FF4D4D4DFF4B49 - 49FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF484646FC2F2E2EB30505 - 055C0000005200000048000000370000002300000011000000062F3F3F010000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00030000000C0000001B0000002F000000422928289B484646F9494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4A4848FF4D4D4DFF535555FF5C6060FF687070FF768484FF7F97 - 9AFF74A1AEFF5DA1BCFF479FC6FF379DCDFF2899D1FF1F97D2FF1E96D4FF2098 - D5FF229AD6FF249BD7FF259BD7FF229AD6FF2199D6FF1E96D4FF1D96D3FF2197 - D1FF2D9ACFFF3C9CC8FF4F9DBEFF669EB2FF78989FFF778788FF6A7474FF5D63 - 63FF545656FF4E4E4EFF4A4949FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4341 - 41E512121277000000550000004B0000003C0000002800000014000000073F3F - 3F01000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000030000 - 000D0000001E000000330B0A0A543B3939CD494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4B4A - 4AFF505151FF595D5DFF677070FF798889FF7E9EA5FF65A4BCFF409FCAFF2498 - D1FF1E97D5FF269CD8FF2CA0DBFF2EA2DDFF30A3DEFF31A4DFFF32A5E0FF33A6 - E1FF33A6E1FF34A6E1FF34A6E1FF34A6E1FF33A6E1FF33A5E0FF32A5E0FF31A4 - DFFF30A2DDFF2DA1DCFF279DD9FF1F98D6FF1B94D2FF2C99CDFF4E9DBFFF709D - ABFF798C8EFF6A7474FF5C6060FF515252FF4C4B4BFF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF484646FC2726269F000000560000004E000000400000002B000000170000 - 0008000000020000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000030000000D0000 - 001F0000003513121269444242E9494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4C4B4BFF525353FF5E63 - 63FF707C7CFF80999CFF6BA5BAFF3A9ECCFF2097D3FF239AD7FF2BA0DBFF2EA2 - DDFF30A4DFFF32A6E1FF34A7E2FF35A9E4FF37AAE5FF37ABE6FF38ACE6FF39AC - E7FF39ADE8FF3AADE8FF3AADE8FF3AADE8FF3AACE7FF39ACE7FF38ACE6FF38AB - E6FF37AAE5FF35A9E3FF33A7E2FF32A5E0FF30A4DFFF2DA1DCFF269CD8FF1B95 - D4FF2697CFFF4D9DBFFF7599A3FF738181FF606767FF535555FF4C4C4CFF4948 - 48FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF363434C30707075E00000050000000420000002D0000 - 0018000000090000000200000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000030000000D0000001F0000 - 0036201F1F80474545F7494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF4B4A4AFF515252FF5F6464FF738080FF80A0 - A6FF57A4C3FF2899D1FF2198D6FF2A9FDBFF2DA2DEFF30A5E0FF32A7E3FF34A9 - E5FF36ABE7FF37ACE8FF39AEE9FF3AAEEAFF3BAFEBFF3CB1ECFF3DB1ECFF3DB1 - ECFF3DB1EDFF3EB2EDFF3EB2EDFF3EB2EDFF3EB1ECFF3EB1ECFF3DB1ECFF3DB0 - ECFF3CB0EBFF3BAEEAFF3AAEE9FF38ACE8FF37ABE6FF34A8E4FF32A6E1FF30A4 - DFFF2CA1DCFF239BD8FF1994D2FF389AC8FF6C9DADFF758587FF616868FF5355 - 55FF4C4B4BFF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF3F3D3DDD0B0B0B6700000051000000440000 - 002F000000190000000903223202000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000030000000C0000001F000000362928 - 2894484646FC494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4A4848FF4F4F4FFF5B6060FF717C7CFF82A0A5FF51A3C5FF2398 - D2FF249BD8FF2AA0DCFF2DA3E0FF30A6E3FF32A8E5FF35ABE7FF36ACE9FF38AE - EAFF39B0EBFF3BB0ECFF3CB1EDFF3DB2EEFF3DB3EEFF3EB3EFFF3EB3EFFF3FB4 - F0FF3FB4F0FF3FB4F0FF40B4F0FF40B4F0FF40B4F0FF40B4EFFF3FB4EFFF3FB3 - EFFF3EB2EEFF3EB2EEFF3DB2EDFF3CB1ECFF3BB0EBFF39AEEAFF37ADE9FF35AA - E6FF33A8E4FF30A5E1FF2DA2DEFF279DDAFF1A95D3FF3099CAFF6A9CAEFF7483 - 83FF5E6464FF505151FF4A4949FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF444242EA0F0E0E71000000520000 - 00440000002F00000018000000082F3F3F010000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000020000000B0000001D000000352A2929974947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4C4B4BFF555858FF687171FF81989AFF5EA6C2FF2498D1FF249BD8FF29A0 - DCFF2CA4E0FF2FA6E3FF31A9E6FF34ABE9FF36AEEAFF38AFECFF39B0EDFF3AB1 - EEFF3BB2EFFF3CB3EFFF3DB3F0FF3DB4F0FF3DB4F1FF3EB5F1FF3EB5F1FF3EB5 - F1FF3EB5F1FF3FB5F1FF3FB5F2FF3FB5F1FF3FB5F2FF3FB5F2FF3FB5F1FF3FB5 - F1FF3FB5F1FF3FB4F0FF3EB4F0FF3EB3EFFF3DB3EFFF3CB2EDFF3BB1ECFF39AF - EBFF37ADEAFF35ABE8FF32A9E5FF2FA6E2FF2CA2DFFF269DDAFF1894D3FF3699 - C7FF7399A4FF6C7777FF585B5BFF4D4C4CFF494848FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF454444EF121111740000 - 0052000000430000002D00000017000000072F3F3F0100000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000002F3F3F01000000090000001A000000322B292996494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF4A4848FF4F4F - 4FFF5D6262FF778686FF79A8B5FF319CCEFF2098D6FF279EDBFF2AA2DFFF2DA6 - E3FF30A9E7FF32ABEAFF35ADEBFF37AFEDFF38B0EEFF39B1EFFF39B2F0FF39B3 - F0FF3AB3F0FF3BB4F1FF3BB4F1FF3CB5F2FF3CB5F2FF3CB5F2FF3CB5F2FF3CB5 - F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3EB5 - F2FF3EB5F2FF3EB5F1FF3EB5F1FF3DB4F1FF3DB4F1FF3DB3F0FF3CB3EFFF3BB2 - EFFF3AB1EDFF39AFECFF37AEEAFF34ABE8FF31A8E5FF2DA5E2FF2AA1DEFF239B - D9FF1893D1FF519DBDFF768C8FFF616767FF515252FF4A4949FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF474545F71413 - 137C00000051000000420000002B00000014000000062F3F3F01000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00002F3F3F0100000007000000160000002F2B2A2A94494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4B4949FF535454FF666E - 6EFF829A9CFF55A5C6FF1F96D3FF249CDAFF27A0DEFF2AA4E3FF2DA8E6FF30AA - E9FF32ADEBFF34AEEDFF36B0EEFF37B1EFFF38B2F0FF38B2F0FF39B2F1FF39B3 - F1FF39B3F2FF39B4F2FF39B4F2FF39B4F2FF39B4F2FF3AB4F2FF3AB4F2FF3AB4 - F2FF3AB4F2FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4 - F2FF3CB4F2FF3CB5F2FF3CB5F2FF3CB5F2FF3CB5F2FF3CB4F1FF3BB4F1FF3BB4 - F0FF3AB3F0FF39B2EFFF39B1EEFF38AFECFF35ADEBFF32AAE8FF2FA7E4FF2BA3 - E0FF289FDCFF1C97D6FF2B98CBFF6F99A7FF6A7575FF555757FF4C4B4BFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4544 - 44EF0F0E0E71000000500000003F000000270000001100000004000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000500000012000000292322227E494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4C4B4BFF565858FF6E7979FF81A5 - ADFF369DCEFF1E97D6FF249EDCFF28A2E1FF2AA5E5FF2DA9E8FF2FACEAFF31AD - ECFF33AFEEFF34B0EFFF35B1F0FF35B1F1FF36B2F1FF36B2F2FF37B2F2FF37B3 - F2FF37B3F2FF37B3F2FF37B3F2FF38B3F2FF38B3F2FF38B3F2FF38B3F2FF38B3 - F2FF38B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3 - F2FF39B4F2FF39B4F2FF39B4F2FF39B4F2FF39B4F2FF39B4F2FF39B4F2FF39B3 - F1FF39B3F1FF39B3F0FF39B2F0FF38B1EFFF37B0EEFF35AEECFF32ACEAFF2FA9 - E7FF2CA5E3FF29A1DEFF229BD9FF1A93D1FF599DB8FF728081FF595D5DFF4C4C - 4CFF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF454444EF0C0C0C680000004E0000003B000000220000000D000000030000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00030000000D0000002315141465484646F9494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF4C4C4CFF595D5DFF758383FF79AAB9FF2598 - D1FF209AD8FF249FDDFF27A3E2FF29A7E6FF2CAAEAFF2EACECFF30ADEEFF31AF - EFFF32AFF0FF32B0F1FF33B0F1FF33B1F1FF33B1F1FF34B1F1FF34B1F2FF34B1 - F2FF34B1F2FF35B1F2FF35B1F2FF35B1F2FF35B2F2FF35B2F2FF36B2F2FF36B2 - F2FF36B2F2FF36B2F2FF36B2F2FF36B2F2FF37B2F2FF37B2F2FF37B3F2FF37B3 - F2FF37B3F2FF37B3F2FF37B3F2FF38B3F2FF38B3F2FF38B3F2FF38B3F2FF38B3 - F2FF38B3F2FF38B3F2FF38B2F1FF37B2F0FF37B1F0FF36B0EFFF34AEEDFF32AD - EBFF2FAAE9FF2BA6E5FF28A2E0FF249DDCFF1694D3FF469CC2FF778A8DFF5C61 - 61FF4E4E4EFF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF424040E50707075D0000004B000000360000001D0000000A2F3F - 3F01000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000002F3F3F010000 - 00090000001C0D0D0D4B464444ED494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF4D4C4CFF5B6060FF7A8A8AFF6BAAC1FF1D95D2FF209A - D9FF239FDEFF26A3E4FF29A7E8FF2BAAEBFF2CABEDFF2EADEEFF2FAFEFFF2FAF - F0FF30AFF0FF30B0F1FF30B0F1FF31B0F1FF31B0F1FF31B0F1FF31B0F1FF32B0 - F1FF32B0F1FF32B1F1FF32B1F1FF32B1F1FF32B1F1FF33B1F1FF33B1F1FF33B1 - F1FF33B1F1FF33B1F1FF33B1F1FF34B1F1FF34B1F1FF34B1F2FF34B1F2FF35B1 - F2FF35B1F2FF35B1F2FF35B1F2FF35B2F2FF35B2F2FF35B2F2FF36B2F2FF36B2 - F2FF36B2F2FF36B2F2FF36B2F2FF36B2F2FF36B1F1FF35B1F0FF34B0F0FF33AF - EEFF31ADECFF2FABEAFF2BA7E7FF28A3E2FF249EDDFF1995D5FF3298C8FF7891 - 95FF5F6565FF4E4E4EFF4A4848FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF3A3939D003030357000000470000002F000000160000 - 0006000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000050000 - 0015040404313F3D3DD2494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4D4C4CFF5C6161FF7D8D8EFF61A8C5FF1A95D3FF1E9ADAFF22A0 - E0FF24A4E5FF27A7E9FF29AAEBFF2AABEDFF2BADEFFF2CAEEFFF2DAEF0FF2DAF - F1FF2EAFF1FF2EAFF1FF2EAFF1FF2EAFF1FF2EAFF1FF2EAFF1FF2FAFF1FF2FB0 - F1FF2FB0F1FF2FB0F1FF2FB0F1FF2FB0F1FF30B0F1FF30B0F1FF30B0F1FF30B0 - F1FF30B0F1FF30B0F1FF31B0F1FF31B0F1FF31B0F1FF31B0F1FF31B0F1FF31B0 - F1FF32B0F1FF32B0F1FF32B1F1FF32B1F1FF32B1F1FF32B1F1FF33B1F1FF33B1 - F1FF33B1F1FF33B1F1FF33B1F1FF33B1F1FF33B1F1FF33B1F1FF33B0F1FF32B0 - F0FF31AFEFFF30ADEDFF2DABEAFF2AA7E7FF27A4E3FF249FDDFF1A96D7FF2996 - CBFF75939AFF606767FF4E4E4EFF4A4848FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF2E2C2CAE0000005200000041000000270000 - 0010000000030000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000030000000E0000 - 0025302F2FA2494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4C4B4BFF5B5F5FFF7C8D8EFF62AAC6FF1894D3FF1D9ADBFF209FE1FF23A4 - E6FF26A7E9FF28A9EBFF28ABEEFF29ACEFFF29ADF0FF2AADF0FF2AAEF1FF2BAE - F1FF2BAEF1FF2BAEF1FF2BAEF1FF2BAEF1FF2BAEF1FF2CAEF1FF2CAFF1FF2CAF - F1FF2CAFF1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAFF1FF2EAF - F1FF2EAFF1FF2EAFF1FF2EAFF1FF2EAFF1FF2EAFF1FF2FAFF1FF2FB0F1FF2FB0 - F1FF2FB0F1FF2FB0F1FF2FB0F1FF2FB0F1FF30B0F1FF30B0F1FF30B0F1FF30B0 - F1FF30B0F1FF30B0F1FF31B0F1FF31B0F1FF31B0F1FF31B0F1FF31B0F1FF31AF - F0FF30AFF0FF2FAEEFFF2EADEDFF2CAAEBFF29A8E8FF26A3E3FF229EDEFF1A97 - D7FF2895CBFF75939AFF5F6565FF4E4E4EFF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF1B1B1B860000004E000000390000 - 001F0000000A1211110100000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000012111101000000080000001B1A19 - 1966494747FF494747FF494747FF494747FF494747FF494747FF494747FF4C4B - 4BFF585C5CFF798989FF67ABC4FF1894D3FF1B9ADAFF1E9EE0FF21A3E5FF24A7 - E9FF25A8ECFF27AAEEFF27ABEFFF28ACF0FF28ADF1FF28ADF1FF28ADF1FF28AD - F1FF28ADF1FF28ADF1FF29ADF1FF29ADF1FF29ADF1FF29ADF1FF29ADF1FF29AD - F1FF29ADF1FF2AADF1FF2AAEF1FF2AAEF1FF2AAEF1FF2AAEF1FF2AAEF1FF2BAE - F1FF2BAEF1FF2BAEF1FF2BAEF1FF2BAEF1FF2BAEF1FF2BAEF1FF2CAEF1FF2CAF - F1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAF - F1FF2EAFF1FF2EAFF1FF2EAFF1FF2EAFF1FF2EAFF1FF2FAFF1FF2FAFF1FF2EAF - F1FF2EAFF0FF2EAEF0FF2DAEEFFF2CACEDFF2AAAECFF28A7E9FF24A2E4FF219E - DEFF1997D7FF2896CBFF789195FF5C6161FF4C4C4CFF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF464444F20A0A0A62000000480000 - 0030000000150000000500000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000400000012090909344543 - 43E6494747FF494747FF494747FF494747FF494747FF494747FF4B4949FF5558 - 58FF748181FF73ADC0FF1793D2FF1A99DAFF1C9EE0FF1FA2E5FF22A6E9FF23A8 - ECFF24A9EEFF25ABEFFF25ABF0FF25ACF1FF26ACF1FF26ACF1FF26ACF1FF27AC - F1FF27ACF1FF27ACF1FF27ACF1FF27ACF1FF27ACF1FF27ACF1FF27ACF1FF28AD - F1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF28AD - F1FF28ADF1FF28ADF1FF29ADF1FF29ADF1FF29ADF1FF29ADF1FF29ADF1FF29AD - F1FF2AADF1FF2AADF1FF2AAEF1FF2AAEF1FF2AAEF1FF2AAEF1FF2AAEF1FF2BAE - F1FF2BAEF1FF2BAEF1FF2BAEF1FF2BAEF1FF2BAEF1FF2CAEF1FF2CAEF1FF2CAF - F1FF2CAFF1FF2CAEF0FF2BADF0FF2BADEFFF2AABEDFF28AAEBFF26A6E8FF23A2 - E4FF1F9DDEFF1796D6FF3298C8FF768A8DFF595D5DFF4C4B4BFF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF373535C8000000510000 - 0040000000240000000D00000002000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000121111010000000A0000001F313030A64947 - 47FF494747FF494747FF494747FF494747FF494747FF4A4848FF525353FF6D78 - 78FF80ACB7FF1F96D1FF1897D9FF1A9DDFFF1CA1E5FF1FA5E9FF21A7ECFF22A9 - EEFF22AAEFFF23AAF0FF23ABF0FF23ABF0FF23ABF0FF24ABF0FF24ABF0FF24AB - F0FF24ABF0FF24ABF0FF24ABF0FF25ABF0FF25ABF0FF25ACF1FF25ACF1FF25AC - F1FF25ACF1FF25ACF1FF26ACF1FF26ACF1FF26ACF1FF26ACF1FF27ACF1FF27AC - F1FF27ACF1FF27ACF1FF27ACF1FF27ACF1FF27ACF1FF27ACF1FF27ACF1FF28AD - F1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF3F83 - A5FF3B8FBAFF2BA9E9FF29ADF1FF29ADF1FF29ADF1FF29ADF1FF29ADF1FF29AD - F1FF2AADF1FF29ADF1FF29ADF0FF29ADF0FF29ACEFFF28ABEDFF27A8EBFF24A6 - E8FF21A1E3FF1D9CDDFF1594D5FF469CC2FF728081FF555757FF4A4949FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF1F1E1E8D0000 - 004C000000350000001900000007000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000040000001417171754484646FC4947 - 47FF494747FF494747FF494747FF494747FF494747FF4F4F4FFF656C6CFF85A5 - AAFF299AD0FF1696D7FF189BDEFF1AA0E4FF1DA4E9FF1EA6EBFF1FA8EDFF20A9 - EEFF20A9EFFF21AAF0FF21AAF0FF21AAF0FF21AAF0FF21AAF0FF21AAF0FF21AA - F0FF22AAF0FF22ABF0FF22ABF0FF22ABF0FF22ABF0FF22ABF0FF23ABF0FF23AB - F0FF23ABF0FF23ABF0FF23ABF0FF23ABF0FF23ABF0FF24ABF0FF24ABF0FF24AB - F0FF24ABF0FF24ABF0FF24ABF0FF24ABF0FF25ABF0FF25ACF1FF25ACF1FF25AC - F1FF25ACF1FF25ACF1FF26ACF1FF26ACF1FF26ACF1FF26ACF1FF2AA3E1FF5658 - 5AFF5B5959FF595D60FF497790FF3596C8FF28ABEEFF27ACF1FF27ACF1FF28AD - F1FF28ADF1FF28ADF1FF28ADF1FF28ADF1FF28ACF0FF27ABEFFF26A9EDFF24A8 - EBFF21A4E7FF1FA0E2FF1B9ADBFF1292D2FF599CB8FF6A7575FF515252FF4948 - 48FF494747FF494747FF494747FF494747FF494747FF494747FF454343EC0707 - 075B00000043000000270000000F000000030000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000010000000B00000021413F3FCC494747FF4947 - 47FF494747FF494747FF494747FF494747FF4C4B4BFF5C6161FF839798FF46A3 - CCFF1494D5FF169ADCFF189EE2FF1BA2E7FF1CA5EAFF1DA7EDFF1DA8EEFF1DA8 - EFFF1FA5E9FF2E3B42FF3E3D3DFF4C4A4AFF535252FF565454FF565454FF5654 - 54FF565454FF565454FF555454FF3B7898FF20A9F0FF20AAF0FF20AAF0FF20AA - F0FF21AAF0FF21AAF0FF21AAF0FF21AAF0FF21AAF0FF21AAF0FF21AAF0FF22AA - F0FF22AAF0FF22ABF0FF22ABF0FF22ABF0FF22ABF0FF22ABF0FF23ABF0FF23AB - F0FF23ABF0FF23ABF0FF23ABF0FF23ABF0FF23ABF0FF24ABF0FF3A81A5FF5856 - 56FF595858FF595858FF595858FF5A5858FF546169FF427E9DFF2F9CD4FF25AC - F1FF25ACF1FF25ACF1FF26ACF1FF26ACF1FF25ACF1FF25ABF0FF25AAEFFF24A9 - EDFF22A6EAFF1FA3E6FF1C9EE0FF1999DAFF1892D0FF6F99A7FF616767FF4D4C - 4CFF494747FF494747FF494747FF494747FF494747FF494747FF494747FF2E2D - 2DB00000004D000000360000001A000000070000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000004000000141F1E1E6D494747FF494747FF4947 - 47FF494747FF494747FF494747FF4A4848FF545656FF758282FF6CADC4FF1292 - D2FF1597DAFF169DE1FF18A1E7FF1AA4EAFF1AA6EDFF1BA7EEFF1BA7EFFF1CA8 - F0FF1CA8F0FF2277A2FF343333FF434242FF4F4D4DFF535151FF545353FF5453 - 53FF545353FF545353FF545353FF515253FF249CD9FF1EA9F0FF1EA9F0FF1EA9 - F0FF1EA9F0FF1EA9F0FF1EA9F0FF1EA9F0FF1FA9F0FF1FA9F0FF1FA9F0FF1FA9 - F0FF1FA9F0FF20A9F0FF20A9F0FF20A9F0FF20AAF0FF20AAF0FF20AAF0FF20AA - F0FF21AAF0FF21AAF0FF21AAF0FF21AAF0FF21AAF0FF22A9EDFF4D5A61FF5755 - 55FF585656FF585656FF585656FF585656FF585656FF585656FF585757FF4F67 - 73FF3B86ACFF28A3E1FF23ABF0FF23ABF0FF23ABF0FF23AAF0FF23AAEFFF22A9 - EEFF22A7ECFF1FA5E9FF1CA1E5FF1A9CDEFF1696D7FF2A97CBFF768C8FFF585B - 5BFF4A4949FF494747FF494747FF494747FF494747FF494747FF494747FF4846 - 46FA0C0C0C6600000043000000270000000E0000000200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000A05050523454343DF494747FF494747FF4947 - 47FF494747FF494747FF494747FF4E4E4EFF666E6EFF87ABB1FF2097D1FF1395 - D8FF159BDFFF169FE5FF17A3E9FF18A4ECFF19A6EEFF19A6EFFF19A7F0FF1AA7 - F0FF1AA8F0FF1AA6EDFF29414DFF393838FF474646FF504E4EFF525050FF5351 - 51FF535151FF535151FF535151FF535151FF3E6B82FF1BA8F0FF1CA8F0FF1CA8 - F0FF1CA8F0FF1CA8F0FF1CA8F0FF1CA8F0FF1CA8F0FF1CA8F0FF1DA8F0FF1DA9 - F0FF1DA9F0FF1DA9F0FF1DA9F0FF1DA9F0FF1DA9F0FF1EA9F0FF1EA9F0FF1EA9 - F0FF1EA9F0FF1EA9F0FF1EA9F0FF1EA9F0FF1EA9F0FF2D8DBFFF535151FF5654 - 54FF565454FF565454FF565454FF565454FF575555FF575555FF575555FF5755 - 55FF575555FF565657FF486D81FF358CB8FF23A7EBFF21AAF0FF21AAEFFF21A9 - EFFF20A8EDFF1FA6EBFF1DA3E9FF1A9FE3FF189ADCFF1292D4FF519DBDFF6C77 - 77FF505151FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF353333BF0000004C00000034000000170000000500000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000030000001127252578494747FF494747FF494747FF4947 - 47FF494747FF494747FF4B4949FF595D5DFF819494FF48A4CDFF1192D5FF1398 - DCFF149DE3FF16A1E8FF17A3EBFF17A5EEFF17A6EFFF17A7F0FF17A7F0FF17A7 - F0FF18A7F0FF18A7F0FF1C82B7FF2F2E2EFF3F3D3DFF4B4949FF504E4EFF514F - 4FFF525050FF525050FF525050FF525050FF504E4EFF2690C6FF19A7F0FF19A7 - F0FF1AA8F0FF1AA8F0FF1AA8F0FF1AA8F0FF1AA8F0FF1AA8F0FF1AA8F0FF1BA8 - F0FF1BA8F0FF1BA8F0FF1BA8F0FF1BA8F0FF1BA8F0FF1BA8F0FF1BA8F0FF1CA8 - F0FF1CA8F0FF1CA8F0FF1CA8F0FF1CA8F0FF1CA8F0FF40667AFF535151FF5452 - 52FF545353FF545353FF545353FF545353FF545353FF555353FF555353FF5553 - 53FF555353FF555353FF555353FF555353FF53575AFF3F728CFF2A8FC2FF1EA9 - EFFF1EA8EEFF1EA7EDFF1DA5EAFF1AA2E6FF189DE1FF1597D9FF1391D0FF7399 - A4FF5E6464FF4C4B4BFF494747FF494747FF494747FF494747FF494747FF4947 - 47FF484646FC0E0E0E6500000040000000230000000B12111101000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000070000001B444242D8494747FF494747FF494747FF4947 - 47FF494747FF494747FF505151FF6D7878FF7CAFBEFF1090D1FF1196DAFF129B - E1FF149FE7FF15A2EAFF15A4EDFF16A5EFFF16A5EFFF16A6F0FF16A6F0FF17A6 - F0FF17A6F0FF17A6F0FF17A6F0FF23495CFF343333FF434141FF4C4A4AFF4F4D - 4DFF504E4EFF504E4EFF504E4EFF504E4EFF504E4EFF435C6AFF18A5EDFF18A7 - F0FF18A7F0FF18A7F0FF18A7F0FF18A7F0FF18A7F0FF18A7F0FF19A7F0FF19A7 - F0FF19A7F0FF19A7F0FF19A7F0FF19A7F0FF19A7F0FF19A7F0FF1AA7F0FF1AA8 - F0FF1AA8F0FF1AA8F0FF1AA8F0FF1AA8F0FF209BDAFF4E4C4CFF535151FF5351 - 51FF535151FF535151FF535151FF535151FF535151FF535151FF535252FF5452 - 52FF545252FF545252FF545252FF545252FF535252FF4F4D4DFF434141FF2E4E - 5EFF1CA7EFFF1CA7EEFF1BA6ECFF1AA3E9FF179FE4FF169ADDFF1294D6FF3699 - C8FF748383FF535555FF494848FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF2F2E2EB5000000490000002F0000001300000003000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000010000000D1F1E1E64494747FF494747FF494747FF494747FF4947 - 47FF494747FF4B4A4AFF5C6161FF879D9EFF359ECFFF0F92D6FF1098DDFF119D - E4FF13A0E9FF13A2EBFF14A4EDFF14A5EEFF14A5EFFF14A5EFFF15A6EFFF15A6 - EFFF15A6EFFF15A6EFFF15A6EFFF188DC9FF2A2B2CFF3A3838FF474545FF4D4B - 4BFF4F4D4DFF4F4D4DFF4F4D4DFF4F4D4DFF4F4D4DFF4E4C4CFF2A81AEFF16A6 - F0FF17A6F0FF17A6F0FF17A6F0FF17A6F0FF17A6F0FF17A6F0FF17A6F0FF17A6 - F0FF17A6F0FF17A6F0FF17A7F0FF17A7F0FF17A7F0FF17A7F0FF17A7F0FF18A7 - F0FF18A7F0FF18A7F0FF18A7F0FF18A7F0FF337496FF504E4EFF514F4FFF5250 - 50FF525050FF525050FF525050FF525050FF525050FF525050FF525050FF5250 - 50FF525050FF525050FF525050FF525050FF504E4EFF494747FF3A3939FF246C - 91FF1AA8F0FF1AA7EFFF1AA6EEFF19A4EBFF17A1E7FF159DE1FF1397DAFF0E90 - D2FF699CAEFF616868FF4C4C4CFF494747FF494747FF494747FF494747FF4947 - 47FF494747FF474545F4070707580000003A0000001D00000008000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000400000015413F3FC3494747FF494747FF494747FF494747FF4947 - 47FF494747FF505151FF6F7A7AFF76AFC2FF0E8FD1FF0F95DAFF0F9AE1FF119E - E7FF12A1EAFF12A3EDFF13A4EEFF13A5EFFF13A5EFFF13A5EFFF13A5EFFF13A5 - EFFF13A5EFFF13A5EFFF13A5EFFF14A5EFFF1E5470FF302E2EFF3F3E3EFF4947 - 47FF4D4B4BFF4D4B4BFF4D4B4BFF4D4B4BFF4D4B4BFF4D4B4BFF465258FF189F - E4FF15A6EFFF15A6EFFF15A6EFFF15A6EFFF15A6EFFF15A6EFFF16A6F0FF16A6 - F0FF16A6F0FF16A6F0FF16A6F0FF16A6F0FF16A6F0FF16A6F0FF16A6F0FF17A6 - F0FF17A6F0FF17A6F0FF17A6F0FF18A3EAFF465158FF4F4D4DFF4F4D4DFF4F4D - 4DFF504E4EFF504E4EFF504E4EFF4F4D4DFF4E4C4CFF4E4C4CFF4E4C4CFF504E - 4EFF514F4FFF514F4FFF514F4FFF514F4FFF4D4B4BFF414040FF323334FF1A9B - DDFF19A7F0FF18A6EFFF18A6EEFF17A5EDFF17A2E9FF159EE5FF1399DFFF1093 - D6FF2F98CAFF758587FF535555FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF2423239900000044000000280000000E000000020000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000815141439494747FF494747FF494747FF494747FF494747FF4947 - 47FF4B4949FF5B5F5FFF869D9DFF389FCFFF0D92D6FF0E98DEFF0F9CE4FF10A0 - E8FF10A2ECFF11A3EDFF11A3EEFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF12A4 - EFFF12A4EFFF12A4EFFF12A4EFFF12A4EFFF1398DBFF26292BFF353434FF4342 - 42FF4B4949FF4D4B4BFF4D4B4BFF4D4B4BFF4D4B4BFF4D4B4BFF4C4A4AFF3073 - 95FF13A5EFFF13A5EFFF13A5EFFF13A5EFFF14A5EFFF14A5EFFF14A5EFFF14A5 - EFFF14A5EFFF14A5EFFF14A5EFFF14A5EFFF14A5EFFF14A5EFFF15A6EFFF15A6 - EFFF15A6EFFF15A6EFFF15A6EFFF2684B4FF4B4A4AFF4E4C4CFF4E4C4CFF4F4D - 4DFF4F4D4DFF4F4D4DFF4E4C4CFF4B4A4AFF474545FF444242FF454343FF4948 - 48FF4D4B4BFF4E4C4CFF4F4D4DFF4E4C4CFF484646FF393838FF25536BFF17A6 - F0FF17A6F0FF17A6F0FF17A5EFFF16A4EEFF16A3EBFF14A0E8FF129BE2FF1096 - DAFF0E90D1FF6C9DADFF606767FF4C4B4BFF494747FF494747FF494747FF4947 - 47FF494747FF494747FF413F3FDD0000004C0000003400000017000000050000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00010000000D2F2E2E93494747FF494747FF494747FF494747FF494747FF4947 - 47FF4F4F4FFF6B7676FF7FB1BFFF0D8FD1FF0E94D9FF0E99E1FF0F9DE7FF0FA0 - EAFF10A2EDFF10A3EEFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF11A4 - EFFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF196187FF2C2B2BFF3B3A - 3AFF464444FF4B4949FF4B4949FF4B4949FF4B4949FF4B4949FF4B4949FF474A - 4CFF1998D9FF12A4EFFF12A4EFFF12A4EFFF12A4EFFF12A4EFFF12A4EFFF13A5 - EFFF13A5EFFF13A5EFFF13A5EFFF13A5EFFF13A5EFFF13A5EFFF13A5EFFF13A5 - EFFF13A5EFFF13A5EFFF13A5EFFF3A5D6FFF4C4A4AFF4D4B4BFF4D4B4BFF4D4B - 4BFF4D4B4BFF4D4B4BFF4C4A4AFF454343FF3B3939FF343232FF353434FF3B3A - 3AFF413F3FFF464444FF4A4848FF494747FF403F3FFF313030FF1A81B6FF15A6 - EFFF15A6EFFF15A6EFFF15A6EFFF15A5EEFF14A3ECFF13A1E9FF119DE4FF0F98 - DDFF0E92D6FF379AC8FF738081FF515252FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF1211116A00000040000000230000000B1211 - 1101000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000300000014464444E1494747FF494747FF494747FF494747FF494747FF4A48 - 48FF575A5AFF819393FF46A4CEFF0C91D5FF0D96DDFF0D9BE4FF0F9FE8FF0FA1 - ECFF0FA2EDFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF10A4EFFF10A4 - EFFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF109DE5FF222F36FF3231 - 31FF403F3FFF484646FF4A4848FF4A4848FF4A4848FF4A4848FF4A4848FF4A48 - 48FF34667FFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF11A4 - EFFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF11A4EFFF12A4 - EFFF12A4EFFF12A4EFFF1A94D3FF484646FF4C4A4AFF4C4A4AFF4C4A4AFF4C4A - 4AFF4C4A4AFF4C4A4AFF484747FF3E3D3DFF2F2E2EFF252424FF242323FF2928 - 28FF302E2EFF363535FF3D3B3BFF3E3C3CFF363535FF273841FF14A5EFFF14A5 - EFFF14A5EFFF14A5EFFF13A5EFFF13A4EEFF12A3EDFF12A1EAFF109EE6FF0F9A - E0FF0E94D9FF0E8FD0FF7499A3FF5C6161FF4A4949FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF2E2D2DB20000004900000030000000140000 - 0004000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00061C1B1B44494747FF494747FF494747FF494747FF494747FF494747FF4C4B - 4BFF636B6BFF8AADB4FF1692D0FF0D93D8FF0D98E0FF0D9DE6FF0E9FEAFF0EA1 - EDFF0FA2EEFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF156D99FF2827 - 27FF393737FF444242FF494747FF4A4848FF4A4848FF4A4848FF4A4848FF4A48 - 48FF484646FF1C8DC6FF10A4EFFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF10A4 - EFFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF10A4EFFF10A4 - EFFF10A4EFFF11A4EFFF2C6E90FF494747FF4B4949FF4B4949FF4B4949FF4B49 - 49FF4B4949FF4A4848FF444242FF363434FF224558FF185A7BFF1A252AFF1D1D - 1DFF212020FF252525FF2B2A2AFF2D2B2BFF282828FF1A678EFF12A4EFFF12A4 - EFFF12A4EFFF12A4EFFF12A4EFFF12A4EFFF11A3EDFF10A1EBFF109FE8FF0E9B - E3FF0E96DCFF0C91D4FF4D9DBFFF6A7474FF4E4E4EFF494747FF494747FF4947 - 47FF494747FF494747FF494747FF474545F4050505550000003C0000001F0000 - 0009000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000A302F2F91494747FF494747FF494747FF494747FF494747FF494747FF5152 - 52FF738080FF69ADC7FF0C90D3FF0D95DBFF0D9AE3FF0E9EE8FF0EA0EBFF0EA2 - EDFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0FA3EFFF0FA3EFFF0FA0EBFF1E35 - 40FF2F2E2EFF3F3D3DFF474545FF4A4848FF4A4848FF4A4848FF4A4848FF4A48 - 48FF494747FF3B5767FF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3 - EFFF10A4EFFF11A0E9FF404A50FF494747FF4A4848FF4A4848FF4A4848FF4A48 - 48FF4A4848FF474646FF3F3D3DFF2F2E2EFF167BAFFF10A4EFFF109FE8FF1374 - A4FF17394AFF1B1A1AFF1D1D1DFF1F1E1EFF1E2123FF1299DEFF11A4EFFF11A4 - EFFF11A4EFFF11A4EFFF10A4EFFF10A4EFFF10A3EEFF0FA2EDFF0F9FE9FF0E9C - E6FF0D98DFFF0C93D7FF2195CEFF788C8EFF545656FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF24232399000000460000002B0000 - 0011000000030000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000010000 - 000E454343CE494747FF494747FF494747FF494747FF494747FF4A4848FF585C - 5CFF85999AFF3BA1D0FF0C92D6FF0D97DEFF0D9CE5FF0E9FE9FF0EA1ECFF0EA2 - EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF127A - B0FF262424FF363434FF434141FF484646FF494747FF494747FF494747FF4947 - 47FF494747FF484646FF237FAEFF0EA3EFFF0EA3EFFF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF2080B2FF474545FF4A4848FF4A4848FF4A4848FF4A4848FF4A48 - 48FF494747FF454343FF393737FF26333AFF0FA1EBFF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF118BC9FF155272FF182025FF154761FF10A4EFFF10A4EFFF10A4 - EFFF10A4EFFF10A4EFFF10A4EFFF0FA3EFFF0FA3EEFF0FA2EDFF0EA0EBFF0E9E - E7FF0D99E1FF0D95DAFF0C8FD1FF709DABFF5E6363FF4B4949FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF424141E20000004E000000370000 - 001B000000070000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000030E0D - 0D21494747FF494747FF494747FF494747FF494747FF494747FF4C4A4AFF636A - 6AFF8DAFB4FF1592D0FF0D94D8FF0D99E0FF0D9DE6FF0EA0EAFF0EA2EDFF0EA2 - EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF1B4053FF2D2C2CFF3C3A3AFF454343FF484646FF494747FF494747FF4947 - 47FF494747FF484646FF404D54FF109EE6FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0FA3EFFF345D72FF494747FF4A4848FF4A4848FF4A4848FF4A4848FF4A48 - 48FF484646FF413F3FFF323030FF1A5D7FFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF0FA3EFFF0FA3EFFF0F9EE8FF0F96DAFF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0EA2EEFF0EA1ECFF0E9F - E8FF0D9BE4FF0D96DCFF0C91D4FF4E9DBFFF6A7474FF4D4D4DFF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF1A19197E000000430000 - 00270000000E1211110200000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000042120 - 205A494747FF494747FF494747FF494747FF494747FF494747FF4F4F4FFF6F7B - 7BFF72B0C4FF0C8FD2FF0D95DBFF0D9AE3FF0E9EE8FF0EA0EBFF0EA2EEFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF1089C7FF242323FF343333FF413F3FFF474545FF494747FF494747FF4947 - 47FF494747FF494747FF484646FF297298FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF1496D8FF444242FF484646FF494747FF494747FF494747FF494747FF4947 - 47FF454343FF3B3939FF2A2828FF118ECEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF0FA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1EDFF0E9F - E9FF0D9CE6FF0D98DFFF0C92D7FF2897CDFF778788FF525353FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF383636C70000004C0000 - 0033000000170000000500000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000072F2E - 2E8E494747FF494747FF494747FF494747FF494747FF494747FF545656FF7D8E - 8EFF4FA8CEFF0C91D5FF0D97DDFF0D9BE4FF0E9FE9FF0EA1ECFF0EA2EEFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF19506CFF2B2A2AFF3B3939FF454343FF484646FF494747FF4947 - 47FF494747FF494747FF494747FF444749FF1398DCFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF286F94FF474545FF494747FF494747FF494747FF494747FF494747FF4846 - 46FF424040FF343333FF1F3F50FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EDFF0EA0 - EBFF0D9DE7FF0D99E1FF0D94D9FF0F8FD0FF78989FFF595C5CFF494848FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF484646FC0E0E0E650000 - 003F000000220000000B12111101000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000094442 - 42BA494747FF494747FF494747FF494747FF494747FF4A4848FF5B5F5FFF8BA1 - A2FF2D9CD0FF0C92D7FF0D98DFFF0D9CE6FF0E9FEAFF0EA1EDFF0EA2EEFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0F94D7FF222628FF323131FF403E3EFF474545FF494747FF4947 - 47FF494747FF494747FF494747FF484646FF316580FF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1 - ECFF3D4C54FF484646FF494747FF494747FF494747FF494747FF494747FF4644 - 44FF3D3C3CFF2E2D2DFF16709EFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA0 - EBFF0E9EE8FF0D9AE3FF0D95DBFF0C90D3FF679EB2FF616767FF4B4949FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF2D2B2BAF0000 - 00490000002F0000001300000004000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000000000B4745 - 45E2494747FF494747FF494747FF494747FF494747FF4B4A4AFF626969FF8FAF - B3FF1491D0FF0D94D9FF0D99E0FF0D9DE7FF0EA0EBFF0EA2EDFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF165E83FF292828FF393838FF444242FF484646FF4947 - 47FF494747FF494747FF494747FF494747FF474545FF198DC9FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1C86 - BDFF454343FF494747FF494747FF494747FF494747FF494747FF484646FF4442 - 42FF383737FF262C30FF0E9CE5FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1 - ECFF0E9FE9FF0D9BE4FF0D96DCFF0C91D5FF4E9DBFFF697272FF4C4C4CFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF464444F20505 - 05550000003B0000001E00000009000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F010E0D0D184947 - 47FF494747FF494747FF494747FF494747FF494747FF4C4C4CFF697272FF85B3 - BEFF0C8ED1FF0D95DAFF0D9AE2FF0E9EE7FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0E9AE1FF202B31FF302F2FFF3F3D3DFF474545FF4947 - 47FF494747FF494747FF494747FF494747FF484646FF395869FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF3160 - 79FF474545FF494747FF494747FF494747FF494747FF494747FF474545FF403F - 3FFF323131FF1B536FFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1 - EDFF0E9FE9FF0D9CE5FF0D97DEFF0C92D6FF3B9BC8FF717E7EFF4F4F4FFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF2322 - 2297000000460000002A00000010000000030000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F011F1E1E374947 - 47FF494747FF494747FF494747FF494747FF494747FF4F4F4FFF707D7DFF71B0 - C6FF0C90D3FF0D95DBFF0D9AE3FF0E9EE8FF0EA1ECFF0EA2EEFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF146A96FF282626FF383636FF434242FF4846 - 46FF494747FF494747FF494747FF494747FF494747FF474545FF2180B0FF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF119AE1FF4245 - 47FF484646FF494747FF494747FF494747FF494747FF494747FF464444FF3C3A - 3AFF2B2A2AFF1284BEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EDFF0E9FEAFF0D9DE6FF0D98DFFF0D93D7FF2898CEFF78898AFF525353FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF413F - 3FDD0000004E000000370000001A000000070000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F01222121514947 - 47FF494747FF494747FF494747FF494747FF494747FF515252FF788686FF5FAD - CCFF0C90D4FF0D97DDFF0D9BE4FF0E9FE9FF0EA1ECFF0EA2EEFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA0EBFF1E323DFF2F2E2EFF3E3C3CFF4644 - 44FF494747FF494747FF494747FF494747FF494747FF484646FF404E56FF0F9F - E9FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF2378A4FF4644 - 44FF494747FF494747FF494747FF494747FF494747FF484646FF434141FF3634 - 34FF223844FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EDFF0EA0EBFF0D9DE7FF0D99E0FF0D94D9FF1792CFFF7B9295FF555858FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF1817177800000043000000260000000D1211110100000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F01232222674947 - 47FF494747FF494747FF494747FF494747FF494747FF545656FF7E8F8FFF4FA9 - CFFF0C91D6FF0D97DEFF0D9CE4FF0E9FE9FF0EA1EDFF0EA2EEFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1278ADFF262525FF363434FF4240 - 40FF484646FF494747FF494747FF494747FF494747FF494747FF484646FF2874 - 9BFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF375463FF4846 - 46FF494747FF494747FF494747FF494747FF494747FF474545FF3E3D3DFF2F2E - 2EFF17668EFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA0EBFF0D9EE7FF0D9AE1FF0D94DAFF0E8FD0FF7A99A0FF585C5CFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF373636C40000004C00000033000000170000000500000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F012423237E4947 - 47FF494747FF494747FF494747FF494747FF494747FF565959FF849696FF43A5 - D1FF0C92D6FF0D97DEFF0D9CE5FF0E9FEAFF0EA1EDFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1B4053FF2D2C2CFF3C3B - 3BFF464444FF484646FF494747FF494747FF494747FF494747FF494747FF4349 - 4CFF1399DEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1592D2FF444242FF4846 - 46FF494747FF494747FF494747FF494747FF484646FF444343FF393838FF2829 - 2AFF0F96DBFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA0EBFF0E9EE8FF0D9AE2FF0D95DAFF0C8ED1FF769DA8FF5C6060FF4A48 - 48FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF484646FC0B0B0B620000003F000000220000000B12111101000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F01242323854947 - 47FF494747FF494747FF494747FF494747FF494747FF585B5BFF889C9CFF38A0 - D0FF0C92D7FF0D98DFFF0D9CE6FF0E9FEAFF0EA2EDFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1187C3FF242323FF3433 - 33FF413F3FFF484646FF494747FF494747FF494747FF494747FF494747FF4846 - 46FF306783FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF276E93FF464444FF4947 - 47FF494747FF494747FF494747FF494747FF484646FF413F3FFF333232FF1E49 - 5FFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA1ECFF0E9EE8FF0D9AE2FF0D95DBFF0C8FD2FF6F9EADFF5E6363FF4A48 - 48FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF2C2B2BAC000000480000002E0000001300000003000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F01242323854947 - 47FF494747FF494747FF494747FF494747FF494747FF5A5D5DFF8BA0A0FF329E - D1FF0C92D7FF0D98DFFF0D9DE6FF0E9FEAFF0EA2EDFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF194E69FF2B2A - 2AFF3B3939FF454343FF484646FF494747FF494747FF494747FF494747FF4947 - 47FF474545FF188FCBFF0EA3EFFF0EA3EFFF0EA3EFFF3A4D58FF484646FF4947 - 47FF494747FF494747FF494747FF494747FF464444FF3D3B3BFF2D2B2BFF137A - AEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA1ECFF0E9EE8FF0D9AE3FF0D95DBFF0C8FD2FF6B9FB1FF5F6565FF4A49 - 49FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF464444EF050505550000003A0000001D00000008000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F01242323844947 - 47FF494747FF494747FF494747FF494747FF4A4848FF5A5E5EFF8CA2A2FF309D - D0FF0C92D7FF0D98DFFF0D9DE6FF0E9FEAFF0EA2EDFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0F92D4FF2226 - 28FF323131FF403F3FFF474545FF494747FF494747FF494747FF494747FF4947 - 47FF484646FF385A6BFF0EA3EFFF0EA3EFFF1594D6FF444242FF484646FF4947 - 47FF494747FF494747FF494747FF484646FF444242FF373535FF243138FF0EA1 - EBFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA1ECFF0E9EE8FF0D9AE3FF0D95DBFF0C8FD2FF6B9FB2FF606767FF4A49 - 49FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF1F1E1E91000000450000002A00000010000000020000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F01242323844947 - 47FF494747FF494747FF494747FF494747FF4A4848FF5A5E5EFF8CA1A1FF319D - D0FF0C92D7FF0D98DFFF0D9DE6FF0E9FEAFF0EA2EDFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF165C - 7FFF2A2828FF393838FF444242FF484646FF494747FF494747FF494747FF4947 - 47FF494747FF474545FF2182B3FF0EA3EFFF2677A0FF464444FF494747FF4947 - 47FF494747FF494747FF494747FF474545FF403E3EFF312F2FFF195C7EFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA1ECFF0E9EE8FF0D9AE3FF0D95DBFF0C8FD2FF6B9FB2FF606767FF4A49 - 49FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF403E3EDA0000004E000000360000001A000000070000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F01242323844947 - 47FF494747FF494747FF494747FF494747FF494747FF5A5D5DFF8B9F9FFF349F - D1FF0C92D7FF0D98DFFF0D9DE6FF0E9FEAFF0EA2EDFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0E9A - E1FF20292DFF312F2FFF3F3D3DFF474545FF494747FF494747FF494747FF4947 - 47FF494747FF484646FF40535DFF0FA0E9FF395D6FFF484646FF494747FF4947 - 47FF494747FF494747FF494747FF454343FF3B3939FF2A2828FF108ECEFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA1ECFF0E9EE8FF0D9AE3FF0D95DBFF0C8FD2FF6E9FB0FF5F6565FF4A49 - 49FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF1616167600000042000000260000000D1211 - 1101000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000007F7F7F01242323834947 - 47FF494747FF494747FF494747FF494747FF494747FF585B5BFF879B9BFF3EA3 - D1FF0C92D6FF0D98DFFF0D9CE5FF0E9FEAFF0EA2EDFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF156893FF282626FF383636FF434242FF484646FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF2C7398FF484849FF494747FF494747FF4947 - 47FF494747FF494747FF484646FF424040FF343333FF1F3F50FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA1ECFF0E9EE8FF0D9AE2FF0D95DBFF0C8ED1FF739FACFF5D6363FF4A48 - 48FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF353333C20000004B00000032000000160000 - 0005000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000002423237B4947 - 47FF494747FF494747FF494747FF494747FF494747FF565858FF839595FF49A7 - D0FF0C92D6FF0D97DEFF0D9CE5FF0E9FE9FF0EA1EDFF0EA2EEFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA0EBFF1E323DFF2F2E2EFF3E3C3CFF464444FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF464444FF3D3C3CFF2E2D2DFF16709EFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EEFF0EA0EBFF0E9EE7FF0D9AE1FF0D95DAFF0D8ED1FF7A9EA6FF5B6060FF4A48 - 48FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF484646FA0B0B0B620000003E000000210000 - 000A121111010000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000242323644947 - 47FF494747FF494747FF494747FF494747FF494747FF535555FF7D8E8EFF57AC - CFFF0C91D5FF0D97DDFF0D9CE4FF0E9FE9FF0EA1ECFF0EA2EEFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF1577AAFF2B2A2AFF3D3C3CFF4C4A4AFF525050FF545252FF5553 - 53FF565454FF565454FF575555FF565454FF555454FF555353FF545252FF5250 - 50FF514F4FFF4D4C4CFF474545FF393737FF262C30FF0E9CE5FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EDFF0EA0EBFF0D9EE7FF0D99E1FF0D94D9FF1291D0FF7D999EFF585C5CFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF2A2929A7000000480000002E0000 - 0012000000030000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000002322224C4947 - 47FF494747FF494747FF494747FF494747FF494747FF515252FF778585FF69B0 - CBFF0C90D4FF0D96DCFF0D9BE3FF0E9EE8FF0EA1ECFF0EA2EEFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0FA3EFFF15A5EFFF1CA8 - F0FF20AAF0FF23ABF0FF304F5FFF403F3FFF4E4C4CFF575555FF595757FF5957 - 57FF595757FF595757FF595757FF595757FF595757FF595757FF595757FF5957 - 57FF595757FF585656FF525050FF434242FF2B5E79FF18A6EFFF12A4EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2 - EDFF0EA0EAFF0D9DE6FF0D98E0FF0D93D8FF1F95CFFF7D9293FF555757FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF464444EF030303520000003A0000 - 001D000000080000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000222121334947 - 47FF494747FF494747FF494747FF494747FF494747FF4F4E4EFF6F7B7BFF7DB5 - C5FF0C8FD2FF0D95DBFF0D9AE2FF0E9EE8FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF15A5EFFF1FA9F0FF26ACF0FF28ACF1FF28AC - F1FF28ACF1FF28ACF1FF2A92C7FF3C3B3BFF4A4949FF565454FF5C5A5AFF5D5B - 5BFF5D5B5BFF5D5B5BFF5D5B5BFF5D5B5BFF5D5B5BFF5D5B5BFF5D5B5BFF5D5B - 5BFF5D5B5BFF5A5858FF514F4FFF424141FF2B91C5FF28ACF1FF28ACF1FF23AB - F0FF1AA7EFFF11A4EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1 - EDFF0E9FEAFF0D9CE6FF0D98DFFF0C92D7FF339BCDFF778787FF515353FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF1E1D1D8C000000450000 - 00290000000F0000000200000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000001010100F4947 - 47FF494747FF494747FF494747FF494747FF494747FF4C4B4BFF677171FF8EB6 - BEFF0E8FD1FF0D94DAFF0D99E1FF0D9EE7FF0EA0EBFF0EA2EDFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0FA3EFFF1AA7EFFF27ACF0FF2CAEF1FF2CAEF1FF2CAEF1FF2CAEF1FF2CAE - F1FF2CAEF1FF2CAEF1FF2CAEF1FF366279FF464545FF545252FF5C5B5BFF5F5D - 5DFF605E5EFF605E5EFF605E5EFF605E5EFF605E5EFF605E5EFF605E5EFF605E - 5EFF5F5D5DFF5A5959FF4F4E4EFF3E515BFF2CAEF1FF2CAEF1FF2CAEF1FF2CAE - F1FF2CAEF1FF2AAEF1FF21AAF0FF14A5EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1 - ECFF0E9FE9FF0D9CE5FF0D97DDFF0C91D6FF459FC6FF707C7CFF4F4F4FFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF3F3D3DD70000004D0000 - 0036000000190000000600000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000014846 - 46E8494747FF494747FF494747FF494747FF494747FF4B4949FF606767FF93AF - B1FF1F95D0FF0D93D8FF0D98E0FF0D9DE6FF0EA0EAFF0EA2EDFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF19A7 - EFFF2AADF0FF30B0F1FF30B0F1FF30B0F1FF30B0F1FF30B0F1FF30B0F1FF30B0 - F1FF30B0F1FF30B0F1FF30B0F1FF319FD7FF414547FF4F4E4EFF5B5A5AFF615F - 5FFF626161FF626161FF626161FF626161FF626161FF626161FF626161FF6261 - 61FF615F5FFF5A5858FF4D4B4BFF387B9EFF30B0F1FF30B0F1FF30B0F1FF30B0 - F1FF30B0F1FF30B0F1FF30B0F1FF2EAFF1FF23AAF0FF12A4EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1 - ECFF0E9EE8FF0D9BE3FF0D96DCFF0C90D4FF5DA1BCFF677070FF4C4B4BFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF141414720000 - 0041000000250000000D12111101000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000004745 - 45B9494747FF494747FF494747FF494747FF494747FF494848FF595D5DFF899E - 9EFF3EA3D0FF0C92D6FF0D97DEFF0D9CE5FF0E9FE9FF0EA1ECFF0EA2EEFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF13A5EFFF29ADF1FF35B1 - F2FF35B1F2FF35B1F2FF35B1F2FF35B1F2FF35B1F2FF35B1F2FF35B1F2FF35B1 - F2FF35B1F2FF35B1F2FF35B1F2FF35B1F2FF3C7491FF4C4B4BFF595858FF6261 - 61FF666464FF666464FF666464FF666464FF666464FF666464FF666464FF6664 - 64FF626161FF595858FF4B4C4CFF36A7E1FF35B1F2FF35B1F2FF35B1F2FF35B1 - F2FF35B1F2FF35B1F2FF35B1F2FF35B1F2FF35B1F2FF31B0F1FF1DA9F0FF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EDFF0EA0 - EBFF0D9EE7FF0D9AE2FF0D95DAFF0C8FD1FF75A1AEFF5F6565FF4A4949FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF343232BD0000 - 004B000000320000001600000005000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000003534 - 348D494747FF494747FF494747FF494747FF494747FF494747FF535555FF7B8B - 8BFF63B0CDFF0C90D4FF0D96DCFF0D9BE3FF0E9EE8FF0EA1ECFF0EA2EEFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1BA8F0FF35B2F1FF39B3F2FF39B3 - F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3 - F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39ACE7FF484F53FF565555FF6261 - 61FF686666FF696868FF696868FF696868FF696868FF696868FF696868FF6967 - 67FF636161FF585656FF46697BFF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3 - F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF39B3F2FF29AD - F1FF11A4EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA2EDFF0EA0 - EAFF0D9DE6FF0D98E0FF0D93D8FF1A93CFFF7F9799FF585B5BFF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF484646FA0A0A - 0A5F0000003D000000210000000A000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000002322 - 2252494747FF494747FF494747FF494747FF494747FF494747FF4E4E4EFF6D78 - 78FF88B8C3FF0C8FD1FF0D95DAFF0D99E1FF0D9EE7FF0EA0EBFF0EA2EDFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF22ABF0FF3CB4F2FF3DB5F2FF3DB5F2FF3DB5 - F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5 - F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF4485A6FF565555FF6462 - 62FF6B6969FF6D6B6BFF6D6B6BFF6D6B6BFF6D6B6BFF6D6B6BFF6D6B6BFF6B69 - 69FF636262FF565555FF4294BEFF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5 - F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5F2FF3DB5 - F2FF33B1F1FF13A5EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1ECFF0E9F - E9FF0D9CE5FF0D97DEFF0C92D6FF3D9ECAFF768484FF515252FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF2827 - 27A4000000470000002D00000012000000030000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001111 - 1111494747FF494747FF494747FF494747FF494747FF494747FF4B4A4AFF6167 - 67FF92AEB0FF2799D0FF0C93D7FF0D98DFFF0D9CE6FF0E9FEAFF0EA1EDFF0EA2 - EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF25ACF0FF41B6F2FF42B7F2FF42B7F2FF42B7F2FF42B7 - F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7 - F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF43B3EDFF58676FFF6866 - 66FF6E6D6DFF716F6FFF716F6FFF716F6FFF716F6FFF716F6FFF706E6EFF6C6B - 6BFF636161FF545E64FF42B5F0FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7 - F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7F2FF42B7 - F2FF42B7F2FF39B3F2FF13A5EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EDFF0EA0EBFF0E9E - E8FF0D9AE3FF0D95DBFF0C90D3FF65A4BCFF687070FF4D4C4CFF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4543 - 43EC03030352000000390000001C000000080000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000484646D0494747FF494747FF494747FF494747FF494747FF494848FF575A - 5AFF829595FF54ABD0FF0C91D4FF0D96DCFF0D9BE4FF0E9FE8FF0EA1ECFF0EA2 - EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF22AAF0FF45B8F2FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8 - F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8 - F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF519BC1FF6D6C - 6CFF737272FF747373FF747373FF747373FF747373FF747373FF737171FF6D6C - 6CFF616161FF50839DFF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8 - F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8F3FF47B8 - F3FF47B8F3FF47B8F3FF39B3F1FF11A4EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA2EDFF0EA0EAFF0D9D - E6FF0D99E0FF0D94D9FF1291D0FF7E9EA5FF5C6161FF4A4949FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF1D1C1C8900000044000000290000000F0000000200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000036343488494747FF494747FF494747FF494747FF494747FF494747FF5050 - 50FF707C7CFF82B7C5FF0C8FD1FF0D95DAFF0D99E1FF0D9DE7FF0EA0EAFF0EA2 - EDFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF17A6EFFF47B8F2FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBA - F3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBA - F3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF50B2E4FF7472 - 72FF777676FF787676FF787676FF787676FF787676FF787676FF757474FF6E6C - 6CFF616060FF4EA9D8FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBA - F3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBAF3FF4CBA - F3FF4CBAF3FF4CBAF3FF4CBAF3FF31B0F1FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1ECFF0E9FE9FF0D9C - E5FF0D97DEFF0C92D6FF379DCCFF798889FF535555FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF3D3C3CD20000004D00000035000000190000000600000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00002322223D494747FF494747FF494747FF494747FF494747FF494747FF4C4A - 4AFF616767FF92ADAEFF2D9CD0FF0C92D7FF0D97DEFF0D9CE5FF0E9FE9FF0EA1 - ECFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF3DB5F2FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BC - F3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BC - F3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF619CBBFF7978 - 78FF7C7B7BFF7C7B7BFF7C7B7BFF7C7B7BFF7C7B7BFF7B7A7AFF777676FF6D6C - 6CFF5E7581FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BC - F3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BCF3FF51BC - F3FF51BCF3FF51BCF3FF51BCF3FF50BCF3FF1DA9F0FF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA2EDFF0EA0EBFF0D9EE7FF0D9A - E2FF0D95DBFF0C8FD2FF6AA5BAFF677171FF4D4D4DFF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF1413137000000041000000240000000C00000001000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000484646E3494747FF494747FF494747FF494747FF494747FF4948 - 48FF555858FF7D8D8DFF68B2CDFF0C90D3FF0D95DBFF0D9AE2FF0E9EE8FF0EA0 - EBFF0EA2EDFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF20AA - F0FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BE - F4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BE - F4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF728995FF7F7D - 7DFF807E7EFF807E7EFF807E7EFF807E7EFF807E7EFF7E7D7DFF787777FF6D6C - 6CFF5C9AB9FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BE - F4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF57BE - F4FF57BEF4FF57BEF4FF57BEF4FF57BEF4FF45B7F2FF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1ECFF0E9FE9FF0D9CE6FF0D98 - DFFF0C93D7FF1F95CFFF80999CFF595D5DFF4A4848FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF333131BA0000004A000000310000001500000004000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000003635358C494747FF494747FF494747FF494747FF494747FF4947 - 47FF4E4E4EFF687171FF93B6BBFF1B94D0FF0C93D8FF0D98DFFF0D9CE6FF0E9F - E9FF0EA1ECFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF44B8 - F2FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0 - F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0 - F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5FB8E7FF807F7FFF8382 - 82FF848282FF848282FF848282FF848282FF838282FF807F7FFF787878FF6C6F - 71FF5CBCEDFF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0 - F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0 - F4FF5CC0F4FF5CC0F4FF5CC0F4FF5CC0F4FF5BC0F4FF1EA9F0FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA2EDFF0EA0EBFF0E9EE8FF0D9AE3FF0D96 - DCFF0C90D3FF57A4C3FF707C7CFF505151FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF484646FA0909095C0000003D000000200000000A000000000000 - 0000000000000000000000000001000000000000000000000000000000000000 - 00000000000023222228494747FF494747FF494747FF494747FF494747FF4947 - 47FF4A4848FF595C5CFF839696FF5BAECFFF0C90D4FF0D96DCFF0D9AE3FF0E9E - E8FF0EA0EBFF0EA2EDFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF14A5EFFF5DC1 - F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2 - F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2 - F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF6FA8C5FF868484FF8887 - 87FF888787FF888787FF888787FF888787FF878686FF828181FF797878FF6A8E - A1FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2 - F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2 - F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF61C2F4FF3AB3F2FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1ECFF0E9FE9FF0D9CE6FF0D98DFFF0C93 - D8FF1893D0FF809FA6FF5E6363FF4B4A4AFF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF272626A1000000470000002C00000012000000030000 - 0000000000000000000000000002000000000000000000000000000000000000 - 00000000000000000000484646C0494747FF494747FF494747FF494747FF4947 - 47FF494747FF4F4F4FFF6B7676FF90B8BEFF1692D0FF0C93D8FF0D98DFFF0D9C - E5FF0E9FE9FF0EA1ECFF0EA2EEFF0EA2EEFF0EA3EFFF0EA3EFFF25ACF0FF66C4 - F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4 - F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4 - F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF7F98A5FF8B8A8AFF8C8A - 8AFF8C8A8AFF8C8A8AFF8C8A8AFF8C8A8AFF8A8888FF838282FF797878FF69AF - D3FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4 - F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4 - F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF66C4F5FF52BCF3FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA2EEFF0EA2EDFF0EA0EBFF0D9EE7FF0D9AE2FF0D96DBFF0C90 - D3FF50A2C5FF738080FF525353FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF444242E70000004F000000390000001C000000070000 - 0000000000000000000000000003000000000000000000000000000000000000 - 0000000000000000000024232350494747FF494747FF494747FF494747FF4947 - 47FF494747FF4B4949FF595D5DFF849797FF60B0CFFF0C90D3FF0D95DBFF0D9A - E2FF0D9DE7FF0EA0EAFF0EA1EDFF0EA2EEFF0EA3EFFF0EA3EFFF34B1F1FF6CC6 - F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6 - F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6 - F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6EC2EDFF8E8F8FFF8F8E8EFF908F - 8FFF908F8FFF908F8FFF908F8FFF8F8E8EFF8C8B8BFF848383FF78848BFF6CC6 - F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6 - F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6 - F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF6CC6F5FF63C3F4FF0EA3EFFF0EA3 - EFFF0EA2EEFF0EA2EDFF0EA1ECFF0E9FE9FF0D9CE5FF0D98DFFF0C93D7FF1A94 - CFFF82A0A5FF5F6464FF4C4B4BFF494747FF494747FF494747FF4A4848FF4B49 - 49FF4B4A4AFF4B4A4AFF4B4A4AFF4B4A4AFF4B4A4AFF4B4A4AFF4B4A4AFF4B4A - 4AFF4B4A4AFF4B4A4AFF4B4A4AFF4A4949FF4A4848FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF1C1B1B8600000044000000280000000E0000 - 0002000000000000000000000002000000000000000000000000000000000000 - 0000000000000000000011101004484646DB494747FF494747FF494747FF4947 - 47FF494747FF494747FF4F4F4FFF697272FF92B5B9FF2297D0FF0C92D6FF0D97 - DEFF0D9BE4FF0E9FE8FF0EA0EBFF0EA2EDFF0EA2EEFF0EA3EFFF3EB5F2FF71C9 - F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9 - F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF78B7D7FF7DB3CFFF7EB5D1FF7EB5 - D1FF7EB5D1FF7EB5D1FF7EB5D1FF7EB5D1FF85AABDFF949393FF949393FF9493 - 93FF949393FF949393FF949393FF939292FF8E8D8DFF858484FF77A5BDFF71C9 - F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9 - F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9 - F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF71C9F6FF70C9F5FF0EA3EFFF0EA3 - EFFF0EA2EEFF0EA1EDFF0E9FEAFF0D9DE7FF0D99E1FF0D95DAFF0C8FD2FF5FA6 - C2FF717C7CFF515252FF494747FF494747FF4A4848FF4E4D4DFF545656FF5A5D - 5DFF5C6161FF5C6161FF5C6161FF5C6161FF5C6161FF5C6161FF5C6161FF5C61 - 61FF5C6161FF5C6161FF5B6060FF585C5CFF525353FF4C4B4BFF494747FF4947 - 47FF494747FF494747FF494747FF3D3B3BCF0000004D00000035000000180000 - 0005000000000000000000000002000000000000000000000000000000000000 - 000000000000000000000000000047454560494747FF494747FF494747FF4947 - 47FF494747FF494747FF4A4848FF575A5AFF7D8D8DFF75B6CCFF0C8FD1FF0D94 - D9FF0D99E0FF0D9CE6FF0E9FE9FF0EA1ECFF0EA2EDFF0EA2EEFF3EB5F2FF77CB - F6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CB - F6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF889CA7FF949393FF989797FF9997 - 97FF999797FF999797FF999797FF999797FF999797FF999797FF999797FF9997 - 97FF999797FF999797FF989797FF969595FF908F8FFF868787FF78C3E9FF77CB - F6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CB - F6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CB - F6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF77CBF6FF73C9F5FF0EA3EFFF0EA2 - EEFF0EA1EDFF0EA0EBFF0E9EE8FF0D9BE3FF0D96DDFF0C91D6FF2C9ACDFF8098 - 9AFF5B6060FF4B4A4AFF494747FF494747FF4C4B4BFF50626AFF6699AFFF75A4 - B8FF79A8BBFF79A9BCFF79A9BCFF79A9BCFF79A9BCFF79A9BCFF79A9BCFF79A9 - BCFF79A9BCFF79A9BCFF78A7BAFF759EAFFF6A6F6FFF515252FF4A4848FF4947 - 47FF494747FF494747FF494747FF494747FF1312126D00000040000000240000 - 000C000000010000000000000002000000000000000000000000000000000000 - 000000000000000000000000000048464604494747DB494747FF494747FF4947 - 47FF494747FF494747FF494747FF4D4C4CFF626969FF90A8A9FF46A6D0FF0C90 - D4FF0D96DBFF0D9AE2FF0D9EE7FF0EA0EAFF0EA1EDFF0EA2EEFF34B1F1FF7DCD - F6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCD - F6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF8DA0AAFF999898FF9C9B9BFF9D9C - 9CFF9D9C9CFF9D9C9CFF9D9C9CFF9D9C9CFF9D9C9CFF9D9C9CFF9D9C9CFF9D9C - 9CFF9D9C9CFF9D9C9CFF9C9B9BFF999898FF919090FF859DA9FF7DCDF6FF7DCD - F6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCD - F6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCD - F6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF7DCDF6FF6BC7F5FF0EA2EEFF0EA2 - EDFF0EA1ECFF0E9FE9FF0D9CE5FF0D98DFFF0C93D8FF1391D1FF79A8B5FF6871 - 71FF4F4F4FFF494747FF494747FF494747FF4D4D4DFF537684FF70CCF6FF80D1 - F7FF80D1F7FF80D1F7FF80D1F7FF80D1F7FF80D1F7FF80D1F7FF80D1F7FF80D1 - F7FF80D1F7FF80D1F7FF80D1F7FF83CAEBFF7D8383FF565858FF4A4848FF4947 - 47FF494747FF494747FF494747FF494747FF302E2EB70000004A000000300000 - 0014000000040000000000000002000000000000000000000000000000000000 - 00000000000000000000000000000000000048464660494747FF494747FF4947 - 47FF494747FF494747FF494747FF4A4848FF525353FF6F7B7BFF90B8BFFF1C94 - CFFF0C92D7FF0D97DDFF0D9BE3FF0E9EE8FF0EA0EBFF0EA1EDFF22AAEFFF82CF - F7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CF - F7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF92A4AEFF9D9C9CFFA1A0A0FFA1A0 - A0FFA1A0A0FFA1A0A0FFA1A0A0FFA1A0A0FFA1A0A0FFA1A0A0FFA1A0A0FFA1A0 - A0FFA1A0A0FFA1A0A0FFA09F9FFF9B9A9AFF929191FF86B9D3FF82CFF7FF82CF - F7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CF - F7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CF - F7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF82CFF7FF5DC0F4FF0EA2EDFF0EA1 - ECFF0E9FE9FF0D9DE6FF0D99E1FF0D95DAFF0C8FD3FF54A4C6FF778686FF5558 - 58FF4A4848FF494747FF494747FF494747FF4D4D4DFF557785FF73CDF6FF80D1 - F7FF80D1F7FF80D1F7FF80D1F7FF80D1F7FF80D1F7FF80D1F7FF80D1F7FF80D1 - F7FF80D1F7FF80D1F7FF80D1F7FF82C9EBFF7B8181FF555757FF4A4848FF4947 - 47FF494747FF494747FF494747FF494747FF474545F70909095B0000003C0000 - 001F000000090000000000000001000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000484646CB494747FF4947 - 47FF494747FF494747FF494747FF494747FF4B4A4AFF595C5CFF7E8F8FFF7AB8 - CBFF0E8FD1FF0D94D8FF0D98DFFF0D9CE5FF0E9FE8FF0EA0EBFF0FA2EDFF74C9 - F5FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1 - F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF96A8B1FFA1A0A0FFA4A3A3FFA5A4 - A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4 - A4FFA5A4A4FFA4A3A3FFA2A1A1FF9C9B9BFF93989BFF88D0F5FF88D1F7FF88D1 - F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1 - F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1 - F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF88D1F7FF38B2F0FF0EA1ECFF0E9F - EAFF0D9DE7FF0D9AE2FF0D96DBFF0C91D5FF339BCDFF829A9CFF5D6262FF4C4B - 4BFF494747FF494747FF494747FF494747FF4C4B4BFF566469FF65BEE6FF80D1 - F7FF80D1F7FF80D1F7FF8EB8CAFF8AA7ACFF7C969CFF738B91FF71888EFF7188 - 8EFF71888EFF71888EFF70878DFF6B7E84FF5F6363FF4F5050FF494848FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF2423239C000000460000 - 002B000000100000000300000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000083A2A238494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4D4D4DFF606767FF8BA1 - A1FF5CAECFFF0C8FD2FF0D94D9FF0D99E0FF0D9CE5FF0E9FE9FF0EA0EBFF4BB9 - F1FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3 - F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF9BACB5FFA5A4A4FFA8A7A7FFA8A7 - A7FFA8A7A7FFA8A7A7FFA8A7A7FFA8A7A7FFA8A7A7FFA8A7A7FFA8A7A7FFA8A7 - A7FFA8A7A7FFA8A7A7FFA4A3A3FF9D9D9DFF92B2C2FF8DD3F7FF8DD3F7FF8DD3 - F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3 - F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3 - F7FF8DD3F7FF8DD3F7FF8DD3F7FF8DD3F7FF82CFF6FF16A4EDFF0EA0EAFF0D9E - E7FF0D9BE3FF0D97DDFF0C92D6FF1E95CFFF81A6ADFF666E6EFF4F4F4FFF4947 - 47FF494747FF494747FF494747FF494747FF4A4848FF525353FF5D7B86FF71CB - F4FF80D1F7FF80D1F7FF81CEF2FF91A7AEFF717E7EFF5E6464FF565959FF5557 - 57FF555757FF555757FF545757FF525454FF4E4F4FFF4B4949FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF434141E50000004E0000 - 0036000000190000000600000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000004947479B4947 - 47FF494747FF494747FF494747FF494747FF494747FF4A4848FF505151FF6770 - 70FF92ADAFFF44A5D0FF0C90D4FF0D95DAFF0D99E1FF0D9CE6FF0E9FE9FF19A5 - ECFF86D0F6FF92D5F7FF92D5F7FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5 - F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF9FAEB7FFA7A6A6FFA9A8A8FFA9A8 - A8FFA9A8A8FFA9A8A8FFA9A8A8FFA9A8A8FFA9A8A8FFA9A8A8FFA9A8A8FFA9A8 - A8FFA9A8A8FFA8A7A7FFA4A4A4FF9F9E9EFF94CBE7FF92D5F8FF92D5F8FF92D5 - F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5 - F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5F8FF92D5 - F8FF92D5F8FF92D5F8FF92D5F7FF92D5F7FF50BBF1FF0EA0EAFF0D9EE7FF0D9B - E3FF0D97DEFF0C92D7FF1391D0FF79AAB9FF6E7979FF535454FF4A4848FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4C4A4AFF565959FF5E91 - A5FF79CFF6FF80D1F7FF80D1F7FF84CBEBFF879496FF616767FF505151FF4A49 - 49FF4A4848FF4A4848FF4A4848FF494848FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF1C1B1B820000 - 003F000000220000000A00000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000A0D0D0104947 - 47E3494747FF494747FF494747FF494747FF494747FF494747FF4A4848FF5354 - 54FF6E7979FF93B5B9FF319ED0FF0C91D4FF0D95DBFF0D99E1FF0D9CE6FF0E9F - E9FF47B7EFFF98D7F7FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7 - F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FFA0B0B8FFA5A5A5FFA6A6A6FFA6A6 - A6FFA6A6A6FFA6A6A6FFA6A6A6FFA6A6A6FFA6A6A6FFA6A6A6FFA6A6A6FFA6A6 - A6FFA6A6A6FFA6A5A5FFA3A3A3FF9EACB3FF98D7F8FF98D7F8FF98D7F8FF98D7 - F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7 - F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7F8FF98D7 - F8FF98D7F8FF98D7F8FF98D7F7FF83CFF5FF17A3EAFF0D9EE7FF0D9BE3FF0D97 - DEFF0C93D8FF0E90D1FF6BAAC1FF758383FF565858FF4B4949FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF4D4C4CFF5A5E - 5EFF5FA5C2FF7ED0F7FF80D1F7FF80D1F7FF89C2DCFF7C8686FF5B6060FF4E4D - 4DFF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF383737C70000 - 00470000002B0000001000000002000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000006674 - 744C494747FF494747FF494747FF494747FF494747FF494747FF494747FF4B49 - 49FF555858FF738080FF91B8BEFF2899CFFF0C91D5FF0D95DBFF0D99E1FF0D9C - E5FF11A0E9FF6FC6F3FF9ED9F7FF9ED9F8FF9ED9F8FF9EDAF8FF9EDAF8FF9EDA - F8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FFA3ABAFFFA4A4A4FFA5A4A4FFA5A4 - A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4 - A4FFA5A4A4FFA4A4A4FFA3A3A3FFA0C3D5FF9EDAF8FF9EDAF8FF9EDAF8FF9EDA - F8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDA - F8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FF9EDAF8FF9ED9 - F8FF9ED9F8FF9ED9F8FF97D6F6FF32AEECFF0D9EE7FF0D9BE3FF0D97DEFF0C93 - D8FF0D8FD1FF61A8C4FF7A8A8AFF595D5DFF4C4B4BFF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF4A4848FF4F4E - 4EFF5D6668FF65B9DCFF80D1F7FF80D1F7FF80D1F7FF8DB7C9FF737D7DFF575B - 5BFF4C4B4BFF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF484646F90707 - 0755000000330000001600000004000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000066757597494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4C4B4BFF575B5BFF768484FF93BAC0FF2899CFFF0C91D4FF0D95DAFF0D99 - E0FF0D9CE5FF1BA3E9FF86CFF4FFA3DBF8FFA3DBF8FFA3DBF8FFA3DCF9FFA3DC - F9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA6ADB1FFA7A7A7FFA7A7A7FFA7A7 - A7FFA7A7A7FFA7A7A7FFA7A7A7FFA7A7A7FFA7A7A7FFA7A7A7FFA7A7A7FFA7A7 - A7FFA7A7A7FFA7A7A7FFA7A8A9FFA3D9F5FFA3DCF9FFA3DCF9FFA3DCF9FFA3DC - F9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DC - F9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DCF9FFA3DB - F8FFA3DBF8FFA1DAF7FF4BB7EEFF0D9DE6FF0D9AE2FF0D97DDFF0C93D8FF0E8F - D1FF61A9C5FF7D8D8EFF5B6060FF4C4B4BFF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4A48 - 48FF515252FF5E7379FF6DC5ECFF80D1F7FF80D1F7FF81D0F5FF8EA9B3FF6A74 - 74FF545656FF4B4A4AFF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF1E1D - 1D860000003A0000001B00000006000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000A0D1D108484646CF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4C4B4BFF585B5BFF768484FF92B8BEFF329ED0FF0C90D4FF0D94 - D9FF0D98DFFF0D9BE3FF1EA4E9FF8DD1F4FFA9DDF8FFA9DDF8FFA9DDF9FFA9DE - F9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DE - F9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DE - F9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DE - F9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DE - F9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DEF9FFA9DDF9FFA9DDF9FFA9DD - F8FFA5DBF7FF54BAEFFF0D9CE6FF0D99E1FF0D96DCFF0C92D7FF0F8FD0FF67AB - C4FF7C8D8EFF5C6161FF4D4C4CFF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4B4A4AFF545656FF5E8492FF75CDF5FF81D1F7FF81D1F7FF83CDF0FF8B9C - A0FF646B6BFF515252FF4A4848FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF3635 - 35BD0000003E0000001F00000008000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000A0D1D124494747EF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF4C4B4BFF575B5BFF738080FF93B5B9FF44A5D0FF0C8F - D2FF0D94D8FF0D97DDFF0D9AE2FF1CA2E7FF81CCF3FFAEDFF8FFAEDFF8FFAEDF - F9FFAEDFF9FFAEE0F9FFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0 - FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0 - FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0 - FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0 - FAFFAEE0FAFFAEE0FAFFAEE0FAFFAEE0F9FFAEDFF9FFAEDFF9FFAEDFF8FFA4DB - F7FF4AB6EDFF0D9BE4FF0D99E0FF0D95DBFF0C91D5FF1993D0FF73ADC0FF7989 - 89FF5B5F5FFF4D4C4CFF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4C4B4BFF575B5BFF5F99AFFF7CD0F6FF81D1F7FF81D1F7FF87C8 - E6FF838F91FF5F6565FF4F4F4FFF4A4848FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4543 - 43E900000041000000220000000A000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000066757544494747FB494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF4C4B4BFF555858FF6E7979FF92ADAFFF5CAE - CFFF0E8FD1FF0C92D7FF0D96DBFF0D99E0FF159EE5FF65C1F0FFAEDFF7FFB3E1 - F9FFB3E1F9FFB3E2F9FFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2 - FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2 - FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2 - FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2FAFFB3E2 - FAFFB3E2FAFFB3E2FAFFB3E2F9FFB3E1F9FFB3E1F9FFB3E1F8FF97D5F5FF30AB - E9FF0D9AE2FF0D97DEFF0D94D9FF0C90D4FF2598CFFF80ACB7FF748181FF585C - 5CFF4C4B4BFF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF4E4D4DFF5B6060FF61ACCBFF80D0F7FF81D1F7FF81D1 - F7FF8BBFD6FF7A8484FF5A5F5FFF4D4D4DFF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF0A09094D000000230000000A000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000039586867494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4B4949FF535454FF677070FF8BA1 - A1FF7AB8CBFF1B94CFFF0C90D4FF0D94D9FF0D97DEFF0D9AE2FF36ADE9FF96D4 - F4FFB8E3F8FFB8E3F9FFB8E3FAFFB8E3FAFFB8E3FAFFB8E4FAFFB8E4FAFFB8E4 - FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4 - FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4 - FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E4FAFFB8E3 - FAFFB8E3FAFFB8E3FAFFB8E3F9FFB8E3F9FFAFDFF7FF68C1EFFF18A0E5FF0D99 - E0FF0D96DBFF0C92D7FF0D8FD1FF45A3CCFF85A5AAFF6D7777FF555858FF4C4B - 4BFF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF4A4848FF504F4FFF606B6EFF8DCCE8FFA4DEF9FFA2DD - F9FF9DDBF9FF9AB8C4FF707A7AFF565959FF4B4A4AFF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF1616165D000000210000000A000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000003958687F494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4A4848FF505151FF6067 - 67FF7E8F8FFF90B8BFFF46A6D0FF0C8FD1FF0C92D6FF0D95DBFF0D98DFFF149D - E3FF52B8ECFFA3DAF6FFBEE5F9FFBEE5F9FFBEE5FAFFBEE5FAFFBEE6FAFFBEE6 - FAFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6 - FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6 - FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FBFFBEE6FAFFBEE6FAFFBEE5 - FAFFBEE5F9FFBEE5F9FFB8E3F8FF80CBF2FF2AA7E7FF0D99E1FF0D96DDFF0D94 - D9FF0C90D4FF1D95D0FF6DADC4FF839798FF656C6CFF525353FF4B4949FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF4A4949FF525353FF677C82FF9CD9F5FFAAE0 - FAFFAAE0FAFFA9DFF9FF96A8AEFF666F6FFF515252FF4A4848FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF1D1C1C6B0000001E00000008000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000003958688F494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF4A4848FF4D4D - 4DFF595C5CFF6F7B7BFF8FA8A9FF77B7CCFF2297D0FF0C90D3FF0C93D8FF0D96 - DCFF0D98DFFF159EE3FF4DB6EBFF99D6F5FFC2E7F9FFC3E7FAFFC3E7FAFFC3E7 - FAFFC3E7FAFFC3E7FBFFC3E7FBFFC3E8FBFFC3E8FBFFC3E8FBFFC3E8FBFFC3E8 - FBFFC3E8FBFFC3E8FBFFC3E8FBFFC3E8FBFFC3E8FBFFC3E8FBFFC3E8FBFFC3E8 - FBFFC3E8FBFFC3E7FBFFC3E7FBFFC3E7FAFFC3E7FAFFC3E7FAFFC3E7FAFFC3E7 - F9FFB4E1F7FF76C7F0FF2CA8E7FF0D99E1FF0D97DEFF0D94DAFF0C91D5FF0E8F - D1FF48A4CDFF88ABB1FF748282FF5C6161FF4F4F4FFF4A4848FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4B4A4AFF555757FF71939FFFA9E0 - FAFFAFE1FAFFAFE1FAFFACD9EFFF848F8FFF5C6060FF4C4C4CFF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF1B1A1A620000001900000005000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000003958688F4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4B4A4AFF525353FF626868FF7C8D8DFF93B5B9FF60B0CFFF1792D0FF0C90 - D4FF0C93D8FF0D95DBFF0D97DEFF0D99E1FF30A9E7FF6DC3EFFFA4DAF6FFC6E8 - F9FFC8E9FAFFC8E9FAFFC8E9FAFFC8E9FBFFC8E9FBFFC8E9FBFFC8E9FBFFC8E9 - FBFFC8E9FBFFC8E9FBFFC8E9FBFFC8E9FBFFC8E9FBFFC8E9FBFFC8E9FBFFC8E9 - FBFFC8E9FBFFC8E9FBFFC8E9FAFFC8E9FAFFC8E9FAFFBAE3F8FF8ED1F3FF4AB4 - EBFF189FE4FF0D98E0FF0D96DDFF0D94D9FF0C91D6FF0C8FD1FF349ECFFF7CAF - BEFF819393FF666E6EFF545656FF4C4B4BFF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4C4C4CFF5A5D5DFF84B2 - C4FFB3E3FAFFB4E3FAFFB4E3FAFFA1B8C1FF687171FF515252FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF1515154A0000001400000004000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000003958 - 687B494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4A4848FF4D4C4CFF575959FF697272FF849797FF90B7BEFF5CAE - CFFF1B94D0FF0C90D3FF0C92D7FF0D95DAFF0D96DCFF0D98DFFF0D99E1FF28A6 - E6FF4EB6EBFF82CCF2FFA3DAF5FFC0E6F8FFCDEBFAFFCDEBFAFFCDEBFAFFCDEB - FBFFCDEBFBFFCDEBFBFFCDEBFBFFCDEBFBFFCDEBFBFFCDEBFBFFCDEBFAFFCDEB - FAFFCAEAF9FFB2E0F7FF94D3F4FF68C1EFFF3BAEE9FF159EE4FF0D99E0FF0D97 - DEFF0D95DBFF0D93D8FF0C91D5FF0C8FD1FF379FCFFF76AFC2FF879D9EFF6D78 - 78FF595D5DFF4E4E4EFF4A4848FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4B4949FF4D4D4DFF4F50 - 50FF4F5050FF4D4D4DFF4B4949FF494747FF494747FF4A4848FF4F4F4FFF6472 - 75FFA8DDF5FFB8E5FBFFB8E5FBFFAFD4E4FF7B8484FF565858FF4A4848FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4846 - 46FC0404042B0000000E00000002000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000039586860494747FB494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF4A4848FF4F4F4FFF595D5DFF6B7575FF8396 - 96FF93B6BBFF67B1CDFF2D9CD0FF0C8FD1FF0C91D4FF0C93D7FF0D95DAFF0D96 - DCFF0D97DEFF0D98E0FF0D99E1FF109BE3FF26A5E6FF3BAFE9FF4DB6EBFF5BBB - EDFF66C0EFFF6CC3EFFF6EC4EFFF69C2EFFF61BEEEFF55B9ECFF44B2EAFF31AA - E8FF1AA0E4FF0D9AE2FF0D99E0FF0D98DFFF0D97DDFF0D95DBFF0D94D8FF0C92 - D6FF0C90D3FF1692D0FF47A4CEFF7FB1BFFF869C9DFF6F7A7AFF5C6161FF5051 - 51FF4B4949FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4B4949FF515252FF5D6161FF656D - 6DFF656D6DFF5D6262FF525252FF4B4949FF494747FF494747FF4A4949FF585C - 5CFF93C0D2FFBDE7FBFFBDE7FBFFB7E0F3FF848D8DFF595D5DFF4A4949FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4543 - 43D80000001D0000000800000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000039586840494747E7494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4B4949FF4F4F4FFF595C - 5CFF687171FF7D8D8DFF91ADAEFF83B7C5FF54ABCFFF2799D0FF0C8FD1FF0C90 - D4FF0C92D6FF0D93D8FF0D94DAFF0D95DBFF0D96DCFF0D97DDFF0D97DEFF0D98 - DFFF0D98DFFF0D98DFFF0D98DFFF0D98DFFF0D98DFFF0D97DEFF0D97DEFF0D97 - DDFF0D95DBFF0D95DAFF0D94D9FF0C92D7FF0C91D5FF0C8FD2FF1592D0FF3BA2 - D0FF69ADC7FF8BAEB4FF819393FF6B7676FF5B5F5FFF505151FF4B4A4AFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4C4C4CFF637C87FFAEDCF0FFB8E0 - F2FFB8E0F2FF95A8AFFF5E6464FF4E4E4EFF494747FF494747FF4A4848FF5658 - 58FF8BACB7FFC2E8FBFFC2E8FBFFBCE1F3FF868F8FFF5A5E5EFF4A4949FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF302F - 2F9C000000120000000300000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000001B7AAA1C494747C3494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4A48 - 48FF4E4E4EFF555858FF616767FF707C7CFF829595FF92AEAFFF88B7C3FF63B0 - CDFF3EA2D0FF1F96D0FF0E8FD1FF0C8FD2FF0C90D4FF0C91D5FF0C92D6FF0C92 - D6FF0C92D7FF0C92D7FF0C92D7FF0C92D7FF0C92D7FF0C92D6FF0C91D6FF0C90 - D4FF0C90D3FF0C8ED1FF1491D0FF2C9CD0FF4FA8CEFF72B0C4FF8EAFB4FF8599 - 9AFF738080FF636B6BFF575A5AFF4F4F4FFF4B4949FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4D4C4CFF677E86FFBEE8FBFFC6EA - FCFFC6EAFCFFADC1CAFF6E7979FF545656FF4A4848FF494747FF4C4A4AFF5B5F - 5FFF9DC9D9FFC6EAFCFFC6EAFCFFBFE2F3FF848D8DFF595D5DFF4A4949FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF1C1B - 1B4A000000090000000100000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000001B7AAA0439586887494747FB494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494848FF4C4A4AFF505050FF575A5AFF616767FF6D7878FF7B8B - 8BFF899E9EFF93AFB1FF8EB6BEFF7DB5C5FF69B1CBFF57ACCFFF49A7D0FF3DA2 - D1FF369FD1FF319DD0FF309DD0FF329ED1FF38A0D0FF43A5D1FF4FA9CFFF5FAD - CCFF71B0C6FF85B3BEFF8FAFB3FF8BA1A2FF7D8E8EFF6F7B7BFF626A6AFF585C - 5CFF515252FF4C4B4BFF4A4848FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4C4A4AFF5D6465FFBAE5F8FFCBEC - FCFFCBECFCFFC2E1F0FF899697FF646B6BFF545555FF505151FF565959FF7083 - 87FFC1E8FAFFCBECFCFFCBECFCFFBBD8E5FF7A8484FF565858FF4A4848FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF454343D10000 - 0010000000030000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000083A3A338494747D74947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494848FF4B4A4AFF4E4E4EFF5355 - 55FF595D5DFF606767FF677171FF6F7B7BFF778585FF7D8E8EFF839595FF879B - 9BFF8A9F9FFF8CA1A1FF8CA2A2FF8BA0A0FF889C9CFF849696FF7E8F8FFF7886 - 86FF707D7DFF697272FF626969FF5B5F5FFF545656FF4F4F4FFF4C4A4AFF4A48 - 48FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4A4848FF555858FF9ABECDFFCFED - FCFFCFEDFCFFCFEDFCFFB8D1DCFF869596FF6E7979FF697373FF788B8FFFB8DA - E7FFCFEDFCFFCFEDFCFFCFEDFCFFA9BBC2FF687171FF505151FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF212020590000 - 0007000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000A0D1D1046675 - 757B494747F7494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494848FF4B4949FF4C4B4BFF4F4E4EFF515252FF535555FF565858FF575B - 5BFF595D5DFF5A5E5EFF5A5E5EFF5A5D5DFF585B5BFF565959FF545656FF5152 - 52FF4F4F4FFF4C4C4CFF4B4A4AFF4A4848FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4F4F4FFF68777CFFC2E5 - F4FFD4EFFCFFD4EFFCFFD4EFFCFFCEEAF8FFBCD9E4FFBCDCE8FFD0EDFBFFD4EF - FCFFD4EFFCFFD4EFFCFFC5DEEAFF7F8888FF5A5E5EFF4C4B4BFF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF424040B9000000090000 - 0001000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00006675751C4947479F494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4A4848FF4A4848FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4B4949FF535555FF7688 - 8EFFC6E5F3FFD8F1FDFFD8F1FDFFD8F1FDFFD8F1FDFFD8F1FDFFD8F1FDFFD8F1 - FDFFD8F1FDFFC8DFEBFF869394FF606767FF505050FF4A4848FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF484646EC10101025000000020000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000049474730494747AF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF4C4A4AFF5456 - 56FF687578FF9DB5BDFFC4E1EEFFD9F0FBFFDDF2FDFFDDF2FDFFD6EEF9FFC5DE - E9FFA3B6BBFF778283FF5F6565FF515252FF4B4949FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FB2C2B2B4600000002000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000004947472C4947479B494747F74947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4B4A - 4AFF505050FF585C5CFF626969FF697373FF6D7878FF6E7979FF6C7777FF6770 - 70FF606565FF565959FF4E4E4EFF4A4949FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FB323131580000000200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000494747144947 - 4773494747D7494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4B4A4AFF4E4D4DFF505050FF525353FF525353FF525252FF4F50 - 50FF4D4C4CFF4A4949FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF484646E732303042000000010000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000004947473049474787494747DB494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF464444A82322221500000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000004947472449474768494747A74947 - 47DF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FB484646B04846 - 4634000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000049474714494747444947476C4947478F494747AF494747C7494747DF4947 - 47EB494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747F3494747D3494747A34947476448464618000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFF007FFFFFFFFFFFFFFFFFFFFFFFFFFF800001FFFFFFFFFFFFFFFFFFF - FFFFFF80000001FFFFFFFFFFFFFFFFFFFFFFFC000000003FFFFFFFFFFFFFFFFF - FFFFF00000000007FFFFFFFFFFFFFFFFFFFF800000000001FFFFFFFFFFFFFFFF - FFFE0000000000007FFFFFFFFFFFFFFFFFF80000000000001FFFFFFFFFFFFFFF - FFF000000000000007FFFFFFFFFFFFFFFFC000000000000001FFFFFFFFFFFFFF - FF8000000000000000FFFFFFFFFFFFFFFE00000000000000007FFFFFFFFFFFFF - FC00000000000000001FFFFFFFFFFFFFF800000000000000000FFFFFFFFFFFFF - F0000000000000000007FFFFFFFFFFFFE0000000000000000003FFFFFFFFFFFF - C0000000000000000001FFFFFFFFFFFF80000000000000000000FFFFFFFFFFFF - 000000000000000000007FFFFFFFFFFE000000000000000000003FFFFFFFFFFC - 000000000000000000001FFFFFFFFFF8000000000000000000001FFFFFFFFFF8 - 000000000000000000000FFFFFFFFFF00000000000000000000007FFFFFFFFE0 - 0000000000000000000007FFFFFFFFE00000000000000000000003FFFFFFFFC0 - 0000000000000000000001FFFFFFFF800000000000000000000001FFFFFFFF80 - 0000000000000000000000FFFFFFFF000000000000000000000000FFFFFFFF00 - 00000000000000000000007FFFFFFE0000000000000000000000007FFFFFFE00 - 00000000000000000000003FFFFFFE0000000000000000000000003FFFFFFC00 - 00000000000000000000001FFFFFFC0000000000000000000000001FFFFFF800 - 00000000000000000000001FFFFFF80000000000000000000000000FFFFFF800 - 00000000000000000000000FFFFFF000000000000000000000000007FFFFF000 - 000000000000000000000007FFFFF000000000000000000000000007FFFFF000 - 000000000000000000000003FFFFE000000000000000000000000003FFFFE000 - 000000000000000000000001FFFFE000000000000000000000000001FFFFE000 - 000000000000000000000000FFFFE000000000000000000000000000FFFFE000 - 000000000000000000000000FFFFC0000000000000000000000000007FFFC000 - 0000000000000000000000007FFFC0000000000000000000000000003FFFC000 - 0000000000000000000000003FFFC0000000000000000000000000001FFFC000 - 0000000000000000000000001FFFC0000000000000000000000000001FFFC000 - 0000000000000000000000000FFFC0000000000000000000000000000FFFC000 - 00000000000000000000000007FFC00000000000000000000000000007FFE000 - 00000000000000000000000003FFE00000000000000000000000000003FFE000 - 00000000000000000000000003FFE00000000000000000000000000001FFE000 - 00000000000000000000000001FFE00000000000000000000000000000FFF000 - 00000000000000000000000000FFF00000000000000000000000000000FFF000 - 000000000000000000000000007FF000000000000000000000000000007FF800 - 000000000000000000000000003FF800000000000000000000000000003FF800 - 000000000000000000000000001FFC00000000000000000000000000001FFC00 - 000000000000000000000000001EFC00000000000000000000000000000EFE00 - 000000000000000000000000000EFE000000000000000000000000000006FE00 - 0000000000000000000000000006FF000000000000000000000000000002FF00 - 0000000000000000000000000002FF800000000000000000000000000002FFC0 - 0000000000000000000000000001FFC00000000000000000000000000001FFE0 - 0000000000000000000000000001FFE00000000000000000000000000000FFF0 - 0000000000000000000000000000FFF80000000000000000000000000000FFF8 - 0000000000000000000000000000FFFC0000000000000000000000000000FFFE - 0000000000000000000000000000FFFF0000000000000000000000000000FFFF - 8000000000000000000000000000FFFFC000000000000000000000000000FFFF - E000000000000000000000000000FFFFF000000000000000000000000000FFFF - F800000000000000000000000001FFFFFC00000000000000000000000001FFFF - FE00000000000000000000000001FFFFFF00000000000000000000000003FFFF - FFC0000000000000000000000007FFFFFFE0000000000000000000000007FFFF - FFF800000000000000000000000FFFFFFFFE00000000000000000000001FFFFF - FFFF80000000000000000000003FFFFFFFFFE0000000000000000000007FFFFF - FFFFFC00000000000000000001FFFFFFFFFFFF80000000000000000007FFFFFF - FFFFFFF800000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFF2800000060000000C0000000010020000000 - 0000809400000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000009F9F9F019F9F - 9F019F9F9F010000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000010000 - 000300000006000000080000000B0000000E0000001000000011000000120000 - 00120000001200000011000000100000000D0000000A00000007000000050000 - 0002000000010000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000100000003000000070000000D000000140000 - 001B00000021000000280000002D000000320000003500000037000000370000 - 0037000000370000003700000034000000300000002C000000250000001F0000 - 0018000000100000000A00000005000000020000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000002000000070000000F00000019000000240000002F000000390000 - 0040000000460000004B0000004E000000500000005200000052000000530000 - 0053000000530000005200000051000000500000004D00000049000000440000 - 003D000000340000002A0000001E000000130000000A00000004000000010000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000025242401030303040000 - 000B0000001700000025000000330000004000000049030303530F0F0F711B1A - 1A8B292828A9302E2EC13D3B3BD4424040E1464444EF464444EF464444EF4644 - 44EF464444EF434141E53E3C3CD7323030C4292828AD1D1C1C900F0F0F750404 - 045B000000520000004C00000045000000390000002C0000001D000000100000 - 0007141313020000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000050505040000000D0000001A0000 - 002B0000003B01010149090909621F1E1E92343333C4413F3FE9474545F84947 - 47FE494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF484646FE474545F94140 - 40EA353434C5201F1F960B0A0A6A010101540000004C00000041000000320000 - 0022000000130202020716161602000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000D0D0D020000000A000000190000002C0000003E0302 - 024E1D1C1C8C363535CB474545F6494747FF494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF474545F6363535CB1B1B1B8C030303590000004F0000 - 0045000000350000002100000011000000062322220100000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00001B1A1A010000000700000015000000290000003D0A0A0A5F282626A64543 - 43EE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE444242ED262525A60A0A - 0A680000005100000045000000330000001E0000000C03030303000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000606 - 06030000000D0000001F0000003608080857292828A6454343F1484646FE4846 - 46FE494747FF494747FF484646FE494747FF494747FF494747FF484646FE4947 - 47FF494747FF494747FE494747FF494747FF494747FE494747FF494747FF4947 - 47FE494747FF494747FF494747FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF484646FE494747FF4442 - 42EF2A2929AB070707620000004E000000400000002A00000014030303062C31 - 3101000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000B0F0F050000 - 0013000000290000004022212192424040E9484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE494747FE494747FE4A49 - 49FE4D4C4CFE505050FE535555FE565959FE595D5DFE5B5F5FFE5B5F5FFE5A5E - 5EFE585B5BFE555757FE515353FE4E4F4FFE4C4B4BFE4A4848FE494747FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE414040E91F1E1E940101015500000048000000340000001D0000 - 0009324343020000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000596B6B0100000008000000190000 - 0033101010663B3939D1494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FF494747FE4A4949FF4E4E4EFF565858FF616767FE6C78 - 78FF728689FF6F909AFE6796A6FF619AB0FF5D9DB7FE5B9EBAFF5A9FBBFF5A9D - B9FE5D9BB5FF6098ADFF6692A2FE6D8C95FF6F8184FF687171FE5C6161FF5354 - 54FF4C4C4CFE4A4848FF494747FF484646FE494747FF484646FE494747FF4947 - 47FF484646FE494747FF484646FE3A3838D30E0E0E6F0000004F0000003E0000 - 00240000000E1A23230300000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000073737301000000090000001D0201013A2121 - 2190454343F1484646FE494747FF494747FF484646FE494747FF494747FF4947 - 47FE4A4848FF4E4D4DFF575A5AFE666F6FFF71868AFF6B98A7FF529CBCFE3B9D - CAFF2D9BD1FF299CD6FE299DD9FF2A9FDBFF2CA0DCFE2DA1DCFF2EA1DCFF2DA1 - DCFE2BA0DBFF2A9EDAFF289DD8FE289BD5FF2B99CFFF3B9AC7FE5198B6FF6890 - 9EFF6B7D80FE606666FF535555FF4C4A4AFE494747FF494747FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE444242F0201F1F95010101540000 - 00430000002A000000112B2B2B03000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000073737301000000090000001F04040442302F2FB44846 - 46FE484646FE484646FE484646FE484646FE484646FE494747FE4A4848FE4F4E - 4EFE5C6161FE717F80FE7099A6FE499DC3FE309CD1FE269BD7FE2BA0DBFE30A4 - DFFE32A6E1FE34A8E3FE36A9E4FE37AAE5FE38ABE6FE39ABE6FE39ABE6FE39AB - E6FE38ABE6FE37AAE5FE36A9E4FE34A8E2FE32A6E1FE30A3DEFE299FDBFE249A - D6FE2F99CDFE4998BAFE6C8F9AFE687272FE565959FE4C4B4BFE494747FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FC2F2D2DB80404 - 0458000000460000002D00000012070707040000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000006B6B6B010000000A000000200B0B0B503B3A3AD2484646FE4947 - 47FF494747FF484646FE494747FF494747FF494848FE4F4F4FFF5E6363FF7386 - 89FE649FB5FF389ECEFF239AD7FE2CA1DDFF2FA4E0FF32A7E3FF35AAE6FE37AC - E8FF39AEEAFF3BAFEBFE3CB1ECFF3DB1EDFF3DB1EDFE3EB2EDFF3EB2EDFF3EB2 - EDFE3EB2EDFF3EB1ECFF3DB1ECFE3CB0EBFF3BAFEAFF39ADE8FE36AAE6FF33A8 - E3FF30A5E0FE2AA0DCFF1F98D6FF399AC8FE6294A6FF6A797BFE565959FF4C4B - 4BFF494747FE494747FF494747FF484646FE494747FF494747FF484646FE3A38 - 38D209090965000000490000002F0000001301131C0400000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000090000001F0C0C0C51403F3FE0494747FE484646FE4947 - 47FF494747FF484646FE494747FF4C4B4BFF575B5BFE708081FF679DB1FF359C - CDFE259CD9FF2BA1DEFF2FA6E2FE32A9E6FF35ACE9FF38AEEBFF39B0ECFE3BB1 - EEFF3CB2EFFF3DB3EFFE3DB4F0FF3EB4F0FF3EB4F0FE3FB4F0FF3FB5F1FF3FB4 - F1FE3FB5F1FF3FB4F0FF3FB4F0FE3EB3EFFF3EB3EFFF3DB2EDFE3BB1ECFF39AF - EBFF37ACE8FE34A9E6FF30A6E2FF2AA1DDFE239AD7FF3398C8FE6591A1FF6570 - 71FF525353FE4A4848FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF3D3C3CDD0B0B0B6A000000480000002E00000012202B2B03000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000060000001B0C0C0C4F3F3E3EDD484646FE484646FE484646FE4846 - 46FE484646FE494747FE4F5050FE646B6BFE77979FFE409EC9FE239AD7FE28A0 - DDFE2CA5E3FE30A9E7FE33ACEAFE36AEECFE38B0EEFE39B1EFFE39B2F0FE3BB3 - F0FE3BB3F1FE3CB4F1FE3CB4F1FE3CB4F1FE3DB4F1FE3DB5F1FE3DB5F1FE3DB5 - F1FE3DB5F1FE3DB5F1FE3EB5F1FE3EB5F1FE3EB4F1FE3DB4F0FE3DB3F0FE3CB2 - EFFE3AB1EEFE38AFECFE36ADEAFE32A9E6FE2EA5E2FE29A0DDFE2098D4FE4297 - BEFE6E878CFE595D5DFE4C4B4BFE494747FE484646FE484646FE484646FE4846 - 46FE484646FE413F3FE60B0A0A6A000000470000002B0000000F202B2B020000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000080B - 0B04000000160C0C0C4B413F3FE0484646FE494747FF494747FF484646FE4947 - 47FF4A4949FF545757FE718182FF61A1BAFF2699D3FE259EDCFF29A3E1FF2DA8 - E6FE31ABEAFF33AEECFF35AFEEFE37B1EFFF37B2F0FF38B2F1FF38B3F1FE38B3 - F2FF39B3F2FF39B3F1FE39B3F2FF3AB3F2FF3AB3F1FE3AB4F2FF3AB4F2FF3AB4 - F1FE3AB4F2FF3BB4F2FF3BB4F1FE3BB4F2FF3BB4F2FF3BB4F1FE3BB4F1FF3BB4 - F1FF3AB3F0FE39B2F0FF39B1EEFF37AFECFE34ACEAFF30A9E6FE2BA4E1FF249D - DAFF2497D0FE6094A8FF646E6EFF4F4F4FFE494747FF494747FF484646FE4947 - 47FF494747FF484646FE3F3D3DE00A0A0A6900000045000000260000000C506B - 6B01000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000002C3B3B020000 - 0011050505373D3B3BD4494747FF484646FE494747FF494747FF494747FE4B4A - 4AFF5A5E5EFF778C8FFE49A0C6FF219AD7FF259FDEFE29A5E4FF2CA9E9FF2FAC - ECFE31AEEEFF33AFEFFF33B0F0FE34B1F1FF35B1F1FF35B2F2FF35B2F1FE36B2 - F2FF36B2F2FF36B2F1FE37B2F2FF37B2F2FF37B2F1FE37B3F2FF37B3F2FF37B2 - F1FE38B3F2FF38B3F2FF38B3F1FE38B3F2FF38B3F2FF38B3F1FE38B3F2FF39B3 - F2FF38B3F1FE38B3F1FF38B2F0FF38B1EFFE36B0EEFF34AEECFE30AAE9FF2CA6 - E4FF27A0DEFE1E97D4FF4C97B8FF6A797BFE515252FF4A4848FF494747FE4947 - 47FF494747FF484646FE494747FF3C3A3AD7070707600000003F000000200000 - 0008000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000000000B0202 - 022A333131B6484646FE484646FE484646FE484646FE494747FE4B4A4AFE5D61 - 61FE79959BFE3B9DCBFE1F9AD8FE24A0E0FE28A6E6FE2AAAEAFE2DACEDFE2FAE - EFFE30AFF0FE30AFF0FE31B0F0FE31B0F0FE31B0F0FE32B0F1FE32B0F1FE32B0 - F1FE32B0F1FE33B1F1FE33B1F1FE33B1F1FE33B1F1FE34B1F1FE34B1F1FE34B1 - F1FE34B1F1FE35B1F1FE35B1F1FE35B1F1FE35B1F1FE35B2F1FE36B2F1FE36B2 - F1FE36B2F1FE36B2F1FE36B2F1FE36B2F1FE35B1F0FE34B0EFFE32AEEDFE2FAB - EAFE2BA7E6FE27A1E0FE1E98D7FE3B97C2FE6E7F81FE535555FE4A4848FE4846 - 46FE484646FE484646FE484646FE484646FE353434C801010152000000380000 - 0018040404040000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000050000001C2726 - 268E494747FF484646FE494747FF484646FE494747FF4B4A4AFF5D6363FE789B - A4FF2F9BCFFF1E9ADAFE22A1E2FF26A6E8FF28A9EBFE2AACEDFF2BADEFFF2CAE - F0FE2DAFF1FF2DAFF1FF2DAFF0FE2DAFF1FF2EAFF1FF2EAFF1FF2EAFF0FE2FAF - F1FF2FAFF1FF2FAFF0FE2FAFF1FF2FAFF1FF30AFF0FE30B0F1FF30B0F1FF30B0 - F0FE31B0F1FF31B0F1FF31B0F0FE31B0F1FF31B0F1FF32B0F0FE32B0F1FF32B0 - F1FF32B0F1FE32B0F1FF33B1F1FF33B0F1FE33B1F1FF32B0F0FE32AFF0FF30AE - EEFF2EABEBFE2AA7E7FF26A2E1FF1E99D9FE3197C7FF6C8489FF545656FE4A48 - 48FF494747FF484646FE494747FF494747FF484646FE292828A90000004D0000 - 00300000000F1312120200000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000002B373702000000111616165E4644 - 44F4494747FF484646FE494747FF494747FE4B4A4AFF5C6161FF78989FFE2D9B - CFFF1C9ADAFF20A0E2FE24A6E8FF26A9EBFF27ABEEFE28ACEFFF29ADF0FF29AD - F0FE29ADF1FF2AADF1FF2AADF0FE2AAEF1FF2AAEF1FF2BAEF1FF2AAEF0FE2BAE - F1FF2BAEF1FF2BAEF0FE2CAEF1FF2CAEF1FF2CAEF0FE2CAFF1FF2DAFF1FF2DAE - F0FE2DAFF1FF2DAFF1FF2EAFF0FE2EAFF1FF2EAFF1FF2EAFF0FE2EAFF1FF2FAF - F1FF2FAFF0FE2FAFF1FF2FB0F1FF2FAFF0FE30B0F1FF30AFF0FE2FAFF0FF2FAE - F0FF2EADEEFE2BABECFF28A7E8FF24A1E2FE1C99D9FF3296C6FF6B8287FE5253 - 53FF494747FF484646FE494747FF494747FF484646FE474545F8181717830000 - 0044000000220101010800000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000008050505283F3E3EDB4846 - 46FE484646FE484646FE484646FE4A4848FE575A5AFE799397FE359CCDFE1A99 - D9FE1D9FE1FE21A4E8FE23A8ECFE25AAEEFE25ABEFFE26ACF0FE26ACF0FE26AC - F0FE27ACF0FE27ACF0FE27ACF0FE27ACF0FE27ACF0FE28ACF0FE28ACF0FE28AC - F0FE28ADF0FE28ADF0FE28ADF0FE28ADF0FE28ADF0FE29ADF0FE29ADF0FE29AD - F0FE29ADF0FE29ADF0FE2AADF0FE2AADF0FE2AAEF0FE2AAEF0FE2BAEF0FE2BAE - F0FE2BAEF0FE2BAEF0FE2CAEF0FE2CAEF0FE2CAEF0FE2CAEF0FE2CAEF0FE2CAE - F0FE2CADEFFE2BACEEFE29AAECFE26A6E8FE22A0E1FE1B98D9FE3897C4FE6C79 - 7BFE505050FE494747FE484646FE484646FE484646FE484646FE403E3EE30706 - 065D000000370000001606060603000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000A090903000000172B2A2A98494747FF4947 - 47FF494747FF484646FE494747FF525454FE778B8DFF43A0CAFF1797D8FE1A9E - E1FF1DA3E8FF20A7EBFE21A9EEFF22AAEFFF23AAEFFE23ABF0FF23ABF0FF23AB - F0FE24ABF0FF24ABF0FF24ABF0FE24ABF0FF24ABF0FF25ABF0FF25ABF0FE25AB - F0FF25ABF0FF25ABF0FE26ACF1FF26ACF1FF26ACF0FE26ACF1FF26ACF1FF27AC - F0FE27ACF1FF27ACF1FF27ACF0FE27ACF1FF27ACF1FF28ACF0FE28ACF1FF28AC - F1FF457995FE3C8CB5FF2EA4E1FF28ADF0FE29ADF1FF29ADF0FE29ADF1FF29AD - F1FF29ADF0FE29ACF0FF28ABEEFF27A9EBFE23A5E7FF1F9FE1FF1896D7FE4798 - BBFF667172FF4D4D4DFE494747FF494747FF484646FE494747FF494747FF302E - 2EB800000049000000290000000B000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000A11111148464444F2494747FF4947 - 47FF494747FF494747FE4E4E4EFF6D7878FE59A4C3FF1696D6FF189CDFFE1BA2 - E7FF1DA5EBFF1EA7EDFE1FA8EFFF238BBFFF2F7295FE377B9EFF3B7FA1FF3C7F - A2FE3C7FA2FF3C7FA2FF3C7FA2FE2A9AD3FF21AAF0FF21AAF0FF22AAEFFE22AA - F0FF22AAF0FF22AAEFFE22ABF0FF22ABF0FF23AAF0FE23ABF0FF23ABF0FF23AB - F0FE23ABF0FF24ABF0FF24ABF0FE24ABF0FF24ABF0FF24ABF0FE25ABF0FF2F98 - CEFF585757FE5A5859FF565F63FF48768DFE3692C2FF29A6E7FE26ACF1FF26AC - F1FF27ACF0FE27ACF1FF26ABF0FF25AAEEFE24A8EBFF20A3E6FF1C9DDEFE1795 - D4FF5A94ACFF5D6363FE4A4949FF494747FF484646FE494747FF494747FF4846 - 46FB121212740000003C00000019090808030000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000200000016353434B6484646FE484646FE4846 - 46FE484646FE4B4949FE5F6565FE75A2AFFE1794D3FE1599DCFE179FE4FE1AA4 - EAFE1BA6EDFE1CA7EEFE1CA8EFFE1F92CDFE33393DFE474646FE525050FE5453 - 53FE545353FE545353FE545353FE44677AFE1FA6EBFE1EA9EFFE1EA9EFFE1EA9 - EFFE1FA9EFFE1FA9EFFE1FA9EFFE1FA9EFFE1FA9EFFE20A9EFFE20A9EFFE20A9 - EFFE20AAEFFE20AAEFFE21AAEFFE21AAEFFE21AAEFFE21AAEFFE22AAEFFE3F73 - 8EFE575656FE585656FE585656FE585656FE585757FE52616AFE417C9BFE2E9A - D1FE23ABF0FE23ABF0FE23ABF0FE23AAEFFE22A9EDFE21A6EAFE1DA1E5FE199A - DCFE1E94CFFE6B8B94FE535454FE494747FE484646FE484646FE484646FE4846 - 46FE383636CE0202024E0000002A0000000A0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000819181859484646F9484646FE494747FF4947 - 47FF494747FF545656FE799295FF309CCFFE1397DAFF159DE3FF17A2E9FE18A5 - EDFF19A6EFFF19A7EFFE19A7F0FF1AA7EFFF236282FE3A3939FF4B4949FF514F - 4FFE535151FF535151FF535151FE515051FF2D88B7FF1BA8F0FF1CA8EFFE1CA8 - F0FF1CA8F0FF1CA8EFFE1CA8F0FF1CA8F0FF1DA8EFFE1DA8F0FF1DA8F0FF1DA8 - EFFE1DA8F0FF1DA8F0FF1EA8EFFE1EA9F0FF1EA9F0FF1EA8EFFE239EDDFF4E57 - 5CFF565454FE565454FF565454FF565454FE565454FF565454FE565454FF5755 - 55FF4E626EFE3A82A7FF299CD7FF21A9EFFE20A9EEFF1FA7ECFF1DA4E9FE1A9F - E2FF1697D9FF3698C6FE697576FF4D4D4DFF494747FE494747FF494747FF4846 - 46FE484646FE1A1919840000003B000000151312120200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000002000000123B3939BE494747FF484646FE494747FF4947 - 47FF4C4B4BFF6B7575FE5BA4C1FF1193D6FE139AE0FF15A0E7FF16A3ECFE16A5 - EEFF16A6EFFF16A6EFFE17A6F0FF17A6F0FF189CE0FE2C363BFF413F3FFF4D4B - 4BFE504E4EFF514F4FFF514F4FFE514F4FFF465B67FF1CA1E5FF19A7EFFE19A7 - F0FF19A7F0FF19A7EFFE19A7F0FF19A7F0FF1AA7EFFE1AA7F0FF1AA7F0FF1AA7 - EFFE1AA7F0FF1AA8F0FF1BA8EFFE1BA8F0FF1BA8F0FF1BA8EFFE317FA7FF5250 - 50FF535252FE545252FF545252FF535252FE545252FF545252FE545353FF5453 - 53FF545252FE545353FF505559FF3D5F71FE2488BBFF1DA7EEFF1CA6EBFE1AA1 - E7FF169BDFFF1293D4FE5D94AAFF5A5E5EFF4A4848FE494747FF494747FF4846 - 46FE494747FF393737D00101014A000000240101010800000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000611111142484646FC494747FF484646FE494747FF4947 - 47FF565959FF7C9CA3FE1F96D1FF1096DBFE129DE4FF13A1EAFF14A4EDFE14A5 - EEFF14A5EFFF15A5EFFE15A6EFFF15A6EFFF15A5EFFE1D6B92FF343333FF4644 - 44FE4E4C4CFF4F4D4DFF4F4D4DFE4F4D4DFF4E4D4DFF2F7BA2FF16A6EFFE17A6 - F0FF17A6F0FF17A6EFFE17A6F0FF17A6F0FF17A6EFFE17A6F0FF17A7F0FF17A6 - EFFE17A7F0FF18A7F0FF18A7EFFE18A7F0FF18A7F0FF19A4EBFE435C69FF514F - 4FFF525050FE525050FF525050FF525050FE525050FF525050FE525050FF5250 - 50FF525050FE525050FF4E4C4CFF3E3D3DFE23749DFF1AA7EFFF1AA6EDFE19A3 - EAFF169FE4FF1497DBFE2795CBFF6B7E82FF4E4E4EFE494747FF494747FF4846 - 46FE494747FF474545F914131375000000320000001022212101000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000D343232A5484646FE484646FE484646FE494747FE4D4C - 4CFE6C7777FE53A5C7FE0E93D6FE0F9AE0FE119FE7FE12A2ECFE12A3EEFE12A4 - EEFE13A4EEFE13A4EEFE13A4EEFE13A4EEFE13A4EEFE149DE4FE253C49FE3B39 - 39FE494747FE4D4B4BFE4D4B4BFE4D4B4BFE4D4B4BFE494E52FE1A9BDDFE15A5 - EFFE15A5EFFE15A5EFFE15A5EFFE15A5EFFE15A5EFFE16A5EFFE16A5EFFE16A5 - EFFE16A5EFFE16A5EFFE16A5EFFE16A6EFFE16A6EFFE248BC0FE4C4D4EFE4F4D - 4DFE4F4D4DFE4F4D4DFE4F4D4DFE4E4C4CFE4C4A4AFE4D4B4BFE4F4D4DFE504E - 4EFE514F4FFE504E4EFE464545FE32383CFE19A0E5FE18A6EFFE18A6EEFE17A4 - ECFE16A0E8FE139AE0FE0F92D5FE5696B1FE5C6161FE494747FE484646FE4846 - 46FE484646FE484646FE313030BB000000410000001C00000005000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000209090928464444EA494747FF494747FF484646FE494747FF5658 - 58FF809CA1FF1A94D1FE0E96DBFF0E9CE4FE10A0EAFF10A2EDFF10A3EEFE11A4 - EFFF11A4EFFF11A4EEFE11A4EFFF11A4EFFF11A4EEFE11A4EFFF1777A8FF2D2D - 2EFE413F3FFF4B4949FF4C4A4AFE4C4A4AFF4C4A4AFF4C4A4AFF336C89FE13A4 - EDFF13A4EFFF13A4EEFE13A5EFFF13A5EFFF13A5EEFE13A5EFFF13A5EFFF13A5 - EEFE14A5EFFF14A5EFFF14A5EFFE14A5EFFF14A5EFFF36667FFE4D4B4BFF4E4C - 4CFF4E4C4CFE4E4C4CFF4D4B4BFF474545FE3E3C3CFF3D3B3BFE434242FF4947 - 47FF4C4A4AFE4B4949FF3D3C3CFF235C79FE16A6EFFF16A6EFFF16A5EFFE15A4 - EDFF14A1EAFF129DE4FE0F96DAFF2695CBFF6C7E81FE4D4C4CFF494747FF4846 - 46FE494747FF494747FF474545F5050505520000002B0000000C000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000005201F1F68484646FE494747FF494747FF484646FE4B4A4AFF676F - 6FFF60A6C1FF0C91D6FE0D98E0FF0E9EE7FE0FA1ECFF0FA2EEFF0FA3EEFE0FA3 - EFFF0FA3EFFF0FA3EEFE10A4EFFF10A4EFFF10A3EEFE10A4EFFF109FE8FF1F42 - 54FE373535FF454343FF4A4848FE4A4848FF4A4848FF4A4848FF474A4DFE1C90 - CCFF11A4EFFF11A3EEFE11A4EFFF11A4EFFF11A4EEFE11A4EFFF11A4EFFF11A4 - EEFE11A4EFFF12A4EFFF12A4EEFE12A4EFFF169BDFFF474A4CFE4C4A4AFF4C4A - 4AFF4C4A4AFE4C4A4AFF4A4848FF3D3B3BFE2C2A2AFF272626FE2D2C2CFF3635 - 35FF3E3C3CFE3F3D3DFF313335FF1887BFFE14A5EFFF14A5EFFF14A5EEFE13A4 - EEFF12A2EBFF109EE7FE0E98DEFF0F91D4FF6094A9FE565959FF494747FF4846 - 46FE494747FF494747FF484646FE1E1D1D8E0000003B00000017121111020000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000A3B3939B8484646FE484646FE484646FE494747FE515151FE7A8F - 91FE2D9BCFFE0C95DAFE0D9BE3FE0D9FE9FE0EA1EDFE0EA2EEFE0EA2EEFE0EA2 - EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2EEFE1283 - BDFE2A292AFE3D3C3CFE484646FE494747FE494747FE494747FE494747FE385E - 72FE10A1EBFE0FA3EEFE0FA3EEFE0FA3EEFE0FA3EEFE0FA3EEFE0FA3EEFE10A3 - EEFE10A3EEFE10A3EEFE10A3EEFE10A3EEFE28769EFE494747FE4A4848FE4A48 - 48FE4A4848FE4A4848FE444242FE313132FE186A93FE174A64FE1C2428FE2120 - 20FE272626FE292828FE203F50FE12A2ECFE12A4EEFE12A4EEFE12A4EEFE11A3 - EEFE10A2EDFE0F9FE9FE0E9AE2FE0D94D9FE3698C6FE666F6FFE4B4A4AFE4846 - 46FE484646FE484646FE484646FE3B3939D70202024C00000026000000080000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000C0C0C22464444EA484646FE494747FF494747FF494747FE5B5F5FFF77A4 - B1FF1092D3FF0C97DEFE0D9DE6FF0DA0EBFE0EA2EEFF0EA3EFFF0EA2EEFE0EA3 - EFFF0EA3EFFF0EA2EEFE0EA3EFFF0EA3EFFF0EA2EEFE0EA3EFFF0EA3EFFF0EA2 - EEFE1B4A62FF323131FF434141FE494747FF494747FF494747FF494747FE4748 - 49FF2183B5FF0EA2EEFE0FA3EFFF0FA3EFFF0FA3EEFE0FA3EFFF0FA3EFFF0FA3 - EEFE0FA3EFFF0FA3EFFF0FA3EEFE119FE7FF3B5461FF494747FE4A4848FF4A48 - 48FF4A4848FE484646FF3E3C3CFF254150FE109FE7FF10A3EDFE1192D4FF1461 - 88FF192F3BFE1B1C1DFF146E9CFF10A3EEFE10A4EFFF10A4EFFF10A3EEFE10A3 - EFFF0FA2EEFF0FA0EBFE0D9CE5FF0D96DCFF1291D1FE70898FFF505050FF4947 - 47FE494747FF494747FF484646FE484646FC1514147700000036000000121616 - 1602000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000219191951484646FC484646FE494747FF494747FF4A4949FE6A7373FF5AA6 - C5FF0C92D6FF0C99E1FE0D9EE8FF0DA1ECFE0EA2EEFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE108AC8FF262C30FF3A3939FE464444FF484646FF494747FF484646FE4846 - 46FF3E525DFF0FA0EAFE0EA3EFFF0EA3EFFF0EA2EEFE0EA3EFFF0EA3EFFF0EA2 - EEFE0EA3EFFF0EA3EFFF0EA2EEFE1B8AC4FF474647FF494747FE4A4848FF4A48 - 48FF494747FE454343FF363434FF196891FE0FA3EFFF0EA2EEFE0FA3EFFF0FA3 - EFFF0F9EE7FE117BB2FF0F9AE1FF0FA3EEFE0FA3EFFF0FA3EFFF0FA3EEFE0FA3 - EFFF0EA2EEFF0EA1ECFE0D9EE7FF0D98E0FF0C91D5FE5C96ACFF585C5CFF4947 - 47FE494747FF494747FF484646FE494747FF323131BF000000440000001F0505 - 0506000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00032B2A2A8B484646FE484646FE484646FE494747FE4E4E4EFE7B8D8EFE309B - CEFE0C94DAFE0D9BE4FE0D9FEAFE0DA1EDFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE18597BFE2F2E2EFE424040FE484646FE484646FE484646FE4846 - 46FE484646FE2777A0FE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE30637DFE484646FE484646FE484646FE4846 - 46FE484646FE3F3E3EFE2B2D2FFE0F97DCFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2 - EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2EEFE0EA2 - EEFE0DA2EEFE0DA1EDFE0D9FE9FE0D9AE3FE0C94D9FE3B97C2FE646D6DFE4A48 - 48FE484646FE484646FE484646FE484646FE454343F40D0C0C65000000300000 - 000F252424010000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00063F3E3EBB494747FF484646FE494747FF494747FF545656FE7E9FA6FF1994 - D2FF0D96DDFF0D9CE5FE0EA0EBFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0F93D7FF233037FE393737FF454444FF484646FF484646FE4947 - 47FF494747FF414E55FE1497DBFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF1397DBFE414B50FF484646FF484646FE494747FF4947 - 47FF464444FE393737FF1F4D65FF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA0EAFF0D9CE4FF0C95DBFE2295CDFF6C7E82FF4C4C - 4CFE494747FF494747FF484646FE494747FF494747FE282727A60000003F0000 - 001B030303040000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0008474545E4494747FF484646FE494747FF494747FF5B6060FE74A7B7FF0F92 - D4FF0D98DFFF0D9EE7FE0EA1ECFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF16658DFE2E2D2DFF403E3EFF484646FF484646FE4947 - 47FF494747FF484646FE2E6B8BFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF237AA7FE474545FF494747FF484646FE494747FF4846 - 46FF434141FE313131FF147AAEFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA1EBFF0D9DE6FF0C97DDFE1292D2FF6C8C96FF5051 - 51FE494747FF494747FF484646FE494747FF494747FF444242EB0302024E0000 - 002A0000000B0000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000D0D - 0D16484646FE484646FE484646FE484646FE4A4848FE646B6BFE64A9C3FE0C92 - D6FE0C99E1FE0D9EE8FE0DA1EDFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0E9EE7FE21333CFE363535FE454343FE484646FE4846 - 46FE484646FE484646FE45494CFE198ECAFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0EA2EEFE395463FE484646FE484646FE484646FE484646FE4745 - 45FE3D3B3BFE263944FE0E9CE5FE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA1ECFE0D9DE7FE0C98E0FE0C91D4FE6395A8FE5557 - 57FE484646FE484646FE484646FE484646FE484646FE484646FE1F1E1E8E0000 - 003A000000160D0D0D0200000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001818 - 1834494747FF494747FF484646FE494747FF4B4A4AFF6C7777FE51A7CBFF0C93 - D8FF0D9AE2FF0D9FE9FE0EA1EDFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF0DA2EEFE1472A2FF2B2B2CFF3E3D3DFF474545FE4947 - 47FF494747FF484646FE484646FF365E73FF0EA2EDFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF1790CEFF454445FE484646FF494747FF484646FE484646FF4543 - 43FF363434FE1A5F83FF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA1EDFF0D9EE8FF0C99E1FE0C92D6FF5497B4FF5A5F - 5FFE494747FF494747FF484646FE494747FF494747FF484646FE3A3838D20202 - 024B000000250000000800000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001A19 - 194B494747FF494747FF484646FE494747FF4D4C4CFF748181FE40A3CFFF0C94 - D9FF0D9BE3FF0D9FE9FE0EA2EDFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF0DA2EEFE0E9EE8FF1E3D4EFF343333FF444242FE4846 - 46FF494747FF484646FE494747FF474546FF1D87BDFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF2A6C8FFF484646FE494747FF494747FF484646FE484646FF413F - 3FFF2D2F30FE118BCAFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA1EDFF0D9FE9FF0D9AE2FE0C93D8FF4798BCFF5F66 - 66FE494747FF494747FF484646FE494747FF494747FF484646FE484646FB1312 - 127300000035000000111A191901000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001B1A - 1A60484646FE484646FE484646FE484646FE4E4E4EFE7A8A8AFE349FD1FE0C95 - DAFE0D9BE4FE0D9FEAFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE1280B9FE282A2BFE3D3B3BFE4745 - 45FE484646FE484646FE484646FE484646FE3C5563FE109DE5FE0DA2EEFE0DA2 - EEFE109DE4FE3C4F59FE484646FE484646FE484646FE484646FE464444FE3A39 - 39FE21465AFE0EA0EBFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0D9FE9FE0D9AE3FE0C94D9FE3E99C3FE646C - 6CFE494747FE484646FE484646FE484646FE484646FE484646FE484646FE312F - 2FBD000000440000001F03030306000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001B1A - 1A64494747FF494747FF484646FE494747FF4F4F4FFF7F9090FE2A9BD2FF0C95 - DBFF0D9BE5FF0DA0EAFE0EA2EEFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA0EBFF1B4B63FF323131FE4341 - 41FF484646FF484646FE494747FF494747FF484646FE2679A4FF0EA3EFFF0DA2 - EEFE1B87BFFF454444FF484646FE494747FF494747FF484646FE434242FF3331 - 31FF1672A1FE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA2EEFF0E9FEAFF0D9BE4FE0C94D9FF3799C6FF6771 - 71FE4A4848FF494747FF484646FE494747FF494747FF484646FE494747FF4543 - 43F20C0C0C630000002F0000000E292727010000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001B1A - 1A64494747FF494747FF484646FE494747FF505050FF819393FE279AD1FF0C95 - DBFF0D9CE5FF0DA0EAFE0EA2EEFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF108CCCFF27282AFE3B39 - 39FF464444FF484646FE494747FF494747FF484646FE414E56FF1399DDFF0DA2 - EEFE2B6A8BFF474545FF484646FE494747FF494747FF484646FE3E3D3DFF2930 - 34FF0E9CE4FE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA2EEFF0E9FEAFF0D9BE4FE0C94D9FF3498C7FF6973 - 73FE4A4848FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF262525A20000003E0000001A060606040000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001B1A - 1A64484646FE484646FE484646FE484646FE505050FE819393FE289AD1FE0C95 - DBFE0D9BE5FE0DA0EAFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE185878FE302E - 2EFE414040FE484646FE484646FE484646FE484646FE484646FE2F6B8BFE0FA0 - E9FE3E515CFE484646FE484646FE484646FE484646FE454343FE373636FE1C56 - 74FE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0D9FEAFE0D9BE4FE0C94D9FE3599C7FE6973 - 73FE4A4848FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE444242EA0202024E0000002A0000000B0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001B1A - 1A63494747FF494747FF484646FE494747FF4F4F4FFF7F9090FE2D9DD2FF0C95 - DBFF0D9BE4FF0DA0EAFE0EA2EEFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0EA3EFFF0F92D4FE242F - 36FF393737FF464444FE484646FF494747FF484646FE494747FF46494CFF2381 - B1FE46494BFF494747FF484646FE494747FF484646FF424040FE2F3032FF1382 - BCFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA2EEFF0E9FEAFF0D9BE3FE0C94D9FF3999C6FF6770 - 70FE4A4848FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE1B1B1B880000003A000000161312120200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001B1A - 1A5E494747FF494747FF484646FE494747FF4E4E4EFF7A8989FE38A0D1FF0C95 - DAFF0D9BE4FF0D9FEAFE0EA2EEFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0EA3EFFF0DA2EEFE1662 - 89FF2E2C2CFF413F3FFE484646FF494747FF484646FE494747FF494747FF454B - 4FFE494747FF494747FF484646FE494747FF474545FF3B3A3AFE243D4AFF0E9F - EAFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA2EDFF0E9FE9FF0D9AE3FE0C93D9FF419AC2FF646C - 6CFE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE393737CF0202024A000000240000000700000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001A1A - 1A48484646FE484646FE484646FE484646FE4C4C4CFE738080FE47A5CFFE0C94 - D9FE0C9AE3FE0D9FE9FE0DA1EDFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0FA3EFFE149B - E1FE293D48FE414040FE504E4EFE555353FE565454FE575555FE575555FE5654 - 54FE565454FE555353FE535151FE514F4FFE4B4949FE373636FE196B94FE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA1EDFE0D9FE8FE0C9AE2FE0C93D7FE4D9ABBFE5F65 - 65FE494747FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FB1212127200000035000000111D1C1C01000000000000 - 0000000000000000000000000000000000000000000000000000000000001A19 - 1931494747FF494747FF484646FE494747FF4B4A4AFF6B7575FE59A9CAFF0C93 - D7FF0D99E2FF0D9EE9FE0EA1EDFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF0EA3EFFF0EA3EEFE10A4EFFF17A6EFFF1FA9F0FF24ABF0FE25AB - F0FF2B7FAAFF413F3FFE515050FF595858FF5B5959FE5B5959FF5B5959FF5B59 - 59FE5B5959FF5B5959FF5B5959FE5A5858FF535151FF3F4549FE269BD8FF1EA9 - F0FF16A6EFFE10A3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA1ECFF0D9EE8FF0C99E1FE0C92D6FF5C9AB2FF5A5E - 5EFE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF302E2EB9000000430000001E04040405000000000000 - 0000000000000000000000000000000000000000000000000000000000000F0F - 0F0F494747FF494747FF484646FE494747FF4A4848FF626A6AFE6CACC3FF0C92 - D6FF0D98E0FF0D9EE8FE0EA1ECFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2 - EEFE0EA3EFFF12A4EFFF1FA9F0FE28ADF0FF2BAEF1FF2BAEF1FF2BAEF0FE2BAE - F1FF2BACEEFF3A525FFE4E4C4CFF5B5959FF5F5D5DFE5F5D5DFF5F5D5DFF5F5D - 5DFE5F5D5DFF5F5D5DFF5F5D5DFE5D5B5BFF525050FF3A6378FE2BADEFFF2BAE - F1FF2BAEF0FE27ACF0FF1EA9F0FF11A4EFFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA1ECFF0D9DE7FF0C98DFFE0D91D4FF6A96A5FF5456 - 56FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF444242F00A09095F0000002E0000000D222121010000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0001484646E6484646FE484646FE484646FE494747FE5A5E5EFE7CA9B6FE1292 - D3FE0C97DEFE0D9DE7FE0DA0EBFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE11A4 - EFFE22AAF0FE2FAFF1FE30B0F1FE30B0F1FE30B0F1FE30B0F1FE30B0F1FE30B0 - F1FE30B0F1FE3490BFFE484A4CFE585757FE626060FE636161FE636161FE6361 - 61FE636161FE636161FE636161FE5E5C5CFE4F4E4EFE368EBCFE30B0F1FE30B0 - F1FE30B0F1FE30B0F1FE30B0F1FE2EAFF1FE20A9F0FE10A3EFFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA0EBFE0D9CE6FE0C96DDFE1793D1FE708C92FE4F50 - 50FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE252424A00000003E0000001A0A0909040000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000444242BA494747FF484646FE494747FF494747FF535454FE84A0A3FF2097 - D1FF0D96DCFF0D9CE5FE0EA0EAFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF1AA7EFFF30B0 - F1FE37B2F2FF37B2F2FF36B2F1FE37B2F2FF37B2F2FF37B2F2FF36B2F1FE37B2 - F2FF37B2F2FF37B1EFFE42687BFF555454FF636161FE676565FF676666FF6766 - 66FE676666FF676666FF666464FE5E5C5CFF4B575DFF37B0EEFE37B2F2FF37B2 - F2FF36B2F1FE37B2F2FF37B2F2FF36B2F1FE36B2F2FF2FAFF1FE17A6EFFF0EA3 - EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EDFE0E9FEAFF0D9BE4FF0C95DAFE2B97CBFF6E7D7FFF4C4B - 4BFE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF424040E70101014D000000290000000A0000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00002D2B2B86484646FE484646FE484646FE494747FE4D4D4DFE7A8B8BFE40A2 - CEFE0C94D9FE0D9AE3FE0D9FE9FE0DA1EDFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE22AAF0FE3AB4F1FE3CB5 - F1FE3CB5F1FE3CB5F1FE3CB5F1FE3CB5F1FE3CB5F1FE3CB5F1FE3CB5F1FE3CB5 - F1FE3CB5F1FE3CB5F1FE3F9FCFFE535759FE656363FE6B6A6AFE6C6A6AFE6C6A - 6AFE6C6A6AFE6C6A6AFE696868FE5D5C5CFE477E9AFE3CB5F1FE3CB5F1FE3CB5 - F1FE3CB5F1FE3CB5F1FE3CB5F1FE3CB5F1FE3CB5F1FE3CB5F1FE39B3F1FE1EA9 - EFFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA1EDFE0D9EE8FE0D9AE2FE0C93D7FE4A9BBFFE636B6BFE4A48 - 48FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE1A19198300000038000000150000 - 0002000000000000000000000000000000000000000000000000000000000000 - 00001C1B1B46494747FD484646FE494747FF494747FF4A4949FE677070FF6BAC - C3FF0C91D5FF0C98E0FE0D9EE7FF0DA1ECFE0EA2EEFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF26ACF0FE42B7F2FF43B7F2FF43B7 - F2FE43B7F2FF43B7F2FF43B7F2FE43B7F2FF43B7F2FF43B7F2FF43B7F2FE43B7 - F2FF43B7F2FF43B7F2FE43B6F1FF528099FF6A6868FE706F6FFF716F6FFF716F - 6FFE716F6FFF716F6FFF6B6969FE5B5F61FF46A5D5FF43B7F2FE43B7F2FF43B7 - F2FF43B7F2FE43B7F2FF43B7F2FF43B7F2FE43B7F2FF43B7F2FE43B7F2FF41B6 - F2FF21AAF0FE0EA3EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA2EEFF0DA0EBFE0D9DE7FF0D97DEFF0C90D4FE6C99A9FF575959FF4947 - 47FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE383737CE02010149000000240000 - 0007000000000000000000000000000000000000000000000000000000000000 - 00000F0F0F17474545E9484646FE494747FF494747FF494747FE595D5DFF81A6 - ADFF1894D2FF0C96DCFE0D9CE5FF0DA0EAFE0EA2EEFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF21AAF0FF47B8F2FE49B9F3FF49B9F3FF49B9 - F2FE49B9F3FF49B9F3FF49B9F2FE49B9F3FF49B9F3FF49B9F3FF49B9F2FE49B9 - F3FF49B9F3FF49B9F2FE49B9F3FF4DAFE1FF717070FE757474FF767474FF7574 - 74FE767474FF747373FF6B6A6AFE597380FF4AB8F1FF49B9F2FE49B9F3FF49B9 - F3FF49B9F2FE49B9F3FF49B9F3FF49B9F2FE49B9F3FF49B9F2FE49B9F3FF49B9 - F3FF46B8F2FE1BA7EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0EA2EDFF0D9FEAFE0D9BE4FF0C95DBFF1D95D0FE75888AFF4F4F4FFF4947 - 47FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE474545F91010106E000000340000 - 0010000000010000000000000000000000000000000000000000000000000000 - 0000000000003F3D3DB8484646FE484646FE484646FE484646FE505050FE7A8C - 8DFE41A2CEFE0C93D8FE0D9AE2FE0D9EE8FE0DA1EDFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA2EEFE0DA2EEFE13A5EFFE47B8F2FE50BCF3FE50BCF3FE50BCF3FE50BC - F3FE50BCF3FE50BCF3FE50BCF3FE50BCF3FE50BCF3FE50BCF3FE50BCF3FE50BC - F3FE50BCF3FE50BCF3FE50BCF3FE5AA7CFFE797777FE7B7979FE7B7979FE7B79 - 79FE7B7979FE777676FE6B6A6AFE5698B9FE50BCF3FE50BCF3FE50BCF3FE50BC - F3FE50BCF3FE50BCF3FE50BCF3FE50BCF3FE50BCF3FE50BCF3FE50BCF3FE50BC - F3FE50BCF3FE41B6F2FE11A4EFFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0DA1ECFE0D9EE8FE0C99E1FE0C92D7FE4B9EC2FE646C6CFE4A4949FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE2E2D2DB4000000430000 - 001D000000050000000000000000000000000000000000000000000000000000 - 00000000000024232360484646FE494747FF494747FF484646FE4A4949FF646C - 6CFF77ADBEFF0C90D4FE0D97DEFF0D9DE6FE0EA0EBFF0EA2EEFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE34B1F1FF58BEF4FF57BEF3FE58BEF4FF58BEF4FF57BE - F3FE58BEF4FF58BEF4FF57BEF3FE58BEF4FF58BEF4FF58BEF4FF57BEF3FE58BE - F4FF58BEF4FF57BEF3FE58BEF3FF6E94A8FF807E7EFE807F7FFF807F7FFF807F - 7FFE807E7EFF797878FF6A7277FE59B7E7FF58BEF4FF57BEF3FE58BEF4FF58BE - F4FF57BEF3FE58BEF4FF58BEF4FF57BEF3FE58BEF4FF57BEF3FE58BEF4FF58BE - F4FF57BEF3FE58BEF4FF2AADF0FF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA2 - EDFF0EA0EAFF0D9CE6FE0D96DDFF1392D2FF6F97A3FE545656FF494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF444242F00909095E0000 - 002D0000000D0000000100000000000000000000000000000000000000000000 - 0000000000000C0C0C19484646E9494747FF494747FF484646FE494747FF5456 - 56FF849A9BFF2E9CD1FE0C94DAFF0D9AE3FE0E9FE9FF0EA1EDFF0DA2EEFE0EA3 - EFFF0EA3EFFF0FA3EFFE54BDF3FF5EC1F4FF5EC1F4FE5EC1F4FF5EC1F4FF5EC1 - F4FE5EC1F4FF5EC1F4FF5EC1F4FE5EC1F4FF5EC1F4FF5EC1F4FF5EC1F4FE5EC1 - F4FF5EC1F4FF5EC1F4FE60BDECFF7E888FFF858484FE868484FF868484FF8584 - 84FE848282FF7A7A7AFF688EA1FE5EC1F3FF5EC1F4FF5EC1F4FE5EC1F4FF5EC1 - F4FF5EC1F4FE5EC1F4FF5EC1F4FF5EC1F4FE5EC1F4FF5EC1F4FE5EC1F4FF5EC1 - F4FF5EC1F4FE5EC1F4FF4BBAF2FF0FA3EFFE0EA3EFFF0EA3EFFF0DA2EEFE0EA1 - ECFF0D9EE8FF0D9AE2FE0C93D8FF3B9BC7FF6E7B7CFE4C4B4BFF494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF484646FE2423239C0000 - 003D000000190000000300000000000000000000000100000000000000000000 - 000000000000020202013B39399D484646FE484646FE484646FE484646FE4C4B - 4BFE697272FE6DAEC5FE0E91D4FE0C97DEFE0D9DE6FE0DA0EBFE0DA2EDFE0DA2 - EEFE0DA2EEFE1DA8F0FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4 - F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4 - F4FE65C4F4FE65C4F4FE6EB4D8FE898889FE8B8989FE8B8989FE8B8989FE8A89 - 89FE868585FE7B7A7AFE68B0D5FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4 - F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4F4FE65C4 - F4FE65C4F4FE65C4F4FE5FC1F4FE18A6EFFE0DA2EEFE0DA2EEFE0DA1EDFE0DA0 - EAFE0D9CE5FE0C97DDFE1091D3FE6B9AAAFE595D5DFE494747FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE413F3FE30000 - 0049000000280000000A00000000000000000000000200000000000000000000 - 000000000000000000001A1A1A2E494747FD494747FF484646FE494747FF4947 - 47FF545656FF849C9DFE329DCFFF0C93D8FE0D9AE2FF0D9EE8FF0DA1ECFE0EA2 - EEFF0EA3EFFF2CAEF1FE6DC7F5FF6DC7F5FF6CC7F5FE6DC7F5FF6DC7F5FF6CC7 - F5FE6DC7F5FF6DC7F5FF6CC7F5FE6DC7F5FF6DC7F5FF6DC7F5FF6CC7F5FE6DC7 - F5FF6DC7F5FF6CC7F5FE81A5B8FF908F8FFF908F8FFE908F8FFF908F8FFF8F8E - 8EFE898787FF7A8890FF6CC7F5FE6DC7F5FF6DC7F5FF6CC7F5FE6DC7F5FF6DC7 - F5FF6CC7F5FE6DC7F5FF6DC7F5FF6CC7F5FE6DC7F5FF6CC7F5FE6DC7F5FF6DC7 - F5FF6CC7F5FE6DC7F5FF6BC6F5FF22AAF0FE0EA2EFFF0EA2EEFF0DA1ECFE0D9E - E7FF0D99E1FF0C93D8FE3E9CC6FF6E7B7CFF4D4D4DFE494747FF494848FF4B4A - 4AFE4D4D4DFF4E4D4DFF4E4D4DFE4E4D4DFF4E4D4DFF4E4D4DFE4E4D4DFF4E4D - 4DFF4D4D4DFE4C4B4BFF4A4949FF494747FE494747FF494747FF484646FE1A19 - 1982000000390000001500000002000000000000000100000000000000000000 - 0000000000000000000000000000484646B7494747FF484646FE494747FF4947 - 47FF4B4A4AFF677070FE77ADBEFF1192D3FE0D96DDFF0D9CE5FF0D9FEAFE0EA1 - EDFF0EA2EEFF32B1F1FE74CAF6FF74CAF6FF74CAF5FE74CAF6FF74CAF6FF74CA - F5FE74CAF6FF74CAF6FF74CAF5FE76C3EBFF889EAAFF8EA0AAFF8FA1AAFE8FA1 - ABFF8FA1ABFF8FA1AAFE94989AFF969595FF969595FE969595FF969595FF9492 - 92FE8A898AFF7AA8BFFF74CAF5FE74CAF6FF74CAF6FF74CAF5FE74CAF6FF74CA - F6FF74CAF5FE74CAF6FF74CAF6FF74CAF5FE74CAF6FF74CAF5FE74CAF6FF74CA - F6FF74CAF5FE74CAF6FF74CAF6FF26ACF0FE0EA2EEFF0EA1ECFF0D9FE9FE0D9B - E4FF0C95DBFF1492D1FE7498A2FF585B5BFF494747FE494747FF4D4E4FFF5A68 - 6DFE68797EFF6B7D82FF6B7D82FE6B7D82FF6B7D82FF6B7D82FE6B7D82FF6B7D - 82FF6A7C81FE647073FF545656FF4A4848FE494747FF494747FF484646FE3735 - 35CA010101480000002300000006000000000000000100000000000000000000 - 000000000000000000000000000048464640484646F8484646FE484646FE4846 - 46FE494747FE525353FE7B8E8EFE4FA7CDFE0C92D6FE0D98DFFE0D9DE7FE0DA0 - EBFE0DA1EDFE2CAEF0FE7BCDF5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCD - F5FE7BCDF5FE7BCDF5FE7BCDF5FE7EC5E8FE93979AFE9B9A9AFE9C9B9BFE9C9B - 9BFE9C9B9BFE9C9B9BFE9C9B9BFE9C9B9BFE9C9B9BFE9C9B9BFE9B9A9AFE9796 - 96FE8C8F92FE7DC3E6FE7BCDF5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCD - F5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCDF5FE7BCD - F5FE7BCDF5FE7BCDF5FE78CBF5FE22AAEFFE0DA1EDFE0DA0EAFE0D9DE6FE0C97 - DEFE0D92D5FE56A1C0FE677070FE4C4B4BFE494747FE494747FE515B5EFE66BB - E3FE7FD0F6FE7FD0F6FE7FD0F6FE7FD0F6FE7FD0F6FE7FD0F6FE7FD0F6FE7FD0 - F6FE7FD0F6FE86BCD6FE646969FE4C4A4AFE484646FE484646FE484646FE4745 - 45F80F0E0E6A000000330000000F000000010000000100000000000000000000 - 000000000000000000000000000048464601535858B1484646FE494747FF4947 - 47FF494747FF4A4848FE5C6161FF87A5A9FE2699D1FF0C94D9FF0C99E1FE0D9E - E8FF0EA0EBFF1AA6EEFE81CFF6FF83CFF7FF83CFF6FE83CFF7FF83CFF7FF83CF - F6FE83CFF7FF83CFF7FF83CFF6FE85C8EAFF9A9EA0FFA1A0A0FFA1A0A0FEA1A0 - A0FFA1A0A0FFA1A0A0FEA1A0A0FFA1A0A0FFA1A0A0FEA1A0A0FFA09F9FFF9998 - 98FE8CA3AFFF83CFF7FF83CFF6FE83CFF7FF83CFF7FF83CFF6FE83CFF7FF83CF - F7FF83CFF6FE83CFF7FF83CFF7FF83CFF6FE83CFF7FF83CFF6FE83CFF7FF83CF - F7FF83CFF6FE83CFF7FF76CAF6FF16A5EEFE0EA0EBFF0D9DE7FF0C99E1FE0C93 - D8FF329ACAFF75898CFE515252FF494747FF484646FE494747FF535B5FFF68BC - E2FE80D1F7FF80D1F7FF82CBEDFE82C8E7FF7FC5E5FF7EC4E4FE7EC4E4FF7EC4 - E4FF7EC4E4FE81B0C6FF616565FF4B4A4AFE494747FF494747FF484646FE4947 - 47FF2E2D2DB4000000420000001D000000050000000000000000000000000000 - 0000000000000000000000000000000000008AAEAE2F484646F2494747FF4947 - 47FF494747FF494747FE4D4D4DFF687171FE79AEBEFF1794D2FF0C95DBFE0D9B - E3FF0D9EE8FF0EA1EBFE6CC6F4FF8AD2F7FF8AD2F7FE8AD2F7FF8AD2F7FF8AD2 - F7FE8AD2F7FF8AD2F7FF8AD2F7FE8CCBEBFF9FA3A5FFA6A5A5FFA6A5A5FEA6A5 - A5FFA6A5A5FFA6A5A5FEA6A5A5FFA6A5A5FFA6A5A5FEA6A5A5FFA4A3A3FF9B9B - 9BFE8DBED8FF8AD2F7FF8AD2F7FE8AD2F7FF8AD2F7FF8AD2F7FE8AD2F7FF8AD2 - F7FF8AD2F7FE8AD2F7FF8AD2F7FF8AD2F7FE8AD2F7FF8AD2F7FE8AD2F7FF8AD2 - F7FF8AD2F7FE8AD2F7FF5DC0F3FF0EA0EBFE0D9EE8FF0D9AE2FF0C94DAFE1D95 - D0FF7298A3FF5A5F5FFE4A4848FF494747FF484646FE494747FF4F5050FF5D8E - A3FE7CCFF6FF80D1F7FF86C7E4FE899DA0FF6E7B7DFF636D6FFE626B6DFF626B - 6DFF616B6CFE5C6263FF515151FF4A4848FE494747FF494747FF484646FE4947 - 47FF434141ED0808085A0000002B0000000B0000000000000000000000000000 - 000000000000000000000000000000000000ABE2E2015E696989484646FE4846 - 46FE484646FE484646FE494747FE515252FE768484FE68ADC7FE0F91D3FE0C96 - DCFE0D9BE4FE0D9EE8FE39B1EFFE8FD4F6FE91D5F7FE91D5F7FE91D5F7FE91D5 - F7FE91D5F7FE91D5F7FE91D5F7FE93CEECFEA3A6A9FEA8A7A7FEA8A8A8FEA8A8 - A8FEA8A8A8FEA8A8A8FEA8A8A8FEA8A8A8FEA8A8A8FEA8A8A8FEA5A4A4FE9CA4 - A8FE92D1F2FE91D5F7FE91D5F7FE91D5F7FE91D5F7FE91D5F7FE91D5F7FE91D5 - F7FE91D5F7FE91D5F7FE91D5F7FE91D5F7FE91D5F7FE91D5F7FE91D5F7FE91D5 - F7FE91D5F7FE8DD3F6FE2AACEDFE0D9EE8FE0D9AE3FE0C95DBFE1091D2FE6CA1 - B3FE636B6BFE4C4B4BFE494747FE484646FE484646FE484646FE4A4949FE5659 - 59FE65AAC8FE7ED0F6FE7FD0F6FE89BACFFE6F7879FE535454FE4B4A4AFE4B4A - 4AFE4B4A4AFE4A4949FE494848FE494747FE484646FE484646FE484646FE4846 - 46FE484646FE2121219600000038000000140000000100000000000000000000 - 00000000000000000000000000000000000000000000ADE4E409494747D64947 - 47FF494747FF484646FE494747FF494747FE555757FF7C8E8FFF5BAACAFE0D91 - D4FF0C96DDFF0D9BE4FE11A0E9FF6DC6F3FF99D7F7FE99D7F8FF99D7F8FF99D7 - F7FE99D7F8FF99D7F8FF99D7F7FE9AD0ECFFA3A6A8FFA6A5A5FFA6A5A5FEA6A5 - A5FFA6A5A5FFA6A5A5FEA6A5A5FFA6A5A5FFA6A5A5FEA5A5A5FFA4A3A3FF9DBA - C9FE99D7F8FF99D7F8FF99D7F7FE99D7F8FF99D7F8FF99D7F7FE99D7F8FF99D7 - F8FF99D7F7FE99D7F8FF99D7F8FF99D7F7FE99D7F8FF99D7F7FE99D7F8FF99D7 - F8FF99D7F7FE5DBFF1FF0F9FE8FF0D9AE3FE0C96DBFF1092D3FF5FA2BCFE6973 - 73FF4E4E4EFF494747FE494747FF494747FF484646FE494747FF494747FF4B4A - 4AFE596467FF6BB8DAFF7FD0F6FE80D0F6FF88ABBAFF656C6CFE4E4D4DFF4947 - 47FF484646FE494747FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF3F3D3DDD000000430000001E0000000500000000000000000000 - 000000000000000000000000000000000000000000000000000088ABAB414A49 - 49F3494747FF484646FE494747FF484646FE4A4949FF595C5CFF819597FE50A7 - CCFF0E92D4FF0C96DCFE0D9BE3FF22A6EAFF89D0F5FEA1DAF8FFA1DAF8FFA0DB - F8FEA1DBF8FFA1DBF8FFA0DBF8FEA1D1E9FFA5A6A7FFA5A5A5FFA5A5A5FEA5A5 - A5FFA5A5A5FFA5A5A5FEA5A5A5FFA5A5A5FFA5A5A5FEA5A5A5FFA5A5A5FFA1D2 - EAFEA1DBF8FFA1DBF8FFA0DBF8FEA1DBF8FFA1DBF8FFA0DBF8FEA1DBF8FFA1DB - F8FFA0DBF8FEA1DBF8FFA1DBF8FFA0DBF8FEA1DBF8FFA0DBF8FEA1DAF8FFA0DA - F8FF81CDF4FE17A2E8FF0D9AE3FF0C96DCFE1092D3FF58A1BEFF6F7C7DFE5051 - 51FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4947 - 47FE4E4D4DFF5C747CFF72C5EAFE80D1F7FF82CDF1FF849DA6FE5C6161FF4C4B - 4BFF494747FE494747FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FD0E0E0E60000000270000000800000000000000000000 - 0000000000000000000000000000000000000000000000000000000000006777 - 777C484646FE484646FE484646FE484646FE494747FE4B4A4AFE5A5E5EFE8299 - 9AFE55A9CCFE0D90D4FE0C96DBFE0D9AE2FE2AA9E9FE98D6F6FEA7DCF8FEA7DD - F8FEA7DDF8FEA7DEF8FEA7DEF8FEA8DBF5FEA8D1E5FEA8D0E4FEA8D0E4FEA8D0 - E4FEA8D0E4FEA8D0E4FEA8D0E4FEA8D0E4FEA8D0E4FEA8D0E4FEA8D1E5FEA7DE - F8FEA7DEF8FEA7DEF8FEA7DEF8FEA7DEF8FEA7DEF8FEA7DEF8FEA7DEF8FEA7DE - F8FEA7DEF8FEA7DEF8FEA7DEF8FEA7DEF8FEA7DDF8FEA7DDF8FEA7DCF8FE8CD1 - F4FE22A5E8FE0D99E1FE0C95DAFE0E90D3FE5DA3BFFE707E7FFE525353FE4947 - 47FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE494747FE505151FE5E8594FE7ACEF5FE80D0F6FE85C9E9FE7D8A8DFE575A - 5AFE4A4949FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE242323970000002E0000000C00000000000000000000 - 000000000000000000000000000000000000000000000000000000000000B8F6 - F6065B6363A9484646FE494747FF484646FE494747FF494747FF4B4949FE595D - 5DFF7E9091FF68ADC8FE1392D2FF0C94DAFF0C99E0FE26A6E8FF8BD0F4FFAFDF - F8FEAFDFF9FFAFE0F9FFAFE0F9FEAFE0FAFFAFE0FAFFAFE0FAFFAFE0F9FEAFE0 - FAFFAFE0FAFFAFE0F9FEAFE0FAFFAFE0FAFFAFE0F9FEAFE0FAFFAFE0FAFFAFE0 - F9FEAFE0FAFFAFE0FAFFAFE0F9FEAFE0FAFFAFE0FAFFAFE0F9FEAFE0FAFFAFE0 - FAFFAFE0F9FEAFE0FAFFAFE0FAFFAFE0F9FEAFDFF9FFAFDFF8FE7FCCF3FF1EA2 - E6FF0C98DFFE0C94D9FF1994D1FF69A4B9FE6D7878FF515252FF494747FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF4A4848FF535555FE639AB1FF7DCFF5FF80D0F6FE87C1DCFF7480 - 81FF545555FE4A4848FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE343333C5000000320000000E00000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000A2D3D311464A4DCE494747FF484646FE494747FF494747FF494747FE4B49 - 49FF565959FF768585FE74AEC1FF2398D1FF0C92D7FE0D97DDFF1AA0E4FF6BC3 - F0FEAFDFF8FFB6E2F9FFB5E2F9FEB6E3FAFFB6E3FAFFB6E3FAFFB5E3F9FEB6E3 - FAFFB6E3FAFFB5E3F9FEB6E3FAFFB6E3FAFFB5E3F9FEB6E3FAFFB6E3FAFFB5E3 - F9FEB6E3FAFFB6E3FAFFB5E3F9FEB6E3FAFFB6E3FAFFB5E3F9FEB6E3FAFFB6E3 - FAFFB5E3F9FEB6E3FAFFB6E2F9FFB5E2F8FEAADDF7FF61BFEEFE149DE3FF0C96 - DDFF0C92D6FE2998CEFF729FADFF687272FE4F5050FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FF4B4949FE575E5FFF73B2CDFF91D7F8FE8FD6F7FF91B8 - C9FF6B7474FE4F5050FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE3F3E3EDB040404370000000E00000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000001B79A921464A4DDE484646FE484646FE484646FE484646FE4947 - 47FE4A4848FE525353FE6D7878FE83A9B1FE44A4CFFE0C90D4FE0C94DAFE0D98 - DFFE37ACE8FE8CD0F3FEBBE4F9FEBDE5F9FEBDE5F9FEBDE5FAFEBDE5FAFEBDE6 - FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE6 - FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE6FAFEBDE5FAFEBDE5 - FAFEBDE5F9FEBDE5F9FEB9E3F8FE81CCF2FE2EA8E7FE0D98DFFE0C94D9FE0F91 - D3FE49A2C9FE7A969BFE606767FE4D4D4DFE494747FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE494747FE4C4C4CFE5F6C70FE95CDE6FEA9E0F9FEA8DE - F7FE94ABB4FE5F6565FE4C4B4BFE494747FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE444242E6060606390000000C00000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000001A7BAC29454B4FDD494747FF494747FF484646FE4947 - 47FF494747FF494747FE4E4D4DFF5E6464FF809393FE71AEC4FF2799D1FF0C91 - D5FE0C95DBFF0E99E0FF34ABE7FE80CBF1FFB3E0F7FFC4E7FAFFC3E7F9FEC4E7 - FAFFC4E7FBFFC3E8FAFEC4E8FBFFC4E8FBFFC3E8FAFEC4E8FBFFC4E8FBFFC3E8 - FAFEC4E8FBFFC4E8FBFFC3E8FAFEC4E8FBFFC4E7FBFFC3E7FAFEC4E7FAFFC4E7 - FAFFAEDEF7FE76C7F0FF2EA8E6FF0C98DFFE0C95DAFF0C91D4FE2E9ACEFF71A4 - B4FF728080FE565858FF4B4A4AFF494747FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FF484646FE494747FF4E4E4EFF677B82FEA6DCF4FFB0E1 - FAFFAEDDF3FE808C8EFF555757FF494747FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE434141E1060606310000000800000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000001A7BAC29464A4DDC494747FF484646FE4947 - 47FF494747FF484646FE494747FF4B4949FF545656FE6C7777FF83A2A6FF60AB - C8FE2197D1FF0D92D5FF0C94DAFE0E98DEFF1EA1E3FF49B4EAFF83CCF2FEAADD - F6FFBEE5F9FFC8E9FAFECAEAFAFFCAEAFAFFCAEAFAFECAEAFBFFCAEAFBFFCAEA - FAFECAEAFBFFCAEAFAFFCAEAFAFEC7E9FAFFBDE5F8FFA5DBF6FE7CC9F1FF45B2 - E9FF1A9EE2FE0D97DEFF0C94D9FF0E92D5FE2798CFFF61A5BFFE7A9093FF6168 - 68FF4F5050FE4A4848FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4A49 - 49FE4B4A4AFF4B4949FF494848FE494747FF494848FF525252FE80A3B1FFB4E3 - FAFFB5E4FAFE9EB8C2FF606666FF4B4949FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE3D3C3CD3030303220000000500000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000001B79A921464A4DCA484646FE4846 - 46FE484646FE484646FE484646FE494747FE494747FE4D4C4CFE595D5DFE717D - 7DFE85A5AAFE65ADC7FE2C9CD1FE0C90D3FE0C93D7FE0C95DBFE0C97DDFE119B - E1FE25A4E5FE3EAEE8FE58BAECFE6BC2EFFE79C8F0FE82CCF2FE86CDF2FE81CB - F2FE78C7F0FE69C1EEFE55B9EBFE3AADE8FE23A3E4FE0F99E0FE0C97DDFE0C95 - DAFE0C92D7FE0E91D3FE309CD0FE68A7BEFE7C9699FE677070FE535454FE4B4A - 4AFE494747FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE494747FE4D4C4CFE575A - 5AFE616767FE5D6363FE525353FE4A4848FE494747FE4A4949FE637175FEAFDE - F2FEBBE6FAFEAECDDBFE6A7171FE4C4B4BFE484646FE484646FE484646FE4846 - 46FE484646FE484646FE343333B2000000130000000200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000001A7BAC0F3F515BA14947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494848FF4D4C - 4CFE585B5BFF6B7575FF84999AFE7CACBAFF54A7CAFF2C9CD1FF1192D2FE0C91 - D5FF0C93D8FF0C94D9FE0D95DBFF0D96DCFF0C96DDFE0D97DDFF0D97DDFF0C96 - DDFE0D96DDFF0D96DCFF0C95DBFE0C94D9FF0C93D7FF0C91D5FE1492D2FF2F9C - CFFF57A5C5FE7AA4B0FF7B8C8CFF626969FE525454FF4B4A4AFE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF555C5FFFA2D0 - E4FEBBE2F5FFAECEDDFF6B7272FE4D4D4DFF494747FF494848FE5C6263FFB0D9 - EBFFC2E8FBFEB4D1DEFF6C7474FF4C4C4CFE494747FF494747FF484646FE4947 - 47FF494747FF484646FE21202070000000090000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000E87C4053859 - 6A70484849EF484646FE494747FF494747FF484646FE494747FF494747FF4947 - 47FE494747FF4C4B4BFF535555FE606666FF717E7EFF80979AFF7FA9B3FE6AAA - C2FF51A6CBFF3AA0CEFE2799D0FF1C96D2FF1894D2FE1594D3FF1593D3FF1694 - D3FE1894D2FF1D96D2FF2999CFFE3CA0CDFF52A5C8FF6BA7BDFE7CA1AAFF7A8E - 90FF6A7474FE5B5F5FFF505151FF4A4949FE494747FF494747FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF55595AFFA9CF - DFFEC8EBFCFFC3E3F3FF869395FE585C5CFF4C4C4CFF4F4F4FFE718389FFC1E6 - F7FFC8EBFBFEB3CDD8FF686F6FFF4C4B4BFE494747FF494747FF484646FE4947 - 47FF494747FF484646F20909091F000000020000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000088B0B236535858CA484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE494747FE4A4848FE4C4C4CFE525353FE5A5F5FFE656E - 6EFE707C7CFE7B8C8CFE829899FE839FA3FE81A2A9FE7FA4ADFE7EA4ADFE7EA3 - ACFE80A1A7FE829DA0FE7F9495FE778686FE6D7777FE616868FE575A5AFE5050 - 50FE4B4A4AFE494747FE494747FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE494747FE4F5050FE8FAD - B9FECEEDFBFECEECFBFEB6CED8FE7A8787FE656D6DFE6E7B7DFEB2D2DFFECEED - FBFECEEDFBFE9FB1B7FE5D6262FE4A4949FE484646FE484646FE484646FE4846 - 46FE484646FE3130309400000006000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000ADE5E502768E8E724C4C4CE6484646FE494747FF494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF494747FF494747FE4A48 - 48FF4B4A4AFF4D4D4DFE505050FF525454FF545656FE565858FF565959FF5558 - 58FE535555FF525252FF4F4F4FFE4C4B4BFF4B4949FF494747FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF4B4949FF5F68 - 6AFEBCDCEAFFD4EFFCFFD4EFFCFECEE9F6FFC2DEEAFFCEECF9FED4EFFCFFD4EF - FCFFBFD7E2FE717A7AFF515252FF494747FE494747FF494747FF484646FE4947 - 47FF444242DC0B0A0A1D00000001000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000004A49491C4846468E494747F0494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF494747FE494747FF494747FF4947 - 47FE494747FF494747FF494747FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4E4D - 4DFE697578FFB0CBD5FFD2EBF7FED9F1FCFFDAF1FDFFD9F0FCFED2EAF6FFB4CA - D2FF798385FE565858FF4A4949FF494747FE494747FF494747FF484646FE4846 - 46F31F1F1F4C0000000100000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000484646244846468A4846 - 46ED484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4947 - 47FE4D4D4DFE595C5CFE707D80FE859395FE8A979AFE869497FE768284FE6167 - 67FE525454FE4B4949FE494747FE484646FE484646FE484646FE484646FC2D2C - 2C63010101020000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000004846 - 460B49474765494747BD484646F6494747FF494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF4A4848FF4C4B4BFE4E4E4EFF505050FF4F4F4FFE4D4D4DFF4B49 - 49FF494747FE494747FF494747FF484646FE494747FF464444E1302F2F4C0000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000049474704484646224947476E494747B4494747E5484646F94947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FF484646FE494747FF494747FF484646FE4947 - 47FF494747FF484646FE494747FF494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FF484646FE494747FF494747FF484646FE494747FF4947 - 47FF484646FE494747FF494747FE484646EF413F3F943837371D000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000004846460F484646354846 - 46604846468B484646AE484646CD484646E4484646F3484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FE484646FE484646FE484646FE484646FE484646FE484646FE484646FE4846 - 46FC484646E2484646B24846466E484646210000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8FFFFFFFFFFFFFFFFF - FFFF80000FFFFFFFFFFFFFFFFFF8000001FFFFFFFFFFFFFFFFE00000003FFFFF - FFFFFFFFFF000000000FFFFFFFFFFFFFFE0000000003FFFFFFFFFFFFF8000000 - 0000FFFFFFFFFFFFE000000000007FFFFFFFFFFFC000000000001FFFFFFFFFFF - 8000000000000FFFFFFFFFFE00000000000007FFFFFFFFFC00000000000003FF - FFFFFFF800000000000001FFFFFFFFF000000000000000FFFFFFFFF000000000 - 0000007FFFFFFFE0000000000000003FFFFFFFC0000000000000001FFFFFFF80 - 000000000000001FFFFFFF80000000000000000FFFFFFF000000000000000007 - FFFFFE000000000000000007FFFFFE000000000000000003FFFFFC0000000000 - 00000003FFFFFC000000000000000001FFFFF8000000000000000001FFFFF800 - 0000000000000000FFFFF0000000000000000000FFFFF0000000000000000000 - 7FFFF00000000000000000007FFFE00000000000000000007FFFE00000000000 - 000000003FFFE00000000000000000003FFFE00000000000000000001FFFC000 - 00000000000000001FFFC00000000000000000000FFFC0000000000000000000 - 0FFFC00000000000000000000FFFC000000000000000000007FFC00000000000 - 0000000007FFC000000000000000000003FFC000000000000000000003FFC000 - 000000000000000001FFC000000000000000000001FFC0000000000000000000 - 01FFC000000000000000000000FFC000000000000000000000FFC00000000000 - 00000000007FC0000000000000000000007FC0000000000000000000003FC000 - 0000000000000000003FE0000000000000000000003FE0000000000000000000 - 001FE0000000000000000000001FE0000000000000000000000FF00000000000 - 00000000000FF00000000000000000000007F00000000000000000000006F000 - 00000000000000000006F80000000000000000000002FC000000000000000000 - 0002FC0000000000000000000000FC0000000000000000000001FE0000000000 - 000000000001FE0000000000000000000000FF0000000000000000000000FF80 - 00000000000000000000FFC000000000000000000000FFC00000000000000000 - 0000FFE000000000000000000000FFF000000000000000000000FFF800000000 - 000000000000FFFC00000000000000000000FFFE00000000000000000000FFFF - 00000000000000000001FFFF80000000000000000001FFFFE000000000000000 - 0003FFFFF0000000000000000003FFFFFC000000000000000007FFFFFF000000 - 00000000000FFFFFFFC0000000000000003FFFFFFFF0000000000000007FFFFF - FFFF00000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28000000480000009000 - 0000010020000000000060540000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000003737370137373702373737043737370637373707373737073737 - 3707373737063737370537373703373737010000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000001000000050000 - 000B000000130000001B00000023000000290000002E00000030000000310000 - 00310000002F0000002C000000260000001E000000160000000E000000070000 - 0002000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000040000000D0000001A000000290000 - 00370000004200000049030303520C0C0C64100F0F7110101073101010741010 - 10740E0D0D6B0707075B000000500000004C000000460000003B0000002F0000 - 0020000000110000000600000001000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000028272701070707060000001300000026000000390303034E121111742423 - 23A1333232C7424040E5474545F9484646FC484646FD484646FD484646FD4846 - 46FD484646FC474545FA444242EE383636D12A2929AF171616840606065F0000 - 004C0000003F0000002D000000190101010A1F1E1E0200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000D0C - 0C04000000120000002900000040121111702D2C2CB6424040E9484646FE4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF454343F23332 - 32C7181717860101015400000046000000320000001A03030308242323010000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000001A1A1A020000000D0000 - 0024020202421B1A1A873C3A3AD9484646FE494747FF484646FE494747FF4846 - 46FE494747FF494747FF484646FE494747FF484646FE494747FF484646FE4947 - 47FF484646FE494747FF494747FF484646FE494747FF484646FE494747FF4846 - 46FE494747FF424040E92322229F0606065E000000460000002E000000140808 - 0804000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000001014140500000017000000341716 - 16783C3A3AD9484646FE494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF4A4949FF4C4B4BFF4D4D4DFF4E4E4EFF4E4E4EFF4D4D - 4DFF4C4B4BFF4A4949FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF424040EA1F1E1E97020202540000003D0000 - 0020010101090000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000040505080000002009090950323131BE4846 - 46FE494747FF484646FE494747FF484646FE494747FF494747FE4C4C4CFF5456 - 56FE606666FF697879FF68848CFE638C9AFF6091A4FE5E94A9FF5E93A9FE5E90 - A4FF618A9AFE66838CFF687779FF5F6565FE545656FF4C4B4BFE494747FF4947 - 47FE494747FF484646FE494747FF484646FE494747FF3B3A3AD9100F0F740000 - 00480000002B0000000F546B6B01000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000505050A0000002718171776424141EA494747FF4947 - 47FF494747FF494747FF494747FF4B4A4AFF545656FF657071FF6A8B95FF5598 - B4FF3F9DC9FF2F9DD4FF2B9FD9FF2CA0DCFF2EA2DDFF30A3DEFF30A3DEFF2EA2 - DDFF2CA0DCFF2B9ED9FF2C9CD4FF399BCAFF4C95B5FF638895FF636E70FF5355 - 55FF4B4949FF494747FF494747FF494747FF494747FF494747FF464444F62322 - 229E010101500000003300000012515151020000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000606060A0101012B25242498484646FA494747FF484646FE4947 - 47FF494747FF4B4A4AFE575A5AFF6C7F82FE5A98B1FF399ECEFE289DD9FF2EA3 - DFFE33A7E3FF35AAE5FF38ACE7FE3AAEE9FF3BAEEAFE3CAFEAFF3CAFEAFE3CAF - EAFF3BAEE9FE39ADE8FF37ABE6FF34A8E3FE30A4DFFF279DD9FE319BCFFF4F93 - B0FE667C81FF565959FE4B4949FF494747FE494747FF494747FF484646FE4846 - 46FE323030C00404045800000037000000140327390200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000404040A0101012C2E2D2DAD484646FD494747FF494747FF494747FF4948 - 48FF525454FF6A7B7EFF599AB5FF2E9DD3FF2AA0DDFF2FA6E3FF34AAE7FF37AD - EAFF39B0ECFF3BB1EEFF3DB3EFFF3EB4EFFF3EB4F0FF3FB4F0FF3FB4F0FF3FB4 - F0FF3FB4EFFF3EB3EFFF3EB2EEFF3CB1ECFF3AAFEBFF36ACE8FF32A7E4FF2BA1 - DEFF289AD4FF4B95B5FF65787CFF525454FF494848FF494747FF494747FF4947 - 47FF494747FF393737D30606065D0000003700000013526E6E01000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000D12 - 1206010101282E2D2DAC484646FE494747FF484646FE494747FF4B4A4AFE5F65 - 65FF6994A3FF349DCFFE269FDCFF2DA6E3FE31AAE8FF35AEECFE38B0EEFF39B2 - EFFE3AB3F0FF3BB4F1FF3BB4F1FE3CB4F1FF3CB4F1FE3DB5F2FF3DB5F1FE3DB5 - F2FF3DB4F1FE3EB5F1FF3DB5F1FF3DB4F1FE3CB3F0FF3BB2EEFE38B0ECFF35AC - E9FE30A7E4FF28A0DDFE2A99CFFF5A8EA3FE5D6363FF4B4A4AFF494747FE4947 - 47FF484646FE494747FF3C3B3BDB0505055B000000350000000F5E7E7E010000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000263333040000 - 001E2D2C2CA6484646FE494747FF494747FF494747FF4E4E4EFF6A7778FF539D - BDFF239BD8FF28A2E1FF2DA8E7FF31ADECFF33AFEEFF35B1F0FF36B2F1FF37B2 - F1FF37B2F2FF37B3F2FF38B3F2FF38B3F2FF38B3F2FF39B3F2FF39B3F2FF39B3 - F2FF39B3F2FF39B3F2FF3AB4F2FF3AB4F2FF3AB4F2FF39B3F1FF39B3F0FF38B1 - EFFF36AFEDFF31ABE9FF2BA5E2FF229BD9FF4196BDFF647478FF4E4D4DFF4947 - 47FF494747FF494747FF494747FF393838D4050505580000002E0304040B0000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000526E6E0100000014201F - 1F82484646FE494747FF494747FF494747FF505050FF6F8285FF419DC7FF219C - DBFF27A4E4FF2BA9EAFF2EADEDFF30AEEFFF31B0F0FF32B0F1FF32B0F1FF32B0 - F1FF33B1F1FF33B1F1FF33B1F1FF34B1F1FF34B1F1FF34B1F1FF34B1F1FF35B1 - F1FF35B2F2FF36B2F2FF36B2F2FF36B2F2FF36B2F2FF37B2F2FF37B2F2FF37B2 - F1FF36B1F0FF34AFEEFF31ACEBFF2BA7E6FF239EDDFF3197C8FF657D83FF4F50 - 50FF494747FF494747FF494747FF494747FF333232C40000004B000000240E11 - 1105000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000B131313584745 - 45F7484646FE494747FF494747FE505151FF70878CFE359CCDFF1F9CDDFE24A4 - E6FF28A9EBFF2AACEEFE2BADF0FF2CAEF0FE2DAFF1FF2DAFF0FE2DAFF1FF2EAF - F0FE2EAFF1FF2EAFF1FF2EAFF0FE2FAFF1FF2FAFF0FE2FB0F1FF30B0F0FE30B0 - F1FF30B0F0FE30B0F1FF31B0F1FF31B0F0FE31B0F1FF32B0F1FE32B0F1FF32B0 - F1FE32B0F1FF32B0F0FE31AFEFFF2EACECFE29A7E7FF239FDFFF2797CEFE6481 - 8AFF505050FE494747FF484646FE494747FF484646FE262525A4000000420000 - 00181B1A1A020000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000001315150405040428413F3FDF4947 - 47FF494747FF494747FF4E4E4EFF6F8285FF379CCCFF1C9CDDFF21A3E6FF25A8 - ECFF27ABEFFF27ACF0FF28ACF1FF28ADF1FF28ADF1FF28ADF1FF29ADF1FF29AD - F1FF29ADF1FF29ADF1FF2AADF1FF2AADF1FF2AAEF1FF2BAEF1FF2BAEF1FF2BAE - F1FF2BAEF1FF2CAEF1FF2CAEF1FF2CAEF1FF2DAEF1FF2DAFF1FF2DAFF1FF2DAF - F1FF2EAFF1FF2EAFF1FF2EAFF0FF2DAEEFFF2BABEDFF27A7E8FF219EDFFF2796 - CDFF647D83FF4D4D4DFF494747FF494747FF494747FF474545F9121212770000 - 00330000000B0000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000102D2C2CA0494747FF4947 - 47FF494747FE4B4A4AFF6B7778FE439EC7FF199ADBFE1DA2E6FF21A7EBFE22A9 - EEFF23AAF0FF23ABF0FE24ABF0FF24ABF0FE24ABF0FF24ABF0FE25ABF0FF25AB - F0FE25ACF0FF26ACF0FF26ACF0FE26ACF1FF26ACF0FE26ACF1FF27ACF0FE27AC - F1FF27ACF0FE27ACF1FF28ADF1FF28ADF0FE28ADF1FF3990BDFE3698CAFF2AAB - EDFE29ADF1FF29ADF0FE2AADF1FF29ADF0FE29ACEFFF28AAECFF24A5E7FE1E9D - DEFF2F96C8FE647376FF4B4A4AFE494747FF484646FE494747FF3E3D3DE00303 - 034F000000201211110300000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000511111148474545F7494747FF4947 - 47FF494848FF5E6465FF589FBBFF1697D9FF199FE4FF1CA5EAFF1EA8EEFF1FA0 - E2FF2F6581FF3D708AFF42748EFF42748EFF42748EFF3B7D9FFF21A9EEFF21AA - F0FF21AAF0FF22AAF0FF22AAF0FF22AAF0FF22AAF0FF23ABF0FF23ABF0FF23AB - F0FF23ABF0FF24ABF0FF24ABF0FF24ABF0FF26A7EAFF535D63FF595959FF5264 - 6EFF4180A1FF2F9ED7FF26ABEFFF26ACF0FF26ACF0FF26ABEFFF24A8ECFF20A3 - E6FF199ADBFF4194BBFF5D6363FF494747FF494747FF494747FF484646FE2524 - 24A1000000390000000E00000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000001010110373636BF484646FE494747FF4947 - 47FF525454FE7096A2FF1996D5FE169CE1FF18A3E9FE1AA6EEFF1AA7EFFE1BA7 - EFFF285C77FF434242FE515050FF535252FE545252FF535152FE2B8EC1FF1DA8 - EFFE1DA8F0FF1DA8F0FF1DA8EFFE1EA9F0FF1EA9EFFE1EA9F0FF1EA9EFFE1FA9 - F0FF1FA9EFFE1FA9F0FF20A9F0FF20A9EFFE3288B4FF565454FE575555FF5755 - 55FE575555FF575657FE4B6979FF3986AEFE27A2E1FF22AAEFFF22A9EEFE20A6 - EBFF1BA0E4FE1796D7FF5B8DA1FE515252FF494747FE494747FF494747FF4442 - 42F10908085A0000002016161603000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000031615154F484646FC494747FF494747FF4B49 - 49FF6D7B7DFF359BCCFF1298DDFF15A0E7FF16A4EDFF17A6EFFF17A6F0FF17A6 - F0FF1998D9FF32373AFF494747FF504E4EFF514F4FFF514F4FFF465D6AFF1BA3 - E9FF19A7F0FF19A7F0FF19A7F0FF1AA7F0FF1AA7F0FF1AA8F0FF1AA7F0FF1AA8 - F0FF1BA8F0FF1BA8F0FF1BA8F0FF1CA7EEFF446272FF545252FF545252FF5452 - 52FF545252FF545353FF555353FF555353FF525659FF40697FFF2689BCFF1DA7 - EDFF1BA3E9FF179CDFFF2295CEFF65767AFF4B4949FF494747FF494747FF4947 - 47FF282727A8000000340202020A000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000B363434B6494747FF484646FE494747FF5658 - 58FF659EB3FE1094D7FF119CE3FE13A2EAFF14A4EEFE14A5EFFF15A5EFFE15A5 - EFFF15A5EFFF1F6487FE3B3A3AFF4C4A4AFE4E4C4CFF4E4C4CFE4E4C4DFF2D7E - A9FE16A6F0FF16A6F0FF16A6EFFE16A6F0FF17A6EFFE17A6F0FF17A6EFFE17A6 - F0FF17A6EFFE18A6F0FF18A7F0FF2294CEFE4E4F50FF514F4FFE514F4FFF514F - 4FFE514F4FFF514F4FFE525050FF525050FE514F4FFF454444FF266A8DFE1AA7 - EFFF19A5ECFE16A0E6FF1396DAFE4B92B1FF555858FE494747FF494747FF4846 - 46FE434242ED0505054D00000017252424010000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000010D0D0D31484646F9494747FF494747FF4B4A4AFF707F - 7FFF2B9AD0FF0E98DEFF109FE8FF11A2EDFF11A4EEFF11A4EFFF12A4EFFF12A4 - EFFF12A4EFFF139BE0FF293841FF434141FF4C4A4AFF4C4A4AFF4D4B4BFF4751 - 57FF189DE1FF13A5EFFF14A5EFFF14A5EFFF14A5EFFF14A5EFFF14A5EFFF14A5 - EFFF15A5EFFF15A5EFFF15A5EFFF356D8BFF4E4C4CFF4F4D4DFF4F4D4DFF4D4B - 4BFF474545FF464545FF4C4A4AFF4F4D4DFF4C4A4AFF383A3CFF1996D7FF17A6 - F0FF16A5EEFF15A2EAFF129AE1FF1C94D0FF657A7FFF4A4949FF494747FF4947 - 47FF484646FE1D1C1C8C0000002A0A0A0A060000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000327262684494747FF494747FF494747FF535555FF6B9D - AEFF0C92D7FF0E9BE3FF0FA0EBFF0FA2EEFF0FA3EFFF0FA3EFFF10A3EFFF10A4 - EFFF10A4EFFF10A4EFFF186E9AFF353434FF474545FF4A4848FF4A4848FF4A48 - 48FF307091FF11A4EFFF11A4EFFF11A4EFFF12A4EFFF12A4EFFF12A4EFFF12A4 - EFFF12A4EFFF12A4EFFF159FE6FF464D51FF4C4A4AFF4C4A4AFF4C4A4AFF4544 - 44FF313030FF2C2A2AFF363434FF403E3EFF3F3E3EFF265065FF14A5EFFF14A5 - EFFF14A5EEFF13A2ECFF109DE5FF0E94D9FF5192ADFF525353FF494747FF4947 - 47FF494747FF373535CD0000003E000000110000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000101010A403E3ED2484646FE494747FF494747FE666F70FF3E9E - CAFF0C96DCFE0D9DE7FF0EA1EDFE0EA2EEFF0EA2EEFE0EA3EFFF0EA2EEFE0EA3 - EFFF0EA3EFFF0EA2EEFE0F9FE9FF233B48FE3E3C3CFF494747FE4A4848FF4947 - 47FE464A4DFF1993D1FF0FA3EEFE0FA3EFFF0FA3EEFE0FA3EFFF0FA3EEFE10A3 - EFFF10A3EEFE10A3EFFF257CA9FF494747FE4A4848FF4A4848FE494747FF3A39 - 39FE1B658CFF16587AFE1C2B33FF232323FE262525FF167DB2FF12A4EEFE12A4 - EFFF11A4EEFE10A2EDFF0F9FE8FE0D97DEFF2696CCFE636B6BFF494747FF4846 - 46FE494747FF484646FC0E0E0E68000000231414140300000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000C0C0C2B484646F7494747FF494747FF4C4B4BFF758E93FF1995 - D3FF0D99E1FF0D9FEAFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF1379ADFF303030FF454343FF494747FF4947 - 47FF494747FF356178FF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0FA1EDFF395969FF494747FF4A4848FF494747FF454343FF2E37 - 3DFF109BE2FF0FA3EFFF0F9BE2FF1371A2FF154964FF109EE7FF0FA3EFFF0FA3 - EFFF0FA3EFFF0FA2EEFF0EA0EBFF0D9AE3FF0D92D5FF668690FF4C4B4BFF4947 - 47FF494747FF494747FF2D2C2CB4000000370101010C00000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000201F1F63494747FF484646FE494747FF535454FE689EB2FF0C93 - D7FF0D9BE4FE0EA1EBFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0EA1ECFE1E455AFF3B3939FE474545FF4846 - 46FE494747FF484646FF1C88C0FE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0DA2EEFE188FCCFF464647FF494747FE494747FF484646FE3E3C3CFF1E59 - 77FE0EA3EFFF0EA2EEFE0EA3EFFF0EA2EEFE0EA3EFFF0EA3EFFF0EA2EEFE0EA3 - EFFF0EA2EEFE0EA2EEFF0DA1ECFE0D9DE6FF0C94DAFE4D92B0FF525454FF4846 - 46FE494747FF484646FE444242F1070707550000001C1F1E1E02000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000067676701312F2F94494747FF494747FF494747FF5E6363FF4EA2C5FF0C95 - DBFF0D9DE7FF0EA1EDFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1186C2FF2C2E2FFF434141FF4846 - 46FF494747FF494747FF3B5766FF0F9FE9FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF2C6B8CFF484646FF494747FF494747FF464444FF343435FF1285 - BFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA2EDFF0D9EE8FF0D97DDFF3396C4FF5D6262FF4947 - 47FF494747FF494747FF494747FE222121980000003001010108000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000067676703393737BE494747FF484646FE494747FF6B7575FE349ECFFF0D97 - DEFF0D9EE8FE0EA2EDFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA2EEFF1B516CFE383737FF4745 - 45FE494747FF494747FF484646FE247CA9FF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0F9EE7FE414B52FF494747FF484646FE484646FF424040FE26404DFF0EA1 - EDFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0DA2EEFE0EA3EFFF0DA2EEFE0D9FE9FF0D99E0FE1E94CFFF657274FF4947 - 47FE494747FF484646FE494747FF3F3D3DE201010145000000162A2929010000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000069696907464444DC494747FF494747FF4A4949FF778787FF1E97D2FF0D99 - E0FF0E9FEAFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1090D2FF292F33FF413F - 3FFF484646FF494747FF494747FF424E55FF119CE2FF0EA3EFFF0EA3EFFF0EA3 - EFFF1F81B4FF474646FF494747FF494747FF484646FF3A3838FF186B95FF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA0EAFF0D9AE2FF1393D4FF677F85FF4A48 - 48FF494747FF494747FF494747FF484646FE1717177D000000290B0B0B050000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000069696909484646F0494747FF484646FE4C4B4BFF7B9396FE1293D4FF0D9A - E2FF0DA0EAFE0EA2EEFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE185D80FF3534 - 34FE464444FF494747FF484646FE484646FF2C7093FE0EA3EFFF0DA2EEFE0EA2 - EEFF345E75FE484646FF494747FF484646FE454343FF2F3437FE1094D8FF0DA2 - EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA0EBFF0D9BE3FE0D92D6FF648793FF4B4A - 4AFE494747FF484646FE494747FF484646FE353434C90000003D000000100000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00006969690B484646FE494747FF494747FF4D4D4DFF78979FFF0F92D5FF0D9A - E3FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0F98DEFF2534 - 3BFF3F3E3EFF484646FF494747FF494747FF45494DFF1693D4FF0EA3EFFF1397 - DBFF43474AFF494747FF494747FF484646FF3F3D3DFF205069FF0EA2EEFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1ECFF0D9BE5FF0C92D7FF608C9DFF4C4B - 4BFF494747FF494747FF494747FF494747FF474545F90E0E0E67000000211414 - 1403000000000000000000000000000000000000000000000000000000000000 - 00006969690B494747FF494747FF494747FF4E4E4EFF769AA3FF0E92D5FF0D9A - E3FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF166A - 96FF333232FF454444FF494747FF494747FF484646FF34637BFF0EA3EFFF227C - AAFF474545FF494747FF494747FF474545FF363536FF147CB2FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1ECFF0D9CE5FF0C93D7FF5E8EA1FF4D4C - 4CFF494747FF494747FF494747FF494747FF494747FF2B2929B0000000350100 - 000B000000000000000000000000000000000000000000000000000000000000 - 00006969690B484646FE494747FF484646FE4E4E4EFF7799A2FE0E92D5FF0D9A - E3FF0DA0EBFE0EA2EEFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0E9F - E9FE223A46FF3D3C3CFF484646FE494747FF484646FE474748FF1D89C1FE3561 - 77FF484646FE494747FF494747FF434141FE293942FF0EA0EAFE0EA3EFFF0DA2 - EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA1ECFF0D9CE5FE0C93D7FF5E8EA0FF4D4C - 4CFE494747FF484646FE494747FF484646FE494747FF464444F30504044F0000 - 001B1F1E1E010000000000000000000000000000000000000000000000000000 - 00006969690A484646FE494747FF494747FF4D4C4CFF7A989EFF0F92D5FF0D9A - E2FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF1478ABFF302F2FFF454343FF484646FF494747FF494747FF3E5866FF454B - 4FFF494747FF494747FF484646FF3C3A3AFF1B6185FF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA2EFFF0EA1ECFF0D9BE4FF0C92D7FF628D9CFF4C4B - 4BFF494747FF494747FF494747FF494747FF494747FF494747FF201F1F940000 - 002F050505070000000000000000000000000000000000000000000000000000 - 000069696907484646F0494747FF484646FE4C4B4BFF7C9295FE1493D4FF0D9A - E1FF0DA0EAFE0EA2EEFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3 - EEFE10A1EBFF25485BFF434141FE504F4FFF525151FE535151FF535151FE5351 - 51FF525050FE504E4EFF4B4949FF333638FE118ECDFF0DA2EEFE0EA3EFFF0DA2 - EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA0EBFF0D9BE3FE0E92D6FF678892FF4B4A - 4AFE494747FF484646FE494747FF484646FE494747FF484646FE3E3C3CDE0202 - 0246000000152928280100000000000000000000000000000000000000000000 - 000069696904484646DB494747FF494747FF4A4949FF768586FF2499D2FF0D98 - E0FF0E9FE9FF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF11A4EFFF1BA7EFFF22AA - F0FF26ACF0FF2992C7FF434243FF565555FF5B5959FF5B5959FF5B5959FF5B59 - 59FF5B5959FF5B5959FF545353FF395A6BFF23A9EFFF1CA8EFFF13A4EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA0EAFF0D9AE2FF1694D3FF697E84FF4A48 - 48FF494747FF494747FF494747FF494747FF494747FF494747FF484646FE1514 - 147A000000270B0B0B0500000000000000000000000000000000000000000000 - 0000000000003A3838BC494747FF484646FE494747FF697373FE3CA1CFFF0D97 - DDFF0D9EE8FE0EA2EDFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0EA3EFFF0DA2EEFE0EA3EFFF13A5EFFE23ABF0FF2DAEF0FE2EAFF1FF2DAF - F0FE2EAFF1FF2EAFF1FF3A667DFE535151FF605E5EFE615F5FFF615F5FFE615F - 5FFF615F5FFE605E5EFF535151FF3586AFFE2EAFF1FF2DAFF0FE2DAFF0FF25AB - F0FE15A5EFFF0EA3EEFE0EA3EFFF0DA2EEFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0DA2EEFE0EA3EFFF0DA2EEFE0D9FE9FF0D98DFFE2496CDFF667172FF4947 - 47FE494747FF484646FE494747FF484646FE494747FF484646FE494747FF3533 - 33C60000003C0000001000000000000000000000000000000000000000000000 - 00000000000034323291494747FF494747FF494747FF5C6161FF58A5C4FF0C95 - DAFF0D9DE6FF0EA1ECFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0FA3EFFF21AAF0FF34B1F1FF36B2F2FF36B2F1FF36B2F2FF36B2 - F1FF36B2F2FF36B2F2FF38A1D8FF4D5255FF616060FF676565FF676565FF6765 - 65FF676565FF636161FF4F5559FF36ADEAFF36B2F2FF36B2F1FF36B2F2FF36B2 - F1FF35B1F1FF25ABF0FF10A3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA1EDFF0D9EE7FF0D96DDFF3C98C2FF5C6060FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4745 - 45FA0C0B0B610000002100000003000000000000000000000000000000000000 - 0000000000002120205C494747FF484646FE494747FF525353FE73A1B0FF0D92 - D6FF0D9BE3FE0EA0EBFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0EA3 - EFFF0FA3EFFF2DAFF0FE3DB5F1FF3DB5F1FE3DB5F2FF3DB5F1FE3DB5F2FF3DB5 - F1FE3DB5F2FF3DB5F2FF3DB5F1FE487D98FF636161FE6C6B6BFF6D6B6BFE6D6B - 6BFF6D6B6BFE646363FF4A7991FF3DB5F1FE3DB5F2FF3DB5F1FE3DB5F2FF3DB5 - F1FE3DB5F2FF3DB5F1FE32B0F1FF12A4EFFE0EA3EFFF0EA3EFFF0DA2EEFE0EA3 - EFFF0DA2EEFE0EA2EEFF0DA1ECFE0D9CE5FF0C94D9FE5894ACFF515252FF4846 - 46FE494747FF484646FE494747FF484646FE494747FF484646FE494747FF4947 - 47FF2A2929AD000000350000000B000000000000000000000000000000000000 - 0000000000000E0D0D22484646F7494747FF494747FF4B4A4AFF788D8FFF2298 - D2FF0D98E0FF0D9FE9FF0EA2EDFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0FA3 - EFFF32B0F1FF46B8F2FF46B8F3FF46B8F2FF46B8F3FF46B8F2FF46B8F3FF46B8 - F2FF46B8F3FF46B8F3FF46B8F2FF48B1E7FF697075FF737272FF737272FF7372 - 72FF727070FF636464FF4AA2CFFF46B8F2FF46B8F3FF46B8F2FF46B8F3FF46B8 - F2FF46B8F3FF46B8F2FF46B8F3FF3AB3F1FF10A4EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA2EEFF0EA0EAFF0D99E1FF1092D4FF6E868BFF4B4A4AFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF434141ED050505500000001A000000010000000000000000000000000000 - 00000000000002010101424141D1484646FE494747FF494747FE646C6CFF4EA3 - C8FF0C95DBFE0D9DE6FF0DA1ECFE0EA2EEFF0DA2EEFE0EA3EFFF0DA2EEFE27AC - F0FF4EBBF3FF4FBBF3FE4FBBF3FF4FBBF3FE4FBBF3FF4FBBF3FE4FBBF3FF4FBB - F3FE4FBBF3FF4FBBF3FF4FBBF3FE50B9F0FF737D82FE7A7979FF7A7979FE7A79 - 79FF757474FE61737DFF4FB9F0FF4FBBF3FE4FBBF3FF4FBBF3FE4FBBF3FF4FBB - F3FE4FBBF3FF4FBBF3FE4FBBF3FF4FBBF3FE31B0F1FF0EA3EFFF0DA2EEFE0EA3 - EFFF0DA2EEFE0EA1EDFF0D9EE7FE0C96DDFF359AC9FE616868FF494747FF4846 - 46FE494747FF484646FE494747FF484646FE494747FF484646FE494747FF4947 - 47FF484646FE1F1E1E900000002E000000070000000000000000000000000000 - 000000000000000000002A29297C494747FF494747FF494747FF525353FF79A0 - AAFF0F92D5FF0D9AE2FF0E9FEAFF0EA2EEFF0EA3EFFF0EA3EFFF11A4EFFF51BC - F3FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BF - F4FF59BFF4FF59BFF4FF59BFF4FF61ADD4FF807E7EFF818080FF818080FF807F - 7FFF777676FF6098B5FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BF - F4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF55BEF3FF18A7EFFF0EA3EFFF0EA3 - EFFF0EA2EEFF0EA0EBFF0D9BE4FF0D93D7FF6094A8FF505151FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF3D3B3BDD01010143000000140000000000000000000000000000 - 0000000000000000000012111123484646F9494747FF494747FF4A4949FF6F7A - 7BFF3EA1CFFF0C96DCFF0D9DE7FF0EA1ECFF0EA2EEFF0EA3EFFF26ACF0FF61C2 - F4FF62C2F4FF62C2F4FF62C2F4FF62C2F4FF62C2F4FF62C2F4FF62C2F4FF62C2 - F4FF62C2F4FF62C2F4FF62C2F4FF769EB4FF888787FF888787FF888787FF8685 - 85FF787A7BFF63BAE7FF62C2F4FF62C2F4FF62C2F4FF62C2F4FF62C2F4FF62C2 - F4FF62C2F4FF62C2F4FF62C2F4FF62C2F4FF62C2F4FF33B1F1FF0EA3EFFF0EA2 - EEFF0EA1EDFF0D9EE8FF0D97DEFF2797CDFF697779FF4A4848FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF484646FD15141477000000260000000500000000000000010000 - 00000000000000000000010101013C3A3AAF494747FF484646FE494747FF5456 - 56FF76A2AFFE1293D5FF0D99E1FE0D9FE9FF0DA1EDFE0EA2EEFF3AB3F1FE6BC6 - F5FF6BC6F5FF6BC6F5FE6BC6F5FF6BC6F5FE6BC6F5FF6BC6F5FE6BC6F5FF6BC6 - F5FE6BC6F5FF6BC6F5FF6CC4F1FE8A959BFF8F8E8EFE8F8E8EFF8F8E8EFE8A88 - 88FF7793A2FE6BC6F4FF6BC6F5FF6BC6F5FE6BC6F5FF6BC6F5FE6BC6F5FF6BC6 - F5FE6BC6F5FF6BC6F5FE6BC6F5FF6BC6F5FE6BC6F5FF49B9F2FF0DA2EEFE0EA2 - EEFF0DA0EAFE0D9BE3FF0D92D7FE5F96ABFF545656FE494747FF4A4848FF4C4B - 4BFE4C4C4CFF4C4C4CFE4C4C4CFF4C4C4CFE4C4C4CFF4C4B4BFE4B4A4AFF4947 - 47FF484646FE494747FF323131C30000003B0000000F00000000000000010000 - 00000000000000000000000000002524243E484646FB494747FF494747FF4A49 - 49FF6C7777FF4AA3CAFF0C94DAFF0D9CE5FF0EA0EBFF0EA2EEFF43B7F2FF75CB - F6FF75CBF6FF75CAF6FF75CBF6FF75CAF6FF75CBF6FF75CAF6FF86A2B1FF919E - A6FF929FA6FF929FA6FF929EA4FF979696FF979696FF979696FF969595FF8D8C - 8CFF79B4D2FF75CBF6FF75CBF6FF75CAF6FF75CBF6FF75CAF6FF75CBF6FF75CA - F6FF75CBF6FF75CAF6FF75CBF6FF75CAF6FF75CBF6FF53BDF3FF0EA2EEFF0EA1 - ECFF0D9DE6FF0C96DCFF3299CAFF677274FF4A4949FF4A4848FF53656DFF6C8D - 9BFF70929FFF70929FFF70929FFF70929FFF70929FFF6F919EFF697B82FF4F4F - 4FFF494747FF494747FF474545F80B0B0B5F0000002000000002000000010000 - 000000000000000000000000000000000000484646B8484646FE494747FF4947 - 47FF515151FE7C979CFF2198D2FE0C97DEFF0D9DE7FE0EA1ECFF3BB3F1FE7FCE - F6FF7FCEF6FF7FCEF6FE7FCEF6FF7FCEF6FE7FCEF6FF7FCEF6FE92A1AAFF9E9D - 9DFE9F9E9EFF9F9E9EFF9E9D9DFE9F9E9EFF9E9D9DFE9F9E9EFF9C9B9BFE8E97 - 9BFF80CBF2FE7FCEF6FF7FCEF6FF7FCEF6FE7FCEF6FF7FCEF6FE7FCEF6FF7FCE - F6FE7FCEF6FF7FCEF6FE7FCEF6FF7FCEF6FE7FCEF6FF4CBAF2FF0DA1ECFE0D9E - E8FF0D98E0FE1693D3FF6C8F99FE505050FF494747FE4A4949FF5A8CA1FF7FD0 - F6FE80D1F7FF7FD0F6FE80D1F7FF7FD0F6FE80D1F7FF7FD0F6FE82ADC0FF5456 - 56FF484646FE494747FF484646FE282727A9000000340000000A000000010000 - 000000000000000000000000000000000000748A8A33484646F7494747FF4947 - 47FF494747FF5C6060FF71A5B7FF1294D5FF0D99E0FF0D9EE8FF1EA7EDFF86D0 - F6FF89D2F7FF89D2F7FF89D2F7FF89D2F7FF89D2F7FF89D2F7FF9AA9B0FFA5A4 - A4FFA6A5A5FFA6A5A5FFA6A5A5FFA6A5A5FFA6A5A5FFA5A4A4FF9F9F9FFF90B1 - C3FF89D2F7FF89D2F7FF89D2F7FF89D2F7FF89D2F7FF89D2F7FF89D2F7FF89D2 - F7FF89D2F7FF89D2F7FF89D2F7FF89D2F7FF88D1F7FF2FAEEFFF0D9FE9FF0D9A - E2FF0E93D6FF5A9AB4FF5B5F5FFF494747FF494747FF4A4848FF566F79FF78CB - F1FF80D0F6FF8BB5C4FF758C92FF697C82FF687B81FF687B81FF606B6EFF4D4D - 4DFF494747FF494747FF494747FF424141EB0404044D00000018000000010000 - 00000000000000000000000000000000000000000000626F6F91494747FF4947 - 47FF484646FE4B4A4AFF687272FE5FA7C3FF0D92D7FE0D99E1FF0D9EE8FE65C3 - F3FF92D5F7FF92D5F7FE92D5F8FF92D5F7FE92D5F8FF92D5F7FEA0ADB4FFA8A7 - A7FEA8A8A8FFA8A8A8FFA8A7A7FEA8A8A8FFA8A7A7FEA8A7A7FFA1A1A2FE94CC - E9FF92D5F7FE92D5F8FF92D5F8FF92D5F7FE92D5F8FF92D5F7FE92D5F8FF92D5 - F7FE92D5F8FF92D5F7FE92D5F8FF92D5F7FE77CAF4FF11A0E9FF0D9AE3FE0C93 - D8FF479CC1FE656F6FFF4B4949FE494747FF484646FE494747FF4E4D4DFF618D - 9FFE7DCFF5FF82CCEEFE7A8C91FF535454FE4B4949FF4A4949FE4A4848FF4947 - 47FF484646FE494747FF484646FE484646FE1D1C1C8B00000027000000040000 - 00000000000000000000000000000000000000000000ABE2E20D4E4F4FDA4947 - 47FF494747FF494747FF4D4C4CFF707D7EFF52A5C8FF0D93D7FF0D99E1FF1FA5 - EAFF8DD2F6FF9DD9F8FF9DD9F8FF9DD9F8FF9DD9F8FF9DD9F8FFA3ACB1FFA5A4 - A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA5A4A4FFA2B0B8FF9DD9 - F7FF9DD9F8FF9DD9F8FF9DD9F8FF9DD9F8FF9DD9F8FF9DD9F8FF9DD9F8FF9DD9 - F8FF9DD9F8FF9DD9F8FF9DD9F8FF97D6F7FF2CABEBFF0D9AE3FF0C94D9FF3B9A - C6FF6C7A7BFF4C4C4CFF494747FF494747FF494747FF494747FF494747FF5152 - 52FF66A3BDFF7FD0F6FF84C4E2FF6F7A7CFF4E4D4DFF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF383737CF000000360000000A0000 - 000000000000000000000000000000000000000000000000000092BABA3D4846 - 46F6484646FE494747FF494747FE4F4F4FFF748384FE52A5C9FF0D92D6FE0D99 - E0FF31ACEAFF9DD8F7FEA6DCF8FFA6DDF8FEA6DDF9FFA6DDF8FEA8C9D9FFA8C6 - D5FEA8C6D5FFA8C6D5FFA8C6D5FEA8C6D5FFA8C6D5FEA8C6D5FFA7D1E7FEA6DD - F9FFA6DDF8FEA6DDF9FFA6DDF9FFA6DDF8FEA6DDF9FFA6DDF8FEA6DDF9FFA6DD - F8FEA6DDF9FFA6DCF8FEA2DAF7FF45B4EDFE0D99E1FF0C93D8FF3C9BC7FE6D7F - 81FF4E4E4EFE494747FF484646FE494747FF484646FE494747FF494747FF4948 - 48FE555C5EFF6EB8D8FE80D0F6FF86B8CEFE636A6AFF4B4A4AFE494747FF4947 - 47FF484646FE494747FF484646FE494747FF474545F90707074B000000100000 - 0000000000000000000000000000000000000000000000000000000000007891 - 916A494747FE494747FF494747FF494747FF4E4E4EFF707D7DFF62A7C2FF1293 - D5FF0C97DDFF2EA9E8FF96D5F5FFB0E0F8FFB0E0F9FFB0E1FAFFB0E1FAFFB0E1 - FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1 - FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E1FAFFB0E0 - F9FFB0E0F9FFA0D9F6FF3DAFEAFF0D98DFFF0F93D6FF4C9DC1FF6C797AFF4E4D - 4DFF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4A4949FF596A70FF75C5E9FF81D1F7FF84A9B8FF5C6060FF4A4848FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF17161674000000140000 - 000000000000000000000000000000000000000000000000000000000000B9F8 - F80138586992494747FE494747FF494747FF494747FF4D4C4CFF677171FF72A5 - B6FF2398D2FF0C94DAFF1A9FE2FF6FC4EFFFB2E1F8FFB9E3F9FFB9E4FAFFB9E4 - FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4 - FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4FAFFB9E4FAFFB6E2 - F8FF7DCAF1FF22A3E4FF0C95DBFF1995D2FF629DB3FF656F6FFF4D4C4CFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4C4B4BFF67828DFF9CD9F6FF9FD9F5FF879AA1FF545555FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF2423238B000000120000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000E88C50638596BA1484646FE494747FF484646FE494747FF4B4949FE5B5F - 5FFF7C9599FF4EA4C9FE1293D4FF0C95DBFE28A5E4FF73C5EFFEB1DFF7FFC2E7 - FAFEC3E7FAFFC3E7FAFFC2E7FAFEC3E7FBFFC2E8FAFEC3E8FBFFC2E8FAFEC3E8 - FBFFC2E7FAFEC3E7FBFFC3E7FBFFC2E7FAFEC3E7FAFFB6E2F8FE7FCAF1FF32A9 - E6FE0D96DDFF0F93D5FE3F9DC8FF739198FE595E5EFF4A4949FF494747FE4947 - 47FF484646FE494747FF484646FE494747FF484646FE494747FF494747FF4846 - 46FE494747FF494747FE4F4F4FFF7B9EACFEADE1F9FFACD9EEFE727B7CFF4C4C - 4CFF484646FE494747FF484646FE494747FF484646FE252424890000000D0000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000E88C60638596A9C494747FD494747FF494747FF494747FF4947 - 47FF505050FF6A7475FF77A1ACFF42A2CDFF1293D5FF0C95DAFF179CE0FF42B0 - E8FF75C6F0FFA0D9F5FFBCE4F8FFC5E8FAFFC9E9FAFFCBEAFAFFCBEAFAFFC9E9 - FAFFC6E8FAFFBFE5F9FFA6DBF6FF7CC9F0FF4BB4EAFF1C9FE1FF0D95DBFF0F93 - D5FF379CCCFF6B9BABFF687272FF505050FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF4A4949FF4D4D - 4DFF4D4C4CFF494848FF494747FF545758FF9CC9DDFFB6E4FAFF95ACB4FF5355 - 55FF494747FF494747FF494747FF494747FF494747FF1C1B1B6E000000070000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000E88C50338596B7D484646FA494747FF484646FE4947 - 47FF494747FF4A4949FE535555FF6D7878FE789EA7FF54A4C6FE279AD2FF0E92 - D5FE0C94DAFF0D96DDFF129ADFFE22A2E3FF2EA7E5FE35AAE6FF36ABE6FE30A8 - E5FF24A3E3FE149BE0FF0D97DDFF0C94DAFE0C92D6FF2198D2FE4AA0C6FF7099 - A6FE6B7677FF535555FE4A4949FF494747FE494747FF494747FF484646FE4947 - 47FF484646FE494747FF484646FE494747FF484646FE4A4848FF64747AFF8DA5 - AFFE7F8F94FF525353FE494747FF4B4A4AFE84A1ACFFBFE7FAFEA5BEC9FF585B - 5BFF484646FE494747FF484646FE494747FF484646FE0F0E0E38000000020000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000296A8B4D47494BE7494747FF4947 - 47FF494747FF494747FF494747FF4A4848FF515252FF616868FF76888AFF769F - ABFF5CA4C0FF43A1CCFF2C9BD0FF1C96D3FF1594D4FF1394D4FF1394D4FF1594 - D4FF1A96D3FF299AD1FF3E9FCCFF56A1BFFF6F9CAAFF748689FF616767FF5151 - 51FF4A4848FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4A4848FF7B939DFFC7EA - FBFFB7D2DFFF676E6EFF4C4C4CFF505151FF98B7C3FFC7EAFBFFA5BCC5FF5759 - 59FF494747FF494747FF494747FF494747FF3F3D3DCF0101010D000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000097CDD11E5C6666AE4947 - 47FE494747FF484646FE494747FF484646FE494747FF494747FE4B4A4AFF5151 - 51FE5A5F5FFF666F6FFF728080FE798D8FFF799397FE77959CFF77959CFE7792 - 97FF788C8EFE717F80FF666F6FFF5A5E5EFE515151FF4B4A4AFE494747FF4947 - 47FE494747FF484646FE494747FF484646FE494747FF494747FF484646FE4947 - 47FF484646FE494747FF484646FE494747FF484646FE494747FF606B6FFFC7E9 - F8FECEECFAFFA4B9BFFE778588FF8CA0A6FEC9E9F8FFCFEDFBFE8B989CFF5050 - 50FF484646FE494747FF484646FE484646FD1F1E1E6100000002000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000008CB1B1015D67 - 674D494747D0494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF4A4848FF4B4949FF4B4B4BFF4C4C4CFF4C4C4CFF4C4B - 4BFF4B4949FF4A4848FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF4D4D4DFF8498 - 9FFFCFEAF7FFD7F0FCFFD6EFFBFFD7F0FCFFD4EEFAFFA7BAC1FF5D6262FF4A48 - 48FF494747FF494747FF494747FF393838B20302020600000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000494747084846465F494747D0484646FE494747FF484646FE494747FF4846 - 46FE494747FF494747FF484646FE494747FF484646FE494747FF484646FE4947 - 47FF484646FE494747FF494747FF484646FE494747FF484646FE494747FF4846 - 46FE494747FF484646FE494747FF484646FE494747FF494747FF484646FE4947 - 47FF484646FE494747FF484646FE494747FF484646FE494747FF494747FF4E4E - 4EFE6A7477FF92A2A8FE9EADB2FF98A9AEFE7C888AFF5A5E5EFE4B4A4AFF4947 - 47FF484646FE494747FF434141D00C0C0C160000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000004947473E4947479D494747E6494747FE4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4A4848FF4C4B4BFF4E4D4DFF4D4D4DFF4B4A4AFF494747FF494747FF4947 - 47FF484646FC3D3C3CA618181811000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000004947470C4947473F4947 - 477E494747B6494747E3494747F8494747FB494747FD494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FD494747F24846 - 46B2444242424442420200000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000D1D0D00DD1D1D127D1D0D036D1D1D13FD1D0D03FD1D1 - D13FD1D0D03FD1D1D13FD1D1D13FD1D0D03FD1D1D13FD1D0D03FD1D1D13FD1D0 - D03FD1D1D13FD1D0D03FD1D1D13FD1D0D03FD1D1D13FD1D1D13FD1D0D03FD1D1 - D13FD1D0D03FD1D1D13FD1D0D03FD1D1D13FD1D0D03FD1D1D13FD1D1D13FD1D0 - D03FD1D1D13FD1D0D03FD1D1D13FD1D0D03FD1D1D13FD1D0D030D1D1D10A0000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF00 - 0000FFFFFFFFFFFFFFFFFF000000FFFFFFC007FFFFFFFF000000FFFFFC00007F - FFFFFF000000FFFFF000000FFFFFFF000000FFFF80000003FFFFFF000000FFFF - 00000000FFFFFF000000FFFC000000007FFFFF000000FFF8000000003FFFFF00 - 0000FFF0000000000FFFFF000000FFE00000000007FFFF000000FFC000000000 - 03FFFF000000FF800000000001FFFF000000FF000000000000FFFF000000FE00 - 0000000000FFFF000000FC0000000000007FFF000000FC0000000000003FFF00 - 0000F80000000000003FFF000000F80000000000001FFF000000F00000000000 - 001FFF000000F00000000000000FFF000000E00000000000000FFF000000E000 - 000000000007FF000000C000000000000007FF000000C000000000000007FF00 - 0000C000000000000003FF000000C000000000000003FF000000C00000000000 - 0001FF0000008000000000000001FF0000008000000000000000FF0000008000 - 000000000000FF0000008000000000000000FF00000080000000000000007F00 - 000080000000000000007F00000080000000000000003F000000800000000000 - 00003F00000080000000000000001F00000080000000000000001F000000C000 - 0000000000001F000000C0000000000000000F000000C0000000000000000F00 - 0000C00000000000000007000000C00000000000000007000000E00000000000 - 000007000000E00000000000000002000000E00000000000000002000000F000 - 00000000000000000000F80000000000000000000000F8000000000000000000 - 0000FC0000000000000000000000FC0000000000000000000000FE0000000000 - 000000000000FF0000000000000000000000FF0000000000000000000000FF80 - 00000000000000000000FFC000000000000000000000FFE00000000000000000 - 0000FFF800000000000001000000FFFC00000000000001000000FFFE00000000 - 000003000000FFFF80000000000007000000FFFFF000000000000F000000FFFF - FC00000000001F000000FFFFFFE000000000FF000000FFFFFFFFFFFFFFFFFF00 - 0000FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF - FFFFFF000000FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF0000002800 - 0000400000008000000001002000000000000042000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000020000 - 00050000000A0000001000000015000000190000001B0000001B0000001A0000 - 0017000000120000000C00000007000000030000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000020000000900000015000000230000 - 00310000003C00000044000000490000004C0000004D0000004E0000004D0000 - 004B000000470000004000000036000000280000001A0000000C000000040000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000121111040000001000000023000000380202024A131212772322 - 22A1323030C13A3939D9444242E9474545F4474545F4474545F4464444F0403E - 3EE1343333CC292828B01A19198B0707075F0000004C0000003E0000002A0000 - 0015090808072D2C2C0100000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000001616 - 160300000010000000280101014218171780323030C3464444F5494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF484646FD3A3939D6201F1F9B0605055C0000 - 0047000000300000001709080806000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000040404090000 - 00220303034422212198414040E9494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF474545F72D2B - 2BB70A0A0A68000000460000002B0000000F1B1A1A0200000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000475F5F0200000012000000331D1C - 1C88424040EA494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4B4A4AFF4E4E4EFF515252FF545656FF555858FF545656FF525353FF4E4E - 4EFF4B4A4AFF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF474545F92A2929B10404045A0000003D0000001C232F2F05000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000272F2F040000001B0A0A0A51383737CE4947 - 47FF494747FF494747FF494747FF494747FF4A4848FF505151FF5F6565FF6A7E - 82FF5F8B9BFF5594AEFF4D99BBFF4B9DC2FF4A9EC5FF499DC3FF4B99BCFF5093 - B0FF598A9EFF667E85FF606767FF515252FF4A4949FF494747FF494747FF4947 - 47FF494747FF494747FF424040EB1616168200000048000000260B0F0F090000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000002F2F2F050000002018181876454343F2494747FF4947 - 47FF494747FF494747FF4C4B4BFF5A5E5EFF6B8389FF5497B3FF3D9FCEFF289D - D8FF2EA2DEFF32A6E1FF35A8E3FF36A9E4FF37A9E4FF37A9E4FF35A8E3FF34A7 - E2FF2FA3DFFF279DDAFF339DD0FF4A95B7FF62838EFF5C6161FF4C4C4CFF4947 - 47FF494747FF494747FF494747FF484646FE292828AD0101014F0000002C0000 - 000B000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000002F2F2F040000002024232392484646FD494747FF494747FF4947 - 47FF4A4949FF5A5E5EFF698A94FF479EC5FF289DD9FF2EA4E0FF33A9E5FF37AC - E8FF3AAFEBFF3CB1ECFF3DB2EDFF3EB2EEFF3FB3EEFF3FB3EEFF3EB2EDFF3DB1 - EDFF3CB0EBFF39AEE9FF36AAE6FF31A6E1FF269DDAFF399AC9FF5C899AFF5C61 - 62FF4B4A4AFF494747FF494747FF494747FF494747FF363434CB030303560000 - 002E00080C0B0000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00002F3F3F030000001D27262698494747FF494747FF494747FF494747FF5051 - 51FF6B7E81FF4C9CC0FF269DD9FF2CA4E2FF32AAE7FF36AEEBFF39B1EEFF3AB2 - EFFF3BB3F0FF3CB4F1FF3DB5F1FF3DB5F1FF3EB5F1FF3EB5F1FF3EB5F1FF3EB5 - F1FF3EB4F1FF3DB4F0FF3CB2EEFF39B0ECFF36ACE9FF30A7E4FF259EDBFF3998 - C5FF637F87FF525353FF494747FF494747FF494747FF494747FF3A3838D60504 - 04580000002C0B0F0F0800000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000005F7F - 7F010000001625242490494747FF494747FF494747FF494848FF585B5BFF6892 - A1FF2D9CD3FF27A1DFFF2DA8E7FF31ADECFF34B0EEFF36B1F0FF37B2F1FF38B3 - F1FF38B3F2FF38B3F2FF39B3F2FF39B3F2FF3AB4F2FF3AB4F2FF3AB4F2FF3AB4 - F2FF3BB4F2FF3BB4F2FF3AB4F1FF3AB3F1FF39B2EFFF37AFEDFF32ABE9FF2BA4 - E1FF249BD6FF538FA9FF5B6060FF4A4848FF494747FF494747FF494747FF3837 - 37D30303035100000025232F2F05000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000D1A191970484646FD494747FF494747FF4A4848FF5F6464FF5E9BB3FF229B - D8FF26A3E3FF2BA9EAFF2FADEEFF30AFF0FF31B0F1FF32B0F1FF32B1F1FF33B1 - F1FF33B1F1FF33B1F1FF34B1F1FF34B1F1FF35B1F1FF35B2F1FF35B2F2FF36B2 - F2FF36B2F2FF36B2F2FF37B2F2FF37B2F2FF37B2F1FF36B1F1FF35B0EFFF31AC - EBFF2BA7E5FF229CDBFF4295BBFF60696AFF4A4949FF494747FF494747FF4947 - 47FF333131C4000000480000001B272A2A020000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000171F1F050D0C - 0C43464444F3494747FF494747FF4A4848FF606666FF569DBBFF1D9ADAFF24A3 - E5FF28A9EBFF2AACEEFF2BAEF0FF2CAEF1FF2CAFF1FF2DAFF1FF2DAFF1FF2EAF - F1FF2EAFF1FF2EAFF1FF2EAFF1FF2FAFF1FF2FAFF1FF2FB0F1FF30B0F1FF30B0 - F1FF30B0F1FF31B0F1FF31B0F1FF31B0F1FF32B0F1FF32B0F1FF32B0F1FF31AF - EFFF2FADEDFF29A7E7FF219EDDFF3895C2FF616B6DFF4A4949FF494747FF4947 - 47FF494747FF242323A10000003C0000000F0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000242323010202021A3C3A - 3AD2494747FF494747FF494747FF5B6060FF5B9DB8FF1A99D9FF20A2E5FF24A8 - ECFF26ABEFFF27ACF0FF27ACF1FF27ACF1FF28ACF1FF28ADF1FF28ADF1FF28AD - F1FF29ADF1FF29ADF1FF29ADF1FF29ADF1FF2AADF1FF2AAEF1FF2AAEF1FF2BAE - F1FF2BAEF1FF2BAEF1FF2CAEF1FF2CAEF1FF2DAFF1FF2DAFF1FF2DAFF1FF2DAF - F0FF2DAEF0FF2BABEDFF26A6E8FF1F9DDDFF3A95BFFF5E6565FF494848FF4947 - 47FF494747FF484646FB101010710000002A0908080500000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000004040409242323854947 - 47FF494747FF494747FF545555FF6799AAFF1998D8FF1BA0E4FF1FA6EBFF21A9 - EEFF22AAF0FF22AAF0FF22ABF0FF23ABF0FF23ABF0FF23ABF0FF24ABF0FF24AB - F0FF24ABF0FF25ABF0FF25ABF0FF25ACF0FF25ACF0FF26ACF0FF26ACF1FF26AC - F1FF26ACF1FF27ACF1FF28AAEDFF4B7185FF3D8BB2FF2CA7E6FF28ADF1FF28AD - F1FF28ADF0FF28ACF0FF27AAEDFF22A5E7FF1B9ADBFF4993B3FF565A5AFF4947 - 47FF494747FF494747FF3D3C3CDE010101470000001500000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000010707072B474545F24947 - 47FF494747FF4C4C4CFF708A8FFF2098D3FF179DE1FF1BA4EAFF1CA7EEFF1DA7 - EEFF314855FF4C4A4AFF555353FF555353FF555353FF3484ADFF1FA9F0FF1FA9 - F0FF20A9F0FF20A9F0FF20AAF0FF20AAF0FF21AAF0FF21AAF0FF21AAF0FF22AA - F0FF22AAF0FF22AAF0FF338CB9FF585656FF595757FF57595BFF487287FF3591 - C0FF25A9ECFF24ABF0FF24AAEFFF22A8ECFF1EA2E5FF1897D8FF5C899AFF4E4E - 4EFF494747FF494747FF494747FF201F1F970000002E09080806000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000072E2D2D9E494747FF4947 - 47FF494747FF646B6BFF409EC9FF1499DDFF16A1E8FF18A5EEFF18A7EFFF19A7 - F0FF1E84B8FF3C3A3AFF4F4D4DFF525050FF525050FF4D565CFF1DA2E5FF1BA8 - F0FF1BA8F0FF1BA8F0FF1BA8F0FF1CA8F0FF1CA8F0FF1CA8F0FF1CA8F0FF1DA8 - F0FF1DA8F0FF1DA8F0FF456577FF555353FF555353FF555353FF565454FF5654 - 54FF525A5FFF407794FF2B95CBFF1FA8EEFF1DA5EAFF199EE2FF2396CEFF6371 - 74FF4A4848FF494747FF494747FF434242EE0303034900000013000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000007070725474545F5494747FF4947 - 47FF505151FF6998A9FF1094D7FF129EE5FF14A3ECFF15A5EFFF15A5EFFF16A6 - EFFF16A6EFFF264D61FF444242FF4E4D4DFF4F4D4DFF4F4D4DFF357394FF17A6 - F0FF17A6F0FF17A6F0FF18A6F0FF18A7F0FF18A7F0FF18A7F0FF18A7F0FF19A7 - F0FF19A7F0FF2197D4FF504E4EFF525050FF525050FF525050FF525151FF5351 - 51FF535151FF525050FF454343FF2282B3FF1BA6EDFF18A2E8FF1498DCFF4892 - B3FF525454FF494747FF494747FF494747FF1F1E1E92000000261B1A1A030000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000327262684494747FF494747FF4947 - 47FF687272FF329CCEFF0F99DFFF11A0E9FF12A3EDFF12A4EFFF12A4EFFF12A4 - EFFF13A4EFFF168DCAFF323233FF494747FF4D4B4BFF4D4B4BFF4B4C4EFF1C97 - D6FF14A5EFFF14A5EFFF15A5EFFF15A5EFFF15A5EFFF15A5EFFF15A5EFFF16A6 - EFFF16A6EFFF347090FF4E4D4DFF4F4D4DFF4F4D4DFF4C4A4AFF494747FF4E4C - 4CFF504E4EFF4D4B4BFF343F46FF18A3EBFF17A6EFFF16A3ECFF139CE3FF1794 - D3FF65787CFF4A4848FF494747FF494747FF3D3C3CDD0000003B0000000B0000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000009424040DC494747FF494747FF4E4E - 4EFF6C97A5FF0D92D7FF0E9CE5FF0FA1ECFF0FA3EEFF10A3EFFF10A3EFFF10A4 - EFFF10A4EFFF10A4EFFF1D5673FF3D3B3BFF4A4848FF4B4949FF4B4949FF3764 - 7BFF11A4EFFF11A4EFFF11A4EFFF12A4EFFF12A4EFFF12A4EFFF12A4EFFF12A4 - EFFF14A0E8FF464E52FF4C4A4AFF4D4B4BFF4B4949FF3B3939FF2C2B2BFF3534 - 34FF413F3FFF3F3E3EFF216385FF15A5EFFF14A5EFFF14A4EDFF119FE7FF0E96 - DBFF4B90AFFF505151FF494747FF494747FF494747FF100F0F690000001C2927 - 2701000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000013121239494747FF494747FF494747FF5D62 - 62FF459FC7FF0D97DDFF0D9EE9FF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF1094D8FF2C3033FF454343FF4A4848FF4A4848FF4947 - 47FF1D8AC2FF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EFFF10A3EFFF10A3EFFF10A3 - EFFF247FAEFF4A4848FF4A4848FF4A4848FF454343FF27485AFF14709FFF1A3A - 4BFF222121FF242425FF1492D2FF12A4EFFF11A4EFFF11A3EEFF0FA0EAFF0E99 - E1FF2195CEFF616969FF494747FF494747FF494747FF2E2D2DB8000000330908 - 0807000000000000000000000000000000000000000000000000000000000000 - 000000000000000000003F3F3F012726267F494747FF494747FF4A4848FF7383 - 85FF1A96D3FF0D9AE2FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF186085FF383737FF484646FF494747FF4947 - 47FF3D5663FF0EA1ECFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF395A6CFF4A4848FF4A4848FF494747FF3C3A3AFF1775A5FF0FA3EFFF0FA3 - EFFF1189C6FF136792FF0FA3EFFF0FA3EFFF0FA3EFFF0FA3EEFF0EA1ECFF0D9C - E5FF0C92D7FF618490FF4A4949FF494747FF494747FF474545F7060606510000 - 0015000000000000000000000000000000000000000000000000000000000000 - 000000000000000000003F3F3F02383737B9494747FF494747FF4D4D4DFF6B98 - A7FF0C93D8FF0D9CE6FF0EA1EDFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0E9CE5FF27343BFF424040FF484646FF4947 - 47FF484646FF247DABFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1692 - D2FF474545FF494747FF494747FF464444FF2E3539FF0E9DE6FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0D9E - E8FF0C96DCFF4A91B1FF4F4F4FFF494747FF494747FF494747FF2422229D0000 - 002B121111040000000000000000000000000000000000000000000000000000 - 000000000000000000003F3F3F05474545E6494747FF494747FF545656FF569F - BDFF0C96DCFF0D9EE8FF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF156E9CFF353434FF474545FF4947 - 47FF494747FF424E54FF109DE5FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF2B6D - 90FF484646FF494747FF484646FF403E3EFF1E5978FF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0E9F - EAFF0D98DFFF3397C6FF585B5BFF494747FF494747FF494747FF413F3FE70101 - 01420000000F0000000000000000000000000000000000000000000000000000 - 000000000000000000004B4A4A14494747FF494747FF494747FF5D6262FF43A0 - CAFF0D97DFFF0E9FE9FF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA0EBFF233B47FF403E3EFF4846 - 46FF494747FF484646FF2C7093FF0EA3EFFF0EA3EFFF0EA3EFFF0EA0EBFF404C - 53FF494747FF494747FF474545FF363535FF1287C2FF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA0 - EBFF0D9AE2FF1F96D1FF626A6AFF494747FF494747FF494747FF494747FF1918 - 1882000000231B1A1A0200000000000000000000000000000000000000000000 - 000000000000000000005150502F494747FF494747FF494747FF676F6FFF319E - D1FF0D99E1FF0EA0EAFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF137BB1FF323131FF4644 - 44FF494747FF494747FF46484AFF1596D8FF0EA3EFFF0EA3EFFF1D84B9FF4846 - 46FF494747FF494747FF444242FF27404DFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1 - ECFF0D9BE4FF1092D5FF68787AFF494747FF494747FF494747FF494747FF3836 - 36CE0000003A0404040A00000000000000000000000000000000000000000000 - 0000000000000000000051515141494747FF494747FF494747FF6E7A7AFF259A - D3FF0D9AE2FF0EA0EBFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1F4559FF3E3C - 3CFF484646FF494747FF494747FF33647DFF0EA3EFFF0EA3EFFF31627BFF4846 - 46FF494747FF484646FF3C3B3BFF196B95FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1 - EDFF0D9CE5FF0C92D6FF678086FF494747FF494747FF494747FF494747FF4846 - 46FE0E0D0D650000001B29272701000000000000000000000000000000000000 - 0000000000000000000052515143494747FF494747FF494747FF737F7FFF1F98 - D3FF0D9AE2FF0EA0EBFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1189C6FF2F2E - 2FFF454343FF494747FF494747FF484646FF1B8BC5FF0F9FE8FF434649FF4947 - 47FF494747FF464545FF313335FF0F98DEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1 - EDFF0D9CE5FF0C92D6FF65828BFF494848FF494747FF494747FF494747FF4947 - 47FF2D2B2BB50000003209080807000000000000000000000000000000000000 - 0000000000000000000052515142494747FF494747FF494747FF727F7FFF1F98 - D3FF0D9AE2FF0EA0EBFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1C52 - 6EFF3B3A3AFF484646FF494747FF494747FF3C5867FF1F85BAFF484646FF4947 - 47FF494747FF424040FF215069FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1 - EDFF0D9CE5FF0C92D6FF66838BFF494848FF494747FF494747FF494747FF4947 - 47FF464444F50505054F00000015000000000000000000000000000000000000 - 0000000000000000000051515140494747FF494747FF494747FF6E7979FF289B - D3FF0D99E1FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0F93 - D7FF2B2F32FF444242FF494747FF494747FF494747FF41525BFF494747FF4947 - 47FF484646FF383737FF147DB3FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1 - EDFF0D9CE5FF0C92D6FF698085FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF2221219A0000002A121111040000000000000000000000000000 - 000000000000000000005151512C494747FF494747FF494747FF666E6EFF369F - D0FF0D99E0FF0EA0EAFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF10A3EFFF16A6 - EFFF256789FF464444FF555353FF575555FF585656FF575555FF575555FF5553 - 53FF4F4E4EFF334148FF11A2ECFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1 - ECFF0D9BE3FF1293D4FF6A7779FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF403E3EE5000000400000000F0000000000000000000000000000 - 000000000000000000004C4C4C10494747FF494747FF494747FF5C6161FF49A2 - C9FF0D97DEFF0D9FE9FF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF17A6EFFF23ABF0FF29ADF0FF2AAD - F1FF2AA6E6FF404B50FF585757FF5E5C5CFF5E5C5CFF5E5C5CFF5E5C5CFF5E5C - 5CFF555353FF367494FF2AADF1FF25ABF0FF1BA7EFFF0FA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA0 - EBFF0D99E1FF2497D0FF626969FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF1716167D000000221B1A1A0200000000000000000000 - 0000000000000000000000000000484646E7494747FF494747FF535555FF5EA1 - BCFF0C95DBFF0D9EE7FF0EA2EDFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF16A6EFFF2BAEF1FF32B0F1FF32B0F1FF32B0F1FF32B0 - F1FF32B0F1FF3982A8FF545353FF636161FF646262FF646262FF646262FF6361 - 61FF525252FF34A1D8FF32B0F1FF32B0F1FF32B0F1FF2EAFF1FF1BA8F0FF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0D9F - E9FF0D98DFFF3A98C4FF575A5AFF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF363535CB000000390404040A00000000000000000000 - 00000000000000000000000000003A3939B7494747FF494747FF4D4C4CFF759A - A5FF0C92D6FF0D9CE5FF0EA1ECFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF22AAF0FF3AB4F1FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4 - F2FF3BB4F2FF3BB2EFFF4E6069FF666565FF6B6969FF6B6969FF6B6969FF6665 - 65FF4D6A79FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4F2FF3BB4F2FF2BAE - F0FF0FA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EDFF0D9E - E7FF0C95DBFF5393AEFF4F4F4FFF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF484646FD0C0C0C620000001A00000001000000000000 - 000000000000000000000000000028272778494747FF494747FF494848FF7381 - 81FF259AD3FF0D99E1FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF26ACF0FF44B7F2FF45B7F2FF45B7F2FF45B7F2FF45B7F2FF45B7F2FF45B7 - F2FF45B7F2FF45B7F2FF4C9BC4FF6D6C6CFF727171FF727171FF727070FF6766 - 66FF4B93B9FF45B7F2FF45B7F2FF45B7F2FF45B7F2FF45B7F2FF45B7F2FF45B7 - F2FF33B1F1FF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0EA1ECFF0D9B - E4FF0E92D6FF6A858CFF4A4848FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF2B2A2AB10000003000000006000000000000 - 000000000000000000000000000016151531494747FF494747FF494747FF5B5F - 5FFF53A3C5FF0C96DCFF0D9EE8FF0EA2EDFF0EA3EFFF0EA3EFFF0EA3EFFF1CA8 - EFFF4DBBF3FF4EBBF3FF4EBBF3FF4EBBF3FF4EBBF3FF4EBBF3FF4EBBF3FF4EBB - F3FF4EBBF3FF4EBBF3FF53B1E1FF787777FF7A7878FF7A7878FF787676FF666B - 6EFF4FB7ECFF4EBBF3FF4EBBF3FF4EBBF3FF4EBBF3FF4EBBF3FF4EBBF3FF4EBB - F3FF4EBBF3FF2BAEF0FF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0D9FEAFF0D98 - E0FF2E99CBFF606667FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF464444F30504044D00000014000000000000 - 000000000000000000000000000000000000444242DB494747FF494747FF4D4D - 4DFF7899A1FF1093D5FF0D9BE4FF0EA0EBFF0EA2EEFF0EA3EFFF0EA3EFFF46B8 - F2FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BF - F4FF59BFF4FF59BFF4FF6A9FBBFF818080FF828080FF818080FF7C7B7BFF648C - A1FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BFF4FF59BF - F4FF59BFF4FF54BDF3FF12A4EFFF0EA3EFFF0EA2EEFF0EA1ECFF0D9DE6FF0C94 - D9FF5993AAFF4F4F4FFF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF2120209600000029000000030000 - 0000000000000000000000000000000000002D2C2C79494747FF494747FF4947 - 47FF656E6EFF43A2CCFF0C97DDFF0D9EE8FF0EA1EDFF0EA2EEFF15A5EFFF63C3 - F4FF64C3F4FF64C3F4FF64C3F4FF64C3F4FF64C3F4FF64C3F4FF64C3F4FF64C3 - F4FF64C3F4FF64C3F4FF80939EFF8A8888FF8A8888FF898888FF7E7D7DFF67B1 - D7FF64C3F4FF64C3F4FF64C3F4FF64C3F4FF64C3F4FF64C3F4FF64C3F4FF64C3 - F4FF64C3F4FF64C3F4FF2AADF0FF0EA3EFFF0EA2EEFF0D9FEAFF0D99E1FF2096 - D0FF697577FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF3F3D3DE10000003F0000000E0000 - 0000000000010000000000000000000000000D0D0D15484646F6494747FF4947 - 47FF4F4F4FFF789BA4FF1293D5FF0D9AE3FF0EA0EBFF0EA2EEFF23ABF0FF6EC8 - F5FF6EC8F5FF6EC8F5FF6EC8F5FF6EC8F5FF6EC8F5FF70C3EDFF74BDE2FF75BE - E3FF75BEE3FF77BADCFF919091FF929191FF929191FF8F8E8EFF7E8C94FF6EC8 - F5FF6EC8F5FF6EC8F5FF6EC8F5FF6EC8F5FF6EC8F5FF6EC8F5FF6EC8F5FF6EC8 - F5FF6EC8F5FF6EC8F5FF3CB4F2FF0EA2EEFF0EA1ECFF0D9CE5FF0C93D8FF5B95 - ACFF515252FF494747FF4D4D4DFF535454FF545555FF545555FF545555FF5455 - 55FF535555FF4F5050FF4A4848FF494747FF494747FF16151579000000210000 - 000200000001000000000000000000000000000000004846468F494747FF4947 - 47FF494747FF616767FF56A5C6FF0C95DAFF0D9DE6FF0EA1ECFF23AAF0FF7ACC - F6FF7ACCF6FF7ACCF6FF7ACCF6FF7ACCF6FF7ACCF6FF82B5CFFF989797FF9B99 - 99FF9B9999FF9B9999FF9B9999FF9B9999FF9A9999FF949393FF80ADC3FF7ACC - F6FF7ACCF6FF7ACCF6FF7ACCF6FF7ACCF6FF7ACCF6FF7ACCF6FF7ACCF6FF7ACC - F6FF7ACCF6FF7ACCF6FF3EB5F2FF0EA1EDFF0D9EE8FF0C97DEFF3199CAFF656E - 6EFF494747FF4B4949FF5E8FA5FF7BBBD8FF7CBDD9FF7CBDD9FF7CBDD9FF7CBD - D9FF7CBCD9FF7896A3FF4F4F4FFF494747FF494747FF353333C8000000370000 - 00090000000100000000000000000000000000000000575D5D18484646F24947 - 47FF494747FF4C4B4BFF758889FF2C9BD0FF0D97DEFF0D9EE8FF13A3EDFF80CE - F6FF85D0F7FF85D0F7FF85D0F7FF85D0F7FF85D0F7FF8CBBD3FFA1A0A0FFA3A2 - A2FFA3A2A2FFA3A2A2FFA3A2A2FFA3A2A2FFA2A1A1FF979898FF86CAEDFF85D0 - F7FF85D0F7FF85D0F7FF85D0F7FF85D0F7FF85D0F7FF85D0F7FF85D0F7FF85D0 - F7FF85D0F7FF85D0F7FF2CADEFFF0D9FE9FF0D99E1FF1694D4FF6B8992FF4D4C - 4CFF494747FF4B4949FF609AB3FF80D1F7FF83CAEBFF81B8CDFF79ADC3FF78AC - C2FF78ACC2FF718B95FF4E4E4EFF494747FF494747FF484646FD0B0B0B5E0000 - 0019000000010000000000000000000000000000000000000000748B8B744947 - 47FF494747FF494747FF525353FF789BA4FF1A96D4FF0D99E0FF0D9EE8FF5EC0 - F2FF90D4F7FF90D4F7FF90D4F7FF90D4F7FF90D4F7FF96C1D7FFA7A6A6FFA8A8 - A8FFA8A8A8FFA8A8A8FFA8A8A8FFA8A8A8FFA6A5A5FF98AEB9FF90D4F7FF90D4 - F7FF90D4F7FF90D4F7FF90D4F7FF90D4F7FF90D4F7FF90D4F7FF90D4F7FF90D4 - F7FF90D4F7FF7CCCF5FF10A0EAFF0D9AE3FF0E93D6FF6197ABFF545656FF4947 - 47FF494747FF494747FF545C5FFF72BFE2FF80D0F5FF83A1ABFF595D5DFF4F50 - 50FF4F4F4FFF4D4C4CFF494747FF494747FF494747FF494747FF2A2929AD0000 - 002C000000040000000000000000000000000000000000000000B6F3F3045052 - 52CB494747FF494747FF494747FF585B5BFF72A3B2FF1394D5FF0D99E0FF1DA4 - E9FF8FD3F6FF9BD8F8FF9BD8F8FF9BD8F8FF9BD8F8FF9EC3D6FFA5A4A4FFA5A5 - A5FFA5A5A5FFA5A5A5FFA5A5A5FFA5A5A5FFA4A4A4FF9DC8DEFF9BD8F8FF9BD8 - F8FF9BD8F8FF9BD8F8FF9BD8F8FF9BD8F8FF9BD8F8FF9BD8F8FF9BD8F8FF9BD8 - F8FF99D7F7FF36AFEDFF0D9AE3FF0C93D7FF559BB8FF5C6161FF494747FF4947 - 47FF494747FF494747FF4A4848FF596E75FF78CAF0FF82CDF0FF76878BFF4E4E - 4EFF494747FF494747FF494747FF494747FF494747FF494747FF444242EF0101 - 013E0000000B000000000000000000000000000000000000000000000000A0D1 - D127484646F3494747FF494747FF494848FF5C6161FF71A4B4FF1595D5FF0D98 - DFFF33ACEAFF9FD9F7FFA6DCF8FFA6DDF9FFA6DDF9FFA7D1E7FFA8C2D0FFA8C2 - D0FFA8C2D0FFA8C2D0FFA8C2D0FFA8C2D0FFA8C3D0FFA6DCF8FFA6DDF9FFA6DD - F9FFA6DDF9FFA6DDF9FFA6DDF9FFA6DDF9FFA6DDF9FFA6DDF9FFA6DCF9FFA5DB - F8FF53BAEEFF0D9AE1FF0D93D7FF559CBAFF606667FF4A4848FF494747FF4947 - 47FF494747FF494747FF494747FF4C4B4BFF5F8493FF7DD0F6FF85C6E4FF6B74 - 75FF4C4B4BFF494747FF494747FF494747FF494747FF494747FF494747FF1514 - 146F000000120000000000000000000000000000000000000000000000000000 - 000083A3A355494747FE494747FF494747FF4A4848FF5B5F5FFF76A0ACFF2198 - D2FF0C96DCFF30A9E8FF9CD7F6FFB1E0F9FFB1E1F9FFB1E1FAFFB1E1FAFFB1E1 - FAFFB1E1FAFFB1E1FAFFB1E1FAFFB1E1FAFFB1E1FAFFB1E1FAFFB1E1FAFFB1E1 - FAFFB1E1FAFFB1E1FAFFB1E1FAFFB1E1FAFFB1E1F9FFB1E0F9FFAADDF7FF4BB5 - ECFF0D98DFFF1294D5FF609BB2FF5E6464FF4A4848FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4E4E4EFF669DB4FF80D0F7FF85B9 - D1FF606666FF4A4949FF494747FF494747FF494747FF494747FF494747FF2625 - 259D000000160000000000000000000000000000000000000000000000000000 - 00000000000032607879494747FF494747FF494747FF494747FF555757FF7993 - 98FF3FA0CDFF0C93D7FF179DE1FF6DC3EFFFB4E1F8FFBBE4F9FFBBE5FAFFBBE5 - FAFFBBE5FAFFBBE5FAFFBBE5FAFFBBE5FAFFBBE5FAFFBBE5FAFFBBE5FAFFBBE5 - FAFFBBE5FAFFBBE5FAFFBBE5FAFFBBE4F9FFBAE3F9FF84CDF2FF26A4E4FF0C94 - DAFF2999CFFF6C939EFF575B5BFF494848FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF535656FF8DC0D6FFA4DE - F9FF92AEB9FF565959FF494747FF494747FF494747FF494747FF494747FF3130 - 30B1000000140000000000000000000000000000000000000000000000000000 - 0000000000000000000032607887494747FF494747FF494747FF494747FF4E4E - 4EFF6C7778FF6AA4B8FF2499D2FF0C94D9FF1FA0E2FF66C0EDFFA5DBF6FFC5E8 - FAFFC5E8FAFFC5E8FBFFC5E8FBFFC5E9FBFFC5E9FBFFC5E9FBFFC5E8FBFFC5E8 - FBFFC5E8FAFFC5E8FAFFB3E1F8FF76C7F0FF2FA7E5FF0C95DBFF1695D4FF549D - BCFF6D7C7DFF505050FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF5B6568FFA4D5 - ECFFB0E0F7FF7A8688FF4C4B4BFF494747FF494747FF494747FF494747FF302F - 2FAA0000000D0000000000000000000000000000000000000000000000000000 - 000000000000000000000000000032607876494747FE494747FF494747FF4947 - 47FF4A4848FF565959FF76888AFF63A3BCFF2B9CD2FF0C92D7FF0C96DCFF24A2 - E3FF50B6EAFF71C4EFFF88CEF2FF96D4F4FF9DD7F5FF99D5F4FF8CD0F3FF78C7 - F0FF58B9EBFF2FA7E5FF0F98DEFF0C93D8FF1D97D3FF529FBFFF728A8FFF585C - 5CFF4A4949FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF515252FF5A5E5EFF525353FF494747FF4B4949FF7E9B - A6FFBAE6FBFF99B1BAFF515151FF494747FF494747FF494747FF494747FF2423 - 2387000000060000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000002A698950494747F0494747FF4947 - 47FF494747FF494747FF4B4949FF565959FF717E7FFF729DA9FF53A3C5FF2E9D - D2FF1193D4FF0C92D7FF0C94D9FF0C95DAFF0C95DBFF0C95DBFF0C94DAFF0C93 - D8FF0E92D5FF2599D2FF48A0C7FF679AACFF718183FF585B5BFF4B4A4AFF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4A4949FF8EAFBEFFBFE5F7FF839195FF4D4D4DFF4A4848FF768B - 92FFC4E9FBFFA1B8C0FF525353FF494747FF494747FF494747FF494747FF1312 - 1240000000010000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000074B4C422575E5EC24947 - 47FF494747FF494747FF494747FF494747FF494848FF4E4E4EFF5A5E5EFF6C77 - 77FF7A8F91FF7399A4FF689DB0FF619FB7FF5E9FB9FF5F9FB7FF659DB1FF6E98 - A5FF788F93FF6E7979FF5B5F5FFF4F4F4FFF4A4848FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF4A4848FF8198A0FFCDECFCFFB5CDD7FF6B7474FF626A6BFFAECC - D9FFCDECFCFF91A2A7FF4E4E4EFF494747FF494747FF494747FF3E3C3CCA0000 - 0006000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000099C5C5016675 - 7563494747E7494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF4A4848FF4C4B4BFF4F4F4FFF515151FF525353FF515252FF4F4F4FFF4C4C - 4CFF4A4949FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF55595AFFB4D0DCFFD6F0FCFFCEE9F5FFCFEAF7FFD6F0 - FCFFB9D0D9FF626767FF4A4848FF494747FF494747FF484646FA1414143A0000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00004947470C49474776494747E4494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494848FF56595AFF87979CFFA3B3B9FFA3B4B9FF8C9A - 9EFF5E6364FF4C4A4AFF494747FF494747FF494747FE2A282867000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000004947470549474752494747AD494747F6494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF4A4949FF4D4C4CFF4D4D4DFF4B4A - 4AFF494747FF494747FF494747FF484646E93533335000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000049474709494747434947 - 477C494747AB494747CF494747E9494747FA494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747F1494747C1484646704442420D0000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFF8001FFFFFFFFFFFC00003FFFFFFFFFF0000007FFFFFFFFC - 0000003FFFFFFFF80000000FFFFFFFE000000007FFFFFFC000000003FFFFFF80 - 00000001FFFFFF0000000000FFFFFE00000000007FFFFC00000000003FFFFC00 - 000000001FFFF800000000001FFFF000000000000FFFF000000000000FFFE000 - 0000000007FFE0000000000007FFE0000000000003FFC0000000000003FFC000 - 0000000001FFC0000000000001FF80000000000001FF80000000000000FF8000 - 0000000000FF800000000000007F800000000000007F800000000000003F8000 - 00000000003F800000000000003F800000000000001F800000000000001F8000 - 00000000000FC00000000000000FC000000000000007C000000000000007C000 - 000000000007E000000000000003E000000000000002E000000000000000F000 - 000000000000F000000000000000F800000000000000F800000000000000FC00 - 000000000000FE00000000000000FF00000000000000FF80000000000000FFC0 - 000000000000FFE0000000000000FFF0000000000001FFF8000000000003FFFE - 000000000007FFFF80000000000FFFFFF0000000001FFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFF2800000030000000600000000100200000000000802500000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000200000008000000110000001A000000210000 - 002400000025000000230000001D000000140000000B00000004000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000A09 - 0901000000090000001B000000310404044B1110106F1B1A1A8C2221219D2322 - 22A1232222A1201F1F98161616830B0B0B640101014700000036000000210000 - 000C050404020000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000A0A0A0A0000 - 0024080707502221219B393838D5464444F7484646FE494747FF484646FE4846 - 46FE494747FF484646FE484646FE484646FD424040EB2E2D2DBD1414147E0000 - 00470000002C0606060F29282801000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000191818040000001C0C0C0C59302E - 2EBD484646FA494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF3F3D - 3DE41E1D1D950101014A000000250F0E0E070000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000202B2B0904040435292828A9474545F94846 - 46FE484646FE494747FE4A4949FF525353FE5D6566FE5E7379FF5B7B87FE5B7F - 8DFE5A7D8AFF5B757EFE5E6A6CFE565858FF4C4B4BFE494747FE494747FF4846 - 46FE484646FE3C3B3BDE12111178000000380C10100F00000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000001C1C1C0D0D0D0D533E3C3CDF484646FE494747FF4947 - 47FE4F5050FE617073FE548CA3FF439CC5FE32A0D7FE2FA3DDFF31A5E0FE33A6 - E1FE32A6E1FF30A4DFFE2FA0DAFE399DCEFF4990B0FE5A7884FE555757FF4948 - 48FE484646FE494747FF474545FB262525A7010101430A0A0A15467287010000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000001A1A1A0D16151568454343F3494747FF494747FF4D4D4DFF6174 - 79FF4C97B9FF2DA0D9FF31A7E3FF36ACE8FF3AAFEBFF3CB2EDFF3EB3EEFF3FB3 - EFFF3FB3EFFF3EB3EEFF3DB1EDFF3AAEEAFF35AAE6FF2BA2DEFF3A9AC9FF567F - 8FFF535555FF494747FF494747FF494747FF323131C50202024A000407160000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00002531310816161665464444F6484646FE494747FF585C5CFE588FA6FF2C9E - D7FE2DA6E4FE33ADEBFE37B0EEFF39B2F0FE3AB3F1FE3BB4F1FF3BB4F1FE3CB4 - F1FE3CB4F2FF3CB4F1FE3DB4F1FE3CB4F1FF3BB3EFFE38B0EDFE33ABE8FF29A1 - DEFE3E95BDFE5A6A70FF4A4949FE494747FF484646FE353333CB02020248080A - 0A11000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000004F6A - 6A030E0E0E4A464444F4494747FF494747FF5E6869FF4699BEFF24A0DFFF2BA9 - E9FF30AEEEFF32B0F0FF33B1F1FF34B1F1FF34B1F1FF35B1F1FF35B2F1FF35B2 - F1FF36B2F1FF36B2F2FF37B2F2FF37B2F2FF37B3F1FF37B2F1FF36B1F0FF33AD - ECFF2BA6E4FF2C9AD1FF597884FF4C4B4BFF494747FF494747FF302F2FBF0000 - 003A171D1D090000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000505 - 0524403E3EE0494747FF494747FE5F6A6BFE3C9AC7FF21A0E1FE27A9EBFF2AAC - EFFE2BAEF0FE2BAEF0FE2CAEF1FF2CAEF0FE2DAFF0FE2DAFF1FF2EAFF0FE2EAF - F0FE2EAFF1FF2FAFF0FE30B0F0FE30B0F1FF30B0F1FE31B0F1FE31B0F1FF31AF - F0FE2FADEEFE29A7E7FF249BD7FE577C8BFF4B4A4AFE484646FE494747FF2221 - 219C000000292221210200000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000000D0D0D092E2D - 2DA6484646FE494747FF5B6061FE4299C2FE1C9EE1FF21A7EBFE24AAEFFF24AB - F0FE25ABF0FE25ABF0FE26ACF0FF26ACF0FE26ACF0FE27ACF0FF27ACF0FE27AC - F0FE28ADF1FF28ADF0FE29ADF0FE29ADF1FF31A0DAFE30A3DEFE2AAEF1FF2AAE - F0FE2AADF0FE29ACEEFF24A5E7FE2299D5FF5A747EFE4A4848FE494747FF4644 - 44F80D0D0D650101011300000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000111111474846 - 46FB484646FE505151FF5594AFFE179BDDFE1BA4EAFF1DA8EFFE297298FF4364 - 75FE48697AFE48697AFE2C94CAFF20A9EFFE20AAEFFE21AAF0FF21AAF0FE21AA - F0FE22AAF0FF22AAF0FE23ABF0FE23ABF0FF476E82FE58595AFE4C6D7FFF398C - B7FE28A7E8FE25ABF0FF24A9EDFE1EA2E5FF2A96CBFE596365FE494747FF4846 - 46FE373535CF000000331E1D1D03000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000007393737C34947 - 47FF4A4848FF658088FF1A98D8FF16A0E8FF17A5EEFF18A7EFFF1B93D0FF3C3E - 3FFF504E4EFF525050FF45616FFF1BA6EDFF1AA7F0FF1AA7F0FF1BA8F0FF1BA8 - F0FF1BA8F0FF1CA8F0FF1CA8F0FF239BD9FF525354FF555353FF555353FF5553 - 53FF53575AFF42728AFF298EC2FF1DA6ECFF189DE0FF448DAEFF4E4E4EFF4947 - 47FF484646FE1514147605040411000000000000000000000000000000000000 - 000000000000000000000000000000000000000000001111113E484646FE4947 - 47FE565959FE3F9AC4FF109BE2FE13A3ECFE13A5EFFF14A5EFFE14A5EFFF225E - 7CFE464444FE4E4C4CFE4E4C4CFF2A82B0FE16A6EFFE16A6EFFF16A6EFFE16A6 - EFFE17A6EFFF17A6EFFE17A6EFFE337699FF504E4EFE514F4FFE504E4EFF504E - 4EFE514F4FFE4D4C4CFF2B627FFE19A6EFFF17A1E8FE1796D7FE5B7179FF4947 - 47FE484646FE353434CA000000282D2B2B010000000000000000000000000000 - 000000000000000000000000000000000000000000022E2D2D9E494747FF4947 - 47FE67828AFE1095D8FF0F9FE8FE10A3EEFE10A3EFFF10A4EEFE10A4EFFF1297 - DBFE31393EFE494747FE4B4949FF44525AFE149FE5FE12A4EFFF12A4EEFE12A4 - EEFE12A4EFFF13A4EFFE14A2EBFE465158FF4D4B4BFE4C4A4AFE3B3A3AFF3534 - 34FE424141FE3E3D3EFF198BC5FE15A5EFFF14A3ECFE109AE1FE408EB2FF4D4D - 4DFE484646FE484646FC090808510F0F0F090000000000000000000000000000 - 0000000000000000000000000000000000000303030B444242E8494747FF4F50 - 50FF4C98B9FF0D99E0FF0EA1ECFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF19668EFF3F3D3DFF494747FF494747FF2C7297FF0FA3EFFF0FA3EFFF0FA3 - EFFF0FA3EFFF0FA3EFFF2183B5FF4A4848FF4A4848FF454343FF205F7FFF1569 - 93FF1D3642FF1E3C4CFF11A3EEFF11A4EFFF10A3EEFF0E9DE7FF1895D3FF5C65 - 66FF494747FF494747FF272525A50000001E0000000000000000000000000000 - 00000000000000000000000000000000000011101038484646FE494747FF5F66 - 66FE299AD1FE0D9CE6FF0DA2EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2 - EEFE0E9CE5FE2A3B44FE464444FF484646FE46494CFE1497DAFF0EA2EEFE0EA2 - EEFE0EA3EFFF0EA2EEFE365E73FE494747FF494747FE393939FE1191D3FF0EA2 - EEFE0EA1EDFE0F97DCFF0FA3EEFE0EA3EFFF0EA2EEFE0EA0EAFE0C96DCFF557D - 8EFE494747FE494747FF424040EC0303033E1B1A1A0500000000000000000000 - 0000000000000000000000000000000000002120206B484646FE494747FF687F - 85FE1095D8FE0D9FE9FF0DA2EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2 - EEFE0DA2EEFE1573A3FE3B3939FF484646FE484646FE336680FF0DA2EEFE0DA2 - EEFE0EA3EFFF1496D8FE464749FE494747FF464444FE274C5FFE0EA3EFFF0DA2 - EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0DA1ECFE0D99E1FF438C - AEFE4B4A4AFE494747FF484646FE1B1B1B880000001500000000000000000000 - 0000000000000000000000000000000000002E2C2C92494747FF4A4848FF618C - 9CFF0C96DCFF0EA0EBFF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA1EDFF264150FF454343FF494747FF484748FF1B8CC6FF0EA3 - EFFF0EA3EFFF297399FF484646FF494747FF403E3EFF1776A6FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EDFF0D9BE4FF3494 - C2FF505151FF494747FF494747FF3A3939D70000003024232302000000000000 - 000000000000000000000000000000000000313030AA484646FE4B4A4AFF5893 - ABFE0D98DFFE0EA1ECFF0DA2EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2 - EEFE0DA2EEFE0DA2EEFE1380B7FF373737FE484646FE494747FF3A5A6BFE0EA1 - ECFE0EA1ECFF3E525DFE484646FE484646FF323B41FE0E9CE4FE0EA3EFFF0DA2 - EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0DA2EEFE0D9DE6FF2796 - CCFE555858FE494747FF484646FE484646FD1110106A0707070E000000000000 - 000000000000000000000000000000000000323030B1484646FE4C4B4BFF5496 - B2FE0D98E0FE0EA1ECFF0DA2EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2 - EEFE0DA2EEFE0DA2EEFE0EA2EEFF214C62FE434141FE494747FF484646FE2281 - B1FE188ECAFF474546FE484646FE444343FF205C7BFE0DA2EEFE0EA3EFFF0DA2 - EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0DA2EEFE0D9DE7FF2196 - D0FE595D5DFE494747FF484646FE484646FE302E2EBD00000025302F2F010000 - 000000000000000000000000000000000000323030B1494747FF4C4B4BFF5596 - B1FF0D98E0FF0EA1ECFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF118CCAFF333537FF484646FF494747FF4150 - 59FF2D6F91FF484646FF484646FF3B3A3BFF1287C3FF0EA3EFFF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0D9DE7FF2296 - D0FF595D5DFF494747FF494747FF494747FF474545F90707074E100F0F090000 - 000000000000000000000000000000000000323030A9484646FE4B4A4AFF5B94 - AAFE0D97DEFE0EA1ECFF0DA2EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2 - EEFE0DA2EEFE0DA2EEFE0EA3EFFF0EA3EFFE205A77FE464545FF4F4D4DFE504E - 4EFE4F4F50FF4E4C4CFE4B4949FE2C4654FF0EA2EDFE0DA2EEFE0EA3EFFF0DA2 - EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0DA2EEFE0D9CE6FF2A96 - CBFE555858FE494747FF484646FE484646FE494747FF252424A10000001C0000 - 0000000000000000000000000000000000002F2D2D8F484646FE494848FF658D - 9BFE0C95DBFE0DA0EAFF0DA2EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2 - EEFE0DA2EEFE13A5EFFE1FA9F0FF26ACF0FE29A1DEFE464B4FFF5B5A5AFE5D5B - 5BFE5D5B5BFF5D5B5BFE575555FE327CA2FF22AAF0FE19A7EFFE0EA3EFFF0DA2 - EEFE0DA2EEFE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0DA2EDFE0D9BE4FF3895 - C0FE505050FE494747FF484646FE484646FE494747FF413F3FE90202023B1918 - 18050000000000000000000000000000000023222268494747FF494747FF6B7F - 83FF1395D7FF0D9EE8FF0EA2EEFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF11A4 - EFFF27ACF0FF33B1F1FF34B1F1FF34B1F1FF34B1F1FF3D7D9DFF5C5B5BFF6563 - 63FF656363FF656363FF555759FF35A8E3FF34B1F1FF34B1F1FF2FAFF1FF19A7 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA1ECFF0D99E0FF488D - ABFF4B4A4AFF494747FF494747FF494747FF494747FF494747FF1A1919840202 - 02140000000000000000000000000000000012111133484646FE494747FF5E64 - 64FE319DD0FE0D9CE5FF0DA2EDFE0DA2EEFE0EA3EFFF0DA2EEFE14A5EFFF38B3 - F1FE3FB6F2FE3FB6F2FE40B6F2FF3FB6F2FE3FB6F2FE40B0E9FF5D696FFE6E6D - 6DFE6F6D6DFF6C6A6AFE51778BFE40B6F2FF3FB6F2FE3FB6F2FE40B6F2FF3FB5 - F2FE23ABF0FE0EA3EFFF0DA2EEFE0EA3EFFF0DA2EEFE0D9FEAFE0C95DBFF5C7E - 8BFE494747FE494747FF484646FE484646FE494747FF484646FE393737D40000 - 002F0000000200000000000000000000000003030305464444E8494747FF4F4F - 4FFE559AB7FE0D98DFFF0DA0EBFE0DA2EEFE0EA3EFFF0FA3EFFE40B5F2FF4DBA - F3FE4DBAF3FE4DBAF3FE4DBAF3FF4DBAF3FE4DBAF3FE4DBAF3FF648FA6FE7877 - 77FE787777FF706F6FFE529FC7FE4DBAF3FF4DBAF3FE4DBAF3FE4DBAF3FF4DBA - F3FE4CBAF3FE1EA9F0FF0DA2EEFE0EA3EFFF0DA2EDFE0D9DE6FE2097D1FF5D63 - 63FE484747FE494747FF484646FE484646FE494747FF484646FE484646FD0F0F - 0F660000000D00000000000000000000000000000000302F2F98494747FF4947 - 47FF6D8287FF1596D7FF0D9DE7FF0EA2EEFF0EA3EFFF29ADF0FF5BC0F4FF5BC0 - F4FF5BC0F4FF5BC0F4FF5BC0F4FF5BC0F4FF5BC0F4FF5BBFF2FF7C888EFF8382 - 82FF828181FF717C82FF5BBEF0FF5BC0F4FF5BC0F4FF5BC0F4FF5BC0F4FF5BC0 - F4FF5BC0F4FF4BBAF3FF0EA3EFFF0EA2EEFF0DA0EBFF0D98DFFF4B90AEFF4C4C - 4CFF494747FF494747FF494747FF494747FF494747FF494747FF494747FF2F2D - 2DBA000000240000000100000000000000000000000016151533494747FE4846 - 46FE545757FE4C9EC2FF0D98E0FE0DA0EBFE0EA2EEFF47B8F2FE69C5F5FF69C5 - F5FE69C5F5FE69C5F5FE69C5F5FF69C5F5FE69C5F5FE70B9DEFF8D8C8CFE8D8C - 8CFE8A8989FF729EB5FE69C5F5FE69C5F5FF69C5F5FE69C5F5FE69C5F5FF69C5 - F5FE69C5F5FE67C4F5FF15A5EFFE0EA2EDFF0D9DE6FE1A96D3FE607074FF4947 - 47FE4A4949FE4B4A4AFF4B4A4AFE4B4A4AFE4B4A4AFF4A4848FE494747FE4745 - 45F80606064B0000000800000000000000000000000000000000484646BB4947 - 47FF494747FF6B7F84FF1E98D5FF0D9CE5FF0EA1EDFF53BDF3FF78CBF6FF78CB - F6FF78CBF6FF78CBF6FF84AFC6FF959DA2FF959EA3FF979B9FFF999898FF9998 - 98FF909091FF7AC0E4FF78CBF6FF78CBF6FF78CBF6FF78CBF6FF78CBF6FF78CB - F6FF78CBF6FF77CBF6FF19A6EFFF0D9FEAFF0D96DDFF518FA9FF4D4D4DFF4C4E - 4FFF699BB1FF75A7BCFF75A7BCFF75A7BCFF75A6BCFF687B82FF4A4848FF4947 - 47FF2322229D0000001B000000010000000000000000000000005C6565384846 - 46FB484646FE4F4F4FFF6397AAFE0F95DAFE0D9EE8FF45B7F1FE87D1F7FF87D1 - F7FE87D1F7FE87D1F7FE93B5C7FFA3A2A2FEA4A3A3FEA4A3A3FFA4A3A3FEA3A2 - A2FE93A5AEFF87D1F7FE87D1F7FE87D1F7FF87D1F7FE87D1F7FE87D1F7FF87D1 - F7FE87D1F7FE78CBF5FF10A1EBFE0D99E1FF3396C5FE5A6061FE494747FF4D4E - 4FFE70BBDCFE82CDF0FF7EA9BAFE7098A9FE7098A8FF647278FE494848FE4947 - 47FF413F3FE80202023900000004000000000000000000000000000000006777 - 7799484646FE494747FF595D5DFE539EBDFE0D96DCFF19A3E9FE8AD1F6FF95D6 - F7FE95D6F7FE95D6F7FE9DBBCAFFA7A6A6FEA7A6A6FEA7A6A6FFA7A6A6FEA6A5 - A5FE99C2D7FF95D6F7FE95D6F7FE95D6F8FF95D6F7FE95D6F7FE95D6F8FF95D6 - F7FE95D6F7FE49B7EFFF0D9AE2FE2397CFFF627378FE494848FE494747FF4947 - 47FE586C74FE7ACAEFFF80ABBEFE545656FE4A4848FF494747FE494747FE4947 - 47FF484646FE1817177C0000000E00000000000000000000000000000000B0EA - EA10515353DB494747FF494747FF5F6667FF4D9FC2FF0D96DCFF38AEEBFFA0DA - F7FFA4DCF8FFA4DCF8FFA6C9DAFFA7BBC5FFA7BBC5FFA7BBC5FFA7BBC5FFA7BB - C5FFA4DAF5FFA4DCF8FFA4DCF8FFA4DCF9FFA4DCF8FFA4DCF8FFA4DCF9FFA4DC - F8FF74C7F2FF0F9BE2FF2297D0FF627C84FF4B4949FF494747FF494747FF4947 - 47FF4A4848FF5F8493FF7FCFF5FF79959FFF4E4D4DFF494747FF494747FF4947 - 47FF494747FF313030BD0000001A000000000000000000000000000000000000 - 00009DCBCB30484748F2484646FE494747FE5E6464FF599DB8FE1296D8FF36AB - E7FE9ED8F6FEB2E1F9FEB2E2FAFFB2E2F9FEB2E2F9FEB2E2FAFFB2E2F9FEB2E2 - F9FEB2E2FAFFB2E2F9FEB2E2F9FEB2E2FAFFB2E2F9FEB2E1F9FEAFE0F8FF69C2 - EFFE1199DEFE3098C9FF63777DFE4B4A4AFF484646FE484646FE494747FF4846 - 46FE484646FE4C4B4BFF6B9EB5FE8AD0F0FE718085FF4B4949FE484646FE4947 - 47FF484646FE413F3FE701010121000000000000000000000000000000000000 - 00000000000021729B4A484849F6484646FE494747FF555858FE69919EFF2C9B - D0FE179BDEFE62BEEDFEABDDF7FFC0E6FAFEC0E6FAFEC0E7FAFFC0E7FAFEC0E7 - FAFEC0E7FAFFC0E7FAFEC0E7FAFEC0E6FAFFBBE4F9FE86CEF2FE32A8E4FF1596 - D7FE4F96B4FE5F6869FF4A4848FE494747FF484646FE484646FE494747FF4846 - 46FE484646FE494747FF515354FE93C1D5FEA7D2E6FF606565FE494747FE4947 - 47FF484646FE464444F10303031F000000000000000000000000000000000000 - 0000000000000000000021729B49484748F1494747FF494747FF4C4B4BFF6570 - 72FF5E99B0FF2B9CD2FF1197DBFF39ABE5FF68C0EDFF8ACFF2FF9ED7F5FFA7DB - F6FFA3DAF6FF94D3F4FF78C7F0FF4FB5E9FF1E9EDFFF1696D6FF469ABFFF657E - 86FF515252FF494747FF494747FF494747FF494747FF494747FF494747FF4A48 - 48FF535555FF515252FF494747FF606C70FFB5E3F8FF86979DFF4A4848FF4947 - 47FF494747FF413F3FE00000000F000000000000000000000000000000000000 - 00000000000000000000000000001D77A52D444B50D7484646FE494747FF4947 - 47FE4D4D4DFE636B6CFE688E9AFF4F9BBCFE359DCEFE1E98D5FF1396D7FE1195 - D8FE1295D8FF1897D6FE2A9BD1FE429BC3FF5B91A6FE68787BFE525353FF4947 - 47FE484646FE494747FF484646FE494747FF484646FE484646FE494747FF4F51 - 52FEB4DBEDFE99AEB6FF4F4F4FFE595F60FEBFE5F6FF8FA0A6FE4A4949FE4947 - 47FF484646FE2F2D2DA000000003000000000000000000000000000000000000 - 000000000000000000000000000000000000A5E4E80D7084848F494848F84846 - 46FE484646FE494747FE4A4848FF4F5050FE5A5F5FFE677071FF6B7B7EFE6A7E - 83FE6A7C80FF687476FE5F6565FE535454FF4B4A4AFE494747FE494747FF4846 - 46FE484646FE494747FF484646FE494747FF484646FE484646FE494747FF4B4A - 4AFE9EB7C2FECBE6F3FF9CAFB5FEB1CAD4FECCE8F5FF707779FE494747FE4947 - 47FF474545F60F0E0E2E00000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000004947472A4947 - 47A7494747FA494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4947 - 47FF535656FF93A4AAFFB1C3CAFFAABCC3FF788284FF4D4C4CFF494747FF4947 - 47FE262424690000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00004846461C48464676494747C8484646F7484646FE494747FF484646FE4846 - 46FE494747FF484646FE484646FE494747FF484646FE484646FE494747FF4846 - 46FE484646FE494747FF484646FE494747FF484646FE484646FE494747FF4846 - 46FE494747FE4A4848FF4C4B4BFE4B4A4AFE494747FF484646FE474545E03C3B - 3B52000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000A3A2A211A3A2A23BA4A3A35FA3A2A276A3A2 - A27FA4A3A37FA3A2A27FA3A2A27FA4A3A37FA3A2A27FA3A2A27FA4A3A37FA3A2 - A27FA3A2A27FA4A3A37FA3A2A27FA4A3A37FA3A2A27FA3A2A27FA4A3A37FA3A2 - A27FA3A2A27FA4A3A37FA3A2A27FA3A2A27FA4A3A377A3A2A248A3A2A2080000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFF - FFFFFFFF0000FFFE001FFFFF0000FFF00003FFFF0000FFE00000FFFF0000FF80 - 00007FFF0000FF0000003FFF0000FE0000000FFF0000FC0000000FFF0000F800 - 000007FF0000F000000003FF0000F000000001FF0000E000000001FF0000E000 - 000000FF0000C000000000FF0000C0000000007F000080000000007F00008000 - 0000007F000080000000003F000080000000003F000080000000001F00008000 - 0000001F000080000000000F000080000000000F000080000000000F00008000 - 000000070000800000000007000080000000000300008000000000030000C000 - 000000010000C000000000010000E000000000000000E000000000000000F000 - 000000000000F000000000000000F800000000000000FC00000000000000FE00 - 000000000000FF00000000000000FF80000000010000FFE0000000030000FFF8 - 000000070000FFFF0000000F0000FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFF - FFFFFFFF0000FFFFFFFFFFFF0000280000002000000040000000010020000000 - 0000801000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000030000 - 000E0000001F0000002D00000033000000340000002F00000022000000110000 - 0004000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000252424040404041F121212672928 - 28AD393838D8444242F0484646F9474545F8414040EB353333CE2221219F0909 - 0958020202251F1F1F0700000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000B0B0B14181818763D3B3BDF494747FF4947 - 47FF494747FF4C4B4BFF4F4F4FFF4E4D4DFF4B4949FF494747FF494747FF4846 - 46FD323030C60B0B0B5F0606061A526262010000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000BBC3C3011011112D343232C4494747FF494848FF565C5EFF507B - 8EFF4892B5FF429FCBFF40A3D4FF40A2D1FF439AC3FF4888A5FF526D78FF4E4E - 4EFF494747FF474545FA2221219D0304042A6183900300000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000151515363F3E3EE3494747FF545858FF4D88A3FF33A2DAFF34AB - E7FF39B0EDFF3DB3EFFF3EB4F0FF3EB4F0FF3DB3EEFF3AAFEBFF31A8E4FF3A9A - C8FF51717EFF4B4A4AFF494747FF2F2D2DBD0103042F7FABAB02000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00001E262625403E3EE2494747FF57696FFF379BCCFF2BA8E7FF32AFEFFF35B1 - F1FF35B2F1FF36B2F1FF37B2F1FF37B3F1FF38B3F2FF38B3F1FF38B2F1FF35AF - EDFF2BA4E2FF4488A8FF4F5050FF494747FF2E2C2CBA090C0C23000000000000 - 000000000000000000000000000000000000000000000000000000000000292E - 2E08363434C2494747FF586B71FF2B9DD5FF25A8EBFF29ACF0FF2AADF1FF2AAE - F1FF2BAEF1FF2CAEF1FF2CAEF1FF2DAFF1FF2EAFF1FF2EAFF1FF2FAFF1FF2FAF - F1FF2EAEEFFF27A6E6FF3C8DB3FF4E4F4FFF494747FF1F1E1E920F0F0F0F0000 - 0000000000000000000000000000000000000000000000000000000000001E1D - 1D6B494747FF565C5EFF2E99CEFF1CA4EAFF2491C8FF397D9FFF3C7FA1FF26A1 - DFFF22AAF0FF22AAF0FF23ABF0FF23ABF0FF24ABF0FF29A3E1FF4E6A79FF3D88 - AEFF2BA5E3FF26ABEFFF1FA2E5FF4583A0FF4A4848FF464444F6080808493230 - 30010000000000000000000000000000000000000000000000000101010B4240 - 40E44B4949FF478DADFF149FE6FF16A5EFFF189EE1FF3D464BFF514F4FFF3B6E - 89FF19A7F0FF19A7F0FF1AA7F0FF1AA7F0FF1BA8F0FF357DA2FF545252FF5452 - 52FF535455FF40687DFF1E9EDEFF1A9BDDFF526871FF494747FF2C2A2AB21413 - 130F0000000000000000000000000000000000000000000000001A19195B4947 - 47FF5B686BFF1799DAFF10A2ECFF11A4EFFF11A4EFFF1D6E98FF474545FF4B4A - 4AFF1E91CBFF13A4EFFF13A5EFFF14A5EFFF15A4EDFF45555EFF4D4B4BFF3F3D - 3DFF454343FF384B55FF16A5EEFF14A1E9FF358CB6FF4B4949FF464444F60403 - 0333000000000000000000000000000000000000000000000000333131AD4947 - 47FF4C87A0FF0D9CE5FF0EA2EEFF0EA3EFFF0EA3EFFF0E9FE9FF30424CFF4947 - 47FF3B5B6DFF0FA3EEFF0FA3EFFF0FA3EFFF1F88BEFF4A4848FF454343FF1874 - A3FF176288FF16709EFF10A3EFFF0FA2EDFF1297DBFF555F62FF494747FF1F1E - 1E8D21202007000000000000000000000000000000009F9F9F02444242E74D4C - 4CFF3798C6FF0D9FEAFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1678AAFF4240 - 40FF484646FF2183B5FF0EA3EFFF0EA3EFFF34637BFF484646FF34444DFF0EA1 - ECFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0D9BE3FF497588FF494747FF3D3C - 3CE00404042000000000000000000000000000000000A6A6A610494747FF5558 - 58FF239CD7FF0EA1ECFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF2A49 - 5AFF484646FF41515BFF0F9FE9FF129AE0FF464849FF474545FF1F678DFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0D9DE7FF3E82A2FF494747FF4947 - 47FF1413136B2B2A2A03000000000000000000000000A8A8A821494747FF5D62 - 62FF1799DBFF0EA1EDFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF1385 - BFFF3E3D3DFF494747FF29769EFF247AA7FF484646FF3F3E3FFF1192D4FF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0D9FE9FF3989AFFF494747FF4947 - 47FF333131C60C0C0C15000000000000000000000000A8A8A820494747FF5C61 - 61FF189ADBFF0EA1EDFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3 - EFFF24536CFF474545FF454B4FFF3C5968FF484646FF2C5165FF0EA3EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF0D9EE9FF3A89AFFF494747FF4947 - 47FF484646FC0A09094A353434010000000000000000A7A6A60F494747FF5557 - 57FF269CD6FF0DA1ECFF0EA3EFFF0EA3EFFF0EA3EFFF0EA3EFFF10A3EFFF1AA7 - EFFF2498D4FF4D4E50FF5B5959FF5A5858FF565454FF2981AEFF17A6EFFF0EA3 - EFFF0EA3EFFF0EA3EFFF0EA3EFFF0EA2EEFF0D9DE7FF4083A1FF494747FF4947 - 47FF494747FF282727A81616160D000000000000000000000000454343E74C4C - 4CFF3B99C4FF0D9FEAFF0EA3EFFF0EA3EFFF0EA3EFFF20AAF0FF35B1F1FF36B2 - F1FF36B2F1FF457A95FF666464FF676666FF5A6064FF37AEEBFF36B2F1FF30B0 - F1FF15A5EFFF0EA3EFFF0EA3EFFF0EA2EEFF0D9AE3FF4D7587FF494747FF4947 - 47FF494747FF444242F104040430000000000000000000000000343232A94947 - 47FF51879EFF0D9BE4FF0EA2EEFF0EA3EFFF27ACF0FF49B9F3FF49B9F3FF49B9 - F3FF49B9F3FF4DB0E3FF747373FF757474FF5A879EFF49B9F3FF49B9F3FF49B9 - F3FF45B8F2FF15A5EFFF0EA3EFFF0DA1ECFF1598D9FF575F60FF494747FF4947 - 47FF494747FF494747FF1D1C1C880000000600000000000000001C1B1B554947 - 47FF5D6769FF1B9AD9FF0DA1ECFF0FA3EFFF59BFF4FF5EC1F4FF5EC1F4FF5EC1 - F4FF5EC1F4FF69ADD0FF858484FF818080FF62B0D8FF5EC1F4FF5EC1F4FF5EC1 - F4FF5EC1F4FF3DB4F2FF0EA2EEFF0D9EE7FF3C8DB3FF4A4949FF494747FF4947 - 47FF494747FF494747FF3C3A3ADD0000001E0000000000000000030303054846 - 46E14A4949FF508EA9FF0D9BE3FF18A6EEFF74CAF5FF74CAF5FF74CAF5FF80B3 - CDFF88ABBEFF8F9FA8FF969595FF88969EFF74CAF5FF74CAF5FF74CAF5FF74CA - F5FF74CAF5FF58BFF3FF0DA1ECFF1698D9FF56676DFF505B60FF678897FF6889 - 97FF688997FF585F62FF494747FF121212660000000300000000000000005E69 - 695F494747FF575B5BFF3399C9FF0F9EE7FF7CCDF5FF8AD2F7FF8AD2F7FF9BB0 - BCFFA5A5A5FFA5A5A5FFA5A4A4FF91B9CDFF8AD2F7FF8AD2F7FF8AD2F7FF8AD2 - F7FF8AD2F7FF4FBAF1FF0D99E1FF4D839AFF4A4848FF526168FF7DCAEEFF7699 - A6FF647E89FF555B5DFF494747FF313030C200000012000000000000000090B7 - B701606C6CB9494747FF5C6A6EFF2999CFFF3BAFEAFF9FD9F8FFA0DBF8FFA4BF - CCFFA6B4BAFFA6B4BAFFA6B3BAFFA1D6F1FFA0DBF8FFA0DBF8FFA0DBF8FFA0DA - F8FF8BD1F5FF179DE2FF458CACFF4E4E4EFF494747FF494747FF5F8291FF7EBA - D5FF535555FF494747FF494747FF474545FB0505053200000000000000000000 - 0000AFE8E815434D53DD494747FF5C676AFF3998C5FF3CACE6FFA1D9F6FFB6E3 - F9FFB6E3FAFFB6E3FAFFB6E3FAFFB6E3FAFFB6E3FAFFB6E3FAFFB5E2F9FF81CC - F2FF239EDDFF4D87A0FF4E4E4EFF494747FF494747FF494747FF4A4949FF71A1 - B6FF87ABBAFF4C4C4CFF494747FF494747FF1515155E00000000000000000000 - 0000000000001580B621434D53DC494747FF535555FF56879BFF2E9DD2FF49B1 - E6FF7FCAF0FFA1D9F5FFAFDFF7FFACDEF7FF97D4F4FF6DC2EDFF33A6E0FF3A95 - BFFF596F77FF4A4949FF494747FF494747FF494747FF4B4A4AFF4F4F4FFF4E4F - 50FFA3CDE1FF6C7578FF494747FF494747FF1514145100000000000000000000 - 00000000000000000000409FC71457686CB5494747FF494747FF565959FF5B7B - 86FF498DABFF3D97C1FF369AC9FF3799C7FF4093B9FF4D849CFF5C6D71FF4D4D - 4DFF494747FF494747FF494747FF494747FF494747FF69767CFFB1CCD8FF595C - 5DFFADCBD8FF757F82FF494747FF464444F10404041200000000000000000000 - 00000000000000000000000000000000000050525255494747D6494747FF4947 - 47FF494747FF4B4A4AFF4D4C4CFF4C4B4BFF4A4848FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF4C4B4CFF99ACB4FFB9CF - D8FF9EAFB6FF505050FF494747FE212020670000000000000000000000000000 - 0000000000000000000000000000000000000000000049474701494747404947 - 4790494747C9494747ED494747FD494747FF494747FF494747FF494747FF4947 - 47FF494747FF494747FF494747FF494747FF494747FF494747FF494747FF4B49 - 49FF494848FB484646CC42404051000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFF80 - 1FFFFE0007FFFC0001FFF00000FFF000007FE000007FC000003FC000001F8000 - 001F8000001F8000000F0000000F000000070000000700000003000000038000 - 0003800000018000000180000000C0000000C0000000E0000000F0000000F800 - 0000FE000001FF000003FFFFFFFFFFFFFFFFFFFFFFFF28000000180000003000 - 0000010020000000000060090000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000006767 - 67066767670F6767671267676710676767076767670100000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000021202002040404201616166F2928 - 28AC333232C9363434D0323030C6252424A510101064010101201D1C1C040000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000262B2B101F1E1E86424040ED494747FF5051 - 51FE535F63FF526269FF525B5EFF4D4C4CFE494747FF3B3A3ADD141313711A1D - 1D14000000000000000000000000000000000000000000000000000000000000 - 000000000000000000004A4A4A20363535C94A4848FE516872FF4590B5FF39A6 - DCFE37ABE6FF39ADE8FF36AAE5FF3CA1D3FE4583A0FF4F595DFE484646FE2827 - 27AB1521271D0000000000000000000000000000000000000000000000000000 - 0000000000004E6767153B3939D34E4F4FFE4789A8FE2DA7E5FE34AFEFFE37B2 - F1FE38B3F1FE39B3F1FE39B3F1FE39B3F1FE36AFEDFE31A2DBFE4A7183FE4948 - 48FE2C2B2BB42B39391500000000000000000000000000000000000000000000 - 0000171A1A022F2D2DAA4D4D4DFF3E8FB5FF23A7EAFE27ACF0FF29ADF0FF29AD - F0FE2AADF0FF2BAEF1FF2CAEF1FF2EABEBFE2FACECFF2DAEF0FE27A5E5FF4875 - 8AFF494747FE1D1C1C892B2A2A05000000000000000000000000000000000000 - 000012121245494747FE497F98FF18A1E7FF1E95D1FE46565FFF436B81FF1DA8 - EFFE1EA9F0FF1EA9F0FF1FA9F0FF3882A8FE535B60FF427793FE2D95CAFF1F9F - DFFF4D616AFE444242F30E0D0D2F000000000000000000000000000000000000 - 0000343333B6545A5CFE1C9ADAFE11A3EEFE12A4EFFE2B5C76FE4C4A4AFE2686 - B8FE14A5EFFE14A5EFFE15A5EEFE455862FE4A4848FE464444FE345E73FE16A4 - ECFE318CB9FE4A4848FE21202090333232020000000000000000000000007C7C - 7C11474545F9497A90FE0D9EE8FF0EA3EFFF0EA2EEFE1192D4FF3E4143FF4152 - 5CFE10A0E9FF0EA3EFFF1D8AC1FF494747FE2C5B73FF1478ACFE1386C1FF0FA3 - EEFF109AE0FE515C60FF3E3D3DE4151515180000000000000000000000008B8A - 8A3F494747FF398EB5FE0DA1ECFF0EA3EFFF0DA2EEFE0EA3EFFF216486FF4746 - 46FE29779FFF0EA3EFFF336580FF464444FE1682B9FF0DA2EEFE0EA3EFFF0EA3 - EFFF0D9EE8FE456F83FF494747FF16151569000000000000000000000000908F - 8F574A4848FF3296C7FE0EA2EDFF0EA3EFFF0DA2EEFE0EA3EFFF0F9AE0FF3942 - 48FE454B50FF1694D5FF45494CFF384851FE0EA1ECFF0DA2EEFE0EA3EFFF0EA3 - EFFF0D9FEAFE3E7894FF494747FF343333C91F1E1E0D0000000000000000908F - 8F564A4848FE3296C6FE0DA2EDFE0DA2EEFE0DA2EEFE0DA2EEFE0DA2EEFE1D6F - 9AFE494747FE435762FE4B4949FE226A90FE0DA2EEFE0DA2EEFE0DA2EEFE0DA2 - EEFE0D9FEAFE3E7894FE484646FE484646FD0F0E0E4500000000000000008C8B - 8B3E494747FF3C8EB4FE0DA1ECFF0EA3EFFF0DA2EEFE15A5EFFF26ACF0FF2EAC - ECFE4F5F68FF615F5FFF5B5B5BFF2FA0DAFE22AAF0FF10A4EFFE0EA3EFFF0EA3 - EFFF0D9DE7FE476F82FF494747FF484646FE292828AA07060606000000007D7C - 7C0E484646F94D7A8EFE0D9DE7FE0DA2EEFE1CA8EFFE44B7F2FE46B8F2FE46B8 - F2FE5499BCFE737272FE607C8BFE46B8F2FE46B8F2FE3FB5F2FE12A4EFFE0DA2 - EEFE129ADFFE525C5FFE484646FE484646FE454343F304030329000000000000 - 0000363434B2555A5BFE1F9BD8FF0DA2EDFF4DBAF3FE62C2F4FF62C2F4FF62C2 - F4FE75A3BBFF878686FF6AA7C7FF62C2F4FE62C2F4FF62C2F4FE35B2F1FF0DA0 - EBFF348BB5FE4A4949FF4A4848FF4A4848FE494747FF1F1E1E88000000020000 - 0000292B2B3D494747FE4F7F94FF0E9CE5FF66C4F4FE7FCEF6FF85C0DEFF9CA0 - A3FE9E9E9FFF989C9EFF80CBF2FF7FCEF6FE7FCEF6FF7FCEF6FE46B7F1FF1799 - DBFF506167FE5D7C8BFF7AB1C8FF729FB2FE585F62FF3D3C3CE0000000160000 - 0000000000006C7F7FA14D4C4CFE438EB0FE3AAEE9FE9CD8F8FE9FCDE5FEA7B1 - B6FEA7B1B6FEA2BFCDFE9DD9F8FE9DD9F8FE9DD9F8FE91D4F6FE22A1E1FE4C74 - 85FE494747FE4D5153FE76B2CDFE596063FE494747FE484646FE121111580000 - 000000000000B5F2F20C3E525DCC4E4E4EFF4A87A2FE46AEE3FF9CD7F6FFB9E4 - FAFEB9E4FAFFB9E4FAFFB9E4FAFFB8E3F9FE86CEF2FF37A1D6FE4F707EFF4947 - 47FF484646FE494747FF546167FF8DB9CCFE4F4F4FFF494747FF232222860000 - 000000000000000000001184BF123C5461BD494848FE56676DFF428BADFF49A9 - D7FE56B5E5FF5BB8E7FF54B3E3FF42A0CCFE467F99FF525859FE494747FF4947 - 47FF484646FE687277FF606567FF8BA5B0FE6A7275FF494747FF1C1B1B640000 - 00000000000000000000000000007B9EA1035459596C484646E8494747FE4F4F - 4FFE595E5FFE596264FE56595AFE4C4B4BFE494747FE484646FE484646FE4846 - 46FE484646FE61676AFEAABFC7FEA8BCC4FE535455FE3F3E3ED70303030B0000 - 00000000000000000000000000000000000000000000767575077675754F7675 - 7590767575B4767575BF767575BF767575BF767575BF767575BF767575BF7675 - 75BF767575BF767575BF777676BF777676BD7674748C58575714000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000000000000000FFFF - FF00FF03FF00F800FF00F0007F00E0003F00C0001F0080000F0080000F008000 - 0700000007000000070000000300000003000000010000000100800000008000 - 0000C0000000C0000000E0000000F0000000FC000100FFFFFF00FFFFFF002800 - 0000100000002000000001002000000000004004000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000001B1A1A01050505221818186D2322 - 2292222121911615156802020220191818010000000000000000000000000000 - 00000000000000000000000000006C7B7B0B2827279349494AF74A6774FF4777 - 8EFF47758BFF4B606BFF444343F01F1E1E844E63660B00000000000000000000 - 0000000000000000000073959509373636BF4B6876FF37A0D4FF36AFEDFF3AB3 - F0FF3BB3F0FF37AFECFF3B97C5FF4A5A62FF292929A94E5F5F09000000000000 - 000000000000000000003131318D496A79FF249EDCFF3295C8FF27AAECFF27AC - F0FF29ADF0FF359BCFFF31A2DCFF2AA0DBFF49585FFF1F1E1E78000000000000 - 000000000000565656194C4E4FF8219AD6FF14A3EBFF3D525DFF2F7CA3FF16A6 - EFFF17A6EFFF475C67FF4B4A4AFF2B7DA7FF2D8CBBFF413F3FE9282727100000 - 0000000000006D6C6C65466C7EFF0DA0EBFF0EA3EFFF187FB4FF434A4EFF139B - E0FF1C8CC5FF434547FF1386C2FF1196DAFF0F9EE6FF4C585EFF201F1F650000 - 0000000000007877778C3B7C9BFF0EA2EDFF0EA3EFFF0EA2EEFF315467FF306B - 8AFF316986FF2E5F79FF0EA3EFFF0EA3EFFF0DA0EBFF426678FF363434CB3231 - 3106000000007877778B3C7C9AFF0DA2EDFF0EA3EFFF0EA3EFFF1C8DC7FF4D4E - 4FFF4D5357FF1E87BCFF0EA3EFFF0EA3EFFF0DA0EBFF436677FF484646FE1F1E - 1E40000000006E6D6D64486D7DFF0DA0EAFF14A5EFFF3AB3F1FF40B6F2FF5B80 - 94FF647077FF40B5F0FF35B1F1FF0FA3EFFF0F9DE6FF4D585DFF494747FF2B2A - 2AAA00000001575757164E4F50F72199D4FF3DB5F1FF69C5F5FF71B8DDFF8599 - A4FF78A4BBFF69C5F5FF69C5F5FF2CAEF0FF2D8AB8FF525D62FF58686FFF494A - 4AF60404042200000000667474864B6976FF3CADE6FF95D6F7FFA3B2BAFFA6AC - AFFF97CFEBFF95D6F8FF90D4F7FF2E9FD8FF4B585DFF5E7D8CFF6B8996FF4C4C - 4CFF1F1F1F8000000000A4D6D605395869B64C6773FF58AAD2FF8DD0F2FFAFDF - F8FFABDEF8FF83CBF0FF4E9BC1FF4C595FFF494747FF4B4A4AFF7A9AA8FF5253 - 54FF2F2E2EAB00000000000000005897AD05586263824C4B4BF44E6570FF4372 - 88FF437085FF4F6067FF4A4848FF494747FF494747FF808E95FF97A9B1FF5557 - 58FE1B1A1A5A00000000000000000000000000000000A4A3A310A4A3A356A4A3 - A37AA4A3A37FA4A3A37FA4A3A37FA4A3A37FA4A3A37FA4A3A37FA4A3A37EA2A1 - A147000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000FFFF0000E01F0000C00F00008007000080070000000300000003 - 0000000100000001000000000000000000008000000080000000C0000000F001 - 0000FFFF0000} - OldCreateOrder = False - Position = poScreenCenter - OnClose = FormClose - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 13 - object bvlSpace: TBevel - Left = 0 - Top = 314 - Width = 527 - Height = 3 - Align = alBottom - Shape = bsBottomLine - end - object jplWizard: TJvPageList - Left = 0 - Top = 0 - Width = 527 - Height = 314 - ActivePage = jspWelcome - PropagateEnable = False - Align = alClient - OnChange = jplWizardChange - object jspWelcome: TJvStandardPage - Left = 0 - Top = 0 - Width = 527 - Height = 314 - Color = clWhite - object imgInstall: TImage - Left = 0 - Top = 0 - Width = 164 - Height = 314 - Align = alLeft - AutoSize = True - Picture.Data = { - 07544269746D6170AE5B0200424DAE5B0200000000003600000028000000A400 - 00003A0100000100180000000000785B0200C40E0000C40E0000000000000000 - 00008C00018900028400047800036E02085F06094B02043500003404022F0401 - 3100004303024D00006200007300008304068000018200008600008700008700 - 018400018000047800046700016508094D00004D01024300004400014804053E - 00004300033C00003E00004302043D00004201034403053E00004201033C0000 - 3E00004302043D00004201034403053E00004201033C00003E00004302043D00 - 004201034403053E00004201033C00003E00004302043D00004201034403053E - 00004201033C00003E00004302043D00004201034403053E00004201033C0000 - 3E00004302043D00004201034403053E00004501023F00004100004603024000 - 004502014504033F00004302013C00003E00004104023900003E030140050338 - 00003B03023300003800003F04023B00004302014D03014C00005D0302570000 - 7002027A03047C00008702058700008A00028400018200018000018000018000 - 018000018400018400018300008000017B00027101016705055D08064E03013F - 00004003003F02004100004D02005200005E00006A00007A05087B00027F0002 - 8200018200018200018000018001008001008601008700008900008700008400 - 017D01017201046604045300014300003E00003F03043D00014300064B000845 - 00014C06063C00004F0A074000008A00018700028000047500046A03085D0609 - 4903043500003303013606043000004908074C00006701027000008405078000 - 018200008600008700008700018400017D0004760104640000680B0C49000051 - 07073E00004804054501024100003F0000420103390000500F113900004E0D0F - 3E00004201033E0000420103390000500F113900004E0D0F3E00004201033E00 - 00420103390000500F113900004E0D0F3E00004201033E000042010339000050 - 0F113900004E0D0F3E00004201033E0000420103390000500F113900004E0D0F - 3E00004201033E0000420103390000500F113900004E0D0F3E00004202024100 - 004502013C000053100F3C0000510E0D3F00004302013F00004202013900004E - 110F3700004C0F0D3C00003E03013800003C03013500004E110F3A0000530E0B - 4800005300005F03025A00007002027B03047C00008702058700008A00028600 - 018200018000017F00017F00017F00017F00017F00017E00017B00027601026A - 03016206055809064904013D0000420200490401430000580704520000670102 - 6800007D06077D00028000028200018400018200018200018001008001008200 - 008401008400008200007F00017801026D02046205044E00004901013900004E - 0F11390000510B124500024B00034D01024300005609074A0000880006820004 - 7D01076D00026403074F00004301023800003403013401003A00004A00005D03 - 036E03057B02068000028301028301018600008500008500007F000079000470 - 02046200015600004F01024500004701024100004600014300004100013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100024000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000004300004200004502014100004302013F000042010041 - 00004000003E00004303023F00004404034000004303024101003E01003E0100 - 4101004300004700004C00005100005900006804046D02047402027B00028000 - 028600028700028900018700018400007F00007C000078000176000076000074 - 00007502056B00006400005600005001004200003C05003C0200480000520000 - 5A03016104036A04057103037801027C00018300038500028700028600018400 - 018100008100007F00007E03017C03017E06067903027606066900005F000051 - 00004C00014500004300033D00004300054000004700034B00005400005B0000 - 6101016303037D00047D04086B00006D06095100005006063D00003A02013802 - 013900004200004F00006202027103037E010382000183010183010184000084 - 00008100007E00007500036D02045C00005704034500004C06063C0000490506 - 3F00004501024000004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004101014000004704033D000048 - 07063A00004706053D00004101003E00004404033B00004908073B0000480706 - 4000004502014300004300004800004C00005201005601005E01006400006D02 - 047201047801027D00028200028600028700028700018600008300007E000078 - 00007301016F01016E01036A0203680203670505550000570402400000440802 - 3500003F03005300005F00006602026D03027303037902037F00028100018500 - 028700028700028600018400018200018000017D01017501007708066B000073 - 0C0A6000006407065100004F00004A00004A04043C00004702054000004F0307 - 4800005801056200006A00006E00027002027602076900006E070C5200005908 - 0B3E00004405073800003D01014100004A000058000069010277020380010382 - 00018301018301018200008200007F00007A00007100036602025A0202480000 - 4F09093A00004B090A3A00004905064200004300033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004301023B00004A09083A00004B0A093900004606053E00004202013B0000 - 4A09083C00004F09093E00004C04044600004900004E00005300005700005D02 - 006403006904027004037402027801027D000280000282000284000286000286 - 00018500008100007A00007302006C02016703036302046104055F0505530000 - 5A0706470000520B083A00004309034400006102006E01007202027703027D03 - 038001028200018300008600018600018600018500028101028001027E020279 - 03026F05046200006B0C09540000630C0A4A00005106044700004C0404420000 - 5006064300005605084900005D080C6102066F00017900007D00027E02026500 - 016906085000005B080A4000004A08093700004203054100004A000055000162 - 00006E00027901028000018400018102018102018001008001007C0000740000 - 6D00026101015100005107053A00004A0D0B3700004B0B0B3B00004503043E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004202023E00004707063A00004C0C0B390000480B09 - 3700004003013F00004807063C0000500A0A4000005208084300005000005500 - 005B00005E00006400006902006F03027404047A03047B00027D000280000282 - 00028400028400028400028400028301017E03017602016E03006402025D0302 - 5603025503025000005704064A00005C0A09470000590E0C4700005806016F04 - 017A02027D03037F03038202038301028400018600018600018400018200017F - 00017C02027903027703027103036200006309094C00005E0C0B430000540A08 - 3F00004904014700005105064900005F0909500000690A0E5E000172070A7B00 - 028301028402038402035C03064D00005608094000004B090A37000045060840 - 00004900005300016000036B00027500037C00018200018400008001007F0100 - 8002017D02007800007001006700005C00005202013F00004B0B0A350000480C - 0C3700004808084100004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420202370000 - 4A0A093700004A0D0B3500004308063C00004404033B00004F09094000005509 - 0A4500005505065200006302006A01006D02006F02007302007802017C010380 - 01038200028200028400028400028400028400028400048000028204037A0502 - 6F04016504005A03015102004A00004900004D00014900005E05085200006B0D - 0E5A00006A0D0C6702007B030382030282030284020286020285010184000184 - 00018100007E00007B01017802017203017003016D04016804025E04044E0000 - 57090A420000500A0A3C00004B08074600004B00004A0000630909570000760D - 106500007A090C7700018102038602028602028602024A00004E06063C000047 - 0A083500004408083900004601044D00005900016700057300037A00017F0000 - 8300008400008001007F01008002017C03017802016D00006300005700004900 - 00470703350000430C09330000460A0A3C00004604053E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004202023C0000440705370000460B09350000450A083600004003014000 - 004807063E00005208084500005808094D00005D03036D030274030176020179 - 01017D0101800001820002860002870002870002860002860002840002820002 - 8200047F00027A03017305006804005C03004F02004500004200004300004800 - 005702065300006F080D6500007F0C0F7300017F050584020285010187010187 - 01018701018701018500028101027E00007800007501006F0200690200660300 - 6302005E02015200005405084200004C08093A00004808073E00004B03034C00 - 005F05045D0000790C0E6D0000830B0C77000080010282030283010183010183 - 01014302013D00004206063300003E08083400004304064700015000005F0002 - 6E00067901057E00018200008500008400007F00007D02007E03017A03017602 - 016C01005E00005400004B01003C000040070530000040080736000044060642 - 02024100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00003F01013800004207053300004108 - 063400004005033D00004303024000004D05054300005606074D00005D060960 - 02037203017B02007D01018000018200018600018700018900018B0002890002 - 8700028600028400028200028000047B00027100006702005E02005301004801 - 004001003D00004000005104085400016A030A6A000085070D8000008E02098A - 0000870000860100870000860000860000840000830101800201790101750100 - 6D02006602006002005A02005700005300005000024700004D03093A00004706 - 083B00004805044900005A04045F000075070972000087080A7F00008B030584 - 00008001007F01007F01007F01003F00003F02003900003D05043701003E0504 - 4000004A00015400006300027201057C01058000018200008500008400007F00 - 007D01017A02027504026F03026302005700004C00004500003F02003800003B - 03023800003F03033F01014404044000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000013E00013D01023C00004201033E0000430003 - 4000004100014100014200023F00004201033E00004001033D00003C00013901 - 003A03003700003B04013800003E03013D00004100004600004C01004C000055 - 00005600006103046401036D05067501007A01007F0100800001840001880002 - 8A00028C00038B00028900048600048000047D00047900047800057002046100 - 005A00005600005100004B00004A00004A00014D00015C05096605096D00057B - 03087F00038A01058B00008B0000890000860000860000860000860000860001 - 8301027F03037801026F01016602025E02015302004B01004500004500004C00 - 004E00024900004C01034600004D03034E000057000068060672060576000080 - 01038000008700028700008701018001007C01007E00007C0100430000400000 - 4002023A00003C03023C00004401004A00005E04046802037301017B01018000 - 018301018501018301018301027D00027806066800015F02034F00004A000142 - 00004000013D00004001033C00004002023E00003F02003E00004000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100023E0001390100360000 - 3C03023C00004301024100004600024700014700014400004500053F00014000 - 053800013A01043501013202013000003403013200003D04023C00004502004A - 00005000005800006301016A0203730205770205790102780000770500770500 - 7A04007D020080010083000086000086000187000484000582040A7901067303 - 0A6600026000025400004C00004A00004E00005200005800005F00016700066F - 03096F01057201047402027802017B01017D0200820100840100820000850000 - 8700008800018800028800038500057F00047A04096900055A00034800004201 - 033400002F03043100004600005100005500005900005F02016703016E040374 - 04047801027B01017F00018000018200018200018200018200018000017F0001 - 8000017F00014400004703043A00004507073500004606054100004F00006004 - 036A03017301017B01018001008301018301018301018100018205076E00006C - 0A0A4E00004F05053D00003F00023B00024003073A00004706083A0000460606 - 3C00003F02003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00003D01023600003B05043300004307073900004905064100004800024600 - 004902053D000047050A3500003F06093300003402023101003606042D00003E - 09063500004906034600005200005B00006300006D01007601027E0103810003 - 8400018100007A04007705007A04007B03008001008200018400028400028000 - 0580040A6E000172060C5C00005F03084E00004C00034300034400044E000558 - 00026200026D00037600057C00067B00047B00027901017902007902007B0300 - 7F02008002008401008600008701018500028500038000027C00047600036D00 - 056402084C00004C040A34000039070B2800003200004A00005700005E000064 - 01006B02007203017A02027F0303800001820001820001820001800001800001 - 7F00017F00018000018000018000018000014701023D0000490909370000480B - 093900004D06034E00006104036A03017402027B010180010082000083010183 - 0101820104760000790B0D5A00005E0A0C4000004605073B00003E0105360000 - 49080A3900004B090A3900004606053C00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073C00003B0302330000430A093500004A0A - 0A3A00004904074100004500033D00004A070A390000460A0B3300003F060735 - 0000390302340000430A083700004D0A09420000560403530000610101690200 - 7202027A02038102038301028600018300007F02007D02007F01008002018101 - 028101028100037E01037D03096C000070060C5500005F050A47000051040846 - 00024200024801045200055E00056700047100047A00047E00057D00027D0002 - 7D01017D02007F01007F02008201008401008802028801038402038001027901 - 027200006A00026200015E00044D00005506094000004F0A0D3A000045050A40 - 00005601006002006502006902006F02007602017C0202800102800001820001 - 8200018200018000018000017F00017F00018000018000018000018000014300 - 004A06073900004A0C0C3700004B0A094200005200006404046D03027601027D - 01018001008200008200008001007D00007F08096500006D0D0D490000510909 - 3A00004004053A000145050A3900004C0B0D3A00004A0A0A3900004003013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004001033A00 - 00410807350000480C0C370000480A0A3900004201033E00004706083900004A - 0B0D370000460A0B3500003E02023C00004707033C0000540D0A4500005C0B08 - 5300006203006904027103037803047D03038202038500028700018600008400 - 008201008200008001008001027E02027A02037702056C00026C07095200005C - 080A4300004E08093B00004503044502014D03035804066403076F0105770004 - 7D00048100038000028000027F00018000018001008200008600008600008902 - 048502057F02047702036C02016000005700004F000049000050060642000055 - 080B4500005D090D4E00005C03066303036804006C0300700301740301790101 - 7E02028101028200018200018200018200018000017F00017D01017D01018000 - 018000018000018000014501023C00004A0A0A3900004C0C0B3C00005106044F - 00006604046F03027801027D01018001008200008001007F01007F02046F0000 - 760B0D5300005B0B0C3E00004807093C00013E01053700004A090B3A00004D0B - 0C3900004707063C00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E0000400202370000480A0A350000480C0C35000041080738 - 00003C0302350000460A0A3700004A0C0C390000470707410000490000450000 - 5809064A0000650E0C5500006C0B086801007205037804037D03038103028402 - 028701018700008700008600008500008400018000017D00027801027002046B - 030460000150000059090A4000004D0B0C3700004007063B00004A0300560502 - 6206056B05067502057B00028000028301028200018200018000018000018200 - 018400018700018600018400067C01057502056A02035C02015101004401003F - 00004205013B000050090647000062070A59000074060C6F0004700403700502 - 7304027703027A02027E02028000018200018200018400018200018200018000 - 017F00017D01017D01018000018000018000018000014100004705063900004A - 0A0A3900004E08084600005700006905057103037901027F0001800100820000 - 7F00007C01007600007707075E0000640A094500004D07073B00004105063A00 - 014404093900004B080B3A00004909093A00004003013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033F000046060639000048 - 0A0A330000420A093300003B03023700003F0706350000480A0A3A00004C0809 - 3F00004C00015000005D04005300006A0C075C0000740D0A6B00007708067804 - 037A02028002018102018501018701018800018800018600008300008100007C - 00007400006D01006501015E02014C00004F04023E00004C0C0B350000420A09 - 3000003E01005204006105006B07037205037A02028000018400018500028400 - 018200017F00017F00018000018200018400028000027700037000036600025E - 01024F02004502003A02003602003901004809054200006009075A0000780508 - 79000085050A7902037504027903027A02027E02028101028200018400018400 - 018400018200018000018000017F00017D01017D01017F000180000180000180 - 00014200013D00004606063900004807064100005402015800006C0405750303 - 7C01038000018200008100007F00007A01007601026A00006907075100005004 - 053C00004304063E02033F00043A00004605073A00004806073A00004404033D - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A000044030540 - 00004400023F00004605073700004108073300003B0504360000380300350000 - 4207053900004C06064300004E02035000006102006200007007046700007609 - 076F00007B08057A03017D02007F010080010082000084000084000087010185 - 01018200017E00017700007100006700005F00005500004E01004700003C0000 - 4407053400004209083400003C04034100005E03006C04007504017A03018001 - 008600008700008802028200017F00017B00027901027901027901027B000478 - 00046600005D00005700015000014701013F02003902003801003C0200410000 - 5B0A075C00007606067500008B02068800037F00017B01017D01017F00018000 - 018200018500028700028600018400018200018000018000017F00017D01017D - 01017F00018000018000018000014100004200013E00004301024100004B0101 - 5000005C00007003057902038001038200018200008100007E00007A01007000 - 006B04025D00005502004600004201003E00014004053E00034100043F000043 - 00033F00004202023D00003E01004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004100014300014400023F00004001033800003B0302 - 3600003701003902003B02003E00004502014700005000005000005900006D03 - 027605037401007B06037700007D04027C01008002018001007F00007F00007F - 00007F00008001008102017F03037801027301016D00026600015C0000520000 - 4A00004500003F00003D03003700003C03013700003E02023E00004C01006703 - 007804007C04008103008500008800008700008602027F000179010174020270 - 02027002047002047002046B02055500004E00004900004700004201003F0200 - 3E01004001004000005103005F0400710A077802018402038700008900018100 - 007F00007F000082000184000186000187000287000286000184000182000180 - 00018000017F00017D01017D01017F0001800001800001800001420202410101 - 4404044000004701014A00005901016300027002047901028000028400018400 - 008200007F01007902007103036400005B01004E00004A02023F00003D01023A - 00003E00033F00024300034100004301023E00003F02003E01004000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E0000410002410001440002420000 - 4300033E00003E02023800003B02003900004005034202014400004700004E00 - 005600005E01026804047403017B02007D02007D02007F010080010080010082 - 00008001007F00007E00007C01007B02007A03017A02027605036D0506640202 - 6103045400005000004500004502003F02003C01003900003C03013A00004202 - 013F00004400015100006F03007D010080000084000087000088000088000281 - 01027901027101016F07086503036706085F00005F00005600004C0103430102 - 4400014300004200004500004700004D00005D06046405026D03027403017B01 - 0182000086000087000084000184000184000186000186000186000186000186 - 00018400018400018200018000018000017F00017D01017D01017F0001800001 - 8000018000014000004606063C00004907084000005404055600006801047401 - 047D00028200028400018400008200007F01007803006C02016506034F000053 - 06033F00004707063800003B01023D00024402073B00004A05083A0000460606 - 3A00003D02003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004200024200004702053B00004805083900004305053900004000004502 - 014801004C00005000005A00006000006703037004037B010180010080010082 - 00008200008200008400008200007E00007C01007C03017A0502750402720301 - 6E01006601005F02035B08074B00005207053E00004607033B00003D05003900 - 003E05033600004707063C00004D050545000056000074060281040085020087 - 01018700008600008100007A00017202026E08095C0000620A0A5100005A0608 - 5100004E00014100003C00004000004600004B00005200005900006000006B04 - 027002027602017B01017F010080010082010084000086000186000186000186 - 00018700018600018600018400018400018200018200018000017F00017F0001 - 7D01017F00018000018000018000018000014103033A00004B0B0B3C00005309 - 094900006305066900017800047F00028400028600018400008200007D020076 - 03006B06045800005B08064300004E0B0A3700004206073800004000053A0000 - 4A070A3C00004B090A3900004407053A00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004401063C00004A070A3A00004C08 - 093C00004903034500004D00005200005800005F00006600016C020171030379 - 05047F01008200008200008400008400008400008200018000017D0000790101 - 7804037205036E04036702006000005700005404034400004F09093A00004909 - 083500004108063A01003C0301360000470A083A000051090943000052040553 - 00006F04017A03018103028303048402038201047B00027300036F07085C0000 - 610B0B47000057090A4300005104074700003E00003C00004300004C00015700 - 036201036D02057502057901027D00027F00018000017F01007F01007D02007F - 0100840001870001870001870001860001860001860001840001840001820001 - 8200018000017F00017F00017F00017F00018000018000018000018000013C00 - 00460808390000500C0D4300005C080A5900007002067B000482000286000287 - 00018600008200007D0200740300650100600905470000550C083A0000480D0B - 3400003C02033C000147050A3A00004F0A0D3A00004A0A0A3700003E03013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 0147050A3A00004F0A0D3E00005207094500005200005900005D00006501016B - 01007202027703027903027D0303800100840000840000840000840000820001 - 8000017F00017B01017702036F03026903046101015A00005300004C00004400 - 00480706390000490C0A350000460B093400003E05033A00004508063900004F - 0C0B4000005309094300005300006100006A00007000007702037B0307790407 - 7204066D04075F0102600A0A450000560C0C42000051080A4200004A01034400 - 004700004E000159010165020470030579040781030880000284000284000182 - 00018001007F01007B02007D0200840001870001870001860001860001840001 - 8400018200018200018200018000018000017F00017F00017F00017F00018000 - 018000018000018000013E02023800004C0C0C3C0000560A0B4C00006906086D - 00027D00048400028700028900018600008200007D0200720400670603500000 - 570A074000004D0D0C3500004208093800004000053900004B080B3C00004D0B - 0C3900004508063A00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083C00004101063700004A090B3C0000550A0C4700005C030658 - 00006601036C01037201047702037A02037E02027F00017F0000820001820001 - 8200018200018200018000027F00027B00027803046F02046501015C00005300 - 004E0000480000450000430201390000470909370000490B0B3700004507073D - 00004202013900004B0A093C0000510B0B3E00004C06064800004F0000570000 - 5D00006402026803056803056502046002065801044A0000560B0D400000560B - 0D4200005104074B00005600005B01006100026701027002047702037F020483 - 02058400028600028600018400018200017F00017D01017F0001840001860001 - 8600018400018400018400018400018200018200018000018000018000018000 - 018000018000018000018000018000018000018000013A000044060639000050 - 0A0B4300005D06095F00007403077D0004860002890002890001860000800100 - 7D02007204006001005A08034300004F0B06370000450C0A3500003D03043C00 - 014604093C00004D080B3A00004909093800003E03013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A000040010338000140050939000050 - 090C4500005F080C5A00006900037001057702057C0103800102810102820001 - 8100008100008200018200018200018200018000027F00027B00027801027002 - 046701025C00005000004800004300004000004002023D00004505053900004A - 0A0A3A00004A08093C00004301023F00004706053C00004B0A093A00004A0908 - 3A00004302014401004800004D01025101025600025500015400015100004A00 - 004F0406400000530A0C42000057080B4C00005A00026802036E020171000374 - 02027801027C0103800103830003840002840002840001840001820001800001 - 8000018000018400018400018400018400018400018200018200018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00013D01013A00004707073F00005305065100006A03067300047F0004870002 - 8B00028B00018600008001007D02007204006104014F00004F06023C00004609 - 073600003F06073A00013F00043C00004904073C00004806073A00004205033B - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053D - 000039000335000045060841000059080B5700006C050A6E00037800057D0004 - 8200028400018600018600008701018501018200018000018000028000027F00 - 027D00027900047401046800006000005500004B00004300003D00003A02013C - 02034201033E00004A05083D00004D07084000004B02044300004600013F0000 - 4706053900004508063600003E05033601003704023903023E02024200014800 - 014900004900004900004A00024300004C03054200005405084D00005C050963 - 00047800047F00017F00027F00017F00017F00017F0002800002800002800002 - 8200028200028400028400028400028400028400018400018400018200018200 - 018000018000017F00017F00017F00017F00017F000180000180000180000180 - 00018000018000018000018000013E00003F01013F0000460203480000590003 - 6700017901068400048900028900028700018400008001007D02007203015C03 - 004E04004500004303003D00004005033B02013E02034000014200023F000043 - 01023F00004202023D00003E01004000004101013E00004202023E0000420202 - 3F00004000004000014101013E00004202023E00004202023F00004000004100 - 014200013E00004202023E00004001033D00003C00013E00013F00023C000042 - 01033F00004300034200004100013E00004200014600005404055A0002690406 - 7201057B02067E00028200008500008800008900008800018901028703037F00 - 017B00027B00047900047601047201046F02046902055800005200004D000047 - 00004200013D01013A02013900013F0002430204410001470205420000480203 - 4500004700004700004600014100004202023C00003E02023800003502003002 - 013002013301013900014000014400024900024D00034B00014D00014B000052 - 00005300006100026702047406087E0001850000840001820001800001800001 - 8001038001037F00027F00028000028200028400028400028600028600028400 - 018200018200018200018000018000017F00017F00017F00017F00017F00017F - 00018000018000018000018000017F00017F00017F00017F0001460001400000 - 3F03033B00004701015200006E00047F00058900048D00028700028200017F01 - 007D02008001007403015100004200004303003F00004202013E000041010040 - 00004100004000004301023E00004202013C00003F02003E01004000003F0000 - 4301023F00004301023F00004200014100004100004000004301023F00004202 - 023E00003F01014000004300004200004301023E00004002023800003A020137 - 01003C03043A01023F03043E00004500034500004B00054A00004D0000540000 - 5E02016703017004037902037F00028500008900018D00008C00008A00008800 - 008700008502008203027800047100047304086C01046805075B00005400004B - 00004A00004400004502013E00004003013C00003D02003A0100390100380000 - 3C03023A00004202023F00004600024700014700014600004700034100004300 - 033E00004100023A00013503053001033604043800004103034200004C000150 - 00005600005D00006600016E02017503037903027B01017E0000800001820001 - 8200018000018000018000018000018000018000018000018000018000018200 - 0182000182000182000182000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000017F00017D00027B0002 - 7B00027B00024600004703043500004108073C00005804066C00008400078D00 - 048F00028600028000017B02007B02008200007602014F00004404033A000047 - 07063A00004706053D00004201004000004504033A0000470706370000440705 - 3A00003F02003F00004404033B00004807063A00004706053F00004201004000 - 004504033B00004707063900004407053A00004101004200004903033B000047 - 07063500004007053300003802013701013E0405380000480508400000530308 - 4C00005700045B00006100006902007203017A02028101028600008A00008D00 - 008F00008D00008900008600008302008102017C020272010571050B62000067 - 060A510000570406460000470101400000420503360000430806370000440705 - 3C00003F02003900003D05043400004307073700004606063F00004400024400 - 004902053F00004A040A3A00004704093C00003D00043700033B060933000042 - 08093A00004D05054A00005600005E0000660000700000790101800201830101 - 8601008500008200018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000017F00027D00027F00027D00024900023E0000430A093300004D0A - 094A00007504088100048D00048F00028600028000017B02007B020082000076 - 02015200003B00004A09083A00004B0A093A00004706053F00004302013B0000 - 490908390000480B093700004407053C00004202013B00004A09083A00004B0A - 093A00004706053F00004302013A0000490908370000480B093500004207053C - 00004301023D00004A0809390000460A0A3300004007063800003D0101390000 - 4B070842000059080B4B00005F050A5D00006501006B03007004007704017F04 - 028301018700008800008B00018900018901038602028102037C030179010173 - 01017305096300016A060B5200005B0407450000500606440100420201380000 - 450A08350000480B093900004706053F00004301023A00004A08093900004B09 - 0A3A00004704073F00004201033A000049080A37000048090B3500004206073A - 00003D030437000048090B3A000052090B4500005805045900006501016B0100 - 7402027A02028103028301018401008300008200018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018200018600028600028700028600024500 - 004A0607330000460D0C3C00005D090B6700008501088D00048D000286000280 - 00017B02007D02008200007602014F00004807063A00004D0C0B3A00004B0A09 - 3A00004302013F00004807063900004C0C0B370000480B093700004202013F00 - 004807063A00004D0C0B3A00004B0A093A00004202013E000045080637000048 - 0D0B350000460B093500004003013F00004806073900004C0C0C370000480A0A - 3700004202023C00004C04044300005C090B4E0000690B0C5E00006B05066F04 - 017504017A05027D040282030285010186000087000087000185000284020380 - 03057B04057303036E00006A000165000268070B5200005F0609490000520607 - 3F00004605043E0000450806350000480D0B3900004A0A093A00004502014500 - 004E05073E00004F0B0C3C00004B090A3900004001033A000043070833000046 - 0C0D330000440A0B3300004001033D00004B0407420000570A0D470000610A0D - 5700006604046B03047103037804037B03038103028102018401008400008200 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018200018900 - 018B00018B00028B00014A01033D0000450C0B3300004C0B0A4A00007305097E - 00038B00048D00028600027F00017B02007D02008200007802015500003C0000 - 4D0A093C00004F0C0B3C00004807063F00004202013900004A0A093900004C0C - 0B3900004707063E00004302013C00004D0A093C00004D0C0B3A00004707063C - 0000400301350000460B09350000480D0B3300004108063A0000420103390000 - 4A090B3900004C0C0C3A00004A07064300004C00014700005E0808520000700B - 0D5F000076090B7301017B04027F040081040082040086020285010186000184 - 00018200028001037B03047704076F04066802036000005D00005E0004500000 - 5E070A49000055090A4000004906053E0000400301350000460B093500004C0C - 0B3900004807064300004C000245000054070A4000004F0B0C39000045070738 - 00003B0302300000410B0A300000450D0C3300004108073F00004B00004A0000 - 5D060A4E00006A0C10590000700B0D6B03047204067604047A04037D03037F04 - 0281020182000082000080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018200018900018B00008B00018B000045000049050633000044 - 0B0A3A00005A07096700008201088900048B00028400027F00017B02007D0200 - 8200007802015100004B05053E00004D0A093C00004C09083B00004302013E00 - 004606053900004A0A093900004909083A00004302014100004906053C00004D - 0A093A00004909083800003E03013A0000420705350000460B09330000430A08 - 3400003E02023C00004604093900004B080B3C00004E08094300004E00015200 - 00600605570000700B096400007C0A0A73000081050582040085020085020085 - 02008701018501018301028101027D00027901057103056A03066302045C0104 - 5500015100004E0000560305450000560A0B4000004C09083A00003F02003A00 - 00420705350000480B093900004909083B00004701014A000054030643000051 - 080A3C00004709093400003B03023500003B0806300000430B0A350000470909 - 3A00004B00025200006400055800006F090E5E0000750C0F6D000278070A7604 - 047902037A02027C02027E030180020181020181020180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000182000186000086000087000086 - 00004B00024000004007063200004606054A00006E03067C0004870004890002 - 8200027D01017B02007D02008200007802015600004300004D05053E00004A07 - 063D00004504034000004101003C00004407053700004707063A000044040340 - 00004401004100004906053C00004807063A00004205033B00003D0200360000 - 4007053300004308063600004005033B00003F00023C00004704093C00004E05 - 074400005401035400006305066400007408076C00007E080777000085060584 - 01008700008701008700008700008600008200008001027C0103770205700305 - 6702045F01055700034E00024A00014700004A00004500004D05053F00004B08 - 073B00004306043B00003D02003800004407053700004707063A000045040344 - 00004B00014800004F03073C00004707073600003D0504360000380300330000 - 4007053700004A07064100004D03035000006801066A00007405096B00007908 - 0C7000007C070A7901057901027901027B01017D01017F00017F000180020181 - 0201800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00017F01007D02007F01007D02004900004501023900003B03023D0000510102 - 6700017C00068700048900028200027D01017B02007D02008200007901015700 - 004A00004700004901014300004502014000004000004000004101003C000040 - 03013E00004202013F00004100004300004600004100004302013F0000400301 - 3D00003C01003A01003B02003800003E03013A00004003013D00004000004100 - 014400044300014B00034A00005300015600005C00006C06077406067602017E - 05037D00008403008500008902008901008800008800008500008100007F0001 - 7A02037603067104066803055D02055400044C00024600024100014000014400 - 014701014100004302013E00004104023D02004005033C01003D02003C000040 - 03013E00004202014000004300004700014800024100004201033A00003C0302 - 3600003701003902003D02003F00004901014A00005300005400005E00007403 - 077D03097900057D04087800037D02067A00037B00027D00027C00017C00007C - 00007E00007F0001800201810302800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000017F00017B0200790200790200790200490000430000 - 3E05043800004205034D00006902057A00068600048700028000027D01017B02 - 007D02008400007B01015F02034E00014C00014600004701014100004302013F - 00004000003D00004003013C00004202013E0000420100410000430000440000 - 4502013F00004302013C00003F02003C01003D02003B00003F04023D00004404 - 034000004403024400014801044900034900004C00005300005C00026502046D - 05066F01037500017A00008001008400008702008A01008A0200890000860000 - 8500008100007F00017A02027503036F04065E00005600005200014700004500 - 033E00013D00043C00014000004000004202013C00004003013A00003D02003C - 01003C01003B00004003013C00004202013E00004201004100004100023D0000 - 3F03043900003D05043800003C05023B02004303024701014B00005100005900 - 006100006A01047403067B000480000480000480000480000480000280000280 - 00027F00027F00017F00017F00017F00017F00017F00017F0001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000017F00017F04027D0402 - 7C03017B02004800004804053600004109083800005406076300007A02078400 - 048600027F00027B01017902007D02008400007B010161000255050646000050 - 04054000004906053D00004101003D0000420503380000450806390000460605 - 3D00004401004400004903033D00004807063900004407053800003D02003B00 - 004205033B00004807063D00004C06064400004B01014B00004E000052000158 - 00025F00046601036D02047303037700017A00007E0000820000860100880100 - 8A02008801008400008100008101027F03037903027202026901026300025600 - 005401034400004A06073900004205093500003A01023B000042050338000045 - 08063500004207053800003D02003B0000400503380000450806390000460605 - 3D00004101013900003B05053400004007083300004108073B00004302014600 - 004E00005800006100006A00017000027601047C010382000484000284000484 - 00028400028200028200028200028200018000018000017F00017F00017F0001 - 7F00017F00018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000017D00007E00007F00018002014C0002400000440B0A320000490C - 0A4400006B06087400038200048400027F00027B01017902007D02008400007D - 01016603054F00005707084500005309093E00004706053E0000400301360000 - 450A083700004A0A093900004706054100004701013F00004C09083A00004A0A - 093700004207053A00004104023B00004A09083E00005309094300005404054E - 00004F00005400005C00026302046B04077104067502057901027C00017E0000 - 8200008400008401008601008702008502007D00007901017A03047404047004 - 036701025C00005500005200014400004E0809390000460A0B3300003F060937 - 00003E0202360000450A08350000460B093500004407053C0000400301380000 - 4909083900004A0A093900004706053C00003A04042E00003E0A0A300000440B - 0A3900004B05054800004D00005800006400006F01037803067D020480010382 - 0001860002860001860002860001860001840001840001820001820001800001 - 8000018000018000018000017F00017F00018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018200018300008500008500018500004800 - 004D0708330000440E0D350000550B0B5C00007802078000048200027D000279 - 01017902007D02008400007D01016400015E070A490000580A0B420000500A0A - 3B00004104023C0000430806350000480D0B3900004A0A093C00004502014300 - 004A07063A00004C0C0B390000480B093500004003013E00004807063E000055 - 0B0B4500005B080A4D00005A00025A00006000006701026E0305750407780304 - 7C01037F00018000018200018400008200008201008201008002007D02007601 - 027103056D02046902056100025A00005100004A00004700004A07063A00004A - 0C0C350000440A0B3200003C02033A0000430806350000480D0B370000480B09 - 3700004003013C00004508063900004C0C0B3900004A0A093A00004002023300 - 003A080A300000460C0D39000052090B4800005800025C000065000070000279 - 0203800305820203830102840001860001860001860001840001860001840001 - 8400018400018200018200018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018200018400 - 028400028500038300014D00033F0000460D0C300000480D0B42000068050770 - 00017F00048200027D00027901017902007B02008400007D0101690406530000 - 5D090B470000560C0C3E00004908073C0000400301350000460B093500004C0C - 0B3900004A07064100004502013C00004B0A093900004C0C0B3700004508063C - 00004403023F0000540A0A4700005F0B0D4E00006204085E00006802036C0201 - 7002027402027901027D01018000018400018400018400008400008001007F01 - 007D02007B02007602016D05066403055F01025A00025100004E000048000045 - 0000430102390000480A0A350000480C0C3500004307073A0000400301370000 - 480B093700004C0C0B3900004707063E00004202013900004A0A093900004C0C - 0B3900004707063C00003C0304310000470B0C3A0000570C0E4A000062040861 - 00006E00047300037900047D00027F0002800001800001820000820000840000 - 8400008200008400008200008200018200018200018200018200018200018200 - 0182000182000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000017F00027A00017900027C00047C01054900004C060733000041 - 0B0A3500005008085900007300047F00048000027B00027901017803007B0200 - 8400007D010166000260070A4A000059090A430000500A0A3D00004104023A00 - 00420705350000460B093900004909083D00004502014100004906053A00004A - 0A09390000470A083800004202014100004D05054500005D090B50000067080C - 5E00006B02057305057605027802017900007D00008000008500008700018701 - 018701018200008001007B02007902007502006E02016204055902065300024D - 00004700004300004100004202023C0000420606350000460A0A350000470909 - 3A00004202023C00004407053900004A0A093900004909083A00004202013E00 - 004606053900004A0A093900004909083A00004002023A00004205093A000055 - 090D4A000067070D6300007201057B03087D02067F00027D00007D00007D0000 - 7C01007F01008001008001008001008001008200008200008200018200018200 - 0182000182000182000182000182000182000182000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000017B00027100046C01046D00056A - 00024C00024200004108073000004007054100006201036D00007D0004800002 - 7B00027901017803007B02008400007F00016C03065800005B04074800005206 - 074400004706053E01003D02003600004207053500004707063A000047040342 - 00004401003F0000470605390000470706380000440403400000450000450000 - 5505064F000065070B5F000070060C6F01057703027903007C01007E00008200 - 008400008800008900008800018701018301027F000179010175010071020068 - 03015600034E00034A00014600004100003F00003D01023C02033B0201360000 - 4207053500004508063A00004504034000004101003C00004706053A00004807 - 063B00004504034000004201003D00004706053A00004707063A00004205033D - 00004000013F00005004084C000065070C62000177050C7900057E0006800004 - 7F00017E00007B00007700007702007902007D02007F02007F01007F01008001 - 0080010080010080010080000180000182000182000182000182000182000282 - 0002800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000178 - 01026201035602045600035200004A00004802033B00003B0401380000460100 - 5A00006C00017900047F00027D01017B01017B02007D02008200007D01016F01 - 036502045900005400024800004805043F02003C03013A01003B02003A000040 - 02023E00004301024000004100004000004101013E00004202013F0000430201 - 4400004900004C00005200005600006201036500017204087302067A05087800 - 007B00007F01008100008601008700008900008700018700028101027C010376 - 01026F03026802036503035C04044800004400004200004100004100023F0101 - 3D01023C00003C00003D01013C00004202013F00004502014400004300003E01 - 003D02003C00004202013F000043020142000045000045000044010043000045 - 02014100004303003F00004300004A000052000156000062010567000375030A - 7901068103097C00017E00007F00007F00007D02007902007803007902007D02 - 007F01007F01007F01007F01007F010080010080010080000180000182000182 - 0001820001820001820002820002820001800001800001800001800001800001 - 8000018000018000017F00018000018000018000018000018000018001007F01 - 007F01007F01008001008001008001008000018000017F00017F00017D01017D - 00027B00027901027901026F02044F00004600004800014A01034B0002450000 - 4303023C00004104024400005401005F00007302057D02048202038301027E00 - 007C01007C03017C04047800037502056B04075100004600003A000039060333 - 03003701003900004201033F00004300033F00004100043C0003380000360000 - 3E04054000004802024600005000005500006605026B04027002027402027900 - 047B00047F00047F000481020382030284020285010186000086000085000081 - 000183030879010672040A6200035902054B00004800013F00004100003F0000 - 4202023E00004202023F00004200014100004300004200004502014300004701 - 014300004800004100003901003500003C04033B00004404044300004802024A - 00004900004A00004B00004A00004700004400004200004A0000680404720104 - 7401047402027801027901027B00027B00027D00027F00017F00017F00017F00 - 017F00017D01017F00017F000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001820001820002820002 - 8200018200018000018000017F00017F00017F01007D02007F01007F01007F01 - 007F01007F01007F02007E04007C04007D03007F03008002007F01007F00007E - 00007D01017B00027D06077502057305076800006300005600004D0003430003 - 4100013E00004700004A04053C00004707063900004906034B00005C00006F03 - 027B03048202038500028200007C01007904017A04037C000081060A6700005E - 04033E00004008033101003405013401003E05043A00004A040A3C0000470409 - 3C00003D00053600023C06063800004806074300005603015600006502006F04 - 017602017901017F000180000282000284000484000282020381020182000081 - 000083000083000182000480000578000774060C5F00015F080C460000480508 - 3600003900013B00004205033800004707063A00004706053F00004600004400 - 004903033F00004C06063E00004B05054100004201003A00003D050435000044 - 08083800004707073E00004701014902004A00004900004A00004D0000500000 - 5201005D00007601027F00017F00017D01017D01017D01017D01017D01017D01 - 017D01017F00017F000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200028400028200018200018000018000017F00017F00017F01 - 007F01007F01007F01007F01007F01008002007F02008004008004007F030080 - 02008002008002007F01007D01017901027B06076A00007008095C0000620405 - 5400005200024000003D00003F00004302044903043F0000490909370000480B - 093C00005306045700006C02017902038102038301028001007E00007A03017B - 0303800103760000770A0C5000005208063500003C0906320200390302340000 - 49080A3A00004D070D3A000046030A3C00024003073B00004E0A0B4200005A08 - 075000006908056B02007403017902007D010180000182000284000286000284 - 00028101027F01007E00007D00007E00017F00027F01067B0307720007610000 - 66080D4A000055090D3A00004005093800004002023A00004909083900004B0A - 093A00004706054100004502013D00004C09083C00004D0A093C000047060541 - 00004701024000004C0809390000460B093300003E0704370000400300410100 - 4700004E00005600006000006901027202027B00028000018000017F00017F00 - 017F00017F00017F00017F00017F00017F00017F000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018200018200018200018000 - 0180000180000180000180000180000180010080010080010080010082000082 - 01008402008601008702008502008302008102017E03017A0202780606690000 - 6E070A5500006106094A00005703074B00014702054201034000013D00004000 - 004907083700004A0C0C3700004C0B0A4500005901016701027402027E010381 - 01028000017E00007B02007D04027D00008207096400006A0D0C4300004A0B07 - 3300003B06033700004307073900004D0A0D3C00004B080D3900004200054100 - 00500709450000610E0D5200006D0C096600007807047902007D020080000182 - 00018400028400028600028200027F00017B02007B0101790101790102760102 - 7300036E00046100006304084C00005A0B0E4000004B0A0C3600003F03043C00 - 004707063900004C0C0B3A00004B0A093A00004202013E00004707063900004C - 0C0B3900004A0A093700004302014900005304074200004E0A0B370000430A08 - 3200003B04013C02004200004C00005700006400006F00017900047F02048000 - 018000018000018000018000017F00018000017F00018000017F00017F00017F - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0182000182000182000180000180000180000180000182000182000182000082 - 00008400008400008400008600008900008900008800018701018301017E0202 - 7903027303036A00016A07095200005E070A4700005306094100004903043E00 - 003E0000400001430204440404390000470B0B3500004A0D0B3A000051070552 - 00006400006E00007A02038001028000018000017F0100800201830205760000 - 7A0C0C5600005F0E0B3E00004508063A01003C03023500004A090B3A00004D0A - 0F3A000047050A4100014C00004C0000650C0F56000075100E6400007B0A0877 - 00007F01008201008400008400008600018600018400028200027A0000780201 - 7803047604047103056B00026200005C00005A00024B000057080B4200004F0A - 0D39000045050A3C00004202023A00004B0A093A00004C0C0B3900004707063C - 0000400301370000460B09350000480D0B3500004308063E00004E0104480000 - 5408093E00004C0B0A3900004508043F00004300004C00005A00006501017201 - 047B000483000384000282000182000182000182000182000180000182000180 - 00018200018000018000018000018000018000017F00017F0001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000182000182000182000182 - 00018400018400018400018400018600018600018600018700018C00018C0001 - 8700018400017F00017700016F01036801045E00014E000059090A420000510B - 0C3A00004605073B00004302044201034000013D00003C000043070733000044 - 0B0A3500004A09084500005502015F00006A00017601027F0204810102820001 - 8001008101028100008205076A0000720E0C4D00005208043D00004306043C00 - 004406063900004B080B3A00004A070C3A00004900034E00006204055D000078 - 10116800007F0C09740000810201840100860100860000860000840001840001 - 8200027F00027700017402027103036E04036703035D00005400004D00004A00 - 004F05053E00004D090A3A000049080A3B00004302043F00004706053A00004B - 0A09390000470A083800003E03013A0000400705330000440B09330000430A08 - 3400004003014500005005074200005008084200005309094900005604035500 - 005E00006901027302057B020681010684000282000084000182000182000182 - 0001820001820001820001820001820001820001820001800001800001800001 - 7F00017F00018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000017F00017F000180000180 - 0001820001820001840001840001840001840001860001860001860001860001 - 8600028700028800038700038200027C00037400026C00016400015A00004C00 - 004E04043E00004C0C0C37000045090A3300003A00013A00003E000040000143 - 02043D03043700003F06073300004307073B00004C04044E00005B0000660001 - 7202027B03048001028200018400018400018503047800007B0607650000660A - 094A00004C02004502004101003C00004606063900004706083A000045020748 - 00005A00006200007407096C00007F0908770000830403820000870000870000 - 8600008400008200018000017F00027B00027301016B00026600015F00005900 - 005200004C00004600004502013D00004707073800004706083B000044030540 - 00004200013F00004706053A00004707063800004005033900003B0200350000 - 3F08053200004009063300003E05033900003F04023D00004906054200005906 - 055600006A05076D00037100017600027B00047E00058102048001037E00017D - 0000820001820001820001820001840001840001840001840001840001820001 - 8200018200018000018000017F00017F00018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00017F00017D01017F0001800001820001820001840001840001860002860002 - 8600028600028400028400028400048200048101067A01057601046E00036500 - 015C00005300004C00004500003B000042060734000041080B3400003C030638 - 00014304064302044100023D00003A01023C03043800003D03043A0000430303 - 4500004E00015400006000006D02047604047C01038000018400018600018301 - 027D01017500007307066400005800004B00004B04014300004101003E000042 - 02023E00004201034000024A00015E00006D00026E0000790302760000800100 - 8200008702008700008700008400008200017F00017D00027901027601046C01 - 036501015D00005300004E00004900004502014404033D02003D040239000040 - 04043D00004302044000004200014300004401003F00004202013E00003E0301 - 3B00003A01003902003A03003800003C03013800003E03013B00003C01003B02 - 004003014300005000015800006A01047400037F010784000687000587000584 - 00027F00017E00017C00017D00027F0001800001800001820001820001840001 - 8600018600018400018400018400018200018200018000017F00017F00018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000017F00017F00017D01017F00017F0001800001820001 - 8400018400018400028400028400028200028200048000047F00047900047203 - 076A03066502045E00045500014E00004500003E00003B00003A020136000039 - 03033400003B02053900033C01053B00003E0000400001430204370003380002 - 3B02033800003E02023E00004401004900005100005A00006301016F03027902 - 038001038500008400008200017F00017A02027403016B010061000054000049 - 00004901014100004303033C00004302043F00004401044B00016502046F0103 - 7200007600007B00007F00008401008601008802028300008202037B00007C04 - 057601047605087005086000005800005700014E00004C00014100003F02003A - 01003901003600003B03023800003E02033E0000420002430000430000420000 - 4302013E00004202013A00003D02003A01003B02003A01004005033E01004205 - 033F00004201004000004101004300004B00005800006500027200037C000384 - 00048A00058C00058C00038700028400027F00007C00007A00008004047F0303 - 8001028000018200018400018700028700028600018400018400018200018200 - 018000017F00017F000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000017F00017E00007C0100 - 7E00007F00018000018101028300038300038300057E00028100057B00007C00 - 067700037B03087203075A00004F00004E00014700004701023F00003F010139 - 00003C03043802023B05053500003B02033700003B0002390000430204420103 - 4000013D00003600023D04073400004307083700004606063F00004800004B00 - 005300005E02016802037503037D00028500008600008200017F00017E020279 - 03027101016700005B00005000004A00004805043B0000450707390000460507 - 3E00004D00036201036D00027000027500017B01017F01008200008200008200 - 008505067500007C07086A000072070A6500016504085800005700034A000051 - 05063E00004606053600003A03003600003B0504310000400807350000460507 - 3D00004400014200004504033B00004707063700004407053800003D02003C01 - 004306043B00004908073F00004D05054600004C00015101005401005B010163 - 00026D00037600057D0004850005870004890002880001860001830000810000 - 7F00007C00007B03037A02027C02027D01018000018200018500028700028600 - 018600018600018400018400018200018000017F000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000017E00007C01007E00007F00018000018101028100038100037D00 - 0281030876000080080D6E000075060A6A00006302064900004504033A000045 - 07073500003F06053400003901003700003D0405340000410708350000440507 - 3C00004100023B00003D00003F00004302043B020533000045080C3700004A09 - 0B3A00004705064100004800004E01005702006303037002027B000284000286 - 00008100008001008001027E02027801027000006500005A0000500301410000 - 490908350000480A0A3900004806074A00005C00006500006B00027202027702 - 037A02027E02027D01017F05057400007C0A0A6300006F0A0C57000060040954 - 00015200024600005207093E00004B090A370000400706370000390302310000 - 420A09330000480A0A3900004705064100004302013B00004A0908390000480B - 093700004407053C00004303023E00004E08084200005608094900005A030659 - 00006702046C01046E00047001057201047502057901057A01057B00007D0000 - 8100018100008300008500008500008100007802017203017602017901017D01 - 0180000183010287000286000186000186000184000184000182000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000017E00007E00008001008001008000 - 018000018001037E01037C01057200007E0A0F660000730C115B00006203074F - 0000430303320000400A09320000420A093300004004043800003F0000390000 - 4806073A00004D090A3E00004D07084500014502054201034000013D00003700 - 0141060A3700004C0A0F3A00004B080B3A00004301024300004800005202015D - 03026C01037901028400028600018100008001008200018101027E0103780102 - 6E01036303034F00004F0805390000480D0B3700004B0B0B3C00004D02045400 - 005D00006601036C040571040674040477020376010273010177090B5F00006E - 0B0D5000005C070B4500004C00034700004E05073E00004D0B0C390000460A0A - 3300003C0302370000410807330000480C0C3900004B090A3A00004301023F00 - 004707063900004C0C0B370000480B093700004202014200004E06064500005C - 090B4E000066070B5800006900057701067C00067A00067A0006790105780004 - 7601047800047800017800017C00007E00008000018400018600018000016F00 - 006B02006F02007403017901017D010180000184000186000187000186000186 - 0001860001840001820001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018001 - 008001008001008001008000017F00017D00027901027500037A090D61000071 - 0D125200005F080C4900004800013800003A0907300000450D0C350000490909 - 3C0000460001460000500306430000560A0B430000540A0A4500004B02043E00 - 003E00004000014302043C00063500004A080D3A00004F0A0D3C00004806073E - 00004000004201004B01005702006701027601048200028700028100007F0000 - 8400008501018301027E02027303036905055502014200004B0B0A350000480C - 0C3700004B07084600004D00005200005B01016104036905056C04056F02046E - 01036F0406610000690A0E4C000058080D4000004603083B00004300033A0000 - 4A090B3900004A0B0D3700004307083A0000400103370000480A0A3900004C0C - 0C3A00004806073F0000420201370000480B093700004A0D0B37000047070641 - 00004A02024600005C080A5200006C080D5D000074040B7100027F0005820004 - 8000048000047E00037C00037A00017A00017901027901027901017A02027C03 - 017C03017E03017904016800006401006902006F02007602017A02027F000182 - 0001860001860001870001860001860001840001820001820001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018001008002008001008001007F00017D01017B000276 - 010475060A6500006B0A0E4E00005A090C4200004A05083C00003C0403320000 - 460B09390000530B0B4300005704065100005D020554000062090C4C00005D0A - 0C4700005204054600004602034201034000013D00003A000242040A3A00004D - 070D3E00004E070A3B00004002023C01003E0100470200510100630101730003 - 8100038700037F00007F00008300008600008600018101027902036C05035300 - 00500604390000460B093500004709093F00004B02044800004B000051010258 - 02025F02036202026501016501016100006305094D000057070C3E000046060C - 3200003A000538000142060735000048090B37000047080A3A00004201033F00 - 004704073A00004B090A3A00004A08093B00004202023C000044070537000048 - 0B093700004909083B00004701014800005703055300006F090E6300007B070E - 7200007E00067E00048100038100038300038300038300038400008200008300 - 038001037C02027802017403006F03006E03006804005C00005E00006401006C - 03007203017903027D0101800001840001860001870001870001860001860001 - 8400018200018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180010083010183020082000080 - 01007F00017D01017800037300036C01046A07094E00005405083E0000450608 - 3400003E05063A00004606053C000055090A4A000063080B5A00006600056700 - 056E070A5C0000690B0C4E00005A07064700004900003F00003E000040000143 - 02043F00053A00004903093E00004E040A3F00004503043D00003900003A0100 - 4202004F02006101017100038000058601047F00007F00008500008600008600 - 008200017901026E040358010046000046070333000043080639000048040545 - 00004300004600004A00005000005500005A00005D00005D00005B0003510000 - 5504073E000045050B31000036030A3200063801043500004005093500004505 - 0A3A00004502054200004600024100004905063C00004806073B00004404043F - 00003F02003800004207053500004508063A00004704034600004E0000520000 - 67060A6600007D091077000385020C7D00037800047800037E00038300038A00 - 018E00019400029400029100028900018200017600006802005E030056030054 - 03005200005800006002006804006F04017504027B0101800001840001860001 - 8700018700018600018600018400018200018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 01008301018302008301018001007F00017C00007700036F0103660002570000 - 5603054000004203053000003706083602024000004500005505065100006706 - 0863000073040872000378040970000373080B5F00006408074F000052030047 - 00004804054302044100023D0000400003410004410000470003430000470003 - 4000003E00003900003C01004101004C01005901016802037501067D02067C00 - 007F00008200008500008700008500007C00017202025F000054010048000044 - 04003E00004303024100004301023F01014101014300004700004C0000510000 - 5500015500015100005000024700004300033A00013802073300073503073900 - 033D01023A00014001033E000143000344000045000147000146000243000045 - 01024100004301024000003E00003C00003B02003A00004003013F0000470101 - 49000050000055000061000069000177060A7A020783050B8000058100067C00 - 037C00017F00018600028900028E00039000038E000389000281000176000068 - 01005C01004F01004501004501004A00005100005D00006902007403017C0202 - 8000018300008400018400018400018400018400018400018600018400017F00 - 027B00027D00027D00027F00027F000180000180000182000182000182000180 - 00018000018001008000018001008301018301018001027B01017601026F0101 - 6802036104035200004C00004400004301023900003B02033501013C02034700 - 005400005900006700036B00007702057800047B02067E03077D040877000374 - 03066400005F03025100004B01014000003E0000400001430204410000400000 - 4301023F00004301023F00004101004000004101004000004603024500005000 - 015000005D02056803057801027F00008300008400008500008500008300017C - 00017705056C05035F03025201004900004000003C00003900003B0203390001 - 3F03043C00004601044400004C01034B00014900004600004701023F00003E02 - 0337000038020239000140000142000045000341000047000343000046000245 - 00014600024400004700034100004500054100004400043D00003D0504390302 - 3B00004000004800005200005F01026902057001057401047800047900047B00 - 027B00027B00027F00028600018800008600008500008200018001037A020374 - 03066D04076201035C03064D00004901013F00004002023F01014502014E0100 - 5D00006D00018000028B00038E00028D00008700008200007F01007D02007F00 - 018200018700028400027800047201057401047800047B00047D000280000282 - 00028702048601038501018200007F00007E00007D00007E00008202037F0002 - 7901056A00006202025000004A00003E00003A01003A03003A03003B02003E00 - 003F00004200004800005C04046802037101017901027F00018001027C02027C - 02027D01017E00008300018000047901056A0104540002460000440104420103 - 4000013D00004200004504033B00004707063900004606053C00004101004000 - 004605043E00004C06064200005105064B000060060675030380000182000183 - 00008600008600008500018100017F02047601026901025D0100520100470000 - 3F01003800003900013E050834000043060A3700004704094000004601044200 - 004702053B00004707073700004206063600003D01014200004B02043F00004C - 06073E00004B05063F00004400024200004702053D00004A040A3C0000480208 - 3E00004100013C03023D01014100004900005400006000016C01047702057B00 - 047D00027F00027F00027D01017B01017901017F00018700008C000088000184 - 02027C02027402026901026101015B02055808094600004B0708370000420607 - 3700003D03043E02034901015B00016D00018400049100039300028F00008700 - 008001007902007803007D010180000187000286000478000572010574000578 - 00057B00047F00048200028400028500028500028400018200007F01007D0200 - 7D02007B02007700027703086500006507084C00004C07043800003503003405 - 013404003601003A00004200004A00005200025A00026503036F01017A000082 - 00018600008301017E03017C03017D02008100008800018700028000066E0004 - 5600034600003C00003D00003F00004302044302013B00004A09083900004A0A - 093700004407053C00004202013C00004D0A093E000051090942000053070859 - 01017103037E02028001028200018600028500018500018300017F0002780102 - 6E02016403005902004E010047000040000042040438000045090A3700004A09 - 0B3900004805084100014300033A0000490909370000480A0A3500004206063A - 00004202023B00004A08093A00004A0A0A3900004605073E00004401043C0000 - 4A070A3A00004C070A3C00004902054100004600014A00004F00005800026300 - 046C01047701067E03078000048200028200028200018000017F00017B02007D - 02008200008400008202037D03037702036D0100620000590000570305490000 - 51080A3C000049080A35000043060A3A00013C02034201005500016800017F00 - 048B00038E00028B00008400007D02007803007603007B01017F000186000286 - 00027F00047B00047D00047F0004800004820004840002840002830001810000 - 8000018001027C02027A03017903027203016B00035C000065070B4A00005509 - 0A3C00004407053800003C04003C02003F00004700004F000057000060010568 - 03056A02037101017D01018400018600008400007E03017C03017D0200810000 - 8600018600027E00066C01045400034400004502054201034000013D00003F00 - 004707063900004A0D0B370000480B093700004003013B00004808073A000050 - 0D0C3E00005109094500005805046E04037903027C0202800102830003840002 - 8500018300017F00017B00027402026B04026202025902005201004A00004400 - 004906093A00004C0B0D3900004B0A0C3900004203053C000045060835000048 - 0C0C370000480A0A3700004002023C00004507073700004A0C0C350000460A0A - 3500004001033C00004706083A00004F0A0D3E00004E070A4000004B00015300 - 015A00006100046700037001057901057E000584010484000286000286000184 - 00018200017F00017D02007B02007D02007C03017802017403016C0000640000 - 5A00005300004F00005105064000004E0A0B39000048090B3800003E04053802 - 023F02005000016200007800048500028800028600008200007B020078030076 - 03007901017D0101840002860002840002840002840004840004860004860004 - 8600028400027F00017F00027C01037A02027702037203016F01016702005500 - 00570406450000550B0B3E00004B0A093900004303024300004600004E000055 - 00005F00006600016F02047204066F03027402027F0001860001870000840000 - 7D02007B02007D02007F00008600018600027E00066C01045400034400003E00 - 003E00004000014302044202013900004A0A093700004A0D0B3500004308063A - 00003E03013800004C0C0B3A00004F0C0B3E00004D07074F0000670303710101 - 7601027A02037E01038000028400028300018100017F00027A02037303036D03 - 026602005E010057000052020344000052090B3E00004D0B0C37000044080839 - 00003B0302320000440B0A330000480C0C3700004707073E00003E0202350000 - 440B0A330000460D0C3300004108073A00004103033900004D090A3E0000530A - 0C4300005304075100006601036E01037201057702057E000581000386000286 - 00018900028900018700018600018200007F01007D02007902007605036F0401 - 6A00006400005E00005900005200005000004C00014000004E08093C00004B0A - 0C39000047050A3B00003602023B02004A00005D01007100037E020284000183 - 00008001007B02007803007603007901017D01018200028600028B00028B0001 - 8B00028B00028900028700028400028000027F02047902037503037002026B00 - 026601006100005900004A00013900004909093900004C0C0C3A00004C060647 - 00004C00005300005D00006601007002047801027C01037B0002760102780102 - 8200018700018700008600007D02007B02007D02007F00008600018400027C00 - 066A01045300034200004401044201034000013D00003E000046060537000048 - 0B09350000450A083600003E03013900004207053700004B0B0A3A00004B0807 - 3E00005003015D00006700006D01007202027902037E01038000028100018500 - 038100038001037A02037601026F01016B010066020257000058030747000053 - 080A3C00004909093600003D05043500003D0706300000440B0A350000490909 - 3B00004202023C0000400706330000430B0A320000420A093400003E02023C00 - 004705063E000054090B4700005C080C5100006201057401047C010380000581 - 00038500038700028800018A00018900018700018600018200017F01007B0200 - 7902007403006905016203005C00005600005100004E00004C00004B01004400 - 004A04043C00004B090A3A000049080A3B00003E02033802013902004800005B - 01006E01037901018000018100008001007D02007902007902007B01017D0101 - 8200028700028D00019000018F00018D00018900028400028000027B00027904 - 057103036A02036301015D00005800005600004D00003A00003B050533000045 - 09093900004E08094500005401005900006200006D01007503037D0204820203 - 8400017E00007A02037A02038400018900018900008600007C01007801007B02 - 007E00008500018400027C00066A01045300034200003D00003E000040000143 - 02044101003C00004407053700004308063600003E05033900003A0100380000 - 4409073900004707063A00004403024800005200005B00006400006C01037302 - 057A01057F00028200028601048601048301028000017D010179010178020171 - 03036300005600005B02054700004E06063C0000410604370200360301310000 - 3D07063200004506083A00004702054000004100023800004206073300004108 - 073400004004043D00004000004100005105064C000060070A59000067060A6B - 00037D00028600018600028700018900018900018A00028A0002870001840001 - 8000017D01017902007603007403006B04015C01005300005000004D00004800 - 004800004600004502014302013E00004806073B00004906093C00004502053C - 00003901003A01004800005801006C0103790101800001820000820000800100 - 7D02007D02007F00018000018200028700028F00019000008D00008900008600 - 017F00017901027202026E03056503035D00015400004F00004A00004A000043 - 01023900013000003E05063700004A06074400005501035900006600016E0002 - 7801027E02028202038501018600008200007E02027E01038800028B00018B00 - 008500007C01007801007B02007E00008500018200027A00066A010453000342 - 00004603064302044100023D00004000004101003E00004003013A00003E0301 - 3900003A01003800003C03013C01004005033B00004101003F00004500004B00 - 005200005C00006402026D02047502057B000280000287020586010487000283 - 00008100008000018102037C04056900006300005900005600024A0000480202 - 3E01003B04013701003603013500003B03023C00004300034200004300014100 - 014100023E00004001033A00003E02023D00004000004100004A00004F00005D - 02056100026C03066F01077A0207820000870000870000880000890001880002 - 8801038702048000017D01017901017602017003016D05006B04016406014E00 - 0048000048000047000044010042020041010040000041010043030240000045 - 03044000004401044100004000013A01003E01004A00005A00006B0002780201 - 7F00008200008400008400008200008200008200018200018400028600018B00 - 018B00008700008400007D01017802017002026904026205045803014F000047 - 00004200004000004202024004043800003A01043C0000450003480000530001 - 5900006200007403067902037E02028001008300008500008500008400007E02 - 028001038A00028D00018D00008600007E00007801007B02007E000083000182 - 00027A00066A01045300034400003E00003E0000400001430204430201400000 - 4303023C00003F04023B00003D04023B02003A01003900003E03013A00004003 - 013C00004101004300004A00004B00005300005500006501016B00007A050681 - 04068100038500038700028600018600008500008300007F00007B0307700305 - 6700035C00005100004900004100003D00003B04013702003C04033800004102 - 044000004601044600024500014400004500033F00004202023E000042010043 - 00004900004F00005800006300026B00037401047900057F0004870002890001 - 8900018700018500008100007D00007800007C05067303037206056500006403 - 005900005A00004F00004900004000004302013E00004202013C00003D02003C - 01003C00003D00004202023F00004300034100004600024100014002023F0000 - 4C00005500006C01037500008000018300008800018800018800018600008600 - 018300008300018300008500028301018405067A02027606066700005F000053 - 00005200004A00004701013E00004002023900003B02013B00003D0000410000 - 4900015000035A00056302066C03067403077800047B00027F00018001008200 - 008201008201008002007D01018000028900018D00018D00008700007F010079 - 02007C03017F0100830001820002790005690003540003450000440104420103 - 4000013D00004300004605043C00004707063700004207053900003D04023900 - 003E05033600004308063700004407053C00004201004200004B040144000058 - 05045500006D07086D00017D06077E0103830102870002870000870000860000 - 8600008300007D02047601046D00026400005B00005000004800004100003E01 - 004106043500004307073700004704074000004801044800004D01054100004C - 05083C00004705063F00004600004A00005200005D00016701027201047B0004 - 8000048400028700028600008400008200007E00007A00007802017303036D03 - 026E09075D0000630A064F00005805034A00004A000042000042050338000043 - 08063500004207053600003B02003B00004004043A00004707073C0000490407 - 4100004400024100004603024500005E04036100007C08077C00008701018900 - 008B00008800008800008500008300008100017F00017C00007D070670000077 - 0B0A6000006308044F00004D00004500004603003B0000440907340000400706 - 3500004000004900005000005500035D00046600056D02057501067A02067D00 - 027F00027F00018001007F01007F02007D02007D02007D01018000028B00018F - 00018D00008700007F01007902007C03017F01008500018400027B00056B0003 - 5600034700003C00003D00003F00004302044903033F00004C09083A00004A0A - 093700004308063C01003E0301360000450A08350000480B093700004606053E - 00004202013B00004D0707450000600A0A59000071090A7202027A0203800102 - 8200018600008600008601008600008300007F00017901027500016D01006400 - 005B00005000004900004903033D00004909093700004A090B39000048050A43 - 00034C000546000052060A4000004D090A3C0000490605430000490000530000 - 6100026D02047702058001038700038700028600028300017E00007B00007700 - 007402026F05046B07076205045700005E0B09470000560B094000004D060341 - 0000420201380000470909350000460A0A3300004007063800003E0202360000 - 4909093900004D090A3C00004B05064300004501023F0000560607500000700A - 0B6A00008408088300008700008900008A00008800008500008100007E000178 - 00017404046500006F0B09550000630C0A480000500604410000410100370000 - 470A083500004A0D0B3700004505044300005A00026200036600056B00057100 - 067600057A00067E00057F00027F00027F00017F01007D02007B030079030079 - 02007D01018000028B00018F00018D00008600007D02007803007A03017F0100 - 8500018600027F00056F00045B00044A00014702054201034000013D00004600 - 004D07073E00004F0C0B3A00004B0B0A3900004005033A000043080635000048 - 0D0B370000480B093900004003013900004308063A0000540C0C490000650B0B - 5F00007105047601027B01018001008200008401008401008601008401007F00 - 007D01017901027402026D00026400005B00005100004B00004F07073C00004D - 0B0C3900004B0A0C39000045020747000153030A420000510A0D3C00004B090A - 3A00004502014800005201005F02016D03027803048102038700028700018200 - 027F00027D00027801027202026D020465030360030453000057070643000055 - 0D0D3C00004C0B0A3A00004303033E0000450707370000480C0C350000440B0A - 3300003C03023A00004307073700004C0C0C3A00004D090A3E00004501024000 - 004B0505450000610C0A570000790E0B74000085060585000088000088000085 - 00008000017D01017801027002026400006508094E00005E0D0A430000520B08 - 3B00004405013B00004407033900004D0C0B3C0000520B084400005502016801 - 047100047300047600057900057D00048000058000058000028000027F00017F - 00017D01017B02007902007902007B01018000028900018D00018B0000860000 - 7B02007803007A03017F01008600018700028100067100045D00044E00024000 - 003E00004000014302044D0303440000520A0A3E00004F0C0B3A00004808073D - 0000400301370000480B093700004C0C0B3900004807063C00003B0302320000 - 460B093A0000580D0B4A00006508076300007002027602017B02007F01008002 - 008201008402008201008100008001007E02027A02027402026D01006400005C - 000057000349000054090B3E00004C0B0D37000044070B3D0002490005430000 - 51070B3C00004A0C0C3500004308063C00004300004B01005902006703017503 - 037E02028500028600018000027C01057A02067704076E03056601035B000051 - 00004F0102430000500A0B3A00004C0C0C3700004506083C00004300033A0000 - 4B080B3900004A0B0D3500004307083A00003E0203350000480A0A3900004D0B - 0C3A00004A06074100004200013C0000540A0A490000670D0C5C00007A0B097B - 02008001008400008400008102017C02027504027004036905055E04044D0000 - 57090A4000004E0B0A3900004609073B00004205013B00004E09064200005909 - 084C00006309096501017502057C01057C01057E000580000580010380000280 - 00028000028000028000027F00027F00027D01017D01017D01017B0002800002 - 8700018B00018900008400007B02007803007A03017F01008700028900028300 - 067600056100055100034801044201034000013D00004A000051050642000051 - 09093E00004C09083D00004404033E0000440705370000480B09390000490908 - 3B00004003013400003A07053300004B0B0A4000005808075300006201006C02 - 017102007803007B02007D02007F02008103008103008301018301018001027E - 02027901027500016D00026701025A00005C030647000051080A3A000045090A - 3500004003074300014D03093C00004A090B330000400A093100003B04003E01 - 004801005402006103006E01007800008200008200017D000279010578030672 - 04066801045D00005200004A00004700004B05063A000048090B35000045080C - 3700004101064100014904073C00004B080B39000047080A3800003E02033A00 - 004206073700004A0A0A3A00004A08093D00004301023D00004606053E000056 - 0C084A0000660A056600007706037E03018002018002017B02007403016C0300 - 6703015E04034F00005106083E00004A09083700004409073700004005034102 - 004C07044300005B08065200006B09096500007606067C010381010281000381 - 0003810003810003800002800002800002800002800002800002800002800002 - 8000028000027D00027F00028700018900018700008200007902007803007902 - 008001008900028A00038400077901066400065400044100003E000040000143 - 02044F01024700005004054200004C06063E00004605044000004101003C0000 - 4606053900004807063B00004704033D00003701002F00003F07063800004D08 - 054700005902005B00006803016E03007302007803007903007C04007E040080 - 04008402028402028301018001007D0101790102760104700305630002560000 - 5702064200004805083700003E05083A00034200044100004605073500003E08 - 072D00003707033402003B03004202004D01005901006600007401007F010081 - 01027C01057600057200036C00026300025A00005100004B0000490003400000 - 47050A38000043060A3700004002083F00024600044300004B03093C00004805 - 0A3A00004403053D00003F00023A00004606063900004806073B000047030440 - 00003E00003B00004808074000005306035000006704006C0100790401790200 - 7902007401006C01006401005C01005401004B00024000004704073700004307 - 073700004106043E01004502004600005906045700007008096C00007D06077D - 0002820001840000840001820001800001800001810102810102800002800002 - 8200028400028400048600048600048400027D00027D00028600018900018700 - 008200007902007603007902008001008900028C00038600077A000667000755 - 00044A03064302044100023D00005600005600005000005101004800004A0300 - 4300004202013E01003F02003C00004202023F00004301024200004000003700 - 003603013500003D04033E00004702004A00005100006005016504016A030070 - 03017603007A04007C0400800300830403840202830101810000810000800001 - 7F02047B03076B00006600005900005400024800004602033E00014001034300 - 014400023E00003E02033500003704023202003502003A030040020048000050 - 00005B00006501007101017303037103076A01046300005C00005300004F0000 - 4C00024A01034200024302043D00024003073D00024101073D00034200044900 - 014D00024A00004E00034A00005000024D00005000005000005100004C00004E - 00014800004901014400004100003E0000400301410000490401460000520000 - 5700006103006904026804006702006302005D00005800005100004A00004100 - 004001033D00004103033D00004404034300004901014900005500005D00006E - 06077302057D06077D0004800002830000830000830000820000800001800001 - 8101028101028000028000028200028400028600028600028700048400027F00 - 027F00028400018600018400008001007902007902007D02008200018900018A - 00038400067A02076801045801044400003E00004000014302047207046E0502 - 6602005B00005100004900004100003D00003E03013A01003F03033C00004302 - 044200004800064400043C00033800003902053700003B02033800003F010141 - 00004B01005000005E02016200007002027600007F02048001028001007F0000 - 8100008200008500008500008500008300017F00027900047302056903045F03 - 025401004B00004600004A01034400014703043F00004103033A00003B020139 - 00003E03014000004603024700004F01024F00005800025400005000004B0000 - 4C00014700004701013F00003F01013C00003C02033A00013D03043B00004102 - 043F00024200054500014D00005600005C02026103046905056E040374020277 - 00017B03047901027301016B00025F02015300004700003E0000430000440000 - 4901014700004E01004A00004D00004C00004A00004700004C02024600004D03 - 034A00004F00034800013D04023904013B02003E01004400004800004E000054 - 00006603056B02057001057400057800057900047B00057D0004800001820001 - 8200018000018000018000018000018000018000018000018000018200018200 - 018200018200028200018000018000018000017F00017F00017D01017D01017F - 00018100008700028700028300007D00027503036902005800004A0103420103 - 4000013D00007B04027603006E01006501005B00005000004600003E00003C01 - 003F06053500004307083900004903094200014800073F000240030734000040 - 070A3000003D07073500003B02014100004D05054D00006306075F0000740608 - 7300007A02037C02027D02008000018300008600008800008800008800008600 - 028000027C01037303036A03016001005800005000004900004B02044000004A - 06073B00004707073B00004103033E00004305053B00004806073E00004B0506 - 4400004A01034200004404033A00004508063500004007053500003A02013900 - 014006073800004607093B00004904074100004B00015700015F00006602026B - 04027503037C02028200008600008C00018900008100007800006A02035C0201 - 4C01004400004400004903034100005006064300004F05054100004200013C00 - 003E05043500004408083A00004A05084400004701023C01003902003E010044 - 01004D00005700005E00006500007201057600057900057B00057D00057D0005 - 7D00057D00047F00028000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302047F00017B01017501006B02006001 - 005501004A000042000044040338000045090A3500004A080D3A00004A040A43 - 00034300053A000047080A350000440A0B3300004206063C0000450403430000 - 570A084A0000660A095900006B05066900007504027A02027E02027F00018400 - 018500008600018600018500018200027E01037702036F03026702006200005A - 00005100004300005106084000004E0A0B3A00004808083F0101400404380000 - 4709093700004B090A3A00004A06074300004301023A0000490909370000460A - 0A3500004206063A00004103033B00004D090A3E000054090B43000053040751 - 00006300026900036D02047103037803047C0202820000850000890000860000 - 8100007901016E03056105045303024902004502013B00004C09083C00004F09 - 093C00004706053C00003C0302340000420A09330000480A0A3A00004A040544 - 00004100004100004900005001005902006202026B03047302057800047B0004 - 7D00047F00048000048000047F00047F00048000028000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00008300 - 008000017B01017203016902005D02005300004900004200004808073700004A - 0B0D3900004B090E3C00004701074100014A040A3A00004C0B0D39000048090B - 3900004202024000004D0707400000570C0A4700005C09074D00005D00006E04 - 037504027703027C02028001028200018500018500018500018400027F00027C - 01037702037002026E0103670303530000580408470000570A0D420000510B0C - 3C00004404043D0000460808350000480C0C370000490B0B3B00004404043E00 - 004707073700004A0C0C370000480A0A3900004301023F00004D050543000059 - 0B0C490000610B0B5300006204056F01057501067603067803047B03047E0202 - 8001008400008700008500007F00007901016F02046303035701014B00003F00 - 004508063900004C0C0B3A00004A0A093700003E030139000041080733000047 - 0B0B3900004C08093E00004B01014B00005000005700005E0100670303700305 - 7704077D04087D00048000048200048200048200048200048200048000028000 - 0280000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302048800008600018101027A02027202026602005D010052 - 00004E02034000004E0A0B3A00004C0B0D3900004807094000004500033E0000 - 4D080B3C00004F0B0C3C00004806073F00004504033B00004E0B0A3C00004F0C - 093E00004C07044900006304016C02017002027503037A02037F000282000283 - 00018500018300018200028100037E01037A0203790203710305650106550000 - 630A0D4A00005C0C0D4300004E06064300004504033B0000490C0A350000480D - 0B3500004209073B00004001033700004A090B3900004C0C0C3A00004C060645 - 00004900004700005B08075000006B0D0E5B0000700C0C6F02047B01077F0107 - 7F01067D02047D02047E02028001008200008501018400007E00007800006F01 - 036501015B00004D0000430201350000460B09350000480D0B35000043080638 - 0000400503360000480B093900004C0B0A3E00004E06064D00005C0000640000 - 6600016D00027401047901057F01068302078400048600048600048600048600 - 0484000484000482000280000280000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00008E00028C000287000281 - 01027801026E02016602025D03025100005305064000004F090A3A00004A070A - 3C00004502053F00004904073C00004D080B3E00004E08093D00004501024200 - 00470605390000490C0A350000450B063600004502005601006201006701026D - 03027303037902037D00027F0001830001830001830001840002820002810003 - 8001037A01056D00036D070C5C0000690A0E5000005E070A4B00004E00014700 - 004A07063A0000480B09370000450A083600004004043C00004604093900004B - 080B3C00005007094400005000014E00005D03025400006F0B09600000790D0C - 7000007E07088400068700068300058100038001038001028002018102018301 - 018200007E00007800007100036800015D00004F000041000042070533000044 - 0B09330000430A083400003E03013E01004707063C00004E0808420000540809 - 4700005903036802037100037300037800047B00048000058300058500058600 - 0487000487000486000486000484000484000482000280000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02049200039100038A00038400027D00027601026F02046905055C00004E0000 - 5204054200004C06063E00004604054000003F01013A00004606063A00004A06 - 073D00004903034200004502013D00004606053600004209073400003C07043E - 01004D00005800005D00016503036C04057302057800047D00047F0003810003 - 8300018500018500018600028400028100057A02076F000275060A6700006D06 - 095D00006104055700005301004900004D06033E00004808043B00004306023E - 01004100023D00004903093E0000500507460000540103540000610304620000 - 7107066900007B0A087400008108068101028900048B00058700048400028000 - 027F00018002018002018102018001007E00007B01017702056E010365000159 - 00004800003A00004207053300004108063400004005033F0000460300440000 - 5205034900005906054E00005B08076002037201047B00027D00027F00028200 - 0284000286000286000287000287000286000286000284000282000282000280 - 0002800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00009300049100038C00038500018100017B0002 - 7803067205076100005C00005200005101024800004A02024500004301023C00 - 003A02013A00004002023E00004501024200004500004200004401003E000041 - 04023900003B06033803003F04024600004F00005600005D03036403056C0405 - 7002047601047A00037E00038000008200008400008600018600018600027F00 - 037E00067900037A02077100027102066800026702045B00005800005000004F - 02004800004A03004700004701014500014600044500014C00034C0000530001 - 5600005C00006B05067307067403017C07047C01008104008100008600008D00 - 048C00048800038300017F00017D01017E03017F04027E00007F00007E00007E - 02027B03077403066D02055F01024A00004200013C00003E03013800003E0301 - 3F00004300004B00005300005500005C00005B00006303036002036B05067700 - 017F000180000282000284000286000287000387000386000286000284000282 - 00028200028000027F00027F0002800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E00004000014302048D00028A0001 - 8A00018500008200007E00007A00037300037003056804046104035A02025301 - 004D00004900004100003D04023603003D06033900004104023E000044010042 - 00004500004200004501023E00004002023800003B02013C0000460001490000 - 5202035200005E03066100026A03066F01057502057B02068102048401048601 - 048800038700018600018800058700058500058200047F00047A000375000371 - 00036C01036602026101015D01005700005100005000004D00004D00014E0003 - 5000035300035900045E00046401036901026F01037500017800007D02008200 - 008502008702008A00018F00068C00068600038000007B00007A00007C03017D - 04027F01007F01008000018001027B02067601046C0001610000500000440000 - 4301023E00004003013E00004401004A00005200005D00006800016E01037003 - 057004036D02046F01017B000282000282000282000284000284000284000284 - 00028200028200028000027F00027F00027D00027B00027B00027F0001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00008800038700028700028500018300018100017E00037800037702 - 056F02046802036202025D01005500005100004A00003C02003C070434000042 - 09073600004606053D00004502014400004903033D00004A06073A0000460606 - 3A00004101014100004B02044400005406074C00005F06095B00006601036D02 - 047201047902037E01038100038500038600018700018A00038A00038A000587 - 00028600048100017E00037A00017601047101016E01036902006400005F0000 - 5F00005B00005700015600035800035D00036100046700036C01037101017500 - 017800007C010080010084010087020088020088000188000587000683000580 - 01037901027802017801007A01007F01008001008000018001027F0106780004 - 7100026300005200004D02043D00004707073700004606054300005100005E00 - 006800007400027901027A02037A02037601027700017F000282000282000282 - 00028200028200028200028200028000027F00027F00027D00027B0002790102 - 7801027901027F00018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302048001038100038100038200028200 - 028100017F00017E00017B00027801027101016C02016602006102005E020154 - 0300430300360000450B06350000490C0A3900004706054000004501023D0000 - 4E08093E00004D080B3C00004904074100004400023C00004D06094200005607 - 0A4900005A03065800006301016901026E00007301017901017D010180010283 - 01028800028A00028900028900018700028600018300017F00008001037C0202 - 7801027403017101016E03006D01006902006200016100046300046700036C01 - 046F01037401047801027A00017C000080010082000084010086010087020085 - 01018000047E00067B02067A0304780304760201760100780000800201820000 - 8200018101028101067900047300026600005700024400004E0809390000480B - 093900004D06035100006600017400027F00048300038401048101027D01017C - 00007F00018000018000018000018000018000017F00017F00017F00017D0101 - 7D01017B01017B01017901017802017901017F00018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00007702 - 037902037A02037E01038001038000028100018100018000027D000279010276 - 01027002026B04026804026106024900004C07043E00004F0C093C00004E0B0A - 3B00004504033F00004806073C00004F0B0C3C00004D080B3E00004500033E00 - 004704073C000050090C4000005306094500005300015800005D00006400006A - 00006E01007403017903027D0303820001860001860001860001870001860001 - 8600018400018200018000017F00017D01017901017903027703027304026D00 - 026C01036E01036F01037401047801027C01037E02027F000180000182000082 - 00008201008201008201007F01007901057302067002046F03026F0302710200 - 7502007A01008102018400008400018400018000057C01057400036900035300 - 005104073C00004A0C0C350000480B094000005500006D02047A02038601048B - 00038B00038701018200007F01008000018000018000018000017F00017F0001 - 7D01017D01017D01017D01017D01017D01017B01017B01017B01017B01017F00 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302046A02036C01037002027702037C01037F000282000283 - 00018500018400028000017D01017903027504027205036B06045C00004D0000 - 5C0907470000570C0A4000004D070740000042020239000048090B3900004C0B - 0D3A00004A040A4100014502073B00004C090E3C00004F0A0D3E00004D050547 - 00004F00005200005800005E00006401006902006F04017304027902007F0100 - 7F01008001008200008200008400008400008300008300008100008001007F01 - 007D02007E03017A02027602017601027801027901027C010380010281010283 - 01028200018200008200008001008001007F01007F01007802016D0506660305 - 6301016100006400006A01007403007D04028402028600008600008600018100 - 057C01057600056900055500024200004A0A0A330000430E0B3300004C070451 - 00006F04067D02048900048F00038D00038A0001820000800100800001800001 - 7F00017F00017F00017F00017F00017F00017F00017F00017F00017F00017F00 - 017F00017F000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00005D000062000067020070 - 02027902037E01038400028600018800018700028600018200018001027A0202 - 7A04037405036700006B0506590000660A094A0000570A084300004504033C00 - 00420606330000440A0B35000047080A3A000043000541000348050A3A00004C - 090E3A00004B080B3C00004603024801004A00005000005300005B0000600200 - 6403006B04017103007502007803007B02007D02007F01008301018501018300 - 008300008300008300008200008001008001007F01007D02007D020080010281 - 02018301028500028500028700028501018501018001007F01007D02007B0200 - 7A01007102006205045802025600005600005C00006501007305017F06048402 - 028800018800008700018300057D02067701066A00064F00004B040735000041 - 0B0A2C0000400B083B00005201006D05067C01038800028E00018E00018A0100 - 8302008103008001008000018000017F00018000017F00018000018000018000 - 0180000182000182000182000182000184000184000182000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02045400005800006201006C02017503037E01038400028900028B00018B0001 - 8900018700018400018001027E03017A02027A02037100007605085F00006306 - 074D00004D05054000003D01013500003D070730000040070A3400004003073D - 00024300063E00014704093A0000480709390000430505400000420200450100 - 4800004D00005100005701005E04006204006A04006E03006F03007403007803 - 007C030180020181020183010184000084000084000084000082000082000082 - 0000820000840100840000860100860000870000870000870000870101850101 - 8101027D01017B01017701007701006C02015500004B00004B00005000005700 - 006401007004007E05038602028A00018800008700018300057D020678020769 - 02074F00013D00003F07062B0000350B062C00004205014D0000690304790102 - 8700018D00008D00008700008103008003008001008200008200008001008200 - 0080010082000082000082000084000086000086000087000087000089000087 - 0000820001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00004700004D00005600006003026D0204750205 - 7D00048400028900028B00018B00018900018600018400018001008000018100 - 038102047700027401046500006100025300004E00014700004200013E000040 - 01033A00003E02033B00023C00033C00013E00033B00003E02033A00003F0304 - 3C00003E02023F02004001004200004500004900004F01005302005804005E05 - 016105006504016B04017003017703027A02027C02027F030381020382020383 - 0101850101840000840000860000870000870000870000890000890000870000 - 8700008600018301028001027C01037601027202026E01036C01036104034700 - 004100004500004C00005501006001006E03007901018503048800028A000086 - 00008300037F02047A02066C03065000004200013700003505012E0100350501 - 3D00004E00006903047800018500008A00008A00008700008103008104008001 - 0082000082000082000082000082000082000082000082000084000086000086 - 0000870000870000870000860000820001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E00004000014302043E02033F0000 - 4701024A00005B00036200017102067A00067D00018200008600008600008700 - 008800018802028602028200018000017F00027D00027B00027800047201046D - 02056200005B00015500015000024B00024400014200023F00023B0203370101 - 3A04043500003B03023600003901003800003B02013B00004202013E00004401 - 004100004600004400004A00004A000055010357000067020469000171030575 - 02057400007600007B00027B00008402038400008B00038B00008A00008A0000 - 8A00008900008900008700028300038101067D02067600057002086400026001 - 055600005400014A00004400013F000046030244000050000056000068020374 - 01047F00028600028900018900018400018000017B01016F0302530000450000 - 4102003700003D06033A01004701014F00006A03067A02078600068A00038800 - 0085000083010183040380010080000180000180000180000180000180000180 - 0001800001820001820001820001820001820001820001820001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00003700033E05083800004B04074800006004096300017102067800 - 057D000482000284000186000186000087010187010182000182000182000182 - 00018200028200027F00047B00047400036C00026500035D00025300024D0001 - 4A00014300003B00003E05043400004108073500004206063800003D01013B00 - 004004043800004507073700004505053C00004101013D000045030443000058 - 04085200006504086200006A01046F01057507096F00007F0809760000850506 - 8100008700018600008600008500008500008300008000027D00047800047000 - 0570040A5E000062060B4C00005104084500004300013D00004204043B00004C - 06074300005A03066200007403077D0004840002890002890001860000820000 - 7D02007203015600004D03003C00004508043700004808074300005300006B01 - 077A020784000788000387000285000083010182030280000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302043D04073500004807093E00005607 - 0A4C00006504086500007102067702057C01037F000180000182000181000081 - 00008200008001008200018200018400018200018000027D00027A0105740104 - 6E00046601035E00035700015200004D00004B00024100005007094000005108 - 0A3E00004905064200004301023A0000490909370000490B0B3500004307073B - 00003E02033700004B07084200005A060A4E00006002065C0000680507620000 - 730B0C6400007C0B0E6F00007E06077800007E03017D02007D01017B01017901 - 027801027300036E01036700055A000063070C49000055080C3E00004903093E - 00004001033900004909093E00005408094C00006906086F00047B0004820002 - 8700028700018600008200007D02007203015D02004700004D0805390000490C - 0A3900004D05054E000068010677010682000787000387000285000083010182 - 0302800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00003B00 - 0246060B3900004E090C42000058070A4F00005D00026702046C010371000376 - 01027901027D01017F00017F01007F0100800100800001820001840001840001 - 8200028000028000057A01057601046F00046900036300026000035D00035700 - 005E04094E000060090D4A00005A060A4500004C00024600004B05063C00004D - 0B0C370000470B0B3600003D04033800004307083900004E0A0B420000570609 - 4900005500015400005F05055200006D0D0D5A0000750D0E6A00007406067205 - 037206027205037104026F03026D03026802036502045700005A030647000055 - 0A0C3E00004A090B3700003F03043A00004507073900004F0B0C4300005F080B - 5D00007304087B00048200028700028700018600008200007D02007203015B00 - 005607044000004D0D093700004C0C0B41000053000166000576000581000687 - 0003870002850000820000820302800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302044301063A00004B080B3C0000500A0B4200005204054E - 00005A00005D00006400006B01007101017703027A04037B03037D02007F0100 - 8001008200008400018400018400018400018300017F00017C00017900047601 - 047201047001056F010570020864000072080E5A00006C080D5300005D02054F - 00005200014500005309093E00004D0C0B3900004508063900003E0405350000 - 490A0C3900004C090C3E00004E05074700004A00004500005808094A0000640B - 0E52000066090A5F02016304016305006304016003005F02015E02015B010157 - 01015100004300005007093A00004A0B0D33000040070A3700003F0304380000 - 4B0B0B3C000055090A4A00006807096D00037900048200028700028700018600 - 008200007D02007403016304014C00005309073A00004B0E0C3900004D07074D - 0000620003720003800006850003860002840001820000810201800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00004100014704093A00004B - 080B3C00004B07083F00004A00004C00005100005900006000006701026D0302 - 7103037605037902007B02007D02007F01008200018400018600018600018400 - 008500018300018200028001037E01037D02067B02067800047E050D6C00007C - 080F62000070040A5D00005F00025900005A030649000057090A4200004D0707 - 3F000042000140000146060B370000490A0C37000049080A3B00004503044200 - 004B0506400000540A0A43000055070848000052000052000054000052000052 - 00005100004E00004E00004A0000430000470403390000450909330000400A0A - 3200003A04043A00004406063900004D090A4200005B07095C00007204087900 - 048000028600028700018600008200007D02007403016201005C07054300004D - 0A073700004A0A094000005000016100026F00027D0005860104870003840001 - 8200008102018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02044600023F00004704073B00004808083900004306043F0000420000470000 - 4D00005300005D01006101016602026C02017403017803007902007B02007F00 - 0182000184000186000187000187000189000187000187000187000287000383 - 00038100067B000182040A7300007F050B6D00007203076A00026801045E0000 - 6306075200005C06064C00005402014B00004A00044000004704093900004306 - 0A3700004105063D01024302043F00004A05083D00004C05083F000048010444 - 00004800004900004900004900004900004700004700004300004100003B0000 - 4105053300004007083100003B05053600003E02023B00004606063C00004F05 - 054C00006305066C01047800048000028600028700018600008200007F010076 - 02016A05035800005505043E00004707063900004805044B00005E00016D0002 - 7B00058401048500038400018200008001008000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00004400004400024000004403053C00003E0504 - 3A01003C03013C01004000004601004B00005200005801005C00006100006D04 - 017004007403017602017901017D01018000018400018800028A00028A00028B - 00018B00018A00008A00008600018100018000057D00028100077B00037D0309 - 7701067504087102066F04076900036803056000006100025C00005900015000 - 004D00044400004400043B00003C01053900013D03043B00004100023F000044 - 0104400000450205410002440203450000470000480100470200470200460300 - 4403024403023F00003F02003A00003E02023800003C02033800003A01023C00 - 004002023F00004301024400005101025D00016C03067601047F000284000286 - 00018400008200007F01007802016B04026003024F00004B01003E0000410402 - 4100004B00005A00006900017900058201048500038400018200008001008000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E0000400001430204450001420000 - 4300033C00003C03023700003802013701003902003900004202014100004B01 - 014C00005200005700006605026703006E04036B00007402027400007A00017D - 00008300008500008800008A00008A00008C00008C00008700008200047F0004 - 7F00047D00047D00047B00047900047800047800047601047401047401047201 - 047201047201046D02056400065800025000014500004302043A00013B020339 - 00003E00013F00004500054100014300053E00013F0004400001430000440000 - 4701014300004701014100004201004100004000003F00004002023C00004001 - 033C00003F00023E00013F01014000004303033F00004901014D00005F020369 - 02057401047D00028200028400018400008200007F01007802016C00005E0000 - 5400004500004201003C00004201004700005C01046A01047A02078102048300 - 0384000182000080010080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00004200004702053A00004506083300003F07063300003802013601 - 003D06033600004707063E00004F05054600005100005600005F02015900006B - 07056200007408077100007C04057D00028000018400018600018900018B0001 - 8B00018700028000027B00027B00047D00027D00047D00027D00047D00027D00 - 047D00027D00047D00027D00047D00027D00047900046E000668010851000052 - 03063D00004307083700003B01023D00004502053F00004C040A3C0000470409 - 3A00003F00024200004903033F00004C06063C00004906053D00004201003F00 - 004404043A00004806073A00004704073D00004200023F00004505053B000048 - 06074000005305065800006904067401047B0002800002840001840000820000 - 7F01007901016F00006802035200005205033A00004508063D00004800005900 - 036801047501067F020481000382000182000080010080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302044301023A0000490909370000440B - 0A3200003F07063700003B03023300004509093700004B090A3C00004B050647 - 00004D00004A00005E0606500000690B0C5C000071090A6E0103750205790203 - 7C01038001038300038500038700038500037D00027901017901027B01017B00 - 027D01017D00027F000180000280000182000282000184000284000186000282 - 00027F020B6B00006A060C4A0000500A0B3700004007063700004202023F0000 - 52060A42000051070B3C00004404093E00004701024100005007093E00004D09 - 0A3C00004705063F00004301023B00004A08093C00004D090A3C00004B050641 - 00004301023B00004A0A0A3A00004F09094500005E0606620001720104790102 - 8000028200018400008200008001007B01017803046400006306074500004D0C - 0B3500004508064400005501036401037302067D020481000382000182000082 - 0000800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00003C00 - 00450707370000480C0C350000460A0A3300003C03023800004307073500004A - 0C0C3700004A0A0A3900004501024500005206074500005B0B0C4A0000610909 - 5400006300026B02056F02047201047702037A02037C01038102047F02047B01 - 017901017901017B01017B01017D01017F00017F000180000182000184000186 - 000186000186000187000186000283000580080D5D0000620C0C400000470C0A - 3300003C03023E00004C060743000056090D4200004D080B3700004001034300 - 00500507400000510B0C3C00004B090A3A00004202023F00004806073A00004F - 0B0C3C00004F090A4000004701023E00004808083900004E0C0D3E0000540809 - 4F00006502047002047901027F00028200018400008200008001007D01017600 - 007306085300005B0B0A3A0000480D0B3800004502015300026100027001057A - 02037F0002820001820000830101800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302043C0302330000460A0A3500004A0C0C3700004706083E - 00004201033900004A090B3700004A0B0D3500004307083A00004504063C0000 - 4F0A0D3E0000550A0C4500005501054E00005F01056302046801046C01036F02 - 047002047502057702037901017B02007B02007D02007D02007F01007F01007F - 01008001008200008200008400008400008400008600008400018A0508760000 - 770C0E4E0000520D0A3300004009043700004202013E000054070A450000550A - 0C3C00004307083C000047000342000051070B3E00004F0A0D3A00004706083C - 00004201033900004A0A0A3A00004F0B0C3C00004C06074300004301023B0000 - 4C0C0C3A00004F0C0B4300005B05055D00006F02047801027F00028200018200 - 008200008001007D01017B03046800006807094900004F0C0B3500004207053F - 00005000015E00016F00047A02037F0002810000820000830101800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00003500003F070633000046 - 0A0A3900004A08093D00004500034100004904073A00004A090B35000043090A - 3300003B020338000142050935000048090B3A00004B06094100004C00025300 - 035700035D00036100026401036602026A02036F01017901017F01007F01007F - 01007F01007F01007F01007F01007F0100800100800100800100800100800100 - 80010082000084000185080A640000630C0A3C0000400A032F00003A06003C00 - 004B050543000056070A4200004C08093600003E02034100004D03073E00004D - 080B3A000049080A3800003E02033A00004206073700004A0A0A3A00004C0809 - 3D00004501023E00004705063900004C0A0B3C00005107074C00006000016F02 - 047801027F00028200018200008001008001007D01017900007704075700005A - 08073C00004409073500004100004F00005D00016E00047801027F0002810000 - 8200008301018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02043603013300003F07063500004707073D0000490205460000480002410000 - 49030939000043060A3300003B04073400023500043200003C04093200004306 - 0A3900004603064500004900004C00005100005500005A00005D000160000168 - 00017B01018400008400008200008200008001008001007F01007F01007D0200 - 7D02007D02007B02007B02007B02007D02008301027A00007009065000004708 - 003000003608003405003D03003F00005004054300004E05073B00003E050439 - 00004200024100004B03093C000047050A3800004004053900003B0102360000 - 4206063500004507073A00004503044000004100003D00004808083C00004A07 - 064200005401005900006D02047601027D00028000018200008001008001007F - 00018003057100006904064B00004D07073700004005033D00004C00005C0000 - 6D00037801027F00027F00008200008301018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00003701003802013800004002023F0000450102 - 4400004700014700014600024100014300053C00013C01053800023700033900 - 043B01063700023D02063800013E01053C00004100014300004700004B000051 - 00005600005B00005F00006800007D0101860000860001840000820001820000 - 8000018001007F00017D02007D01017B02007901017803007901017802017600 - 007103035F02005206003D00003703003102003606003A020041020041000047 - 01013F00003E02023600003901004000014600044100014300053F0001420005 - 3D00003C00013C00013D01023A00004002023E00004202024000004100003F00 - 004202023E00004205033D00004600004C00005700006903047201047B00027F - 00018200018200008000017F0001800305780306630000560302450000420503 - 3A01003E01004A00005800026900037601047D00028100008400018501018200 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E00004000014302043C00013B0000 - 4001033E00004201033F00004200024100014100014000004300033E00004201 - 033C00003F00023E00014100034200024300053E00014000053C00003F000240 - 00014501024900025000015400005A00006200016800047302067F0002840001 - 8400028400018200028200018000028000017F00027D01017D00027B01017B00 - 027901017B00027202025D01005202014C02004502003F02003A020039020036 - 01003B04013B04013A03003A03003803003303003203003502003F0000420000 - 4200004200004200004200004200004000004300034100014401044200004601 - 044100004400024200004000003B00003C03013600003C03013C00004601004F - 00006205046D02047601047D00028000028200018200028000017C0001720000 - 6804025400004A03003B00003B02003C01004400005300026502047302057D00 - 028500008A000089000184000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004200024400024B01073F00004A - 05083900004405073A00004101014501024C02025300025A0002600001680002 - 6E00057800058000048400028400028200028200028200028000028000027F00 - 027F00027D00027D00027B00027B00027B00027002045700004C00014B000049 - 00004800004500004300004000004302014202013F02003D02003B02003A0100 - 3A01003C01004101014200014200024200014400024400014400024400014500 - 034A06074000004C08093E00004A060740000043010240000043060437000042 - 09073400004508044200005000006205046D02047601047D0004800002820002 - 8400028000027B00007706046200006009054100004306023600003C03014200 - 005101026302047103057D00048500018C00008D000184000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073F - 00004700033F00004C070A3A00004A0A0A390000460606410000480000500203 - 5B02056201036900036F00027700047B00058000048200028200028200028200 - 028000028000028000027F00027F00027D00027D00027B00027B00027B000276 - 01046600006000006000005D00005C00005A0000580000560000580000560000 - 5300005200005200004F00004F00004B00004200003F00003F00003F00003F00 - 003F00003F00003F00004204043A0000480A0A370000490B0B3700004406063F - 00004701014100004C09083A00004B0B073E00005005035100006604046F0204 - 7801027F0002820002840002820002800002800102720000740A09510000540A - 083900004007053B00004200005101026103047103057D00048500018C00008B - 0001840001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004300034100004A06073A00004D0B0C3900004A0A09 - 3A00004701014B00005502016104056A03067302067700037E00048000048200 - 028200018200028200018200028000018000028000018000027F00017F00027D - 01017D00027B01017D00027901027500037300037300047200026F00026F0001 - 6D00026B00006B00036901026600026501016400016400006400015E00015100 - 004B00004B00004A00004B00004A00004A00004A00004600004F080540000053 - 0C09400000510A074000004B01014D000056030545000055090A430000550806 - 4A00005B00006B03047401047B00028000028200028400028200028200027D00 - 008208086400006B0E0B4500004B0B0736000040050342000051010261030470 - 03057B00048300018A00008B0001840001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E00004301023A0000 - 4A0A093900004C0C0B3A00004A07044700005100005C02016905057305077B02 - 0680010386000486000284000184000084000182000082000182000082000180 - 01008000017F01007F00017F01007F00017D02007F00017F0001810204810003 - 8000058001038000057D00027B00047901027A01057902037800047601027500 - 037301017300037100036D020469030469020568040469020568040468030566 - 0404630204590000680A0B530000690B0C5300006305065A0000610002570000 - 6508094E0000630B0B5000006306056100007002047800047F00028200028400 - 028400028200018200018601037900007C0C0C5500005C0C0B3E00004609073E - 01004400005101026103047003057B0004830001880000890001840001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004202023C00004407053700004A0B073900004A0A063F00004E01005500 - 005F02016C04057604048102048400028B00028C000287000084000086000084 - 0000840000840000840000820000820000820000800100800100800100800100 - 8001008001008400018400028200028200028200028200028000027F00028102 - 047F02047F02047E01037C01037B00027B00027B00027E01037E01037E00057C - 01037C01057C01037C01057A02037700037D08096E00007F0D0D6A00007C0A0A - 6C00007302056D000274060A620000710C0E5B0000700B0D6400007103057800 - 047D00028200028600028400028400028000018200018400008707086B000070 - 0C0A4A00005009063B0000440403440000510102610304700305790004810001 - 8600008700018200018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003D02003800004208033700004708 - 043D00004B04004D00005801006302006F03027903028200018700018F000190 - 0002890000860000870000860000860000860000860000840000840000840000 - 8400008400008400008400008400008200008100007F00007F00007F00007E00 - 007E00007E00007C00007E02027C02027C02027B01017B01017B01017A00007F - 00008800008C00008C00018A00008A00018800008800018600008A0206820000 - 8C070A7F00008A070A7D00008603067F00017D02067500027A060B6C00007609 - 0B6A00007605087700037D000282000286000287000186000184000180000182 - 00018901038100007E07086000005C0606440000460504410100440000510102 - 6103046E03057800047F00018500008600018200018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003C01 - 003B03003A00004003003E00004503004800004E00005A01006302006F020079 - 01018100008600008D00018E0002890000870000870000870000870000870000 - 8600008600008600008600008600008600008600008600008600008400008000 - 017F00017F00017F00017D01017D01017D01017E02027D01017D01017D01017C - 00007C00007B00007B00008000008C00029100029000029000028E00028E0002 - 8C00028C00028900018800028500008801038300008500028300008300018000 - 027F00057900017A00067200007601047600017C000182000286000289000189 - 00018700018400018000018200018900018902047700006B04025300004C0200 - 4100004303024400005101026103046E03057800047E00018300008600018200 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003A01003901003E04003C00004204004100004A01004E - 00005A0300620100710603770100830405830000890001860000870000850000 - 8500008400008400008500008500008600008600008600008600008600008700 - 008700008700008400008000017D01017D01017D01017D01017D01017F00017F - 00017F00017F00017F00017F00017F00017F00017F0001800001860103870002 - 8400018300008100008100008100007F00008000017F00017F00017D01017D01 - 017B01017D01017F00028200028200028000027E00037A00037A00037D000280 - 00028600028900018B00018B00018700008400007F0100800100890001850000 - 7C04056700005802024700004100003E00004701014E00015C00006800017601 - 047F020483010284000182000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900003E060136000045 - 08043900004907024300004D00005400006205026400007A0B09730000840808 - 7F00008301028301028001008100008100008100008100008200018301018100 - 008100008100008100008300008300008300008100007E00007E00007E00007E - 00007D00007D00007E00007E00007F00007F0000810000810000810000810000 - 8300008100008101028001027F00017E00007B00007B00007C00007C00007C02 - 027C02027C02027A02027A02027A02027A02027E020284000486000482000480 - 00047D00047E01038001038300038700018B00018D00018B0001870000820000 - 7F01008001008600008B0406740000710A084F00004D06033C00004101004502 - 014E00015900006600017401047D020481010282000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003E0301340000450A083700004A0B073A00004B0603470000520100510000 - 6909095E00007A0E0D6A00007D08097600007801027802017800017800007800 - 017800007901027901017B00027B01017B00027B01017D00027D01017D00027D - 00027E00017F00017F00017F0001810001810001830001830001860002860002 - 8700028700028700028700028900028600028101027E02027D01017C00007C00 - 007C00007C00007C00007E02027E02027E02027C02027C02027C02027C020280 - 01028200048400048000027F00027D00027D00027F00028200018700018B0001 - 8D00008B00008600008200007F01007F0100890204800000800B0C5D00005F0C - 0B3E00004606053D00004502014B00005700006501017201047D020481010282 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004001033A00004308063500004A0D0B3700004A0B07 - 3C00004702004700005607044C0000670D0C5300006D0C095F00006A03016B00 - 026B01006A00016A00006C00016C00006D00026D010071030571030371030573 - 03037302057303037302057702037A01057C01037C01057E01037E0005810204 - 8201068201048200048200028400048400028600048600028600048400028001 - 037E02027D00027C00007C00017D01017D00027E02027E00017E00007E00017E - 00007E00017E00007E00017F00017F00017F00037C00017A0001790000790000 - 7D00008000008700018B00018B00008900008600008001007D02007F01008300 - 008808096B000071100D4900004E0B083700004106044201004B000057000064 - 00007201047A0203810102810000800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000400103370000 - 480A0A3700004A0C0C3900004707063F0000480202410000550A084500005D0B - 0A4A00005A04045200005A00005A00005B00005B00005B00005B00005D00005D - 00006201036202026201036402026401036402026401036701026B00036D0002 - 6E00046F01037201057201047501067702057800057800047900057B00047D00 - 057D00047D00057D00047C01057B00027B00047A00017D00047D000280000580 - 01037F00037F00018100038100018300038300018300038100017F00027B0002 - 7901027801027700017800017C00007F00008600008900008B00008900008601 - 008002007D02007D02008503047700007A0C0C5300005A0D0B3A0000430A083B - 02004101004A00005400006200007100037A0203800001810000800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E0000440507370000480A0A3700004709093800004202013F00 - 004706053C00004E09063E00004D06034200004800004B00004B00004C00004C - 00004C00004C00004F00004F0000510000510000520000520000520000520000 - 5400005600005800005A00005A00005B00005D00006000016000016200016601 - 036700036900036B00036D00036D00036E00036E00036E00036E00026E00026F - 00017000027300037300037601047901057A01057C01057C01057E00057E0005 - 7E00057E00057901027601027503037503037503037803047B03038102038400 - 008700008900008900008401008002007B03007B03007D000080060665000067 - 0C08430000490A063500003E07043F0200470000540000620000710003790102 - 7F00018100008000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100043C00004604093700004506 - 083600004004053B00003E02023900004407053700004407053700004303023E - 00004101004101004000003F0000400000410000440001440100450000450000 - 4700004700004900004900004900004700004200004200004300004600004700 - 004A00004B00004E000151010253000254000256000258000258000258000258 - 00005700005700005700005900005900005C00005E0001610002640103660103 - 6700036900036B00036B00036B00036D00026E00006F00006D00006E00007003 - 017304027903027F03038400008700008900008700008401008002007B03007B - 03007D01017200006E07055200004F05033700003C07043904013E0100470000 - 5400006100006F01037901027F00018000008000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 034100043F00014300033E00004201033D00003E00003C00003B02003800003B - 04013800003E05033B02003E05033E03013D02003B02003A01003A01003D0101 - 3D01014002024202024301024500034501024501024501024301024202023900 - 003800003A00003B00003E01003F020042020143020143000045000045000047 - 00004900004900004A00004900004800004800004700004700004900004A0000 - 4D00005000005200015300005500015700005700015900005900015B00005B00 - 005D00005C00005E00005F00006302006901026E020174020278010278010278 - 01027602017203016F04016F04016D00006C01035E00005401004300003E0100 - 3801003C05023E01004700005200006100007000007B01018300008400008200 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000013E00013F000043000343000049000345000046000143 - 00004000003B00003B04013501003B04003700003B03003C02004004003E0200 - 3F05003800003B03023600003A00013A00004100014200004700054300004701 - 023F00004101003E01003D01013C00003F03033B00004204043D000041030341 - 0101410101400000430102410000460203410000470102430000460203440100 - 4703044200004602034200004701024500004700004600004B00024700004B00 - 024800004B00014A00004900004600004900024500004B00024700004B00014C - 00004E00004F00005200014E00005200014C00004F0000500000510000500000 - 5200024800004900033F00003F00023E00004301024600005300005D00007302 - 007D00008C00018C000084000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F00023D00004203053D00004E - 04084300005003064500004600013F00004005033300003E0A043000003F0803 - 3800003F0300410100450700370000420A053300003F07063600003E02033F00 - 024701073F00004C05083C00004705063A00003F02003E00004305053A000046 - 08083900004507073C00004103033D00004303033900004606063A0000460405 - 3C00004000003F00004204043800004507073700004305053B00004101013F00 - 004404043B00004806073A00004705063D00004101013D000040040536000043 - 07083500004206073A00003F00023D0000420305380000450608370000440507 - 3C00004200024400004B01054100004C05083C00004704093C00003F00024000 - 004903034A00006405026800008506058900008E000086000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00004001033800004A070A3E000053080A4300004F0406430000420201360000 - 420B06300000430C073300004407033F00004404003C0000480C06350000450E - 0B3200004108093A00014000053A00004A070A3A00004A0A0A3700004207053A - 00004303033C00004A0A0A3900004B0B0B3900004707073F00004101013A0000 - 4808083900004A0A0A3900004505053D00003E0202360000440808350000460A - 0A3500004206063A00003E0202360000450909350000460A0A3500004206063A - 00003C020334000043090A330000440A0B3300004206073A00003E0203360000 - 45090A350000460A0B3500004206073C00004202023B00004A070A3A00004A09 - 0B3700004206073800004004043C0000530806500000740B087000008C070485 - 0000840001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004001033C00004506083A0000510A0D42000053080A - 4000004501023E0000430806320000450E09330000480B073A00004503004300 - 004C08013A00004D0F09350000460D0B3500003E04053A000145050A3700004A - 0B0D370000460A0A3500004003013F00004C06073E0000510B0C3E00004D090A - 3C00004301024000004907083A00004E0C0D3A00004C0A0B3B00004404043C00 - 00440808350000490D0D350000460D0C3500003F060538000041080733000045 - 0D0C320000430B0A3200003B0302380000430708350000480C0D350000440A0B - 3300003C0203380000410708330000460C0D330000430A0B3300003C03023A00 - 004507073700004A0B0D370000460A0B3200003B02033800004508063E00005F - 0D085700007C0E0A780000840300820001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C0000400103370000 - 4B080B3E0000530A0C4200004E0507410000420201350000440C073300004A0D - 093A00004C07044700004D0300440000520B073E00004E0D0C3700004607093A - 00003E0203350000460A0B350000480C0C3500004308063E00004A0202440000 - 54080943000055090A4200004E04044300004A0202410000500A0A3E0000500D - 0C3C00004B08073F0000430302370000490C0A3700004B0E0C3500004409073A - 00003C0301330000430C09320000450E0B3000003E09063700003E0202370000 - 480A0A3700004A0C0C3500004307073A00003C0302330000430B0A320000450D - 0C3000004008073700003C0302330000460A0A330000460C0D3200003E080835 - 00003B05043400004B0B074500006A0F0A6200007F0A057A0000800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004001033C00004405073A00004F080B4000005007093F00004301023C00 - 00420705350000480B073A00004E09064400005001005200005907024A000058 - 0B084200004E08083E00004201033C0000420607350000460A0A370000470A08 - 3A00004701015100005B04074C00005F080B4A00005A06084A00004F00004B00 - 005103044500005408094300005107074300004A00004500004B05053E00004E - 08083E00004A07063A00004100003E0000460605370000460B09350000450A08 - 3600004003013F00004905063E00004D090A3C00004A08093B00004202023C00 - 00440606350000440B0A330000430A093400003C030138000040070535000046 - 0A0A35000043090A3300003903023702004008033A0000560C06520000710D08 - 6E00007D05007F00018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003F00023A00004704073E00004E05 - 074100004703044000003F02003800004208033900004C070444000054020154 - 00006205025F01006508055500005D07074D00004F02054500004200023A0000 - 4406063700004707073D00004B03034D00006204056300006A07095C00006706 - 085900006002035A00005C00005500005D05054E00005C06064D000057040352 - 00005603025100005906054B00005705044800004E01004900004B0000460000 - 4F05034000004E07043F00004904014600004B00004800005404054500005105 - 064300004D03034600004600004100004906053A00004807063A00004404033F - 00004101003C00004707033A00004807063A00004204043B00003F04023B0000 - 4B0603470000650A066300007608047701007F00018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000013E00 - 013F00023F00004500034300004701024000004000003E01003D02003C000043 - 03004700005000005400005C00006D06047007046C02016A05036100005F0203 - 5200014F00034500014200023E00004301024300004C00014F00005700006E03 - 067504086F00047203076C00026F010569000168000267000368030564000167 - 04066000016403055F01026302046904066A0507660103670406600000610002 - 5B00005B00005900005800005300005500005100005300005000005100005500 - 005800005500005900015300005500015000005100005000004F00004A00004C - 00014800004B01014800004700004700004801004700004B01004700004B0101 - 4600004500004401004702004800005503005E00006E05027302007902007F00 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000013E00013D00004300034100004501024100004200013E - 00003D02003B0000420300430000510402560000630506690304730200790302 - 7902037500017201056C03066200065400014B00014400004501024500005103 - 045600006205066902057800047D00047B00047B000479000479000478000476 - 01047401047201047201047002046F02046F02046D0204700204760104780004 - 7800047601047601047401047201047002046F02046D02046D02046B03046903 - 046903046903046903046C05086D04076902056700036400015F00005C00005B - 00005C00005B0000590000570000570000550000550000530000550200550200 - 5601005500005600005300005000004F00004F00005100005400005B00006500 - 007001007902007E03017F000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023D00004203053B000048 - 05083C00004705063C00003F01013B00004005033A00004E07044B0000610707 - 6300007204067800008002018101027E00017B00047501066900055A00014D00 - 004D02044100005006064C00006406076400007603067F000484000284000482 - 00028200048000028000047F00027D00047B0002790004790102780004780102 - 7601047901028000048400028200048200028000048000027F00047D00027B00 - 0479010279000478010276010476010276010476010475020575020574000571 - 00037000036D00016C00026900006B0003690102670003670102660103660202 - 6401036202026104016003006203006301016400006300006100025E00015D00 - 025D00005F00006400006D00007600007F010080010080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004001033800004A070A3A00004B090A3A00004406063A00003C0301360000 - 4A0A064200005F090958000072070A7500037E00008501018700028300018200 - 047C00066E00055D00005300024400005008084300006109095C00007706097A - 0003840002870001870002870001870002860001860002840001820002800001 - 8000027F00017F00027F00017D00028000018700028B00018900028900018900 - 028700018700028600018400028200018200028000018000028000017F00027F - 00027D00027B00027C01057C01037C01057B03047B02067A0304770205750303 - 7502057303037302057303037103057004036F06036F06037005027002027201 - 047100036E00036D00036B00036900036A00016D00007600007C000084000086 - 0000820001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033C00004706083900004D0A0D3A00004A0A0A - 3700003E02023800004508063C0000570C0A5000006F0A0C6800007C03077F00 - 008701018800028600008600047E00057000055F00004E000050050740000057 - 0B0C50000070090C6E0000830205860001890001870001870001870001870001 - 8700018600018400018400018200018200018200018200018000018400018900 - 018D00018B00018B00018B00018B000189000189000187000186000186000186 - 0001860001860001840001840001820002800002810003800103820104810204 - 8203058003057C00017A00017A00017800017A00017800017800017701007706 - 037706037A04037B03037C01037C01057B000578000577010674000574010477 - 00037A00017F0000870001870000820001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0C0C3700004307073800003D04023700004D0A07450000670A - 0B5E00007A060B7900027F00008501018700028500008400047E00056E00055B - 00004F01023E00004D0A09420000630B0B5E00007E060A7E0000840001860000 - 8600008600008600008600008600008400008400008400008400008400008200 - 0082000082000084000086000087000087000087000087000087000086000086 - 0000860000840000840000840000840000840000840000840001830003830003 - 8300038100038300038000028000028000027F00017F00017F00017E00017F00 - 017E00017E00017C00007B04027B05007E03018101028300038300058200057F - 00057D01077B01077A01057B00047F0002840001870001880002820001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B3900004709093600003C03023800 - 004407053C000059090853000072070A7100008002077E000081030085000283 - 00008200047C01056D00035A0000470000460605390000520B084C00006E0809 - 7200008302058200018200008200008200008200008200008200008200008200 - 0082000082000082000082000080010082000082000082000082000082000082 - 0000820000820000800100800100800100800100820000820000820000820000 - 8200008200008402038300038300038200028100018100018000008000008300 - 038300038300038300038300038300038300038101027D02007D020082000084 - 00008700028700028600048200058200077E00067E00057D0004800002840002 - 8A00028800028200018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004507 - 073600003E05043800003B04013800004B06034800006504066600007C02087E - 00037C01007E03008101027F00007F0004790105690003560000470101380000 - 4208033B00005A07055F00007B04057E00017F00017D02007D02007D02007D02 - 007D02007F01007F01007F01007F01008001008001008001007F01008001007F - 01007B02007902007902007902007B02007B02007B02007B02007B02007B0200 - 7D02007D02007D02007D02007D02007F01008001028101028101028000018000 - 0180000181000081000083010283010285000285000285000285000285000283 - 01027E00007E01008300008600008900028900028700048400048300067F0005 - 7D00047E00038000028400028800028901038200018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004002023900003A01003A01003F020043000053 - 01005C00006E00047700037E01037A01007C03018001027F00007F0004790105 - 6700035400004300003B02003800004404005000006703037600028001037D01 - 017D02007D02007D02007D02007D02007D02007D02007F01007F01007F01007F - 01007F01007F01007F01007D0200790200780300790200790200790200790200 - 7902007902007B02007B02007B02007B02007D02007D02007D02007D02007F00 - 017F000181010281010281010281010283010284020382000182000182000182 - 00018400018200018400018200017F00007F0000840000860001870001870002 - 8600028400048200047F00037E00037E00017F00018200028700028801038200 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000003F00004301023F00004300033E00003F00023C - 00013B00003E00004802024B00005D00006900007A02067A00017A01007E0301 - 8101028100008000047A01056900035600004400003C01003F04024000005600 - 006700007D02068100018000017F00017F00017F00017F00017F00017F00017F - 00018000018000018000018000018000018000018000017F00017F00017D0101 - 7F00017F00017F00017F00017F00017F00017F00017F00017F00017F00017F00 - 017F00017F00017F000180000180000180000180000180000180000180000180 - 0001800001800001800001800001820001800001820001800001800001800001 - 8200018200018200018200018200018200028000028000028000028000018000 - 0180000182000182000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004101013F00004404033B000048 - 06073A00004605073C00003F00043A0000460606410000540403540000710608 - 7300007C02027A00007E03018301028100008200047A01056B00055600004500 - 004407053800004906054F00006F06097A000183000382000280000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004202023A00004A08093A00004B080B3900004604093C00013D01023C0000 - 4F090A4700006507086300007C07087800007A00007E03018301028100008200 - 047A01056B00055600004800003A0000460B093C000060080861000083050A7F - 0000820002800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004202023E00004707063A00004D0B0C3A00004A090B - 3900004000053900004808083E0000590908530000750A0C7000007D03037A00 - 007E03018301028100008200047A01056B00055600004400004609073500004E - 0B0A4E0000730A0D770000840104820002800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420202390000 - 4B090A3A00004D0A0D39000047050A3C00013D01023B0000510B0C4700006709 - 0A6100007E090A7800007A00007E03018301028100008200047A01056B000556 - 0000480000390000480D0B3C0000620A0A5F000085070C7F0000820002800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004202023E00004606053A00004B090A3A000049080A3A00004000053900 - 004707073E000057070653000074090B7100007C02027A00007E030183010281 - 00008200047A01056B00055600004400004508063500004C09084E000072090C - 7800008300038200028000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004101013C00004705063A00004805 - 083A00004402073D00023C00013E00004C06074700006103046500007B060779 - 00007A00007E03018301028100008200047A01056B00055600004700003C0000 - 4308063C00005C04046300008204098000008200028000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000004000 - 004101003F00004301023F00004201033F00023E00033A00004303034400004F - 00005800006D02047500017B01017A00007E03018301028100008200047A0105 - 6B00055600004500004104023B00004401005300006B02057C00038200028200 - 0280000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017B01017D01017F00018200018500008700028700027F - 00007901017304026B02005A00004600003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000004000003F00004301023F00004300033E00004100043E - 00033B00004000004802034B00005D00006900007803047A00007A00007E0301 - 8301028100008200047A01056B00055600004600003E01003F04024000005800 - 006700017F010681000182000280000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018000017F00017D01017B01017D01017F000182 - 00018500008700028700027F00007901017304026B02005A00004C0103420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004101013F00004404033B000048 - 06073A00004605073C00003F00043A0000460606410000540403540000710608 - 7300007C02027A00007E03018301028100008200047A01056B00055600004500 - 004407053800004906054F00006F06097A000183000382000280000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018200018000017F00017D - 01017B01017D01017F00018200018500008700028700027F0000790101730402 - 6B02005A00004400003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004202023A00004A08093A00004B080B3900004604093C00013D01023C0000 - 4F090A4700006507086300007C07087800007A00007E03018301028100008200 - 047A01056B00055600004800003A0000460B093C000060080861000083050A7F - 0000820002800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018200018000017F00017D01017B01017D01017F0001820001850000870002 - 8700027F00007901017304026B02005A00004D02044201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004202023E00004707063A00004D0B0C3A00004A090B - 3900004000053900004808083E0000590908530000750A0C7000007D03037A00 - 007E03018301028100008200047A01056B00055600004400004609073500004E - 0B0A4E0000730A0D770000840104820002800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018200018000017F00017D01017B01017D0101 - 7F00018200018500008700028700027F00007901017304026B02005A00004600 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420202390000 - 4B090A3A00004D0A0D39000047050A3C00013D01023B0000510B0C4700006709 - 0A6100007E090A7800007A00007E03018301028100008200047A01056B000556 - 0000480000390000480D0B3C0000620A0A5F000085070C7F0000820002800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001800001 - 7F00017D01017B01017D01017F00018200018500008700028700027F00007901 - 017304026B02005A00004C01034201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004202023E00004606053A00004B090A3A000049080A3A00004000053900 - 004707073E000057070653000074090B7100007C02027A00007E030183010281 - 00008200047A01056B00055600004400004508063500004C09084E000072090C - 7800008300038200028000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018000017F00017D01017B01017D01017F00018200018500 - 008700028700027F00007901017304026B02005A00004500003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004101013C00004705063A00004805 - 083A00004402073D00023C00013E00004C06074700006103046500007B060779 - 00007A00007E03018301028100008200047A01056B00055600004700003C0000 - 4308063C00005C04046300008204098000008200028000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018000017F00017D01017B01 - 017D01017F00018200018500008700028700027F00007901017304026B02005A - 00004E03054302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000004000 - 004101003F00004301023F00004201033F00023E00033A00004303034400004F - 00005800006D02047500017B01017A00007E03018301028100008200047A0105 - 6B00055800004500004104023B00004401005100006B02057A00038200028000 - 0280000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 018000017F00017D01017D01017D01017F00018000018300008500028301027E - 00007B01017703026E01005D00004700003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000004000003F00004301023F00004300033E00004100043E - 00033B00004000004802034B00005D00006900007803047A00007800007C0100 - 8100008200018300057800036800025700004600003E01003F04024000005600 - 006700017D020681000180000280000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000017F00017F00017D01017F00017F - 00017F00017F00017F00017D01017D01017B01017901016D03024F0003420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004101013F00004404033B000048 - 06073A00004605073C00003F00043A0000460606410000540403540000710608 - 7300007C02027800007A01008100008400018300057A00036B00035A00004700 - 004606053A00004906054D00006D060976000183000380000280000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00017F00017F00017D01017D01017D01017D01017D01017D01017D01017F0001 - 7F00017002024900003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004202023A00004A08093A00004B080B3900004604093C00013D01023C0000 - 4F090A4700006507086300007C07087800007901017A01008100008400018300 - 057A00036B00035B00014A00003C0000480B093C00005C09085F00007F060A7D - 0000800002800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000017F00017F00017F00017F00017F00017F0001 - 7F00017F00017F00018000018000017202025201044201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004202023E00004707063A00004D0B0C3A00004A090B - 3900004000053900004808083E0000590908530000750A0C7000007D03037901 - 017A01008100008300008200047B00046C00045C00024600004808073700004E - 0B0A4A0000700B0D720000820104800002800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000018000017F00017F0001 - 7F00017F00018000017F00018000018000018000018000018000017202024B00 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420202390000 - 4B090A3A00004D0A0D39000047050A3C00013D01023B0000510B0C4700006709 - 0A6100007E090A7800007A02027A01008000008300008400047D00046F00065E - 00044A00003B00004A0D0B3C00005D0B0A5C00007E090C7C0000800002800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000018000017F00017F0001 - 8000018000018000018000018000018000018200018000018200018200018200 - 018200018200017402025100034201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004202023E00004606053A00004B090A3A000049080A3A00004000053900 - 004707073E000057070653000074090B7100007C02027A02027D020080000083 - 00008400047E00057000076001054700004707063700004C09084900006D0A0C - 6F00007E01037F00028000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000017F00017F00018000018000018000018000018200018200018200 - 018200018200018200018200018200018200017402024A00003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004101013C00004705063A00004805 - 083A00004402073D00023C00013E00004C06074700006103046500007B060779 - 00007A02027D02008000008500008600048000057301086102064A00003F0000 - 4508063C00005705045C00007706097900007F00028000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000017F00017F00018000018000018200 - 0182000184000184000184000184000184000184000182000182000182000174 - 02025302054302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000004000 - 004101003F00004301023F00004201033F00023E00033A00004303034400004F - 00005800006D02047500017B01017B03037D0200800000840000860004810005 - 7301086403074A00004403023D00004201004C00006403057100037B00027F00 - 0280000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000017F00 - 017F000180000180000182000182000184000184000186000186000184000182 - 00018200018000018000017202024B00003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000004000003F00004301023F00004300033E00004100043E - 00033B00004000004802034B00005D00006900007803047A00007901017D0200 - 8200018600018700048000047400076602074D00004200004104023E00005000 - 005900006F01037901027F000280000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000017F00017F000180000182000184000184000186000186 - 00018500008600018500028402038202038102037E0202700403510003420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004101013F00004404033B000048 - 06073A00004605073C00003F00043A0000460606410000540403540000710608 - 7300007C02027901017D02008200018600018700048200047600076602074D00 - 004704033900004807064500006003046900007A03047D000280000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000017F000180000182000182 - 00018400018400018600018600018700028500028200018000017D01017C0202 - 7A02026C05034700003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004202023A00004A08093A00004B080B3900004604093C00013D01023C0000 - 4F090A4700006507086300007C07087800007901017D02008200018600018700 - 048200047600076802075200013E0000470A083A000056090750000070050775 - 00017D0002800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001820001840001860001860001870001860001880103830102 - 8000017C00007800007602017203016905034E01044201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004202023E00004707063A00004D0B0C3A00004A090B - 3900004000053900004808083E0000590908530000750A0C7000007D03037901 - 017D02008200018700018900048400047800076802074E00004C06063900004D - 0C0B4300006109096200007904057D0002800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001820001840001840001860001860001 - 8700018600018400018000017E02027A02027403016F02006B02005F02004600 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420202390000 - 4B090A3A00004D0A0D39000047050A3C00013D01023B0000510B0C4700006709 - 0A6100007E090A7800007901017D020084000187000189000484000478000769 - 02075400023F00004B0B0A3A0000550A084E00006F07087200007D0002800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001820001 - 8400018600018700018700018600018600017F00007E00007B03037905047205 - 036A03006300005700004A01034201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004202023E00004606053A00004B090A3A000049080A3A00004000053900 - 004707073E000057070653000074090B7100007C02027901017D020084000187 - 00018900048400047900076902074F00004B05053900004A0A094300005F0707 - 6100007705057D00028000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018400018600018600018700018700018600018400017E00 - 007C00007A04037506046E05026502005D00005100004300003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004101013C00004705063A00004805 - 083A00004402073D00023C00013E00004C06074700006103046500007B060779 - 00007901017D02008400018700018900048400047900076B0107530001420000 - 4606053900005005035100006A04057301017D00028000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018400018600018600018700 - 018700018600018400018101027C02027403016E03006602005F010058000050 - 00004A04054302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000004000 - 004101003F00004301023F00004201033F00023E00033A00004303034600004F - 00005800006D02047700017B00027B01017F0001840001860001860002820004 - 7D00056F01075100004701023F00004202014400005401006700007702037D01 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001820001820001820001820001800001800001 - 7F00017F00017F00017F00017F00017F00017F00017F00017F00018000018200 - 018200018400018400018600018600018400018000018006067803046D010063 - 00005A00005200004E02004C03004000003F00004100014401044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000003E00003F00004301023F00004300033E00004100043E - 00033D00004000004A01034D00005F00006900007A03047C00017F0002800002 - 8400018200007B02007B01018200027800055400014200004301063B00004202 - 014D00006E03007D02007F000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001820001860002870002 - 8600018400018200017F00017D01017B01017B02007902007902007B02007B02 - 007D02007D02007F01007D00007F00008200008301018301028101028001037B - 00027604046B00026303035200004B01003F00003E04003D0200440203450102 - 4300004000003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004101013D00004205033B000048 - 06073A00004605073C00003F00043C0000470506430000560403560000730608 - 7500007E01037F00048000028400017F01007604007803008400017B00045200 - 004502073B000045050A3500005107036C000082040080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018200018600028600028400018200018000017F00017D01017B01017B02 - 007B02007B02007B02007D02007F01007F020080020082000082000081020180 - 01027E02027802017301016D01006602026307064D00005107053A0000420705 - 3600003C05023B00003E00004000004402034201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004002023800004A08093A00004B080B3900004604093C00013F00023D0000 - 51080A4900006706086500007E07087A00007F00048000028400017F01007604 - 007803008400017B00045500033C000049060D370000460B094300007507037F - 0100800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000017F00017F00017F00 - 017F00017F00017F00017F000180000180010082000082000084000084000086 - 00008B00038901038402037E01037402026902005F0201570200520503440000 - 4F09093C00004A09083A00004806074100004204043E02023C00003900003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004202023C00004508063A00004D0B0C3A00004A090B - 3700004000053B00004808084000005B0908550000750A0C7000007F02047F00 - 048000028400017F01007604007803008400017B000451000048050A3900004A - 0A0F350000560C08690000830501800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000017F00017B01 - 017B01017B01017D01017F000180000182000184000184000186000186000086 - 00008600008600008600008700018C01048901058102047702036A02035D0100 - 5001004601003F0000430904350000490C0A3A00004D0A094100004703043900 - 003500003701003A04034201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000400202370000 - 4B090A3A00004D0A0D39000045050A3A00013D01023B0000530A0C4700006709 - 0A6100007E090A7800007F00048000028400017F01007604007803008400017B - 00045600043B00004B080F370000470C0A4300007608047E0000800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000017D01017802017602017802017B01017F000182000186000187 - 00018900018B00018B00018900018900018700018700018600018400067E0005 - 7702056C01035F01025301004601003D00003B0401300000420A09330000490B - 0B3A00004C05084200003C04033704013502003200003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004202023C00004606053A00004B090A3A000049080A3800003E01053900 - 004507073E0000570706520000720A0B6F00007C01037F00048000028400017F - 01007604007803008400017B000451000047040939000048080D350000540A06 - 6A00008305018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000017D01017802017602017802017B - 01018000018400018700018B00018D00018D00018B0001890001870001860001 - 8400027D00027200036B00036500045E01025400024C00014300003D00003700 - 003E0704320000440B0A3500004709093B00004002023600003500003702003A - 05024100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004101013C00004705063A00004805 - 083A00004202073B00023A00013C00004C06074500005E040461000079070777 - 00007F00048000028400017F01007604007803008400017B00045500033E0000 - 46030A3700004207054600007305017F01008000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018000018000018000017F - 00017901017802017B01017F00018400018700018B00018D00018D00028B0002 - 8900028600028000027D00027B00047002045800004F00005000024E00014E00 - 024B00014900004600004701023E00004706083600004208093400003B050537 - 00004106044304004102003D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000004000 - 004101003F00004301023F00004201033D00023C00033800003F03034200004D - 00005500006804047101017901027F00048000028400017F0100760400780300 - 8400017B00045300014300053F00034000053900004D03006E00008103008000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000017F00017D01017D0101800001840001870001890001 - 8B00018B00018900028600028200027D00027800047201046F02046204054700 - 003E00004000004300004800014A00014A00004A00004A00014A010343000144 - 03053B00003C03043300003901004200004800004C00004F02004000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000004000003F00004301023F00004300033E00003F00043C - 00033C02033C00004503044800005800006000007002027902037D0004800002 - 8400017F01007604007803008400017B00045400024000024300073B00003E03 - 0149000071030080020080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001820001840000860000 - 8700018900018800008800008700008400008200047C00037B03076F01036B04 - 075E00005800004B00004000003900003E02033C000043000343000048000149 - 00004900024700004701024000004202023B00003C00004000005000005B0000 - 6101016303033F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004101013F00004404033B000048 - 06073A00004605073A00003B00043900013F06053C00005107054D0000660404 - 6A00007904057D00048000028400017F01007604007803008400017B00045200 - 004502073B000045050A3500005107036C000082040080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018200018900008A00008900008900008700008600008400028100037900 - 047605086600006706085100005705044700004901013F000040040538000045 - 06083700004406063C00004101014200014804053E00004B03034200004F0505 - 4800005602046200006A00006E00027002024201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004301023B00004C08093C00004B080B3900004205093800013C0304360000 - 4A0A0A4000005C09085600007107067601027D00048000028400017F01007604 - 007803008400017B00045500033C000049060D370000460B094300007507037F - 0100800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018400018B00008C00008B00008700008400 - 008000017D02047904057306086000006508094A00005206073E000048070642 - 00014900034100004E0809390000440B0A3000003B08063101003A0704350000 - 4A07064300005B04075300006C060B6E00047500007900007D00027E02023E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004202023F00004807063C00004F0B0C3A00004A090B - 3500003C0105380000420908390000540D0A4A0000670A096300007806067D00 - 048000028400017F01007604007803008400017B000451000048050A3900004A - 0A0F350000560C08690000830501800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018400018B00 - 008D00008900008400007F00017802016F01016803015F02015F090947000051 - 09093C00004608083600004505054800005504074200004D0B0C3300003D0D09 - 2900003205013101004109043E00005D0A0857000077090B7300008404098000 - 018301028402038402034201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E00004301023A0000 - 4D090A3C00004D0A0D39000043060A3800013D04053400004A0C0C3E00005C0A - 095300007009077301017D00048000028400017F01007604007803008400017B - 00045600043B00004B080F370000470C0A4300007608047E0000800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018200018600008702008402027E05037504026B02005E000055 - 0000530302440000500A0A3A0000490B0B3500004206073F00004E0002490000 - 53080A3C0000480D0B3000003A0A063101003A0300390000580B085200007A0D - 0F6F00008A070A8500008601038602028602028602023E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004202023F00004706053C00004D090A3A000049080A3600003B02053800 - 00400807370000500B084900006408076400007606067D00048000028400017F - 01007604007803008400017B000451000047040939000048080D350000540A06 - 6A00008305018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018001008200008003007B040274 - 06026A03005D0100500000460000430000460703370000480C0C35000047080A - 3800004200024700005003064000004D0A09390000450B063600004004004300 - 00540802520000720E0C6B0000870B0B80000088000286020283010183010183 - 01014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004200013D00004905063C00004805 - 083A00004003073800023C03043700004507073F00005705045600006D060472 - 02027D00048000028400017F01007604007803008400017B00045500033E0000 - 46030A3700004207054600007305017F01008000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018000018000018000017F - 01007C03017803006E02006602005C01005101004700004000003D0300360000 - 4007053400004607093B00004603084000004200013D00004706053C00004C07 - 044300005003014F00005E04035F00007009076A0000800A097800008305047E - 00007F01007F01007F01007F01004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000004000 - 004101004100004501023F00004001033B00023C00033D01023F03033C000044 - 04004800005902006A00007A03047D00048000028400017F0100760400780300 - 8400017B00045300014300053F00034000053900004D03006E00008103008000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000017F00017F00017F00017F00017F00017F00017F00017F00018000018200 - 018200018200018000018000017F00017F00017F00017F00017F000180000180 - 00018200018200018400017F00017405036A03006100005700004E0000480000 - 4303003F05003A03003904013700003C03023C00004302044200044702054100 - 004202004300004B01004E00005700005900006000006F05047505057400007A - 02027700007E03017B00007E03017D02007C01007E00007C01004000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003C00003D00004501024100004001033A00003F000441 - 00034800024400003D04033600004003004D0000710101800002800004800002 - 8400017F01007604007803008400017B00045400024000024300073B00003E03 - 0149000071030080020080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001820001820001 - 8200018200018000018000017F00017D01017D01017D01017D01017D01017D01 - 017D01017D01017F00018602028701018400008100007E00007C01007A000079 - 01017C02027B00008001037C00008500038500008C0105810106600000520000 - 5200004A00004902004100003F02003C01003B03023901003C02033700003E02 - 033B00004100044200004700004E00005300005900006302006A030171030378 - 04037901017D01017F00017F00017F00017F00017F00017F00017F00017F0001 - 8000017F00013F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900004005033D00004A - 06073700004206073A00004400044B00004D02043500003C0A04300000510703 - 7000008800048200048000028400017F01007604007803008400017B00045200 - 004502073B000045050A3500005107036C000082040080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018200018400018200018200018000018000017F00017D01017D01 - 017D01017D01017D01017D01017D01017D01017F000183010185010184000082 - 00008001008001007F00017D01017B000081050578000085080A770000840507 - 7A00007100045400004D03034100004C06063A00004606053A00003D01013800 - 003D03043700004607093800004605073B00004700005000005700005E000064 - 01006B02007203017A02027F0303800001820001820001820001800001800001 - 7F00017F00018000018000018000018000014201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003C03023600004C08093C000048090B3500004404094100014E0003440000 - 430A092E0000410D074300007904058500018200048000028400017F01007604 - 007803008400017B00045500033C000049060D370000460B094300007507037F - 0100800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018200018200018200018000 - 018000018000017F00017F00017F00017F00017F00017F00017F00017F00017F - 00017E03018002018102018501018700028800028A00028B00038700037A0000 - 850A0C6B0000770C0E5D00006404045100004C00013F00004C08093A00004A0A - 0A3700004406063C00003C00003700004909093A00004F0B0C3E00004C030548 - 00005801006002006502006902006F02007602017C0202800102800001820001 - 8200018200018000018000017F00017F00018000018000018000018000013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023800004308063C00004F0B0C370000460A0B - 3700004500054A0000500507330000410F09300000560C086D00008901058200 - 048000028400017F01007604007803008400017B000451000048050A3900004A - 0A0F350000560C08690000830501800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018200 - 0182000182000182000180000180000180000182000182000182000182000182 - 00018200018200018200018000017D02007D02008102018802028B00038D0003 - 8F00038D000385000187080A6A0000740F0D5000005A0B084000004202003F00 - 004707073900004C0C0C370000480A0A3700004202023D00004706053E000055 - 0B0B430000570A084900005702006104016804006C0300700301740301790101 - 7E02028101028200018200018200018200018000017F00017D01017D01018000 - 018000018000018000014201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003C0302350000 - 4D090A3C00004A0B0D35000045050A4100014F0004430000450C0B2E0000420E - 084300007A05068400008200048000028400017F01007604007803008400017B - 00045600043B00004B080F370000470C0A4300007608047E0000800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000182000182000182000184 - 0001840001840001860001860001860001860001860001840001820001800001 - 8500028801038B00048B00048800038400028204096E0000700A0B4E0000550B - 093700003E0A043300003B0203350000460A0B350000480C0C3700004707063F - 00004903034300005508064900005E08084E00006309085F02006A0602700502 - 7304027703027A02027E02028000018200018200018400018200018200018000 - 017F00017D01017D01018000018000018000018000013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023800004207053C00004D090A37000045090A3800004500054A00 - 004F04063300003F0D07300000540A066E00008901058200048000028400017F - 01007604007803008400017B000451000047040939000048080D350000540A06 - 6A00008305018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001820001840001840001860001860001870001870001870001870001870001 - 8700018700018500008600018700028601038300038000027900007300006E01 - 036A08084C00005107053900003E0A042D00003708043300003F060932000044 - 0A0B3500004909093B00004701014B00005506034C00006108045300006B0A07 - 6200006F08057104027504027903027A02027E02028101028200018400018400 - 018400018200018000018000017F00017D01017D01017F000180000180000180 - 00014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003B02013800004905063C00004506 - 083600004202074200024E00034600004007062E00003D090346000077020385 - 00018200048000028400017F01007604007803008400017B00045500033E0000 - 46030A3700004207054600007305017F01008000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00017F00017F0001800001800001820001840001860001870001870001890001 - 8900018900018700018700018700018900018A00018B00028700038001037800 - 046E00026300005900005503024700004906033900004005033300003E07043A - 02013802023300003F06093300004507073B00004B0303490000520000520000 - 6205025E00007009066900007709057403007802017B01017D01017F00018000 - 018200018500028700028600018400018200018000018000017F00017D01017D - 01017F00018000018000018000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003A01 - 003D02004100004501023C00003E02033D00024300034C00014B000239000037 - 05003400004D03007200008700038200048000028400017F0100760400780300 - 8400017B00045300014300053F00034000053900004D03006E00008103008000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000017F00017F0001800001800001840001840001 - 8600018700018700018700018700018700018600018600018600018600018600 - 018600028001037702056A02035F02015100004800004000003C02003700003C - 03013900004003014000004002023A00013A01043800014001033F0000490101 - 4B00005100005400005E00006600007207037504017B09037903007B03007E00 - 007F00007F000082000184000186000187000287000286000184000182000180 - 00018000017F00017D01017D01017F00018000018000018000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003A01003B00004501024100004001033A00003F000443 - 00034D00024800003D0403320000390500490000750001860002820004800002 - 8400017F01007604007803008400017B00045400024000024300073B00003E03 - 0149000071030080020080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000018000017F00017F0001 - 8000018000018400018400018600018600018801038700028600018300008100 - 007F00007F00007F00017E03057601047204066300005C02024D00004801003E - 00003C01003700003D04033B00004404044300004802034600014102043E0203 - 4100024300004600004A00004E00005600006604046B04027203017603007902 - 007D02007F020080020082000084000184000186000186000186000186000186 - 00018400018400018200018000018000017F00017D01017D01017F0001800001 - 8000018000013F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900004005033D00004A - 06073700004206073A00004400044B00004D02043500003C0A04300000510703 - 7000008800048200048000028400017F01007604007803008400017B00045200 - 004502073B000045050A3500005107036C000082040080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000017F00017F00018000018200018400018400018600018600018400 - 018400018200017F00017D01017A02027903027303036400006205045500005C - 06064900004F05034100004201003C00004205033900004808083B00004C0607 - 4400004900024300004300004700004B00004F00005500005C00006200006D03 - 027203017803007B02007F020080020082020084010086000086000186000186 - 00018700018600018600018400018400018200018200018000017F00017F0001 - 7D01017F00018000018000018000018000014201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003C03023600004C08093C000048090B3500004404094100014E0003440000 - 430A092E0000410D074300007904058500018200048000028400017F01007604 - 007803008400017B00045500033C000049060D370000460B094300007507037F - 0100800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018200018200018400 - 018400018400018400018000007D00007D01017A020275040272050370050265 - 06034B01003C00004B08073E00005109094200005003064900004C0002450000 - 52060A4000004F080B3C00004603064000004800004C00005000005500005D00 - 016402026903047004037402027802017D02007F010082010084010084010086 - 0100860000870001870001870001860001860001860001840001840001820001 - 8200018000017F00017F00017F00017F00018000018000018000018000013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023800004308063C00004F0B0C370000460A0B - 3700004500054A0000500507330000410F09300000560C086D00008901058200 - 048000028400017F01007604007803008400017B000451000048050A3900004A - 0A0F350000560C08690000830501800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018200018200018200018400018400018200018000017E000078000076020171 - 04026E05026805016305005605003A00003A0802320000490C0A3C0000510909 - 4600005300034F000057030747000055080C4000004C070A3900004700035000 - 005700005C00006000006802037004037505057A06057901017D010180010082 - 0000840100840100860100860000870001870001870001860001860001840001 - 8400018200018200018200018000018000017F00017F00017F00017F00018000 - 018000018000018000014201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003C0302350000 - 4D090A3C00004A0B0D35000045050A4100014F0004430000450C0B2E0000420E - 084300007A05068400008200048000028400017F01007604007803008400017B - 00045600043B00004B080F370000470C0A4300007608047E0000800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018200018400018400018400018400018200018000017F - 00017B03037605037005026905016004005C04005403004903003C05002C0000 - 400D0B3300004C0C0C3E00005104084A000052000548000056060D4300005208 - 0E3E000048050A4800005C00006500006A00006D01007202027903027D030380 - 0404800001820000840000840000860000860000860000860000860001860001 - 8600018400018400018400018400018200018200018000018000018000018000 - 018000018000018000018000018000018000018000013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023800004207053C00004D090A37000045090A3800004500054A00 - 004F04063300003F0D07300000540A066E00008901058200048000028400017F - 01007604007803008400017B000451000047040939000048080D350000540A06 - 6A00008305018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000182000184000184000184000184 - 00018400018200018000017B01017A06057205036905015F03005602004F0100 - 4901004302003B03003F0A07330000460D0C3700004909093B00004400024500 - 014E040842000052050C42000053060D46000057020668030171030075010078 - 03007B0101800102810102850002860000860000860000860000860000860000 - 8600008600008600018400018400018400018400018200018200018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003B02013800004905063C00004506 - 083600004202074200024E00034600004007062E00003D090346000077020385 - 00018200048000028400017F01007604007803008400017B00045500033E0000 - 46030A3700004207054600007305017F01008000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000182 - 00018400018600018600018600018400018200017F00017901017706046D0401 - 6002005600004D00004601004103004203004802024300004A06073A00004307 - 073400003905053400003A03063700004604093E000052030C4D00015D040E62 - 00067202027903007D02007F0200800100840000860000870000890000890000 - 8900018700018600018600018400018400018400018400018400018200018200 - 018000018000017F00017F00017F00017F00017F000180000180000180000180 - 00018000018000018000018000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003A01 - 003D02004100004501023C00003E02033D00024300034C00014B000239000037 - 05003400004D03007200008700038200048000028400017F0100760400780300 - 8400017B00045300014300053F00034000053900004D03006E00008103008000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018001 - 0080010080010080010082000182000182000182000182000182000182000180 - 00018000018000018000018000018400018400018200018000017D0101790101 - 7403016F03026905035F04005501004C00004600004100004103004305004400 - 004800014100004202023800003B03023600003802013B010242010345000050 - 00025600006300086700077202097800007E0100800100820100840000860000 - 8701018800018700008700008700018600018600018400018200018200018200 - 018200018200018200018000018000017F00017F00017F00017F00017F00017F - 00018000018000018000018000018000018000018000018000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003A01003B00004501024100004001033A00003F000443 - 00034D00024800003D0403320000390500490000750001860002820004800002 - 8400017F01007604007803008400017B00045400024000024300073B00003E03 - 0149000071030080020080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018001007F020080020080020082010084000084000086000086 - 00008701018701018500028200018000017F00007E00017E0001830102810102 - 8205077702037307066400005A01004F00004A00004600004702004100004302 - 013F00004201004000003C02033900013C03043900003F03033F00004701014A - 00004F00005800006301016C01037503037902037D00027E00007F0001800100 - 8000018001008200018200018200018200018200018200018200018200018200 - 0182000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000013F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900004005033D00004A - 06073700004206073A00004400044B00004D02043500003C0A04300000510703 - 7000008800048200048000028400017F01007604007803008400017B00045200 - 004502073B000045050A3500005107036C000082040080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018001007F02007F030080020082 - 0100840100860100860000870000880001870101850002840001820001800001 - 7F00027F00027E0000800606720000770B0A5C00005D09044A00004602003F00 - 004006013600004308063700004606063D00004100023701013B060933000042 - 08093A00004D05054A00005600005E0000660000700000790101800201830101 - 8601008500008200018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000014201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003C03023600004C08093C000048090B3500004404094100014E0003440000 - 430A092E0000410D074300007904058500018200048000028400017F01007604 - 007803008400017B00045500033C000049060D370000460B094300007507037F - 0100800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018000018000018000017F - 01007D02007B03007D02007F0200800100820000840000860000860001860001 - 8400018500028300038100038100037E01037B03046E000076090B5B0000670B - 0A4A00005006043F0000400301340000430A0935000048090B3900004704073F - 00003F030437000048090B3A000052090B4500005805045900006501016B0100 - 7402027A02028103028301018401008300008200018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023800004308063C00004F0B0C370000460A0B - 3700004500054A0000500507330000410F09300000560C086D00008901058200 - 048000028400017F01007604007803008400017B000451000048050A3900004A - 0A0F350000560C08690000830501800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000017F00017B02007903007B03007D02007F0100800100 - 8200008200008400018400018200018200018100038001038001037A02036E00 - 006F0708590000670B0A4A0000550A083F00004404033A000041080633000048 - 0C0C3700004A090B3C00004500033F00004B0407420000570A0D470000610A0D - 5700006604046B03047103037804037B03038103028102018401008400008200 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000014201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003C0302350000 - 4D090A3C00004A0B0D35000045050A4100014F0004430000450C0B2E0000420E - 084300007A05068400008200048000028400017F01007604007803008400017B - 00045600043B00004B080F370000470C0A4300007608047E0000800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000017F00017B0200790200 - 7B02007D02007D02007F01007F00018000017F00017F00017F00027F00027D00 - 047B00047B000474010468020356000060080849000055090A3E00004808073B - 00003C0302320000440A0B3500004A0B0D3900004A05084500004D00004A0000 - 5D060A4E00006A0C10590000700B0D6B03047204067604047A04037D03037F04 - 0281020182000082000080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023800004207053C00004D090A37000045090A3800004500054A00 - 004F04063300003F0D07300000540A066E00008901058200048000028400017F - 01007604007803008400017B000451000047040939000048080D350000540A06 - 6A00008305018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000017F00017D02007D02007D02007D02007D02007D01017D01017D01017A00 - 017A00017800017700017200027000026F000168000258000056060745000050 - 08083C00004808073700003E050438000040070635000048090B3900004C070A - 3F00004E00035400006400055800006F090E5E0000750C0F6D000278070A7604 - 047902037A02027C02027E030180020181020181020180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003B02013800004905063C00004506 - 083600004202074200024E00034600004007062E00003D090346000077020385 - 00018200048000028400017F01007604007803008400017B00045500033E0000 - 46030A3700004207054600007305017F01008000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018200018200018200018000017F00 - 017D00027B00027901027601047100036E00026A000165000163000060000059 - 00004C00014200004905063900004507073700003F06053A01003B0102380000 - 4405073A00004A05084100004D01055000006701066A00007405096B00007908 - 0C7000007C070A7901057901027901027B01017D01017F00017F000180020181 - 0201800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003A01 - 003D02004100004501023C00003E02033D00024300034C00014B000239000037 - 05003400004D03007200008700038200048000028400017F0100760400780300 - 8400017B00045300014300053F00034000053900004D03006E00008103008000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018200018600 - 018700018600018400018000027D00027901027402026F02046802036402025F - 01025800005400005100004A00004100004002023B00003F03033B00003E0504 - 3A01003E02023E00014100024100004700034700004C00024B00005700007203 - 077D03097900057D04087800037D02067A00037B00027D00027C00017C00007C - 00007E00007F0001800201810302800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000018000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003A01003B00004501024100004001033A00003F000443 - 00034D00024800003D0403320000390500490000750001860002820004800002 - 8400017F01007604007803008400017B00045400024000024300073B00003E03 - 0149000071030080020080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018400018B00028C00018A00018500018200047C010575020571 - 04066500025B00005802024D00004C02024200004300003D00003B0201380000 - 3D04033900004004043B00004103034101014703044701024800004A00004E00 - 0052000058010563020678000580000480000480000480000480000280000280 - 00027F00027F00017F00017F00017F00017F00017F00017F0001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000013F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900004005033D00004A - 06073700004206073A00004400044B00004D02043500003C0A04300000510703 - 7000008800048200048000028400017F01007604007803008400017B00045200 - 004502073B000045050A3500005107036C000082040080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018400018900008C00018A000386 - 00068000057800046E00026500025900005704034600004D07073A0000420705 - 3500003904013600003D05043400004108073800004707074000004901014900 - 004E00005200005500015A00025E01026001056A01047D000484000284000484 - 00028400028200028200028200028200018000018000017F00017F00017F0001 - 7F00017F00018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000014201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003C03023600004C08093C000048090B3500004404094100014E0003440000 - 430A092E0000410D074300007904058500018200048000028400017F01007604 - 007803008400017B00045500033C000049060D370000460B094300007507037F - 0100800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000182 - 00018500008700048600068100077A00066E00036300005A0000530001440000 - 4C0809370000440C0B2E00003B0A083302003A0403340000450A083700004B0A - 094000005004054E00004F00005600005D00006502046A03066C04056B020571 - 0003800002860001860002860001860001840001840001820001820001800001 - 8000018000018000018000017F00017F00018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023800004308063C00004F0B0C370000460A0B - 3700004500054A0000500507330000410F09300000560C086D00008901058200 - 048000028400017F01007604007803008400017B000451000048050A3900004A - 0A0F350000560C08690000830501800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000028000047E00057900057400056C0002630000 - 5A00005100004A00004C0606390000470E0D300000410E0C2E00003906043700 - 004308063900004F0C0B4200005909084D00005C00005C00006300006B000270 - 0403740404740404740202780001820001860001860001840001860001840001 - 8400018400018200018200018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000014201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003C0302350000 - 4D090A3C00004A0B0D35000045050A4100014F0004430000450C0B2E0000420E - 084300007A05068400008200048000028400017F01007604007803008400017B - 00045600043B00004B080F370000470C0A4300007608047E0000800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000017D00027603066F0105 - 6800026300005A00005500004F00004A00004B02043C00004C0B0D350000470D - 0E3300004007083800004104023B0000500B084200005C0C0B4E000063060560 - 00006E01037101017601027802017901017B01017D01017F0001820000840000 - 8400008200008400008200008200018200018200018200018200018200018200 - 0182000182000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023800004207053C00004D090A37000045090A3800004500054A00 - 004F04063300003F0D07300000540A066E00008901058200048000028400017F - 01007604007803008400017B000451000047040939000048080D350000540A06 - 6A00008305018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000017901026903045F02035700005000004E00004800004900004701014100 - 004808083900004B0A0C39000049080A3A00004301024100004B06034200005A - 0B084E0000670A096100006F03027904057B03037D01017E00007E0000810000 - 8200008301018200008001008001008001008200008200008200018200018200 - 0182000182000182000182000182000182000182000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003B02013800004905063C00004506 - 083600004202074200024E00034600004007062E00003D090346000077020385 - 00018200048000028400017F01007604007803008400017B00045500033E0000 - 46030A3700004207054600007305017F01008000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000017601025A00004C00014900004600004300 - 004200004200014202024201033C00004704073D00004D050B4300004F020949 - 00014700004500005506034F00006609086100007408077602017C02027F0100 - 8100008500008500008701008801008603008002007F02007F01007F01008001 - 0080010080010080010080000180000182000182000182000182000182000282 - 0002800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003A01 - 003D02004100004501023C00003E02033D00024300034C00014B000239000037 - 05003400004D0300720000870003840004820002840001800100760300780300 - 8600027B00045300004300033F00024001033900004D03006E00008102018000 - 0180010080000182000182000182000182000182000182000182000182000182 - 0001820001820001800001800001820001820000820000820000820000820001 - 8000018000017F00017D01017B01017901017802017602017601026B03044F00 - 004600004200004100004101013D01013D01013A01003900003C00013D000046 - 01044600004F0206500003550105510000580000590000640300670000730505 - 7703027F05057C00008000008300008601008801008902008902008603008002 - 007F01007F01007F01007F01007F010080010080010080000180000182000182 - 0001820001820001820002820002800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000018000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003A01003B00004501024100004001033A00003F000443 - 00034D00024800003D0403320000390500490000750001870002860002860002 - 8700028200017802017901028600027D00045400004000004303023B00003E04 - 0049000071000480000282000182010082000084000086000086000087000087 - 0000870001870001860001860001840002840002820002820001880202890200 - 8902008801008601008300008000007C00007F05057703027305056700006403 - 005900005800005100005000004800004A000442000042030539000138040434 - 02023302003603013B02014101014500004900004D00005500006D0204760201 - 7601027802017901017B01017D01017F00018000018000018200018200008200 - 0082000082000082000080010080000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000013F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900004005033D00004A - 06073700004206073A00004400044B00004D02043500003C0A04300000510703 - 7000008900048700028700028700028400027901027901028700047D00045200 - 004505003B00004508043700005306046C000182010680000180020082010084 - 0100860000860000870000870000870001870001870001860001860002840002 - 8200028200018803008802008700008500008500008100007F01007C02027602 - 017408076100006609064F00005506034500004900004800004D000740000049 - 060B3600003E08083200003504023704023802013B0000410000480000500000 - 5500016300007801028000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000014201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003C03023600004C08093C000048090B3500004404094100014E0003440000 - 430A092E0000410D074300007904058600018600028600028700028200027901 - 027901028700047D00045700003E00004A0A06370000480B0745000075030A7F - 00037F00017F0200800200800200820000840000860000860000860001860001 - 8600028400028200028000028000028000018301018201008100007E00007E00 - 007D01017B03037904056F0302610000670A094E00005A0A094200004B060341 - 00004301023B000047080A350000440A0B3200003E0605370000400202410000 - 4500004C00005400005C00006401036F02047B00028000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023800004308063C00004F0B0C370000460A0B - 3700004500054A0000500507330000410F09300000560C086D00008901058400 - 028400028600028200027801027901028600047D00045300004A08033A00004C - 0D093900005A0A096B00008301087D01017D02007D02007F0200800100820000 - 8200008400008400018400018400028200028000027F00027F00027D00027D01 - 017B01017B01017901017802017601027101016E01036000006306054E00005C - 0C0B420000500B083B0000410402390000400708320000440B0C330000450909 - 3900004501024900004D00005300005A00006300006A00027001057803067D00 - 0280000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000014201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003C0302350000 - 4D090A3C00004A0B0D35000045050A4100014F0004430000450C0B2E0000420E - 084300007A05068400008200028000028400028000027801027901028600047D - 00045801003D00004C0C083900004B0C0847000078040B7E00037D01017B0200 - 7B02007D02007F01008001008200018200018200018200018200028000028000 - 027F00027F00047B00047700017402027604047404047004036B00026300005C - 00005C00004D00005909084200004F0C0B3900004308063700003906042D0000 - 3F0C0A320000490B0B3A00005005074D00005300005C00006400006C00027400 - 057900057C01057D000480000280000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023800004207053C00004D090A37000045090A3800004500054A00 - 004F04063300003F0D07300000540A066E00008901058000027F00028200027F - 00027601027901028600047D00045300004B07023C00004B0B07390000580807 - 6C00008301087D01017B02007B02007D02007F01008001008200018200018200 - 018200018200028000027F00027F00027D00047900046F01036B03046C030669 - 04066502045D00005600004F00004E00005004054000004B0A09370000450A08 - 3400003A04033302003A09073000004509093C00005408094E00005F01056100 - 006A00007400037A00067F010782010682000480000080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003B02013800004905063C00004506 - 083600004202074200024E00034600004007062E00003D090346000077020383 - 00017F00027D00028000027D00027601027801028700047F0004590000420000 - 4906033A00004607034A00007501087F00047D01017D02007F01008001008000 - 018200018200018400018400028200028200048000047F00047F00047D000476 - 01046801046002035E00045A00025700015200004E0000490000490002400000 - 4707073800004108073400003D05043600003A05023600004407053C00005406 - 075200006605096B00037100027700027F000481000584000685000383000180 - 0000800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003A01 - 003D02004100004501023C00003E02033D00024300034C00014B000239000037 - 05003400004D03007200008500037F00027D00027F00027D0002740202780102 - 8700047F00045700004703004200004203003B00004F02006E00038100067F00 - 017F010080010082000082000184000184000184000184000284000282000480 - 00047F00047D00047D00047400056302065801045200014C00004A0000480000 - 4701024703044101014103033B00003E05043900003D04033800003B02013F02 - 004302014500005000015600006702046D00037803067F010681000583000584 - 0002830001830001810001800002800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000018000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003A01003B00004501024100004001033A00003F000443 - 00034D00024800003D04033200003905004900007500018400027D00027B0002 - 7F00027D00027601027901028700047F00045A00004501004404003F00004006 - 014C01006E00067E00047F000181000083000083000083000085000085000185 - 00018400048300038400067F00038103097B00057D03097203075700004B0000 - 4C00034700004900034100004100023E00013E02023A01003E05043900003F03 - 033B00004002024100004A00005000005600005D00006800027000027800037F - 00048200048400028400028200028200027F00017D01017D01017F0001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000013F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900004005033D00004A - 06073700004206073A00004400044B00004D02043500003C0A04300000510703 - 7000008601047D00027B00027F00027D00027601027901028700047F00045700 - 004A06013C0000450804350000510A076700017E000683000385000285000285 - 000285000285000285000383000383000586050A79000082070B7100007A0409 - 6E00006A00065000004D01054100004A05083A00004405073800003B01023A01 - 003F06053700004507073A00004905064200004C00015A00006100006500016C - 00017200027900047F00048300038400028400028400028200017F00017B0101 - 7901017901017F00018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000014201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003C03023600004C08093C000048090B3500004404094100014E0003440000 - 430A092E0000410D074300007904058300017F00027D00028000027F00027801 - 027B00028900048000045A0000400000490A06350000450E094000006C060B77 - 000381000383010283000383000383000381000381000580000581060A770002 - 800A0F67000076080C5F00006900035900005000023F00004C070A3900004809 - 0B3500004007063800003E05043700004808073C000052080845000056060758 - 00006A01047100037300037800047B0004800103830003850003840002840001 - 8200018001007D02007902007803007803007D01018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023800004308063C00004F0B0C370000460A0B - 3700004500054A0000500507330000410F09300000560C086D00008702057F00 - 027D00028200027F00027901027B00028900048000045500004A080337000046 - 0E092E00004F0F0B5B00007701067B00027F00017F00027F00027D00027B0002 - 790004780004740104780A0C620000710C0E5500006406075200005000004700 - 004A05083A00004A0B0D350000440B0A3200003C03023B00004808073E000055 - 0A084900006008085600006703037502057C01057C01057E0103800103800002 - 8200028200018200018200018001007F01007D02007902007803007902007F00 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000014201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003C0302350000 - 4D090A3C00004A0B0D35000045050A4100014F0004430000450C0B2E0000420E - 084300007A05068400008000027F00028400028000027B00027D00028B000480 - 00045B01003D0000480B0732000040100A37000064060A6B0000760104790102 - 7901027801027601027402027002046D02046902055C0000670A0B4C00005D0A - 0C4500005004054300004701023A00004A090B370000480C0C3300004108073A - 00004404033F0000550A084A0000670A0B5900006F07086E00007B00027F0002 - 7F00027F00027F00017F00007F00007F00008000018001007F01007F01007F02 - 007D02007D02007D02007F000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023800004207053C00004D090A37000045090A3800004500054A00 - 004F04063300003F0D07300000540A066E000089010582000280000284000282 - 00027B00027F00028D00048200045A00004B0904350000410D072B0000450B06 - 5300006A00027103057303037303037303037103036E04036A04056505055900 - 005A0404470000540A083C00004A0A093900004104023F000047040739000048 - 0A0A350000430A083400004003003F00005007034A0000670B0A5B0000760A09 - 6E00007B03047E00017F00017F00017E00017E00007E00007D00007D00007F01 - 007F01007F01007F010080020080020082010082010080010080000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003B02013800004905063C00004506 - 083600004202074200024E00034600004007062E00003D090346000077020385 - 00018200028200028600028400027D00027F00028D00048200045F0302430100 - 4309042E0000340A033300005700036000006B00026B01006B01006902006701 - 026402025F03025B0402510000460000490603380000410A0731000039090535 - 02004101013D00004606063700004307073600004005033F00004601004A0000 - 5D08065C0000770B0A7200008005077E00007E00017E00017E00007C00007A00 - 007A00007B02007B02007B02007D02007F020080020084010086010087010086 - 0100820000800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003A01 - 003D02004100004501023C00003E02033D00024300034C00014B000239000037 - 05003400004D03007200008700038200028200018400028400027F0002800002 - 8900047F00046003024D06024001003B04002E00003902004900005900005A00 - 005A00005A00005900005500005100004E00004A00004700004502013D00003D - 04023601003805023303003704013E01004101003E00004202013F0000450200 - 4400004A00004E00005801006001007107067503037E06078001028101027F00 - 007E00007C01007F01008600018301027A02027703027901017B010180000182 - 0000860001870000870000860000820001800001820001820001820001820001 - 8400018400018400018400018200018200018200018200018000018000018200 - 0182000182000182000182000182000182000182000182000182000182000182 - 0001820001820001820001820001820001800001820001800001820001800001 - 8200018000018200018000018200018000018200018000018200017F00027901 - 027900048000048400028600028600028200018000017F00017F00017F000180 - 00018000018000017F00017F00018000018000018000018000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003A01003B00004501024100004001033A00003F000443 - 00034D00024800003D04033200003905004900007500018400028000017F0100 - 8200018200018200018000028000047800046603055100004800003E00004005 - 033900004100004700004A00014900004B00034500004700034100004100023E - 00013F01013B00003E02023A00004002023C00003F01013D00004006003E0500 - 3F01004000004700005100005A03006405026904026F04017203017602017901 - 017B01017D01017F0100810300780000860A047C00009F00049E040970000071 - 060878050874000085030A8100018500068B050B7F0001820004820002820002 - 8400028600028600028700028900028900028900028900028700028600028600 - 0284000282000282000284000284000284000284000286000286000287000287 - 0002870002870002860002860002840002840002840002840002840002820002 - 8400028200028400028200028400028200028904077700008F0A0D7B00008300 - 017E00008400027A000374080E62000074000090030E8D000296020A84000088 - 070A7901017901017D01018000018200018000017D00027B00027F0001800001 - 8000018000013F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900004005033D00004A - 06073700004206073A00004400044B00004D02043500003C0A04300000510703 - 7000008601037F00017D02008001008200008400018000017D00047401046601 - 035B03034500004C06063A00004305053700004001034200024701083B000047 - 040B3700004205093600003A01043900003E0405360000450707390000460405 - 3E00004300004204004104004502004900005201005E02006804007104027602 - 017901017D01017D01017F00017F00017F00017F01007F03008007007B060080 - 0000A00105830000720E0E4D0000530000640307690308740D12620001620003 - 66050966070B6103046104036303036503036703036802036A02036A02036C01 - 036A020368020367030365030363030361040361040363030365030365030365 - 0303670303670303670303670303680203670303670303650303650303650303 - 6503036503036703036703036703036703036703036703036703036703036400 - 006300006D09095D00006A06066000006B07077113145300045F020B921C2777 - 00008A00019000048400017900007802017802017D0101800001840001820001 - 7D00027B00027F00018000018000018000014201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003C03023600004C08093C000048090B3500004404094100014E0003440000 - 430A092E0000410D074300007904058300007F00017D02008001008200008400 - 018000017D00047401046904065100005305063E00004B0B0B3700004004043F - 00004700054100004E060C3C00004B080D3900004206073800003F0304370000 - 4509093700004909093A00004504033F00004802004B02005101005802006103 - 006804007104027905047B01017F00018000018200018200018200018000017F - 01007C04008211076300006600008A04048C1615FFEDE7FFFDF5FFFCF7FFFBF8 - FFEBE8FFFBF8FFF4F0FFFDF8FFFDF8FFFDF7FFFFF8FFFFF8FFFFF8FFFEF8FFFE - F8FFFEF8FFFDF8FFFDF8FFFDF8FFFDF8FFFEF8FFFEF8FFFEF8FFFFF8FFFFF8FF - FFF8FFFEF8FFFEF8FFFEF8FFFEF8FFFEF8FFFEF8FFFEF8FFFEF8FFFEF8FFFEF8 - FFFEF8FFFEF8FFFEF8FFFEF8FFFEF8FFFEF8FFFDF8FFFCF8FFFCF8FFFCF8FFFC - F8FFFCF8FFFCF8FFFCF8FFFCF8FFFCF8FFF8F4FFF8F4FFFCF8FFFCF8FFF6F2FF - E8E5FFF9F9FFECF2FFDDE5850E178B040E8600038504097D0204760201780201 - 7F00018400018700018400017F00027D00027F00018000018000018000013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023800004308063C00004F0B0C370000460A0B - 3700004500054A0000500507330000410F09300000560C086D00008702047F00 - 017D02008001008200008400018000017D00047401046500025D050545000052 - 0C0C3900004709093500004303034300014E040A40000051090F3C00004B080B - 3900004001033C00004507073700004C0C0C3A00004A09083C00004A00005301 - 005A02005F03006603006D04017504027A02027F030380000184000184000186 - 00018600018400018400018001007100007D0902740D04740A037F0303610000 - FFF5EEFFFFF7FFFFF6FFFDF6FBF5EEFFFFF9FFFFF9FBFFF8F8FFF9E7F5EAF3FF - FAF2FFFAF3FFFBF5FFFAF7FFFBF7FFFAF9FFFBFAFFFAFAFFFBF9FFFAF7FFFBF7 - FFFAF5FFFBF3FFFAF3FFFBF3FFFAF5FFFBF5FFFAF5FFFBF5FFFAF7FFFBF7FFFA - F7FFFBF7FFFAF7FFFBF7FFFAF7FFFBF7FFFAF5FFFBF5FFFAF5FFFBF7FFFAFCFF - FBFEFFFAFEFFFBFEFFFAFEFFFBFEFFFAFEFFFBFEFFFAFCFDF9FFFFFBFFFFFCFF - FFFBF8F9F5F7F9F3FFFFFCFFFFFBFFFDFBFFF9FBFFF5F9600000770005810106 - 7F01067E06077602017901018200018700018900018700018000027F00028000 - 018000018000018000014201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003C0302350000 - 4D090A3C00004A0B0D35000045050A4100014F0004430000450C0B2E0000420E - 084300007A05068200007F00017D02008001008200008400018000017D000474 - 01046A05075000005507083E00004D0D0D3700004105053E0000470005400000 - 51070B3E00004F0A0D3C00004805083F00004402033A00004D090A3C0000510B - 0B3E00004E06064E00006203006C03007003017504027A02027E020282000183 - 000087000187000187000187000187000186000186000186000097100E7E0000 - 7502006B00007D00006D0909FFFDF7FFFFF8FCFFF8FBFFFBFAFFFBF1FCF4F0FF - F7E5F9EDEDFFF9F1FFFBF3FFFEF7FFFEF9FEFFF9FFFEFAFEFFFAFFFEFCFEFFFC - FEFEFCFEFFFCFEFEFAFEFFFAFFFEF9FEFFF7FFFEF7FFFFF7FFFEF9FEFFFAFFFE - FAFEFFFAFFFEF9FEFFF9FFFEF9FEFFF9FFFEF9FEFFF9FFFEF9FEFFF9FFFEFAFE - FFFAFFFEFAFEFFF9FFFEF3FFFFF2FFFEF2FFFFF2FFFEF2FFFFF2FFFEF2FFFFF2 - FFFEF3FFFFEBF9F7EFFDFCF3FFFFECFAF9F3FFFFF3FFFFDFE7E6F5F4F0FFFCFA - FFF8F95500046F01077F070B6A00006F00007802017D01018600018900018B00 - 018900018200027F00028000018000018000018000013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023800004207053C00004D090A37000045090A3800004500054A00 - 004F04063300003F0D07300000540A066E00008702047F00017D020080010082 - 00008400018000017D00047401046500025C0404450000500A0A390000460808 - 3500004103033F00004904073E00004D080B3C00004C08093F00004701024500 - 004D050542000055090A4500005A0A094E00005F03026F03027903027A02027E - 02028101028400018600008800008B00018B0001890001870001870001860001 - 8600018700019102047C00008408087A0203850107730E10FFF6F2F8F9F0F6FA - F4FBFFFCF0F6F1F1F7F2FBFFFCFBFFFBF3FAF5F9FEFCFFFEFFFFFDFFFFFDFFFF - FDFFFFFDFFFFFCFFFFFCFFFFFCFFFFFCFFFFFCFFFFFCFFFFFDFFFFFDFFFFFDFF - FFFDFFFFFDFFFFFDFFFFFCFFFFFCFFFFFDFFFFFDFFFFFDFFFFFDFFFFFDFFFFFD - FFFFFDFFFFFDFFFFFDFFFFFDFFFFFCFFFFFCFFFFFDFFFDFEFFFAFFFFFBFEFFFA - FFFFFBFEFFFAFFFFFBFEFFFAFFFFFBFEFFEEF3F6F4F7FBFAFFFFFBFEFFFAFFFF - F8FBFFFAFFFFF8FFFCFFFFFBFFF7F54B00026300027D080B740000850D0E7B01 - 017F00018700018D00018D00018900018000027F000280000180000180000180 - 00014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003B02013800004905063C00004506 - 083600004202074200024E00034600004007062E00003D090346000077020383 - 00007F00017D02008001008200008400018000017D0004740104690406530000 - 5002033F00004808083700003F03033C00003F01013A00004606063900004806 - 073D00004B02044800004C00004C00005804065100006407085A000067060869 - 01027901028000018200018400018600018700018A00028C00028B00018B0001 - 8900018700018400018200018200018600018B00008B00008405067F04067B00 - 00690005FFFAF8FFFFFBFFFFFCFCF0F03020211400011C04061B00001E000221 - 02051B01071901091B00091B00091B00091D00091D00091D00091D00091D0009 - 1D00091B00091B00091B00091B00091B00091D00091D00091D00091B00091B00 - 091901091901091901091901091901091901091B00091B00091D00091D00091D - 00091D00091B00091D00091B00091D00091B00091D00091B00091B0007220710 - 2A0D161B00091700031500033C1F28F8E9EDF4FBF6FDFDF7FFF9F74F090A6D07 - 0C7200007600017700007F00018200018900018D00018D00018700017F00027D - 00027F00018000018000018000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003A01 - 003D02004100004501023C00003E02033D00024300034C00014B000239000037 - 05003400004D03007200008500027F00017D0200800100820000840001800001 - 7D00047401046702045800004900004802023F00003F01013900003B02013901 - 003A02013800004002023E00004502014800004E00005100005800005B000066 - 01036800007003057002047A03047E00008200008400008500008700018A0002 - 8B00038C01048900018700018600018400018000017F00017F00018200018A00 - 009106097000007E060A7F00066A030AFFFBFBFFFDFAFFF7F7FFFDFE13000020 - 01042400012700003000042900002200011E00011E00011E00011E00011E0001 - 1E00011E00011E00011E00011E00011E00011E00011E00011E00011E00012000 - 012000012000011E00011C00011C00011B00011B00011B00011B00011C00011C - 00011E0001200001200001220001230001230001250001230001250001230001 - 250001230001250001270005250001230001390C15230001250001FFFBFFFAFE - F9FEFEF8FFFBF94C030570060C6B0000890B107E00008000018600018B00018F - 00018D00018600017D00027901027F00018000018000018000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003A01003B00004501024100004001033A00003F000443 - 00034D00024800003D04033200003905004900007500018400017F00017D0200 - 8001008200008400018000017D00047401046803055500004D00004300004404 - 043B00003C00003A01003704013303003904013700004202014200004C000052 - 00006103046703036E01037401047900047E0103800103830003840001860001 - 8600018600018600018700018700018600018600018400018000017F00017D01 - 017B01017B01017D01018100007D01016F03026A02037501085D0308FFFDFBFB - FFFCFFFFFEFFFEFF1E0B0E1C01052F060D2900023D09102E00022E050A1E0000 - 39161A2200032A070B1F00002D0A0E2200033C191D1E00002D0A0E2704082C09 - 0D1E000027040823000231090E2A0207310C101E00002D0C101E00013112151B - 00002B0C0F1B00002B0A0E1F00022F0C102400032D050A25000132060C250000 - 43151B25000035070D2500003F111725000032040A2C000634060C2700013608 - 0E27000135070DFFFBFCFFFEFBFFFFFBFFFAF957060971000680000483000385 - 00038400018700018D00018D00018B00018400017801027601027D0101800001 - 8000018000013F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013900004005033D00004A - 06073700004206073A00004400044B00004D02043500003C0A04300000510703 - 7000008601037F00017D02008001008200008400018000017D00047401046601 - 035B03034500004C06063A00004305053700003C030236030038080432000040 - 05033C00005005034F00005E02016802036F01037700037D0002820002870003 - 8A00038A00038600018600018600018400018400018400018400018400018200 - 018000017D01017B01017901017802017802017901017F00007B01016D030268 - 0203710108590408FFFEFBF8FFFCF6FBF9FCFAFA100305130000200004230000 - 2F01072700002300002501012000001F00002604042200002402021E00001E00 - 002A08083715151E00001E00002301012000002200002300002300002200002F - 0B0B1E00001C00001B00002C0E0D1C00002608071C00001E0000200000220000 - 2300002B0304280001230000230000391112240000320A0B2300002300002400 - 00230000270000230000290102230000270000FFF8F7FFFEFAFFFEFBFFF8F95E - 04097700068400048600038800038600018700018B00018D0001890001820001 - 7601027402027D01018000018000018000014201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003C03023600004C08093C000048090B3500004404094100014E0003440000 - 430A092E0000410D074300007904058300007F00017D02008001008200008400 - 018000017D00047401046904065100005305063E00004B0B0B37000040040439 - 00003E07043400004508043A00005107054900006509086703036F0103770001 - 7D00028400028700028B00019000028E00028700018400018400018200018200 - 018200018000018000017F00017D01017B01017901017901017802017802017B - 01018500008400017402026F01037900085D0308FFFDFBFAFFFCFAFFFEFDFFFE - 140E0F110305210B0D1B00012E0D112100002B070729060334110E200000300F - 0C2403001D00002809063314112203002706031E000045221F20000039131122 - 00003A13112400003812102805022E0D0A1C0000270A061900002005011B0000 - 341512270603401D1A22000038110F220000300F0C1B00002E110D1B00002A0D - 091C000030130F1B0000270A06230602290C081D00002B0E0A1D0000290C08FF - FDF9FFFDFAFFFCFBFFF7F96303097A0006870004860003880003860001860001 - 8900018B00018700018000017601027402027D01018000018000018000013E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023800004308063C00004F0B0C370000460A0B - 3700004500054A0000500507330000410F09300000560C086D00008702047F00 - 017D02008001008200008400018000017D00047401046500025D050545000052 - 0C0C3900004709093500004104023E00004A0704400000580B084A0000680C0B - 6200007408077601027D00028200028600018900018D00018F00018D00018600 - 018400018200018200018000018000017F00017F00017D01017D01017B01017B - 01017901017901017802017F00018A00008B00007B0101770001800006660207 - FFFCF9FFFFFBFAFBF7FCFAF90C04040C00001601031500001F04071900001B00 - 002A0D081B00001900001E05011A02001500001500001500009A847E8A716DD9 - C1BBD9BEBAFFFDF8FFFDF91C00001E00002D0D081C0000190000170000150000 - 1D09049E8C85FFFEF998857E1903001700001B000032140F2B0A071E00002003 - 001900002106021E04001C01001900001E03002B110B1A00001900001D020019 - 00001F04001900001D0200FFFAF5FFFDFAFFFCFBFFF6F9650309780006860004 - 8500038500038200018400018700018900018700018000017801027601027D01 - 018000018000018000014201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003C0302350000 - 4D090A3C00004A0B0D35000045050A4100014F0004430000450C0B2E0000420E - 084300007A05068200007F00017D02008001008200008400018000017D000474 - 01046A05075000005507083E00004D0D0D3700004105053F00004D00004C0000 - 610A08520000710F0F610000780A0A7500017B00028000018200018400018700 - 018700008900008700008400018200018200018200018000018000017F00017F - 00017F00017F00017D01017D01017D01017D01017D0101840001910000920000 - 8400017F00018800066F0107FFFAF9FFFFFBFFFFFCFFFEFC1F0D0C180302250B - 0B1B00002D0E0F1C00002613100E00000C0000110700180F0B090100A39D98CE - C8C1FFFFFBFFFBF4FFFFFBCBC3BCB8ADA9FFFFF9BFB0AD1F0F09271411120000 - 251613100400180D099A948DFFFDF8F3F1E9FFFEF9FFFFF9FFFAF58B837C1F13 - 0F0E00001502001E0803280C0B1B00002D0F0E1B0000381A191B00002A0C0B1B - 0000260807230602290B0A1D00002B0D0C1D0000290B0AFFFDFBFFFDFAFFFCFB - FFF7F96204097500067F00047E00038001037D01017F00018600018700018700 - 018200017901027801027F00018000018000018000013E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023800004207053C00004D090A37000045090A3800004500054A00 - 004F04063300003F0D07300000540A066E00008702047F00017D020080010082 - 00008400018000017D00047401046500025C0404450000500A0A390000460808 - 350000480202550000690304600000790C0E690000800B0C7300007E01038001 - 0281010282000182000182000082000081000081000082000182000182000182 - 00018200018000018000017F0001800001800001800001800001800001800001 - 8000018600008E00008D00007F01007C00008700056F0105FFFBF8FFFFF9FFF9 - F6FFF7F61803021700001E00001C00002604051B00001200000F0200160A0809 - 0000918A87FAF5F2FFFFFCAFACA87A7773787571787370FFFFFCD9D0CD8B7F7D - 1306040E00001000001001001B0E0C090000D6CFCCBAB7B3878682848581F7F8 - F40C0B0784817DC4BDBAFFFFFCC1B4B2A492911300001A00001C00001E00001E - 00001C00001C00002000012303041D00001C00002000011C00002202031C0000 - 200001FFF7F7FFFDFAFFFDFBFFF8F95C05096E00067900047700037902037802 - 017B01018200018700018700018600017D00027B00027F000180000180000180 - 00014100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003B02013800004905063C00004506 - 083600004202074200024E00034600004007062E00003D090346000077020383 - 00007F00017D02008001008200008400018000017D0004740104690406530000 - 5002033F00004808083700003F03034900006801047100007D06077300008508 - 0A7A00008404057E00008301028101028002017D02007D02007A01007801007A - 0100800001840001840001820001820001820001820001800001820001820001 - 8200018200018400018400018600018400008100007B03006F04006E03007C01 - 05660305FFFCF8FFFFF9FFFFFBFFFEFB240D0B1E02012A0B0A220000340E0E21 - 0000290C0F291216715C5FFFFCFFFFF7FAFFFDFF8C7F81180B0D180B0D241719 - 1507091302051C090C1200001600031B02062E1317170000967D81FFFBFE8F7E - 81140709090000867E7FFFFEFF090000180B0D120104180306957E82FFF9FDFF - F4F991717629090E1B00001B000046262B1B000023030823030826060B230308 - 29090E1D00022B0B101D000229090EFFFCFEFFFEFBFFFEFBFFF9F95506096701 - 067201047100037303037203017602018000018600018900018700018200027F - 00028000018000018000018000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003A01 - 003D02003F00004501023C00004001033D00004100014700014701023900003B - 04013900004F02006C00007E01037F00017F01008001008200008000017F0001 - 7901027201046802035D00005000005101004B00004B00004700005600007403 - 068203057D00008100037C00008300038000008301028301028101028002017D - 02007B0200780100770200780100800001820001840001820001820001820001 - 8200018200018200018200018200018400018400018400018600018200007C01 - 007404006B05006C03007A0105640305FFFDF8FFFFF9FFFBF6FFFAF61A03011B - 00002400012000002804041C0000190002FFEDF19D868A917A7EFFF6F9190407 - 120000120000190407120000160003170004150000150000250A0E1700009C80 - 86FFEEF4D6BCC2998287847075FFF1F59E8F93897B7DFFFCFF1406080E000012 - 000020090D1500001A00039C7E83DFBFC4FFF7FCE3C2C99A7C8119000125070C - 1900011900001B00031900001F00051B00002100071B0000210006FFF7FBFFFE - FBFFFEFBFFF9F95506096801067201047100037103037003017403017F000186 - 00018900018900018400018000017F00017F00017F00017F00014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003C00003B00004202013F00004302013E00004101013E - 00004002023F02004106043D00004802024E00006302046F01037D0002820001 - 8200017F00017D01017901017403017002026B01006500006100006300006A03 - 016D06046F03026E00007B000280000180000180000180000180000180000180 - 00018000018000018000017F00017F00017F00017D01017F0001800001800001 - 8200018000018000018000018000018000018000018000018000018200018200 - 018200018200018000017C0100790200760201770001850006690207FFFCF9FD - FFFBFEFFFAFFFFFC260E0E1C00002E060B300B0D1C0000170201FFFBFC938384 - 180607D6C4C598838513000021090B1F04072B101317000024090C22070A2409 - 0C150000331B1D887274FFF2F59C8B8E958487C0AFB2FFFCFF7D6F712413168D - 7D7EFFFCFF857576322021100000210F101402031F0B0A19040323080B1B0001 - 927479FFFAFDFFFBFF8D727523080C190001290E1217000034161B1B00002C0C - 111C00003E1A20FFF2F5FFFEFBFFFEFBFFF8F95C05096F000679000477000377 - 02037203017403007D02008200008700008700008600008000017A0000790101 - 7901017A02023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013B000040050338000047 - 07063C00004706053C00003D02003A0100400705390000490807430000580507 - 5600006A03067D00028400018200017F00017B01017602017203017003016E01 - 006B00006B00006F00007802017B03037D01017C000080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000017F00017E00007B02007B00027E - 00038800066B0108FFFCF9FAFFFBF3F9F4FFFFFC1500001E0000340C111E0000 - 170000D7C5C49285830B00009A8B89FFFCFB1300001F07071900001900001F00 - 011900001A00001700002A10109D8585FFF2F1D1BFBE180B0D73686AFFF7F992 - 87890B0000887B7DFFFDFEFFFDFEFFF1F2FFFDFEF1E2E09182800C00000D0000 - 271B171000001800022005081500001D0507957D7FA48E90FFFCFEC5AFB1907A - 7C2810121700001900001F00032605091F0000FFFAFDFFFEFBFFFEFBFFF7FB5E - 04097300067F00047C00037A02027403017603007D0200820100870000870000 - 8400008001007B00007A00007D01017E02024201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003E0202360000470A083900004D0A093A00004606053A00003D0402360000 - 470C0A3A0000540A0A49000060070A6600027D00028600018400017F00017B01 - 017802017403017203017102006F00006F00007300007A02027E04047E02027D - 0000800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018000018000018000017F - 00017E00007B02007B00027E00038800066B0108FFFCF9FAFFFBFBFFFCFFFEFA - 1C0406300D112800052300043A2020FFEEED0F00001D0E0CC2B3B19D8B8A220D - 0C1500002A1010200606280C0C2004042206062B1111C2AAAAFFFBFA9B86850E - 0000877F80C3BEBF251F20827C7DD5CDCEFFFEFFFFF7F7FBF1F1FFFEFEFFFEFE - FFFEFCFFF6F4FFFEFCBFB3B1877C780C00001702041B05071500011200001B06 - 081200002D181A988385CCB7B9FFFCFED0B5B81C00023011141C0000351216FF - F5F8FFFEFBFFFEFBFFF8FB5E04097500068000047E00037E0202780201790200 - 7F01008400008700018700018400018200018800048900048800038700023E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023A00004308063700004C0C0B3C00004B0A09 - 3900003E03013800004209073500004E0D0C4200005C090B5300006A03067F00 - 028600018400018000017D010179010176020174030174030172010073000077 - 01007C0202800404800102800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000017F00017E00007B02007B00027E00038800066B0108 - FFFCF9FAFFFBF9FFFAF7F4F01C04062000012200002200038A70709B87861A08 - 07190706FFF5F4998584150000190101210707170000190000170000907676FF - F2F2A89392120000200C0B0C00000500000202027D7B7BF6F4F4FDF8F9F2EDEE - FFFFFEFFFFFEFFFCFBF2EDECFFF9F6FFFBF8FFFFFCFFF9F6FFFFFBFFFFFB9484 - 851000002210110E000019090A1404050E00000F0000160405150002D0B8BAD5 - BABD1B00001C00001C0000FFFCFEFFFEFBFFFEFBFFF9F95E0409750006840004 - 8300038100037D01017D02008001008400008700018600018000018000018A01 - 058D00048C00038B00024201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003E0202350000 - 480B093900004F0C0B3A00004707063A00003D0402340000470C0A3A0000550B - 0B49000060070A6500017F00028600018400018200017F00017B010179010178 - 02017802017802017800007B01017E0202810203810102800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000017F00017E00007B0200 - 7B00027E00038800066B0108FFFCF9FAFFFBF9FFFAFFFFFC20080A1E0000370F - 14240105FEE4E49D8988180403120000FFFDFC8A7272371F1F170000290F0F17 - 00002E1414D8BEBEFFFCFC8B76751803021200001F0D0C1C100E9A9898EFF1F1 - FDFFFFFDFFFFFFFFFFFFFFFFEFEDECFDFBFAFFFCFB888483DCD7D4FFFFFCFFFC - F9FFFFFCFFFFFBFDF4F0F9EDEDFFFEFEB9ADAD867C7C180E0E1107071C10100C - 0000100001100000978183C7AFB133161927080B27060AFFFCFEFFFFFBFFFFFB - FFF9F95C05097700068700048600038700038000018000018400018600018600 - 028200027B00027B00028200028500018600028700033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023A00004207053700004A0A093C00004A09083A00003E03013800 - 004007053500004B0A094200005906085300006902057F000286000186000182 - 00017F00017D01017B01017901017901017901017B01017D01017F0001800001 - 8200018200018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000017F00017E00007B02007B00027E00038800066B0108FFFCF9FAFFFBF6FC - F7FFFFFB1500001E00002A02071E0000FFFCFC897574200B0A1C0404D7BFBF99 - 7F7F170000240A0A170000967C7CFFFCFC856D6D130000210D0C170302100000 - 948583BCB0AEF7F5F5FBFFFFFBFFFFFBFFFFF7F9F9F1F3F39C9D9B7F7D7CFFFF - FE110D0C040100050000CCC5C2FFFFFCFFF8F4FFFFFBFFFEFEFFF7F7FFFFFEFF - FFFEF5F0EF7F77779189890900001D0F100E0000120000FFFCFE170000190000 - 240508F7E2E1FEFFFBFFFFFBFFF9F95C05097800068900048A00038A00038400 - 018200018400018400018200027F00027601027402027A02067A020378000375 - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003D01013800004407053900004A07 - 063B00004404033B00003B02003600004207053A00004F05054A00005C030666 - 00027F00028600018600018200018000017F00017D01017B01017A00007D0101 - 7D01017F00017F00008100008300008400018200018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000017F00017E00007B02007B00027E00038800 - 066B0108FFFCF9FAFFFBFBFFFCFFFFFC1F07092C090D220000280509FFF1F190 - 7B7A240C0C170000907676FFFCFC2F1515170000FFF6F6DFC7C7200808130000 - 220D0C120000210D0C9C8A89FFFEFCFFF6F4FEFCFCFDFFFFFDFFFFFBFDFDC5C7 - C70000000D0E0C807E7DFAF6F5070201140D0A1B120F160A08998C8AFFF3F0FF - FCF8FEF6F6FFFFFEFBF7F6FFFBFAFFFFFEFFFEFDFFFEFDFFFEFE7C70701D0F10 - 8A7879FFFCFE1700001F02053A1B1EFFFDFCFCFFFBFFFFFBFFFAF95C05097800 - 068900048C00038C00038400028200028200028200027F00047900047002046B - 03046C07096806066300025F00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00003C00 - 003D02003C00004202014100004302013F00003C01003900003C03013A000043 - 02014600005200015700016700037D0002860001840001820001800001800001 - 7F00017D01017D00007E00007F00018000018000008200008400008300008200 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000017F00017E00 - 007B02007B00027E00038800066B0108FFFCF9FAFFFBF0F6F1FFFFFC1500001E - 00002700041E00009A8080D0BBBA170000220606200404FFEDEDA187871E0404 - 977F7F1300001300001C0807120000968281FFFDFC837170796A68FFFEFCFFFE - FFF8F8F8FEFEFE8A8A8A0000008E8E8E020000040000FFFFFE0D03030C00000C - 00001200001200009D8684FFFEFBFFFAFAFFFFFEFEFCFBFCFAF9FFFFFEFFFFFE - F3EEEDFFFEFEFFFEFEFEF0F1FFFDFED0BABC1800021900001B0000FFFCFBFAFF - FBFFFFFBFFFAF95A05097800068900058A00038A00038400028000028000027D - 00027900047201046902056204055805045404035202015101004000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00003C00003B00004003013E00004502013F00004101003C - 01003B02003700003D02004000004C02024D00005800026801047B0002840001 - 8400018200018000018000018000017F00018000018000018000018200018200 - 0184000186000184000182000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000017F00017E00007B02007B00027E00038800066B0108FFFCF9FA - FFFBF9FFFAFFFFFC250D0F1E0000340C111E00002D1313FFFDFC2105051B0000 - 270B0B1F0303FFF6F69B8181240C0C130000230E0D120000FFF1F0FFF9F8A795 - 94100000251312FFF7F5FFFEFF8D8788040000140F10B6B1B2FFFEFF807B7A07 - 0000FFFCFC0F0102210F0E1300002F15151900002F100FFFFDFB918787777574 - C5C3C2FCFAF9FFFFFEFFFFFEFFFEFDFFFEFEFFFEFEFFF3F4FFFDFE8973753119 - 1B19000026070AFFFCFBFAFFFCFFFFFBFFFAF95A050977000686000487000286 - 00048001037C01038005097901057605096700015D00024F00004C0202450201 - 4300004000003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00003F01013B000040050338000047 - 07063C00004706053C00003D02003A01003D0402350000490807430000540103 - 5300006A03067901028200018200018200018000018000018000018000018000 - 0180000182000182000184000184000186000184000182000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000017F00017E00007B02007B00027E - 00038800066B0108FFFCF9FAFFFBFBFFFCFDFAF61800021E00002E060B1E0000 - 1B0101907B7AE2C6C61C0000190000170000907676FFFCFC846F6E220E0D1200 - 009A86859E8C8B100000100000120000170302998A880B00000700008D8586FF - FEFFFFFEFFFFFAFB948C8C0B0101FFFDFE1000001803021700002E0E0F200000 - 240000997B7ABEB2B21915140400000E0A097F7B7AF0ECEBFFFFFEFEF6F6FFF5 - F5A89A9B816F701701031700001900002C0D10FFF9F8FBFFFBFFFFF9FFFBF859 - 060875000684000583000381000577000179070770000078090D630000660509 - 5100004B00003E00003D00003F00004303024201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073C - 00003E0202360000470A083900004D0A093A00004606053A00003D0402330000 - 4409073A0000540A0A4900005C03066500027801028000018000018000018000 - 0180000180000180000182000182000182000182000184000184000184000184 - 0001820001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018000018000018000017F - 00017E00007B02007B00027E00038800066B0108FFFCF9FAFFFBFBFFFCFEFBF7 - 1800022100022800052502061B01011E0908D2B8B8DBBFBF270B0B170000331B - 1B897473FFFDFCD2BEBD210D0C1000001804038F7B7AFFFCFB8D7877200B0A12 - 00009B8E90CCC4C5FFFAFBFFFEFFF3EBECFFFAFB9187870B0000FFFDFE120000 - 1901011B00002D080A2800022800002C0808FFFDFE847C7C1914130500001813 - 12CDC5C5FFFEFE8B81811608090E000029141617010323080B1B0001250609FF - FDFCFDFFFBFFFFF9FFFBF85906087200078000067D00047A0206710406630000 - 70090C5B000068090D4F00005304074500004B02044701024500004200003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004002023A00004308063700004C0C0B3C00004B0A09 - 3900003E03013800003F06043500004E0D0C4200005906085000006A05077601 - 027F00017F00017F00017F000180000180000180000182000182000182000182 - 0001840001840001840001820001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000017F00017E00007B02007B00027E00038800066B0108 - FFFCF9FAFFFBFAFFFBFFFFFC1E0608250206230000230004280E0E1300001900 - 00DAC0C0FFFAFA937B7B1300002E1A19120000907C7BFFFDFCCEBCBBD5C1C0FF - FDFC927D7CFFF8F8230B0B8F7A79F3E6E8FFFEFFFFFEFFFBF5F6FFFEFFFFFEFF - 756D6D160C0CFFFCFD1604051F07071E000027020428000037080A2200009781 - 83C4B8B8140808090000110707FFFCFC7F73730C00001F0F101000001B050715 - 00001C00021B00001C0000FFFAF9FEFFFAFFFFF9FFFAF85707086F01077A0006 - 760104710406620000650908500000630A0D4C000057080B3F00004502054400 - 004700004700004A01034201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003E0202350000 - 480B093900004F0C0B3A00004707063A00003D0402330000450A083A0000560C - 0C4900005D04076500027601027D01017D01017D01017D01017F000180000180 - 0001800001800001820001820001820001820001820001820001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018000018000018000017F00017E00007B0200 - 7B00027E00038800066B0108FFFCF9FAFFFBF0F6F1FFFFFC1A02041F00002200 - 001E0000260C0C1500001F07071B0101917979FFFDFCDEC9C88B777628141312 - 00001C0A098B79788B7776170201281010FFEDED2C1010917C7BFFFDFFFFFEFF - FFFEFFFFFEFFFAF8F8F2F0F07D79780B0605FDF3F31B0B0C1A05041900002702 - 04230000330708260000190103FFFDFE1000000E0000958586FFFDFE16060718 - 08091B090A1200001901031700002D0E112D0C102C0B0FFFFCFCFFFFFAFFFFF9 - FFF9F75406076A00067400056C01036705055A04044B000057090A4500005508 - 0B3E000046060B3D00004801044B00034900014600003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023A00004207053700004A0A093C00004A09083A00003E03013900 - 003E05033500004C0B0A4200005704065100006904067402027B01017B01017B - 01017D01017D01017F0001800001800001800001820001820001820001820001 - 8200018200018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000017F00017E00007B02007B00027E00038800066B0108FFFCF9FAFFFBF5FB - F6FFFFFC1600001E00002A02071E00001C02021601001500001B030313000012 - 0000988483D2C0BFFFEEEDD1BFBE1000001200002C1716150000170000FFFCFC - 1E0000897171FFFEFFF8F8F8FFFFFFFDFFFFF3F5F5FDFFFF979896020000FFFA - F9160A0A1200001700002A0A0B2200002700002600001A00008F797B97818312 - 00008F7A7C8671732D181A1200001601031F090B250A0D1900001B00001C0000 - 200001FFFCFCFFFFFAFFFFF9FFF9F75305066500046D00036400005B04024B00 - 004D08053C00004C08093C00004807093400003D04073D000043000045000148 - 01044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003D01013800004407053900004A07 - 063B00004404033B00003C03013500004106043B00005006064900005B020564 - 01037202027901017901017B01017D01017D01017F00017F0001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000017F00017E00007B02007B00027E00038800 - 066B0108FFFCF9FAFFFBFBFFFCFFFFFC1B03052603072800052100021D030312 - 000025100F130000341F1E150100100000DCCDCBFFFEFCD7C8C6877574A69291 - 130000150000391D1DFFFBFC240405A89090FFFEFFFAFFFEF6FBFAFAFFFFFAFF - FFECF4F36C7370050A08FFFFFE0700001306041702012509091F000026000022 - 00002D0E111B0003FFFCFE150000DAC2C48973751600022C1618130000190103 - 1800002104072F101328070B260307FFFAFAFFFEFAFFFFF9FFF8F65204056100 - 026600005B00005301004502003B00004407053700004506083500003A040935 - 00033F05063F03043D01023900004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00013C00 - 003D02003C00004202013F00004302013F00003E01003C00003C01003B000045 - 04034500004D00005000006104056F02047602017801027901017B01017D0101 - 7D01017F00018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000017E00 - 007D02007B00027E00038800066B0108FFFDF9FAFFFBFBFFFCF5F2EE21090B2A - 070B220000210000230909130000170000260C0C1500001702011D0908837170 - FFFEFCFFF1EFFFFEFCFFEEEDFFFDFCFFFDFCFFF0F3FFFCFC230407846E70FAF6 - F5FAFFFFFAFFFFF2FAF9F7FFFEF8FFFF818885000100FFFFFE070000190C0A1A - 06051700001C00002904062000001B0000170000D2BABCA08A8CC8B2B4250F11 - 1300001500001700011F04071900001C00001E00011C00001C0000FFFCFCFFFE - FAFFFFF9FFF8F74604055300015900015000004B00004101003E04003B00003F - 03033B00003E03073700033702053600003800003A00013D03044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000013E00013D00004201033E00004201033E000041000240 - 00003E00013D00004201033E0000430003410000460002500000670003700000 - 7300037601027A02037C01037E01038001038000018000018000018000018001 - 008001007F01007F010080000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000017F00008001007D00027F00038A00066B0108FFFDF9FA - FFFBFBFFFCFFFFFC230B0D23000430070C2400012C0D0E1C00002E0F0E1E0000 - 200001270B0B2208081300001F0D0E1202031D0D0E1303041303041F0D0E1B06 - 091300003922267D6D6EFFFFFEFBFFFEF8FDFBF9FEFCFBFFFEF9FCFA7A7B790B - 0706FFFEFE11050519090A18020426090C2000032C070B240203270B0B150000 - 857170FFFDFCFFFEFC0E00002C1A1913000022080822030429090A2000002B0B - 0C1D0000270B0BFFFDFCFFFDFBFFFEFCFFFBFC2F00023C000143000049010144 - 00004300003F00004003013C00004002023A00003D01023C0001410204400103 - 3E00013B00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004A00015F00006B00006E00027401047801027901027D00027E00018000 - 018200018200018200018001008001008001007F010080000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018100008001007F00027F - 00038A00066B0108FFFDF9F8FFFBF6FCF7FEFBF71A02041E0000290003230000 - 2304051B00002000002F09092803051C00001E0202947F7E7967680F0102897B - 7C867A7A86787A8E8082938285857477867376978A8CFFFDFCF9FEFCF3F8F6F4 - F9F7FDFFFEFFFFFE888483050000FFF9F90C00001100001300001C00021C0000 - 2000011C0000190000200B0A210F0EFBECEAC7BAB81205030E00001804031A00 - 001C00002200011E00002202031900001B0101FFF9F8FFFBFBFFFEFEFFF4F42D - 0B0B2B00004108073D00004401004200004505013A0000450806370000440606 - 3C00004100023B00003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605074500005700006300006800016F01037401 - 047800037B00007C000082000284000284000184000182000080010080010080 - 0100800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018100008001007F00027F00038A00066B0108FFFDF9F8FFFBFBFFFCFFFFFC - 240C0E23000433070D2500012D0E0F1E00002500002B03042000001C00001C02 - 02DFCAC99A88890E0001FFFEFEFFFEFEFFFDFFFFFBFDFFFDFFFFFDFFFFF9FCFF - F4F6FFFDFCFDFFFEFDFFFEFDFFFEF4F5F3F5F6F48682810E0606FFFEFE120405 - 1D080A1B0305270A0D2000032A070B230206280C0C190101120000E3D4D2C3B6 - B41508061C0D0B1804032509092404052C0A0B2000002C0C0D1D0000250B0BFF - FDFCFFFEFEFFFAFAFFFCFC1E00003A090B3300004707074100004502003B0000 - 490908370000480A0A3700004605073E00004403054201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004701025000 - 005A00006200006A02037002047700037B00007D000084000286000286000186 - 0001840000820000800100800100800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018100008001007F00027F00038A00066B0108 - FFFDF9F8FFFBF6FCF7FEFBF71A02041E00002900032300002304051B0000350F - 0F230000200000270708170000D9C5C48676770B0000FFFAFAFFFEFEFFFEFFFA - F2F3FFF7F9FFFDFFFFFDFFFFFEFFFFFFFEF7FAF8FFFFFEFFFFFEFFFFFEFFFFFE - 85807F070000FFF9F90C00001300001500001C00021B00001E00011C00001900 - 001F0707120000948583FFF8F60C00001000001300001A00001C000024000120 - 00002402031B00001B0101FFF9F8FFFAFAFFFEFEFFF0F03210102B0000460D0C - 3A00004502014100004808043900004A0D0B370000480A0A3900004201033D00 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706084100004A00005100005901016302046D02047401047C000381 - 0003860002870002870001870001860001840001820001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001810000800100 - 7F00027F00038A00066B0108FFFDF9F8FFFBFBFFFCFFFFFC240C0E2300043307 - 0D2500012D0E0F1E00002B0505230000351012220203170000D8C4C38F7F8009 - 0000FDF5F5FFFFFEFFFEFFFFFDFEFFFEFFFFFAFBFEF6F7FFFDFEFFFFFEFEFFFD - FCFAF9F8F6F5FBF9F8FFFFFE928D8C110909FFFEFE1404051D080A1B03052409 - 0C1F000328070B2302062B0F0F1600001E0A09897A78FFFCFA0D00002D1B1A13 - 00002408082404052E090B2200002E0C0D1D0000250B0BFFFDFCFFFEFEFFF9F9 - FFFCFC1E00003C0B0D3300004808084100004502003A00004A0A093700004A0C - 0C3700004706083E00004302044201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004301024300004A00005101005C - 02026602027002047B0004820004860002890002890002870001860001840001 - 8200018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018100008001007F00027F00038A00066B0108FFFDF9F8FFFBF6FC - F7FDFAF61A02041E00002800022300002304051B00002D0707230000330E101D - 00001C0202D6C2C1928485070000FFFFFEFFFFFEFEFCFCFFFFFFFFFFFFFFFFFF - FDF8F9FFFDFEFFFBFAFFFFFEFFFFFEFFFEFDFFFFFEFEF9F87D7575090000FFF9 - F90E00001300001300001A00021900001E00011C00001900001B030312000027 - 1514FFFDFB0E00001000001601001C00001E00002400012000002402031B0000 - 1B0101FFF8F7FFFBFBFFFEFEFFF1F1310F0F2B0000440B0A3B00004502014100 - 00470703390000480B093700004709093A00004201033C00003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00003E01004001004801005100005D00006A0002780004800005860004870002 - 8900028700028600018400018200018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018100008001007F00027F00038A00 - 066B0108FFFDF9F8FFFBFBFFFCFFFFFC240C0E23000433070D2500012D0E0F1E - 0000300A0A230000220000220304220808CAB8B7877B7B070201FFFFFEFFFFFE - F8F8F8F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFFFEFDFFFDFCFFFFFEFFFF - FEBAB5B4312929090000FFFEFE1204051B090A19030524090C1D000327080B22 - 0306290D0D170000230E0D100000FFFEFC0E0000231110170201260708260405 - 2E090B2200002E0C0D1E0000270B0BFFFDFCFFFEFEFFFCFCFFFCFC2000003706 - 083600004505054200004401003D00004606053700004507073800004403053F - 00004504064302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00003E00003902003901003F0000480000550000630000 - 7100037C01058000048600048600028600028400028200018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018100 - 008001007F00027F00038A00066B0108FFFDF9F8FFFBF6FCF7FEFBF71A02041E - 00002900032300002304051B00002200002901022400011E0000150000D0BEBD - 8D8181050000F6F4F3FFFFFEFDFFFFFCFEFEFBFDFDFBFDFDF9FBFBFCFCFCFFFF - FEFFFFFEFFFFFEFAF5F48C87860803020700008A8282FFFAFA0C000010000112 - 00001901031700001C00021900001900001C0202190403100000FFFCFA1F100E - 1200001500001D00001E00002600012200002601031C00001E0202FFF9F8FFFC - FCFFFEFEFFF8F82907072E00003E05043F00004300004300004202003E000040 - 03013C00004002023F00004000013D00003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100023C0000390401370200 - 3F04024300005301005900006600006D00007D02067F00048100037F00007D00 - 007D00007E00017F000280000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018100008001007F00027F00038A00066B0108FFFDF9F8 - FFFBFBFFFCFFFFFC230B0D23000432060C2500012C0D0E1E00002C0808240000 - 2E0C0D1D0000230B0BD5C3C28E82820B0605FFFFFEFFFFFEFDFFFFFBFFFFFBFF - FFF9FEFDFDFFFFFEFEFEFFFFFEFFFEFECDC5C50700001D1817080302C1BCBBFF - FEFEFFF9F9897D7D1F11121505061F0A0C1300002D1517160000270B0B250B0B - 261110867473FFFEFC0E00002E1A191500002607082503042F080A2400002F0A - 0C1E0000270B0BFFFDFCFFFDFDFFFEFEFFFCFC2402023201033A010042020242 - 00004300004000004202013C00004002023C0000410002400001430204420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00003D01023701003A07043500004807064300005903035900006600007201 - 047700037A00037B00027C00017C00017D00027D00027F000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 018000018000018000018000018000018000018000018100008001007F00027F - 00038A00066B0108FFFDF9F8FFFBF6FCF7FEFBF71A02041E0000290003230000 - 2304051B0000230000220000240203190000180302C9BAB8857979050000FEFC - FBF4F5F3FDFFFFE5EAE9FBFFFFFDFFFFFCFEFEFAF8F8FDF8F7847C7C0700000D - 0807898483FCF7F6FFFEFDFFFFFEFFFCFCFFFEFEFFFBFB7B6D6E908081B09E9F - 8570728F797B8E7474947A7A968180FFFAF99B89881000001200001500001D00 - 002000002600012200002601031C00001D0101FFF9F8FFFBFBFFFEFEFFF4F42D - 0B0B2B00004108073D00004401004200004505013A0000450806370000440606 - 3C00004100023B00003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073C00003D0504330000430A083900005109 - 094500005A04045A00006500026A00026E00027401047800047A01057A02037B - 00027F0001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018100008001007F00027F00038A00066B0108FFFDF9F8FFFBFBFFFCFFFFFC - 240C0E23000433070D2500012D0E0F1E00002D09092300002C0C0D1C0000220D - 0CD3C4C28F83830B0605FFFFFEF3F4F2FAFCFCFDFFFFFBFDFDFFFFFFFFFFFF81 - 7F7F211C1B150D0D8F8A89FFFDFCFAF5F4FFFFFEFFFFFEFFFCFBFDF9F8FFFFFE - FFF9F9FFFBFBFFFEFEEDDFE0FFFDFEFFFCFEFFFCFCFFFCFCFFF2F2A28E8D200E - 0D1000003D292815000028080928030530090B240000300B0D200000290A0BFF - FDFCFFFEFEFFFAFAFFFCFC1E00003A090B3300004707074100004502003B0000 - 490908370000480A0A3700004605073E00004403054201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004001033900 - 004209083500004A0D0B3A0000520A0A4500005402015700005D00006602026D - 02047103057502057902037901027F0001800001800001800001800001800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 00018000018000018000018000018100008001007F00027F00038A00066B0108 - FFFDF9F8FFFBF6FCF7FEFBF71A02041E00002900032300002304051900002100 - 00200000220203190000180302C9BAB8857979050000EBE9E8FFFFFEFBFBFBFE - FEFEFFFFFFBEBCBC04000004000005000075706FFFFFFEFAF6F5FFFDFCFDFBFA - FFFFFEFFFDFCFFFFFEFDF9F8FFFFFEFFFEFDFAF0F0FFFBFBFFFEFEFFF3F4FFF9 - F98C70702109091200001000001000001500002107071D000020000027000123 - 00002801031E00001F0001FFF9F8FFF9FAFFFEFEFFF0F03210102B0000460D0C - 3A00004502014100004808043900004A0D0B370000480A0A3900004201033D00 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E0000420404390000490B0B3700004A0D0B39000049080744 - 00004A00005100005B01016201036B03047002047401047801027D0101800001 - 8000018000018000018000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001810000800100 - 7F00027F00038A00066B0108FFFDF9F8FFFBFBFFFCFFFFFC240C0E2300043307 - 0D2500012D0E0F1C00002B09092100002C0C0D1B0000210C0BD3C4C28F83830D - 0505FFFFFEFFFFFEECEAEAFFFFFF817C7D0500001C1415847C7DFFFFFEFCF7F6 - F8F3F2FFFFFEFFFFFEF7F8F6FFFFFEF6F7F5EDEEECF8F9F7F7F5F4FFFFFEFFFC - FBFFFFFEF4ECECDACCCD170000240808260E0E1200002E1C1B1000001D080717 - 000027070828030531090B250000320B0D200000290A0BFFFDFCFFFDFEFFF9F9 - FFFCFC1E00003C0B0D3300004808084100004502003A00004A0A093700004A0C - 0C3700004706083E00004302044201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A000042010341000048060739000048 - 0A0A350000430A08360000400503400000470000500000590101630101690102 - 6E00027500017D00028000018000018000018000018000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018100008001007F00027F00038A00066B0108FFFDF9F8FFFBF6FC - F7FDFAF61A02041E00002800022300002304051900002100001E000022020317 - 0000160201C9BAB8857979070000FDF8F7F8F4F39C97980500000B0506857D7E - D2C7C9FFFDFFE4DFDEFFFFFEFFFEFDF7F5F4FFFFFEFCFFFDF6F9F7FDFFFEFDFF - FEF8FBF9FDFFFEFFFFFEF9F7F6FFFFFE807C7B0C00001E06062307071500001D - 08071200001501001A05041700001F00002200002700012300002801031E0000 - 1F0001FFF7F7FFFAFBFFFEFEFFF1F1310F0F2B0000440B0A3B00004502014100 - 00470703390000480B093700004709093A00004201033C00003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A000044030540 - 00004802034200004705063700004108073200003A07043702003A0200400100 - 4900005100005B00006400006B00007300007D00028000018000018000018000 - 0180000180000180000180000180000180000180000180000180000180000180 - 0001800001800001800001800001800001800001800001800001800001800001 - 8000018000018000018000018000018000018100008001007F00027F00038A00 - 066B0108FFFDF9F8FFFBFBFFFCFFFFFC240C0E23000433070D2500012D0E0F1C - 0000290A091F00002B0C0D190000200C0BD3C4C28F83830D0505C9C4C38E8988 - 0E08090E0607CDC2C4FFFDFFFFFDFFFFF4F6FFFFFEFEFAF9FFFFFEF7F5F4FFFF - FEEDF0EEFDFFFEFBFFFEE8EDEBF9FEFCFAFFFDF6F9F7898A8802000017151409 - 00001D05051900002F151519040324100F1200002914131700002907082A0305 - 31090B250000320B0D2200002A0A0BFFFCFCFFFDFEFFFCFCFFFCFC2000003706 - 083600004505054200004401003D00004606053700004507073800004403053F - 00004504064302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004100014600014802034000004103033800003C0403 - 3701003904013A03003E01004200004900005000005800005F00006500007202 - 027601027601027601027801027801027901027901027B00027B00027D00027D - 00027F00027F00027F00027F00027F00017F00017F00017F00017F00017F0001 - 7F00017F00017F00017F00017F00017F00017F00017F00017F00018000018100 - 008000017D00027C0003830008660208FFFCFBFDFFFBF8FCF7FFFAF71C010420 - 00002600032000002304051B00002300002000002503041900001A0202CCBAB9 - 8678790900000904030702017F797AFFFBFCFFFDFFFCF1F3FFF7F9FFFEFEFFFF - FEF3F4F2FFFFFEFFFFFEFDFFFEFDFFFEF4F7F5FFFFFEFFFFFEFFFFFEC4C2C104 - 00000904030700000900001002031800001C00001800001500001300001F0A09 - 1500001F03031E00002000002600012200002601031E0000210102FFF8F8FFFB - FCFFFEFEFFF8F82907072E00003E05043F00004300004300004202003E000040 - 03013C00004002023F00004000013D00003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E0000410002400001410001400000 - 4201033E00004001033C00003D01023C00003E00003F00004301024100004701 - 024500004A00014E00005500005A00005E02015C00006505056602026B05066E - 03057305077302057A05087700037D04087A00037F01067D00047C00017A0000 - 7D00027900007E01037900007D00027B00007C00017A00007D00027900007E01 - 037900007D00027D00007E00007D00017A020771000474010B580008FFFBFBFF - FFFCFFFFFEFFFEFE290A0B27000229090A1D00002C0E0D2100003A0D10290000 - 2D04092B060A331619C2ACAED8C8C9090000837E7DBFBBBAFBF7F6FFFFFEFFFF - FEFFFDFCFFFCFCFFFBFAF5FAF8F8FFFCFAFFFCF6FCF7FDFFFCF3F4F0FFFFFCFE - F9F6FFFDFA8A7E7C2A1B191000001F0A091C04042309091A0000270809210203 - 2509091C0000270B0B1E020224080820010226070823030429090A1E00002B0B - 0C1E0000290A0BFFFCFCFFFCFDFFFEFEFFFCFC2402023201033A010042020242 - 00004300004000004202013C00004002023C0000410002400001430204420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004200014400004C010046000055 - 05044C00005B05055700005F01026500026D040768000076070B6D00007C060B - 7500027A02077700037A05067100007D08097000007C07087300007803047500 - 017A05067100007D08097000007C07087300007B02067B00018002086E000372 - 080F6300035A0A11FFF6F8FFFEFCFCFAF9FFF9F92101022200001F0100170000 - 2306022000002500002800002500021C0000170000E7D2D4C4B8B8837E7DFFFF - FEFFFFFEF9FCFAF5F8F6F9FAF8FFFFFEFFFFFEFFFFFEFAFFFCF4FEF8F6FDF8FB - FFFCF2F6F1FFFFFCFFF8F59185831809071000001300001700002405061C0000 - 2100001C00001E00001B00001E00001B00002001021B00001C00001B00001C00 - 001B00001F00011B00002102031B00001F0001FFF8F8FFFAFBFFFEFEFFF4F42D - 0B0B2B00004108073D00004401004200004505013A0000450806370000440606 - 3C00004100023B00003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073F - 00004300003E00004C07044000005308064700005604035100005A0000560000 - 6906085A000070090C61000072070A6B00036E0305660000750A0C620000760B - 0D6400007207096A00016E0305660000750A0C620000760B0D6400007207096D - 00017500026E000075090F5900006D0A12460000FFFBFCFFFFFCFFFFFEFFFEFE - 2B0B0C270002290B0A1900002E0F0C21000024040528090C2005081400011709 - 0A817979FFFFFEF5FAF8F1FAF7F4FFFCF6FFFEF6FFFEF8FFFEEFF8F5F5FCF9FA - FFFEF0F6F1F4FAF5FDFFFCFDFEFAFFFFFCC0BBB88A817E0D0000100000120000 - 2810101C02022001021D00002F0D0E22020328080922030428090A1E00002A0B - 0C200102270809210203270809230405290A0B1D00002B0C0D1D0000290A0BFF - FCFCFFFDFEFFFAFAFFFCFC1E00003A090B3300004707074100004502003B0000 - 490908370000480A0A3700004605073E00004403054201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004202023E00004809053900004E0E0A3C0000520B08 - 4200004F02004B00005704034C0000620A0A50000066090A5700006002035A00 - 00630605530000680B0A5300006609085500005F02015A000063060553000068 - 0B0A5300006609085500006300026400006D020555000064080D5000004F090F - FFF0F1FFFFFCF8FBF9FFFAF92101022200001F01001700002405021C00001F03 - 031500001200000E0000201616040000F3F6F4F9FFFDF6FFFEF0FEFAEEF9F6F3 - FEFBF6FFFEF8FFFEF6FDFAF2F7F5FFFFFCF0EFEBFFFEFAFFFFFC7B7471170E0B - 0E01001000001F0B0A1601001E04041900001B00001C00002301021E00001E00 - 001B00001E00001B00002001021B00001C00001B00001C00001B00001F00011B - 00002102031B00001F0001FFF8F8FFF9FAFFFEFEFFF0F03210102B0000460D0C - 3A00004502014100004808043900004A0D0B370000480A0A3900004201033D00 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083C00003F0604350000 - 460D0B3500004B0E0C390000490807410000470101400000530909430000580A - 0B4700005505064B000050000147000057070847000059090A4700005404054B - 000050000147000057070847000059090A4700005404054E00005B0000530000 - 5C080A4700005C080D370000FFFCFCFEFDF9FBFFFEFFFFFE2B0B0C270002290B - 0A1900002E0F0C1F00002E14141701031A05070E00002418180F0A09939190FD - FFFEF7FCFAFAFFFEFBFFFEF8FDFBFBFEFCFDFFFEFFFFFEFFFFFEFFFFFCFFFFFC - BFB3B11205031407050E0000210F0E1300001B03031700002105051E00002606 - 071F00002C0A0B22000128080923030429090A1F00002B0B0C21010227070822 - 02032707082404052A0A0B1E00002C0C0D1E00002A0A0BFFFCFCFFFDFEFFF9F9 - FFFCFC1E00003C0B0D3300004808084100004502003A00004A0A093700004A0C - 0C3700004706083E00004302044201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004002023700003D0805320000430C093200004209073600004003013D00 - 004606053A00004D0A093C00004B08073E00004600004300004B05053E00004F - 09093E00004E08083F00004701014300004B05053E00004F09093E00004E0808 - 3F00004B01014E00005705044200004F090A420000440B0EFFF5F4FDFFFCF5FC - F9FDF9F82001022200001E00001700002405021C00001B00001900002E131619 - 03051402030E00000B00000900008C8484B4ACACD2CACACCC4C4C0B6B6C4B8B8 - CBBDBECCBEBFCABBB982706F1A08071200001200001C07061C0404170000280E - 0E1900001B00001B00001E00001C00002100001E00001E00001C00001F00001C - 00002101021C00001D00001C00001D00001C00002000011C00002202031C0000 - 200001FFF7F7FFFAFBFFFEFEFFF1F1310F0F2B0000440B0A3B00004502014100 - 00470703390000480B093700004709093A00004201033C00003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053D00003A02013200003C07043000003E09 - 063300003D06033900003B02003800004207053700004508063900004306043E - 01004202023D00004706083A00004807093B00004504063F00004201033D0000 - 4706083A00004807093B00004504064000004800004400004707063700004906 - 09300000FFFEFCFBFFFCF8FFFEFFFFFE2A0B0C270002290B0A1900002D100C21 - 00003D161823000030080D2400031C00001B000045282B170000260B0E22070A - 1C01041B00012506092D0E1129080C1B0000250B0B230B0B220A0A1C02023F25 - 251700001900002408082307071B00002102032505063313142606072707081C - 000028080923030429090A1F00002B0B0C210102270708220203270708240405 - 2A0A0B1E00002C0C0D1E00002A0A0BFFFCFCFFFDFEFFFCFCFFFCFC2000003706 - 083600004505054200004401003D00004606053700004507073800004403053F - 00004504064302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00003E00013A01 - 003B04013801003C05023801003D06033A03003C05023800003A01003700003D - 04023900003F06043C03013E05043B00003D01023A00003E02033900003E0203 - 3B00003C00013B00003D01023A00003E02033900003E02033B00003E00003F00 - 00410200360000390100390000330406FFF9F7FAFFFCF3FCF9FEFAF920010222 - 00001D01001700002306021E00002500002F0107270000280002260002220000 - 2100002000002200012000002200002200002300002500002500002500011C00 - 001900001B00001900001B00001B00003213141B00002001021B00002303041C - 00001C00001C00002404051E00001F00001C00001F00001C00002101021C0000 - 1E00001C00001E00001C00002000011C00002202031C0000210102FFF8F8FFFB - FCFFFEFEFFF8F82907072E00003E05043F00004300004300004202003E000040 - 03013C00004002023F00004000013D00003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100024000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100023E00013E00003B00003E02023A00003E02023A00003D01013A - 01003C00003B00003E02023A00003C03023800003B02013A01003C00013D0002 - 4000053C00014000053C00013F00043E00033E00033D00024000053C00014000 - 053C00013F00043C00013F040232000045120F2E000043090A290000FFFEFCF5 - FBF6F4FBF8FFFFFE1F00012B0406311514150000280D0922030230080A2A0004 - 31050B250000330A0F2600032D050A2500022F070C2700042F060B2500003509 - 0F2B000332040A2800022B090A2001022808091B00002C0C0D2000012707081F - 000028090A2001022708091B00002B0C0D1F00012607081E000028090A200102 - 2708091B00002B0C0D1F00012607081E0000240506270809290A0B1B00001C00 - 002A0B0C1B0000FFFCFCFFFDFEFFFDFDFFF8F82100004211133600004A0A0A3C - 00004300004000004202013C00004002023C0000410002400001430204420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004404043A000047 - 07073900004406063A00003F01013D0000420404380000430707350000420606 - 3800003D01013D00004202073A000045050A3900004404093C00003F00043F00 - 024202073A000045050A3900004404093C00003F00023900003F0B052B00003C - 0B09330000491A1CFFF0EEFDFFFCFAFFFEFCF7F6200001220000230A08130000 - 1C03001900002000011E00002100021E00002401051E00001E00011C00002200 - 031E00002300022000002601052200002400012200002200011C00001F00001C - 00002202031B00001E00001B00001F00011B00001E0000190000210203190000 - 1D00001900001F00011900001E00001900002102031900001D00001900001B00 - 001900002506072509092B0C0D1900001B0000FFF4F4FFFDFEFFFEFEFFE9E930 - 0E0E2B0000370000390000520F0E4200004505013A0000450806370000440606 - 3C00004100023B00003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004301023B00004A08093A00004B090A3A00004705063E00004202023A0000 - 490909370000480A0A3700004406063E00004201033A00004A070A3900004B08 - 0B3900004704073E00004300033A00004A070A3900004B080B3900004704073C - 00003400003300004919152E00004E12132F0000FFEFEEFFFFFCFBFFFEEDE5E5 - 4222232200001C030112000028140F230E0C1B07061601031B06081400011D08 - 0A1601031A05071500021B06081601031C06081500011E080A1901031D05071A - 00022405061F00012405061D00002607081D01012304051C00002206061D0101 - 2206061900002408081B01012105051A00002206061B01012206061900002408 - 081B01012105051A00002C10101700001900001700001F0303190000472B2BFF - F5F4FFFBFBFFF8F8FFFCFC1E00004211133300004707073C00004502003B0000 - 490908370000480A0A3700004605073E00004403054201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033F00004A06073C00004F0B0C3C00004D090A - 3A00004301023F00004806073900004C0C0C3900004A0A0A3900004202023F00 - 004805083A00004D0A0D3A00004B080B3A00004300033F00004805083A00004D - 0A0D3A00004B080B3A00004202023D02003D06013906033200003F0000370205 - FFFDFCFFFFFCFAFBF9FFFEFEFFE9EAFFF6F8FFFDFBFFFCF9FFFCF7FFEFECFFFE - FCFFFEFEFFFEFEFFFEFEFFFEFEFFFEFEFFFDFEFFFEFEFFFDFEFFFDFEFFFDFEFF - FDFEFFFDFEFFFDFEFFFDFEFFFDFEFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFC - FFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFC - FCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFFCFCFFF7F7FFFCFCFFFCFCFF - FCFCFFFCFCFFEDEDF7DFDFFFFDFCFFFEFEFFFEFEFFF5F52000002B00004A1110 - 3F00004704034100004808043900004A0D0B370000480A0A3900004201033D00 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E00004300033A0000 - 4B080B3A00004D0A0D3A00004805083F00004300033A00004B080B3A00004D0A - 0D3A00004805083F00004301023A00004B090A3A00004D0B0C3A00004806073F - 00004301023A00004B090A3A00004D0B0C3A00004806073E0000430302350000 - 3B0401370000510C0F320000FFFCFCEDE6E3FDFBFAFFFEFEFFFAFCFFF9FBFFFD - FBFFF8F5FFFFF9FFFEFBFFF9F7FFFAFAFFF9F9FFFBFBFFF8F8FFFBFBFFF9F9FF - FBFBFFF9F9FFFAFAFFF9F9FFFBFBFFF8F8FFFBFBFFF9F9FFFAFBFFF8F7FFF8F8 - FFF7F7FFF9F9FFF6F6FFF9F9FFF7F7FFF9F9FFF7F7FFF8F8FFF7F7FFFAF9FFF6 - F6FFFAF9FFF7F7FFFAF9FFF8F7FFF9F8FFF8F7FFFAF9FFF7F6FFFAF9FFF8F7FF - FAF9FFF6F5FFFDFCFFFAF9FFF1F0FFFDFCFFFDFCFFFDFCFFF9F8FFFEFEFFFBFB - FFFCFC2B09093F0E103500003C00004906054502003A00004A0A093700004A0C - 0C3700004706083E00004302044201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3B00004201033F00 - 004605073A00004B080B3A00004A070A3B00004300033F00004705063A00004B - 090A3A00004A08093B00004301023F00004705063A00004B090A3A00004A0809 - 3B00004302013B00004203003A00004F1111410000420509FFFBFCFFFFFCFFFC - FBFFF9FAFFFAFCFFF8FAFFFBF9FFFBF8FFFBF5FFFEFAFFFEFCFFFDFEFFFDFEFF - FDFEFFFCFDFFFDFEFFFDFEFFFDFEFFFDFEFFFDFEFFFDFEFFFDFEFFFCFDFFFDFE - FFFDFEFFFDFEFFFDFCFFFDFCFFFDFCFFFDFCFFFCFBFFFDFCFFFDFCFFFDFCFFFD - FCFFFDFCFFFDFCFFFDFCFFFCFBFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFF - FDFCFFFCFBFFFDFCFFFDFCFFFDFCFFFAF9FFFDFCFFFBFAFFFDFCFFFBFAFFFDFC - FFFCFBFFF7F5F9EFEFFFFEFEFFFBFB2A08083100023500004808084401004100 - 00470703390000480B093700004709093A00004201033C00003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00003F00023A00004405073700004506 - 083800004403053D00004100023A00004605073900004706083A00004403053F - 00004101013C00004606053900004707063A00004404033F00004101003C0000 - 4606053900004707063A00004404034000004D0A073F00005212113A00005407 - 0B400003FFE2E3FFFEFCFFFEFEFFFDFEFFFAFCFFFAFCFFFDFBFFFFFBFFF7F1FF - F9F6FFF5F4FFFBFDFFF4F7FFFBFEFFF1F4FFFBFEFFF5F8FFFBFEFFF3F6FFFAFD - FFF4F7FFFBFEFFF2F4FFFCFEFFF6F8FFFCFEFFF5F4FFFCFBFFF6F5FFFDFCFFF3 - F2FFFDFCFFF7F6FFFDFCFFF5F4FFFCFBFFF6F5FFFDFCFFF3F2FFFDFCFFF7F6FF - FDFCFFF5F4FFFDFBFFF6F5FFFEFCFFF3F2FFFEFCFFF7F6FFFEFCFFFDFCFFFEFC - FFF9F8FFFEFCFFF5F4FFFEFCFFF8F7FFFEFCFFFEFEFFFEFEFFFCFC1E00004918 - 1A3300005313133C00004401003D00004606053700004507073800004403053F - 00004504064302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000013E00 - 013D01023C00004001033C00004001033D00003E00013E00013F00023C000040 - 01033E00004201033F00004000014000004101003E00004202013E0000420201 - 3F00004000004000004101003E00004202013E00004202013F00004100003C00 - 004A07063A00004C0809480000470409300607290D0D1300002408082A000031 - 02041D00002108061C03002C100F2300002D0608270001330B0D2300002F0709 - 2A000232070A2600002E0608270001330B0D2200002C07092700022B090A1E00 - 002408071D0101290D0C190000250908200102280A091E00002608071F00012B - 0D0C1B0000270908210102280A091C00002408071D0101290D0C190000250908 - 1E0202260A091D01012105041900002A0E0D1900002D11101900002208081500 - 002B11111E00002500003703034D1112390000500F0E4300004201003E000040 - 02023C00004002023F00004000013D00003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100024000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013D00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100024000014000013F0000 - 4201033E00004201033E00004100024000004000013F00004201033E00004201 - 033E00004100024000004100004000004202023F00004500033E00003A010235 - 00033301033400023C0105380000390303330000360202350101370003380002 - 3B02053700013B02053700013A01043900033900033800023B02053700013B02 - 053500013A010437000335000334000037020533000037020533000036010435 - 0101350003340000370205330000370205330000380104350101350003340000 - 3702053300003702053300003601043501013500033400003702053300003702 - 053300003601043500033301033400023902053700003E02033C000041000240 - 00004100003F00004202023E00004201033E0000410002400001430204420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023B00003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004403054201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033D00 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004302044201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033C00003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004504064302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000013D00003E00004000014302044000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100024000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100024000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100024000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E00004100024000014000013F0000 - 4201033E00004201033E00004100024000014000013F00004201033E00004201 - 033E00004100024000014000013F00004201033E00004201033E000041000240 - 00014000013F00004201033E00004201033E0000410002400001430204420103 - 4000013D00003F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023F00004403053A00004706083900004605073C00004100023F00 - 004403053A00004706083900004605073C00004100023F00004403053A000047 - 06083900004605073C00004100023F00004403053A0000470608390000460507 - 3C00004100023B00003D00003F00004302044201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004201033A000049080A3900004A09 - 0B3900004605073E00004201033A000049080A3900004A090B3900004605073E - 00004201033A000049080A3900004A090B3900004605073E00004201033A0000 - 49080A3900004A090B3900004605073E00004403054201034000013D00003E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033E00 - 004706083900004C0B0D3900004A090B3900004201033E00004706083900004C - 0B0D3900004A090B3900004201033E00004706083900004C0B0D3900004A090B - 3900004201033E00004706083900004C0B0D3900004A090B3900004201033D00 - 003E00004000014302044201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004201033900004A090B3900004C0B0D3900004706083E - 00004201033900004A090B3900004C0B0D3900004706083E0000420103390000 - 4A090B3900004C0B0D3900004706083E00004201033900004A090B3900004C0B - 0D3900004706083E00004302044201034000013D00003E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033E00004605073900004A - 090B39000049080A3A00004201033E00004605073900004A090B39000049080A - 3A00004201033E00004605073900004A090B39000049080A3A00004201033E00 - 004605073900004A090B39000049080A3A00004201033C00003E000040000143 - 02044100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004100023C00004605073900004706083A00004403053F00004100023C0000 - 4605073900004706083A00004403053F00004100023C00004605073900004706 - 083A00004403053F00004100023C00004605073900004706083A00004403053F - 00004504064302044100023D00004000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000014000014100023E00004201033E0000420103 - 3F00004000014000014100023E00004201033E00004201033F00004000014000 - 014100023E00004201033E00004201033F00004000014000014100023E000042 - 01033E00004201033F00004000013D00003E0000400001430204} - end - object lblWelcome: TLabel - Left = 172 - Top = 10 - Width = 318 - Height = 50 - Caption = 'Welcome to the Metamod:Source (version) Setup Wizard' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -21 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - WordWrap = True - end - object lblInfo1: TLabel - Left = 172 - Top = 82 - Width = 331 - Height = 26 - Caption = - 'This wizard will guide you through the installation of Metamod:S' + - 'ource (version).' - WordWrap = True - end - object lblInfo2: TLabel - Left = 172 - Top = 120 - Width = 335 - Height = 39 - Caption = - 'It is recommended that you close all other applications before s' + - 'tarting a setup for e.g. Half-Life 2 or other games. Otherwise y' + - 'ou should restart your system after this installation.' - WordWrap = True - end - object lblInfo3: TLabel - Left = 172 - Top = 176 - Width = 108 - Height = 13 - Caption = 'Click Next to continue.' - end - end - object jspLicense: TJvStandardPage - Left = 0 - Top = 0 - Width = 527 - Height = 314 - object pnlLicense: TPanel - Left = 0 - Top = 0 - Width = 527 - Height = 49 - Align = alTop - BevelOuter = bvNone - Color = clWhite - TabOrder = 0 - object imgIcon1: TImage - Left = 486 - Top = 8 - Width = 32 - Height = 32 - Picture.Data = { - 0A54504E474F626A65637489504E470D0A1A0A0000000D494844520000002000 - 0000200806000000737A7AF40000000467414D410000AFC837058AE900000019 - 74455874536F6674776172650041646F626520496D616765526561647971C965 - 3C000008ED4944415478DAD556096C54D7153D7FE6CFFC59BC321EE3F1162F60 - 833DB6C10B019C60410007D43649518480B64924BAD0D00401A58AD456EA42A4 - 268A4848216D43054A55910588484A020D2EE09D181BDB78C106DB638FEDB1F1 - 18DBE3F12C7FFED2FBBFC1402090B46AAB3EE96966DEBCE5DC7BCF3DF732AB57 - 3F8EFFE6D06AB5686C6C80CBE5527F33FF8F00CC34B9AF7340969529836120B1 - 2C3BDED07001C3C3C35F19004B7339CDB5744911DD9328430E67C02817D264EE - 7B58926408A20893914320C08B3A1DDBD9D3D3BDB7B3B3E3FDAF02600341DF29 - 8872BE286BC1EA39707AFA6419D5A2202F83E74380C883D5021A0D73D7E346A3 - 1E3F78E69B489D930247B71307DEF9580182CB97DBB7381C3D7FF832007134F7 - 0BA2F494ACE1101F6B4656BC0F732CE3B09A791875324472ABC7CF6060C288F6 - E128740C6AE1F54E41AF9566BC120886B0A2380BDF5B5F8ADFED3B8A977EB20E - 474FD4E2A393B5049819AFACACB0DF0B400645EC3819362F26D68255760F8A13 - 5D88B725C2146B87C69C044617465B44C8C1318426AEC0E36A419B730A7FBFFA - 102E748A80E023B269542F994D9C1227F294803FEEDE80831F36A0ACBC590D49 - 7D7DDDFA2F02502C3FC70B4CC6FC0C2B36E5B6213BD10073E626B0519960345A - C892A0D00A924C618086EE26DF0B531086CEC1DD7E0CA77A5270AC2E0281A949 - C54A8ABF043E24E1575B164267B6E2B7FBCB2189210A234B002E6CBE1D8086E6 - DFC8F235F6F9B3F1C385E7911C1B0EA3FD456828759A1D22AE793420C354F215 - A6F230734A9C152611109D19D24407BC4D7B503698834395B3C0FB271122BC1B - 4B6D5856908C1D7B9BE0A330190D3A088218AAAAAA58C19496AE515D45F35951 - 940FC6C55BB1BDA41369BA361873B781E1ACD02288CFDA67C1311E01032B4224 - 721526B8919B14002FDE229E863523D47F0ABEDE933836B00A7F39A34141860E - AF6F5F884FEAFCE8EC19414B970703435E0C0D0D5636355D5CCBE4E717107B35 - E6A8A8E866B0E6B4CDAB24AC8CFA94DC351BBAF4F58A79D03012DA5D61180B18 - 31EC35C0E531C0C28DE3E9FC6BE40D8AF50C021DE4C93EF08E0F302E5AF04A4D - 31A6A6043C5A10A7440D1CC7A2B27114DDCE71345EACFBB1DBED7E8BD1EBF588 - 8B8B5B3F37D3FE6E669A053B1757221A2E30FA30B0B615605813794702AB91C1 - E944B40E46E2484B32B990C7A6050EA4C70AAA17981B00C4894E88A3F5F4A084 - F29102BC713A1641BF173733D4C8E9303939DE535B5B53425E77AACB0B16E4BF - 1F13F7D0D31B96C978D2F6992A9732B15C634E80262243BD4C3141A79531E4D1 - 615F7506A67816453627BEF3F02802218DCA03884188D79B2841FCAAFC8DF251 - 78B972097A9C93D0B1D308585687E6E6C657FBFB9DBB542122361A962C296E8B - B6C6A5EE5CD98B1C632318AD7EDAADF4B0C6685179408B30E9451CA88C468533 - 0D0612244E1EC32F4ABB1161A444080520FB06200B816952D2F11089C581D665 - 38D940DE632525D42442018F42BE502854AF02309BCDC9458B96B627265A4D2F - 9534205ED74BABBADB845C525D6B301AD03164C42F4FCE87DE14AD7A64CA17C2 - F78B9AF18D6C377D0F4E8BBEE2094C678A4CE9F651DF221CAC88849EE1A1D3E9 - 70F5EA950F3A3A2E6FA42D82BA2F2C2C2CBBA070496366BA95DDB5B41A167644 - B5F6F6A1643C47ECFFD9311BCE0F6722D512443817428B2B02B931DD78EDDB0E - 08127B8B8CEA1905630865AE3CEC3F1307AD1C5016C4EAEAAA755EAFF7F8CC3E - 05402101C8488FB901C07D1700935E467927879F7F9A05D61085AD4BDB616405 - BC7ACE0E569AC09E275A30CF16425060EE02F00F572EF69DB141AF1194D43B7F - F162C36AFAC733B38F42904221684D4A8CA110D4C3A673DE118269F64AD8FA5E - 323A3D69C8B47AF1C6130D18F3EBF1E2F185182652AEB7B7E285E56E7883B780 - DF0CC1C7BD853848BC51F4A3AEEEFC0B947A6FDEE15D62BC69C9D2475A2DD6B8 - 949D8F75C16E6EA130EA67DC19669070B4DE88D7CA73603499F0D3925694660C - 931831D85D361FA7AFC623DE3088031B3A10499D829F57C8379D968A0CFFB9B5 - 18279BF4084E5DEFABA9A95652CF716778D5345C782CC696FAD4A64702F856FC - 594AC3E9782AB2EB0BCAF8D1BBE918E293B138D98DDF3CDEA23EAE5854E9B010 - 885C88C4FC67165CC2D098041BF173D3121EFEA084EB41135EAE5A8ADE411E1D - 979BF7F4F5F56DFF62E55301D86CF1DFCDCEC97F675E6A38763C5C812876420D - 8362FD818A701C6AB0233A9CC5AF57372327DE4379AF55C185A8F0ED3A9107E7 - 7818BC93E3F0F21C526679F1F6C6AB30698328776560EFD964F0BE715F7575E5 - 63C160B0F69E00480BA2480B9A4C1131C99B974F6265ECE7249B7A38DC1A3C7F - 641E021A1B9ECCEEC3B647AFC02F686F1E839974E17063320E5D9843592223DA - 2460EE2C379E2BEC22D594F14A55212E39240C3ABB4EB4B5B5AEA323C17B0250 - 466242E2D6ACECBC3767CF8EC08E920E6484F7E3D250241A5C5698382D4A5287 - 610DE311923433C754659C34128054E42578A8405D872D22A0880D8E74CCC3E1 - 9A704A046FB0A6A66A9DCFE73B817B8C1900D4C57054984E455BE24BEC734CD8 - B2A81D49E113D4824D133240960B92A270CCF42995E6D37D2129377542B21A92 - 50C087B37D09F853790C756A3CDADA2EBDD5D7D7BB8D4EF0F705A00C83C19051 - 54B4E834678C4A9A9F66C2B3454ECC891CA5326B80ACD1DDD87E03C08DEF37B1 - 2875C017E471BA2B0E876B23C0533BD6EFEC296B6D6D798EFE75E24BC65D2D2D - E9C262F2C47B9C3132D932CB88B5797E14278F20C6A474315AA57ADC925BF28D - D221F979115D6E033EA19EA1B6430B860468A0BFF72C3DFE3CA55D1BEE33EED9 - 53731C97939565FFBD35366E9944D9906065919714C2DCD800628907D4D0A81D - AF27C0A07F5C8F9601035AFBB5540F04305250E8EABAF2576ABD77D35557F080 - 71BFA63ED266B36D494949DB6C0E8B4C97C972C5039C9E514BAB4C0002216ACB - 69529347BF7969D47DEDF3EEEEAEB73D1ECF87747EEC418F3F08C04D72A6582C - 96353131D695111111597ABDC14A65D500E55951F005027ED7D8D858D3C8C8B5 - B2C9C9C9725AEF03EEA84BFF1E80DB23433396A47B360130290BA2284E499244 - E51354C1E0FB1A77FD4B00FE23E37F0EE09F19A8E321D9E34DB9000000004945 - 4E44AE426082} - Stretch = True - Transparent = True - end - object lblTitle1: TLabel - Left = 12 - Top = 8 - Width = 116 - Height = 14 - Caption = 'License Agreement' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -12 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - end - object lblSubTitle1: TLabel - Left = 22 - Top = 28 - Width = 408 - Height = 13 - Caption = - 'Please review the following license terms before installing Meta' + - 'mod:Source (version).' - end - object bvlSpacer1: TBevel - Left = 0 - Top = 46 - Width = 527 - Height = 3 - Align = alBottom - Shape = bsBottomLine - end - end - object freLicense: TmxFlatRichEdit - Left = 10 - Top = 62 - Width = 507 - Height = 207 - Lines.Strings = ( - 'The zlib/libpng License' - '' - 'Copyright (c) 2006, AlliedModders' - '' - - 'This software is provided '#39'as-is'#39', without any express or implie' + - 'd warranty. In no event will the ' - - 'authors be held liable for any damages arising from the use of t' + - 'his software.' - '' - - 'Permission is granted to anyone to use this software for any pur' + - 'pose, including commercial ' - - 'applications, and to alter it and redistribute it freely, subjec' + - 't to the following restrictions:' - '' - - ' 1. The origin of this software must not be misrepresented; y' + - 'ou must not claim that you wrote the ' - - 'original software. If you use this software in a product, an ack' + - 'nowledgment in the product ' - 'documentation would be appreciated but is not required.' - '' - - ' 2. Altered source versions must be plainly marked as such, a' + - 'nd must not be misrepresented as ' - 'being the original software.' - '' - - ' 3. This notice may not be removed or altered from any source' + - ' distribution.' - '') - ReadOnly = True - ScrollBars = ssVertical - TabOrder = 1 - Activate = True - BorderColor = clBtnShadow - Flat = True - ShowBorder = True - Version = '1.26' - end - object frbAgree: TFlatRadioButton - Left = 10 - Top = 274 - Width = 231 - Height = 17 - Caption = 'I accept the terms in the License Agreement' - TabOrder = 2 - OnClick = CheckNext - end - object ftbDontAgree: TFlatRadioButton - Left = 10 - Top = 290 - Width = 265 - Height = 17 - Caption = 'I do not accept the terms in the License Agreement' - Checked = True - TabOrder = 3 - TabStop = True - OnClick = CheckNext - end - end - object jspInstallMethod: TJvStandardPage - Left = 0 - Top = 0 - Width = 527 - Height = 314 - object lblInstallMethod: TLabel - Left = 124 - Top = 124 - Width = 144 - Height = 13 - Caption = 'Please select a install method:' - end - object pnlHeader2: TPanel - Left = 0 - Top = 0 - Width = 527 - Height = 49 - Align = alTop - BevelOuter = bvNone - Color = clWhite - TabOrder = 0 - object imgIcon2: TImage - Left = 486 - Top = 8 - Width = 32 - Height = 32 - AutoSize = True - Picture.Data = { - 0A54504E474F626A65637489504E470D0A1A0A0000000D494844520000002000 - 0000200806000000737A7AF40000000467414D410000AFC837058AE900000019 - 74455874536F6674776172650041646F626520496D616765526561647971C965 - 3C000008ED4944415478DAD556096C54D7153D7FE6CFFC59BC321EE3F1162F60 - 833DB6C10B019C60410007D43649518480B64924BAD0D00401A58AD456EA42A4 - 268A4848216D43054A55910588484A020D2EE09D181BDB78C106DB638FEDB1F1 - 18DBE3F12C7FFED2FBBFC1402090B46AAB3EE96966DEBCE5DC7BCF3DF732AB57 - 3F8EFFE6D06AB5686C6C80CBE5527F33FF8F00CC34B9AF7340969529836120B1 - 2C3BDED07001C3C3C35F19004B7339CDB5744911DD9328430E67C02817D264EE - 7B58926408A20893914320C08B3A1DDBD9D3D3BDB7B3B3E3FDAF02600341DF29 - 8872BE286BC1EA39707AFA6419D5A2202F83E74380C883D5021A0D73D7E346A3 - 1E3F78E69B489D930247B71307DEF9580182CB97DBB7381C3D7FF832007134F7 - 0BA2F494ACE1101F6B4656BC0F732CE3B09A791875324472ABC7CF6060C288F6 - E128740C6AE1F54E41AF9566BC120886B0A2380BDF5B5F8ADFED3B8A977EB20E - 474FD4E2A393B5049819AFACACB0DF0B400645EC3819362F26D68255760F8A13 - 5D88B725C2146B87C69C044617465B44C8C1318426AEC0E36A419B730A7FBFFA - 102E748A80E023B269542F994D9C1227F294803FEEDE80831F36A0ACBC590D49 - 7D7DDDFA2F02502C3FC70B4CC6FC0C2B36E5B6213BD10073E626B0519960345A - C892A0D00A924C618086EE26DF0B531086CEC1DD7E0CA77A5270AC2E0281A949 - C54A8ABF043E24E1575B164267B6E2B7FBCB2189210A234B002E6CBE1D8086E6 - DFC8F235F6F9B3F1C385E7911C1B0EA3FD456828759A1D22AE793420C354F215 - A6F230734A9C152611109D19D24407BC4D7B503698834395B3C0FB271122BC1B - 4B6D5856908C1D7B9BE0A330190D3A088218AAAAAA58C19496AE515D45F35951 - 940FC6C55BB1BDA41369BA361873B781E1ACD02288CFDA67C1311E01032B4224 - 721526B8919B14002FDE229E863523D47F0ABEDE933836B00A7F39A34141860E - AF6F5F884FEAFCE8EC19414B970703435E0C0D0D5636355D5CCBE4E717107B35 - E6A8A8E866B0E6B4CDAB24AC8CFA94DC351BBAF4F58A79D03012DA5D61180B18 - 31EC35C0E531C0C28DE3E9FC6BE40D8AF50C021DE4C93EF08E0F302E5AF04A4D - 31A6A6043C5A10A7440D1CC7A2B27114DDCE71345EACFBB1DBED7E8BD1EBF588 - 8B8B5B3F37D3FE6E669A053B1757221A2E30FA30B0B615605813794702AB91C1 - E944B40E46E2484B32B990C7A6050EA4C70AAA17981B00C4894E88A3F5F4A084 - F29102BC713A1641BF173733D4C8E9303939DE535B5B53425E77AACB0B16E4BF - 1F13F7D0D31B96C978D2F6992A9732B15C634E80262243BD4C3141A79531E4D1 - 615F7506A67816453627BEF3F02802218DCA03884188D79B2841FCAAFC8DF251 - 78B972097A9C93D0B1D308585687E6E6C657FBFB9DBB542122361A962C296E8B - B6C6A5EE5CD98B1C632318AD7EDAADF4B0C6685179408B30E9451CA88C468533 - 0D0612244E1EC32F4ABB1161A444080520FB06200B816952D2F11089C581D665 - 38D940DE632525D42442018F42BE502854AF02309BCDC9458B96B627265A4D2F - 9534205ED74BABBADB845C525D6B301AD03164C42F4FCE87DE14AD7A64CA17C2 - F78B9AF18D6C377D0F4E8BBEE2094C678A4CE9F651DF221CAC88849EE1A1D3E9 - 70F5EA950F3A3A2E6FA42D82BA2F2C2C2CBBA070496366BA95DDB5B41A167644 - B5F6F6A1643C47ECFFD9311BCE0F6722D512443817428B2B02B931DD78EDDB0E - 08127B8B8CEA1905630865AE3CEC3F1307AD1C5016C4EAEAAA755EAFF7F8CC3E - 05402101C8488FB901C07D1700935E467927879F7F9A05D61085AD4BDB616405 - BC7ACE0E569AC09E275A30CF16425060EE02F00F572EF69DB141AF1194D43B7F - F162C36AFAC733B38F42904221684D4A8CA110D4C3A673DE118269F64AD8FA5E - 323A3D69C8B47AF1C6130D18F3EBF1E2F185182652AEB7B7E285E56E7883B780 - DF0CC1C7BD853848BC51F4A3AEEEFC0B947A6FDEE15D62BC69C9D2475A2DD6B8 - 949D8F75C16E6EA130EA67DC19669070B4DE88D7CA73603499F0D3925694660C - 931831D85D361FA7AFC623DE3088031B3A10499D829F57C8379D968A0CFFB9B5 - 18279BF4084E5DEFABA9A95652CF716778D5345C782CC696FAD4A64702F856FC - 594AC3E9782AB2EB0BCAF8D1BBE918E293B138D98DDF3CDEA23EAE5854E9B010 - 885C88C4FC67165CC2D098041BF173D3121EFEA084EB41135EAE5A8ADE411E1D - 979BF7F4F5F56DFF62E55301D86CF1DFCDCEC97F675E6A38763C5C812876420D - 8362FD818A701C6AB0233A9CC5AF57372327DE4379AF55C185A8F0ED3A9107E7 - 7818BC93E3F0F21C526679F1F6C6AB30698328776560EFD964F0BE715F7575E5 - 63C160B0F69E00480BA2480B9A4C1131C99B974F6265ECE7249B7A38DC1A3C7F - 641E021A1B9ECCEEC3B647AFC02F686F1E839974E17063320E5D9843592223DA - 2460EE2C379E2BEC22D594F14A55212E39240C3ABB4EB4B5B5AEA323C17B0250 - 466242E2D6ACECBC3767CF8EC08E920E6484F7E3D250241A5C5698382D4A5287 - 610DE311923433C754659C34128054E42578A8405D872D22A0880D8E74CCC3E1 - 9A704A046FB0A6A66A9DCFE73B817B8C1900D4C57054984E455BE24BEC734CD8 - B2A81D49E113D4824D133240960B92A270CCF42995E6D37D2129377542B21A92 - 50C087B37D09F853790C756A3CDADA2EBDD5D7D7BB8D4EF0F705A00C83C19051 - 54B4E834678C4A9A9F66C2B3454ECC891CA5326B80ACD1DDD87E03C08DEF37B1 - 2875C017E471BA2B0E876B23C0533BD6EFEC296B6D6D798EFE75E24BC65D2D2D - E9C262F2C47B9C3132D932CB88B5797E14278F20C6A474315AA57ADC925BF28D - D221F979115D6E033EA19EA1B6430B860468A0BFF72C3DFE3CA55D1BEE33EED9 - 53731C97939565FFBD35366E9944D9906065919714C2DCD800628907D4D0A81D - AF27C0A07F5C8F9601035AFBB5540F04305250E8EABAF2576ABD77D35557F080 - 71BFA63ED266B36D494949DB6C0E8B4C97C972C5039C9E514BAB4C0002216ACB - 69529347BF7969D47DEDF3EEEEAEB73D1ECF87747EEC418F3F08C04D72A6582C - 96353131D695111111597ABDC14A65D500E55951F005027ED7D8D858D3C8C8B5 - B2C9C9C9725AEF03EEA84BFF1E80DB23433396A47B360130290BA2284E499244 - E51354C1E0FB1A77FD4B00FE23E37F0EE09F19A8E321D9E34DB9000000004945 - 4E44AE426082} - Transparent = True - end - object lblTitle2: TLabel - Left = 12 - Top = 8 - Width = 137 - Height = 14 - Caption = 'Choose install method' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -12 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - end - object lblSubTitle2: TLabel - Left = 22 - Top = 28 - Width = 263 - Height = 13 - Caption = 'Choose a install method for installing Metamod:Source.' - end - object bvlSpacer2: TBevel - Left = 0 - Top = 46 - Width = 527 - Height = 3 - Align = alBottom - Shape = bsBottomLine - end - end - object pnlInstallMethod: TPanel - Left = 122 - Top = 142 - Width = 267 - Height = 97 - BevelOuter = bvLowered - TabOrder = 1 - object frbDedicatedServer: TFlatRadioButton - Left = 4 - Top = 4 - Width = 135 - Height = 17 - Caption = 'Steam Dedicated Server' - Checked = True - TabOrder = 0 - TabStop = True - end - object frbListenServer: TFlatRadioButton - Left = 4 - Top = 22 - Width = 115 - Height = 17 - Caption = 'Steam Listen Server' - TabOrder = 1 - end - object frbSelectMod: TFlatRadioButton - Left = 4 - Top = 58 - Width = 117 - Height = 17 - Caption = 'Select mod directory' - TabOrder = 3 - end - object frbFTP: TFlatRadioButton - Left = 4 - Top = 76 - Width = 35 - Height = 17 - Caption = 'FTP' - TabOrder = 4 - end - object frbStandaloneServer: TFlatRadioButton - Left = 4 - Top = 40 - Width = 107 - Height = 17 - Caption = 'Standalone Server' - TabOrder = 2 - end - end - end - object jspSelectMod: TJvStandardPage - Left = 0 - Top = 0 - Width = 527 - Height = 314 - object lblInfo: TLabel - Left = 138 - Top = 114 - Width = 255 - Height = 26 - Caption = - 'The following mods were detected. Please select the mod you want' + - ' to install Metamod:Source to:' - WordWrap = True - end - object shpMods: TShape - Left = 136 - Top = 142 - Width = 255 - Height = 104 - Pen.Color = clBtnShadow - end - object pnlSelectMod: TPanel - Left = 0 - Top = 0 - Width = 527 - Height = 49 - Align = alTop - BevelOuter = bvNone - Color = clWhite - TabOrder = 0 - object imgIcon5: TImage - Left = 486 - Top = 8 - Width = 32 - Height = 32 - AutoSize = True - Picture.Data = { - 0A54504E474F626A65637489504E470D0A1A0A0000000D494844520000002000 - 0000200806000000737A7AF40000000467414D410000AFC837058AE900000019 - 74455874536F6674776172650041646F626520496D616765526561647971C965 - 3C000008ED4944415478DAD556096C54D7153D7FE6CFFC59BC321EE3F1162F60 - 833DB6C10B019C60410007D43649518480B64924BAD0D00401A58AD456EA42A4 - 268A4848216D43054A55910588484A020D2EE09D181BDB78C106DB638FEDB1F1 - 18DBE3F12C7FFED2FBBFC1402090B46AAB3EE96966DEBCE5DC7BCF3DF732AB57 - 3F8EFFE6D06AB5686C6C80CBE5527F33FF8F00CC34B9AF7340969529836120B1 - 2C3BDED07001C3C3C35F19004B7339CDB5744911DD9328430E67C02817D264EE - 7B58926408A20893914320C08B3A1DDBD9D3D3BDB7B3B3E3FDAF02600341DF29 - 8872BE286BC1EA39707AFA6419D5A2202F83E74380C883D5021A0D73D7E346A3 - 1E3F78E69B489D930247B71307DEF9580182CB97DBB7381C3D7FF832007134F7 - 0BA2F494ACE1101F6B4656BC0F732CE3B09A791875324472ABC7CF6060C288F6 - E128740C6AE1F54E41AF9566BC120886B0A2380BDF5B5F8ADFED3B8A977EB20E - 474FD4E2A393B5049819AFACACB0DF0B400645EC3819362F26D68255760F8A13 - 5D88B725C2146B87C69C044617465B44C8C1318426AEC0E36A419B730A7FBFFA - 102E748A80E023B269542F994D9C1227F294803FEEDE80831F36A0ACBC590D49 - 7D7DDDFA2F02502C3FC70B4CC6FC0C2B36E5B6213BD10073E626B0519960345A - C892A0D00A924C618086EE26DF0B531086CEC1DD7E0CA77A5270AC2E0281A949 - C54A8ABF043E24E1575B164267B6E2B7FBCB2189210A234B002E6CBE1D8086E6 - DFC8F235F6F9B3F1C385E7911C1B0EA3FD456828759A1D22AE793420C354F215 - A6F230734A9C152611109D19D24407BC4D7B503698834395B3C0FB271122BC1B - 4B6D5856908C1D7B9BE0A330190D3A088218AAAAAA58C19496AE515D45F35951 - 940FC6C55BB1BDA41369BA361873B781E1ACD02288CFDA67C1311E01032B4224 - 721526B8919B14002FDE229E863523D47F0ABEDE933836B00A7F39A34141860E - AF6F5F884FEAFCE8EC19414B970703435E0C0D0D5636355D5CCBE4E717107B35 - E6A8A8E866B0E6B4CDAB24AC8CFA94DC351BBAF4F58A79D03012DA5D61180B18 - 31EC35C0E531C0C28DE3E9FC6BE40D8AF50C021DE4C93EF08E0F302E5AF04A4D - 31A6A6043C5A10A7440D1CC7A2B27114DDCE71345EACFBB1DBED7E8BD1EBF588 - 8B8B5B3F37D3FE6E669A053B1757221A2E30FA30B0B615605813794702AB91C1 - E944B40E46E2484B32B990C7A6050EA4C70AAA17981B00C4894E88A3F5F4A084 - F29102BC713A1641BF173733D4C8E9303939DE535B5B53425E77AACB0B16E4BF - 1F13F7D0D31B96C978D2F6992A9732B15C634E80262243BD4C3141A79531E4D1 - 615F7506A67816453627BEF3F02802218DCA03884188D79B2841FCAAFC8DF251 - 78B972097A9C93D0B1D308585687E6E6C657FBFB9DBB542122361A962C296E8B - B6C6A5EE5CD98B1C632318AD7EDAADF4B0C6685179408B30E9451CA88C468533 - 0D0612244E1EC32F4ABB1161A444080520FB06200B816952D2F11089C581D665 - 38D940DE632525D42442018F42BE502854AF02309BCDC9458B96B627265A4D2F - 9534205ED74BABBADB845C525D6B301AD03164C42F4FCE87DE14AD7A64CA17C2 - F78B9AF18D6C377D0F4E8BBEE2094C678A4CE9F651DF221CAC88849EE1A1D3E9 - 70F5EA950F3A3A2E6FA42D82BA2F2C2C2CBBA070496366BA95DDB5B41A167644 - B5F6F6A1643C47ECFFD9311BCE0F6722D512443817428B2B02B931DD78EDDB0E - 08127B8B8CEA1905630865AE3CEC3F1307AD1C5016C4EAEAAA755EAFF7F8CC3E - 05402101C8488FB901C07D1700935E467927879F7F9A05D61085AD4BDB616405 - BC7ACE0E569AC09E275A30CF16425060EE02F00F572EF69DB141AF1194D43B7F - F162C36AFAC733B38F42904221684D4A8CA110D4C3A673DE118269F64AD8FA5E - 323A3D69C8B47AF1C6130D18F3EBF1E2F185182652AEB7B7E285E56E7883B780 - DF0CC1C7BD853848BC51F4A3AEEEFC0B947A6FDEE15D62BC69C9D2475A2DD6B8 - 949D8F75C16E6EA130EA67DC19669070B4DE88D7CA73603499F0D3925694660C - 931831D85D361FA7AFC623DE3088031B3A10499D829F57C8379D968A0CFFB9B5 - 18279BF4084E5DEFABA9A95652CF716778D5345C782CC696FAD4A64702F856FC - 594AC3E9782AB2EB0BCAF8D1BBE918E293B138D98DDF3CDEA23EAE5854E9B010 - 885C88C4FC67165CC2D098041BF173D3121EFEA084EB41135EAE5A8ADE411E1D - 979BF7F4F5F56DFF62E55301D86CF1DFCDCEC97F675E6A38763C5C812876420D - 8362FD818A701C6AB0233A9CC5AF57372327DE4379AF55C185A8F0ED3A9107E7 - 7818BC93E3F0F21C526679F1F6C6AB30698328776560EFD964F0BE715F7575E5 - 63C160B0F69E00480BA2480B9A4C1131C99B974F6265ECE7249B7A38DC1A3C7F - 641E021A1B9ECCEEC3B647AFC02F686F1E839974E17063320E5D9843592223DA - 2460EE2C379E2BEC22D594F14A55212E39240C3ABB4EB4B5B5AEA323C17B0250 - 466242E2D6ACECBC3767CF8EC08E920E6484F7E3D250241A5C5698382D4A5287 - 610DE311923433C754659C34128054E42578A8405D872D22A0880D8E74CCC3E1 - 9A704A046FB0A6A66A9DCFE73B817B8C1900D4C57054984E455BE24BEC734CD8 - B2A81D49E113D4824D133240960B92A270CCF42995E6D37D2129377542B21A92 - 50C087B37D09F853790C756A3CDADA2EBDD5D7D7BB8D4EF0F705A00C83C19051 - 54B4E834678C4A9A9F66C2B3454ECC891CA5326B80ACD1DDD87E03C08DEF37B1 - 2875C017E471BA2B0E876B23C0533BD6EFEC296B6D6D798EFE75E24BC65D2D2D - E9C262F2C47B9C3132D932CB88B5797E14278F20C6A474315AA57ADC925BF28D - D221F979115D6E033EA19EA1B6430B860468A0BFF72C3DFE3CA55D1BEE33EED9 - 53731C97939565FFBD35366E9944D9906065919714C2DCD800628907D4D0A81D - AF27C0A07F5C8F9601035AFBB5540F04305250E8EABAF2576ABD77D35557F080 - 71BFA63ED266B36D494949DB6C0E8B4C97C972C5039C9E514BAB4C0002216ACB - 69529347BF7969D47DEDF3EEEEAEB73D1ECF87747EEC418F3F08C04D72A6582C - 96353131D695111111597ABDC14A65D500E55951F005027ED7D8D858D3C8C8B5 - B2C9C9C9725AEF03EEA84BFF1E80DB23433396A47B360130290BA2284E499244 - E51354C1E0FB1A77FD4B00FE23E37F0EE09F19A8E321D9E34DB9000000004945 - 4E44AE426082} - Stretch = True - Transparent = True - end - object lblSelectMod: TLabel - Left = 12 - Top = 8 - Width = 68 - Height = 14 - Caption = 'Select Mod' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -12 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - end - object lblSelectModInfo: TLabel - Left = 22 - Top = 28 - Width = 332 - Height = 13 - Caption = - 'Please select the mod Metamod:Source (version) shall be installe' + - 'd to.' - end - object bvlSelectMod: TBevel - Left = 0 - Top = 46 - Width = 527 - Height = 3 - Align = alBottom - Shape = bsBottomLine - end - end - object trvMods: TTreeView - Left = 137 - Top = 143 - Width = 253 - Height = 102 - BorderStyle = bsNone - Indent = 19 - MultiSelectStyle = [] - ReadOnly = True - RightClickSelect = True - RowSelect = True - TabOrder = 1 - OnClick = trvModsClick - end - end - object jspFTP: TJvStandardPage - Left = 0 - Top = 0 - Width = 527 - Height = 314 - object lblStep1: TLabel - Left = 44 - Top = 56 - Width = 100 - Height = 13 - Caption = '1. Set your FTP data' - end - object lblStep2: TLabel - Left = 44 - Top = 146 - Width = 244 - Height = 13 - Caption = '2. Connect to server and select the mod directory:' - end - object lblStep4: TLabel - Left = 44 - Top = 296 - Width = 64 - Height = 13 - Caption = '4. Click Next.' - end - object lblStep3: TLabel - Left = 44 - Top = 252 - Width = 223 - Height = 13 - Caption = '3. Select the operating system of your server:' - end - object pnlHeader3: TPanel - Left = 0 - Top = 0 - Width = 527 - Height = 49 - Align = alTop - BevelOuter = bvNone - Color = clWhite - TabOrder = 0 - object imgIcon3: TImage - Left = 486 - Top = 8 - Width = 32 - Height = 32 - AutoSize = True - Picture.Data = { - 0A54504E474F626A65637489504E470D0A1A0A0000000D494844520000002000 - 0000200806000000737A7AF40000000467414D410000AFC837058AE900000019 - 74455874536F6674776172650041646F626520496D616765526561647971C965 - 3C000008ED4944415478DAD556096C54D7153D7FE6CFFC59BC321EE3F1162F60 - 833DB6C10B019C60410007D43649518480B64924BAD0D00401A58AD456EA42A4 - 268A4848216D43054A55910588484A020D2EE09D181BDB78C106DB638FEDB1F1 - 18DBE3F12C7FFED2FBBFC1402090B46AAB3EE96966DEBCE5DC7BCF3DF732AB57 - 3F8EFFE6D06AB5686C6C80CBE5527F33FF8F00CC34B9AF7340969529836120B1 - 2C3BDED07001C3C3C35F19004B7339CDB5744911DD9328430E67C02817D264EE - 7B58926408A20893914320C08B3A1DDBD9D3D3BDB7B3B3E3FDAF02600341DF29 - 8872BE286BC1EA39707AFA6419D5A2202F83E74380C883D5021A0D73D7E346A3 - 1E3F78E69B489D930247B71307DEF9580182CB97DBB7381C3D7FF832007134F7 - 0BA2F494ACE1101F6B4656BC0F732CE3B09A791875324472ABC7CF6060C288F6 - E128740C6AE1F54E41AF9566BC120886B0A2380BDF5B5F8ADFED3B8A977EB20E - 474FD4E2A393B5049819AFACACB0DF0B400645EC3819362F26D68255760F8A13 - 5D88B725C2146B87C69C044617465B44C8C1318426AEC0E36A419B730A7FBFFA - 102E748A80E023B269542F994D9C1227F294803FEEDE80831F36A0ACBC590D49 - 7D7DDDFA2F02502C3FC70B4CC6FC0C2B36E5B6213BD10073E626B0519960345A - C892A0D00A924C618086EE26DF0B531086CEC1DD7E0CA77A5270AC2E0281A949 - C54A8ABF043E24E1575B164267B6E2B7FBCB2189210A234B002E6CBE1D8086E6 - DFC8F235F6F9B3F1C385E7911C1B0EA3FD456828759A1D22AE793420C354F215 - A6F230734A9C152611109D19D24407BC4D7B503698834395B3C0FB271122BC1B - 4B6D5856908C1D7B9BE0A330190D3A088218AAAAAA58C19496AE515D45F35951 - 940FC6C55BB1BDA41369BA361873B781E1ACD02288CFDA67C1311E01032B4224 - 721526B8919B14002FDE229E863523D47F0ABEDE933836B00A7F39A34141860E - AF6F5F884FEAFCE8EC19414B970703435E0C0D0D5636355D5CCBE4E717107B35 - E6A8A8E866B0E6B4CDAB24AC8CFA94DC351BBAF4F58A79D03012DA5D61180B18 - 31EC35C0E531C0C28DE3E9FC6BE40D8AF50C021DE4C93EF08E0F302E5AF04A4D - 31A6A6043C5A10A7440D1CC7A2B27114DDCE71345EACFBB1DBED7E8BD1EBF588 - 8B8B5B3F37D3FE6E669A053B1757221A2E30FA30B0B615605813794702AB91C1 - E944B40E46E2484B32B990C7A6050EA4C70AAA17981B00C4894E88A3F5F4A084 - F29102BC713A1641BF173733D4C8E9303939DE535B5B53425E77AACB0B16E4BF - 1F13F7D0D31B96C978D2F6992A9732B15C634E80262243BD4C3141A79531E4D1 - 615F7506A67816453627BEF3F02802218DCA03884188D79B2841FCAAFC8DF251 - 78B972097A9C93D0B1D308585687E6E6C657FBFB9DBB542122361A962C296E8B - B6C6A5EE5CD98B1C632318AD7EDAADF4B0C6685179408B30E9451CA88C468533 - 0D0612244E1EC32F4ABB1161A444080520FB06200B816952D2F11089C581D665 - 38D940DE632525D42442018F42BE502854AF02309BCDC9458B96B627265A4D2F - 9534205ED74BABBADB845C525D6B301AD03164C42F4FCE87DE14AD7A64CA17C2 - F78B9AF18D6C377D0F4E8BBEE2094C678A4CE9F651DF221CAC88849EE1A1D3E9 - 70F5EA950F3A3A2E6FA42D82BA2F2C2C2CBBA070496366BA95DDB5B41A167644 - B5F6F6A1643C47ECFFD9311BCE0F6722D512443817428B2B02B931DD78EDDB0E - 08127B8B8CEA1905630865AE3CEC3F1307AD1C5016C4EAEAAA755EAFF7F8CC3E - 05402101C8488FB901C07D1700935E467927879F7F9A05D61085AD4BDB616405 - BC7ACE0E569AC09E275A30CF16425060EE02F00F572EF69DB141AF1194D43B7F - F162C36AFAC733B38F42904221684D4A8CA110D4C3A673DE118269F64AD8FA5E - 323A3D69C8B47AF1C6130D18F3EBF1E2F185182652AEB7B7E285E56E7883B780 - DF0CC1C7BD853848BC51F4A3AEEEFC0B947A6FDEE15D62BC69C9D2475A2DD6B8 - 949D8F75C16E6EA130EA67DC19669070B4DE88D7CA73603499F0D3925694660C - 931831D85D361FA7AFC623DE3088031B3A10499D829F57C8379D968A0CFFB9B5 - 18279BF4084E5DEFABA9A95652CF716778D5345C782CC696FAD4A64702F856FC - 594AC3E9782AB2EB0BCAF8D1BBE918E293B138D98DDF3CDEA23EAE5854E9B010 - 885C88C4FC67165CC2D098041BF173D3121EFEA084EB41135EAE5A8ADE411E1D - 979BF7F4F5F56DFF62E55301D86CF1DFCDCEC97F675E6A38763C5C812876420D - 8362FD818A701C6AB0233A9CC5AF57372327DE4379AF55C185A8F0ED3A9107E7 - 7818BC93E3F0F21C526679F1F6C6AB30698328776560EFD964F0BE715F7575E5 - 63C160B0F69E00480BA2480B9A4C1131C99B974F6265ECE7249B7A38DC1A3C7F - 641E021A1B9ECCEEC3B647AFC02F686F1E839974E17063320E5D9843592223DA - 2460EE2C379E2BEC22D594F14A55212E39240C3ABB4EB4B5B5AEA323C17B0250 - 466242E2D6ACECBC3767CF8EC08E920E6484F7E3D250241A5C5698382D4A5287 - 610DE311923433C754659C34128054E42578A8405D872D22A0880D8E74CCC3E1 - 9A704A046FB0A6A66A9DCFE73B817B8C1900D4C57054984E455BE24BEC734CD8 - B2A81D49E113D4824D133240960B92A270CCF42995E6D37D2129377542B21A92 - 50C087B37D09F853790C756A3CDADA2EBDD5D7D7BB8D4EF0F705A00C83C19051 - 54B4E834678C4A9A9F66C2B3454ECC891CA5326B80ACD1DDD87E03C08DEF37B1 - 2875C017E471BA2B0E876B23C0533BD6EFEC296B6D6D798EFE75E24BC65D2D2D - E9C262F2C47B9C3132D932CB88B5797E14278F20C6A474315AA57ADC925BF28D - D221F979115D6E033EA19EA1B6430B860468A0BFF72C3DFE3CA55D1BEE33EED9 - 53731C97939565FFBD35366E9944D9906065919714C2DCD800628907D4D0A81D - AF27C0A07F5C8F9601035AFBB5540F04305250E8EABAF2576ABD77D35557F080 - 71BFA63ED266B36D494949DB6C0E8B4C97C972C5039C9E514BAB4C0002216ACB - 69529347BF7969D47DEDF3EEEEAEB73D1ECF87747EEC418F3F08C04D72A6582C - 96353131D695111111597ABDC14A65D500E55951F005027ED7D8D858D3C8C8B5 - B2C9C9C9725AEF03EEA84BFF1E80DB23433396A47B360130290BA2284E499244 - E51354C1E0FB1A77FD4B00FE23E37F0EE09F19A8E321D9E34DB9000000004945 - 4E44AE426082} - Transparent = True - end - object lblTitle3: TLabel - Left = 12 - Top = 8 - Width = 269 - Height = 14 - Caption = 'Installing Metamod:Source (version) via FTP' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -12 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - end - object lblSubTitle3: TLabel - Left = 22 - Top = 28 - Width = 189 - Height = 13 - Caption = 'Do the following steps and press Next. ' - end - object bvlSpacer3: TBevel - Left = 0 - Top = 46 - Width = 527 - Height = 3 - Align = alBottom - Shape = bsBottomLine - end - end - object pnlFTPData: TPanel - Left = 44 - Top = 72 - Width = 441 - Height = 64 - BevelOuter = bvLowered - TabOrder = 1 - object lblHost: TLabel - Left = 4 - Top = 4 - Width = 26 - Height = 13 - Caption = 'Host:' - end - object lblUserName: TLabel - Left = 180 - Top = 6 - Width = 52 - Height = 13 - Caption = 'Username:' - end - object lblPassword: TLabel - Left = 308 - Top = 4 - Width = 50 - Height = 13 - Caption = 'Password:' - end - object lblPort: TLabel - Left = 132 - Top = 4 - Width = 24 - Height = 13 - Caption = 'Port:' - end - object txtHost: TFlatEdit - Left = 4 - Top = 20 - Width = 121 - Height = 19 - ColorFlat = clBtnFace - ParentColor = True - TabOrder = 0 - end - object txtUserName: TFlatEdit - Left = 180 - Top = 20 - Width = 121 - Height = 19 - ColorFlat = clBtnFace - ParentColor = True - TabOrder = 2 - end - object txtPassword: TFlatEdit - Left = 308 - Top = 20 - Width = 127 - Height = 19 - ColorFlat = clBtnFace - ParentColor = True - PasswordChar = '*' - TabOrder = 3 - end - object txtPort: TFlatEdit - Left = 132 - Top = 20 - Width = 43 - Height = 19 - ColorFlat = clBtnFace - ParentColor = True - MaxLength = 5 - TabOrder = 1 - Text = '21' - OnChange = txtPortChange - end - object chkPassive: TFlatCheckBox - Left = 4 - Top = 44 - Width = 139 - Height = 16 - Caption = 'Use PASV (Passive) Mode' - Checked = True - TabOrder = 4 - TabStop = True - end - object cmdProxySettings: TFlatButton - Left = 350 - Top = 42 - Width = 83 - Height = 18 - ColorFocused = 16245198 - ColorDown = 16245198 - ColorHighLight = 8623776 - ColorShadow = 8623776 - Caption = 'Proxy-Settings' - TabOrder = 5 - OnClick = cmdProxySettingsClick - end - end - object cmdConnect: TFlatButton - Left = 416 - Top = 161 - Width = 71 - Height = 20 - ColorFocused = 16245198 - ColorDown = 16245198 - ColorBorder = clBtnShadow - ColorHighLight = clBtnShadow - ColorShadow = clBtnShadow - Caption = 'Connect' - TabOrder = 3 - OnClick = cmdConnectClick - end - object pnlDirectory: TPanel - Left = 44 - Top = 162 - Width = 367 - Height = 83 - BevelOuter = bvLowered - TabOrder = 2 - object trvDirectories: TTreeView - Left = 1 - Top = 1 - Width = 365 - Height = 81 - Align = alClient - BorderStyle = bsNone - Images = ilImages - Indent = 19 - TabOrder = 0 - OnChange = trvDirectoriesChange - OnCollapsing = trvDirectoriesCollapsing - OnExpanding = trvDirectoriesExpanding - OnExpanded = trvDirectoriesExpanded - OnMouseDown = trvDirectoriesMouseDown - end - end - object pnlOS: TPanel - Left = 44 - Top = 268 - Width = 441 - Height = 21 - BevelOuter = bvLowered - TabOrder = 4 - object optWindows: TFlatRadioButton - Left = 1 - Top = 3 - Width = 62 - Height = 14 - Caption = 'Windows' - Checked = True - TabOrder = 0 - TabStop = True - end - object optLinux: TFlatRadioButton - Left = 173 - Top = 3 - Width = 82 - Height = 14 - Caption = 'Linux (32-bit)' - TabOrder = 1 - end - object FlatRadioButton1: TFlatRadioButton - Left = 353 - Top = 3 - Width = 82 - Height = 14 - Caption = 'Linux (64-bit)' - Enabled = False - TabOrder = 2 - end - end - end - object jspInstallProgress: TJvStandardPage - Left = 0 - Top = 0 - Width = 527 - Height = 314 - Caption = 'jspInstallProgress' - object ggeAll: TFlatGauge - Left = 8 - Top = 84 - Width = 509 - Height = 24 - AdvColorBorder = 0 - Color = clBtnFace - ColorBorder = 8623776 - MaxValue = 8 - Progress = 0 - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentColor = False - ParentFont = False - end - object lblProgress: TLabel - Left = 8 - Top = 66 - Width = 46 - Height = 13 - Caption = 'Progress:' - end - object ggeItem: TFlatGauge - Left = 8 - Top = 112 - Width = 509 - Height = 24 - AdvColorBorder = 0 - Color = clBtnFace - ColorBorder = 8623776 - Progress = 0 - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentColor = False - ParentFont = False - end - object lblDetails: TLabel - Left = 10 - Top = 152 - Width = 36 - Height = 13 - Caption = 'Details:' - end - object bvlSpace2: TBevel - Left = 4 - Top = 142 - Width = 519 - Height = 3 - Shape = bsTopLine - end - object pnlHeader5: TPanel - Left = 0 - Top = 0 - Width = 527 - Height = 49 - Align = alTop - BevelOuter = bvNone - Color = clWhite - TabOrder = 0 - object imgIcon4: TImage - Left = 486 - Top = 8 - Width = 32 - Height = 32 - AutoSize = True - Picture.Data = { - 0A54504E474F626A65637489504E470D0A1A0A0000000D494844520000002000 - 0000200806000000737A7AF40000000467414D410000AFC837058AE900000019 - 74455874536F6674776172650041646F626520496D616765526561647971C965 - 3C000008ED4944415478DAD556096C54D7153D7FE6CFFC59BC321EE3F1162F60 - 833DB6C10B019C60410007D43649518480B64924BAD0D00401A58AD456EA42A4 - 268A4848216D43054A55910588484A020D2EE09D181BDB78C106DB638FEDB1F1 - 18DBE3F12C7FFED2FBBFC1402090B46AAB3EE96966DEBCE5DC7BCF3DF732AB57 - 3F8EFFE6D06AB5686C6C80CBE5527F33FF8F00CC34B9AF7340969529836120B1 - 2C3BDED07001C3C3C35F19004B7339CDB5744911DD9328430E67C02817D264EE - 7B58926408A20893914320C08B3A1DDBD9D3D3BDB7B3B3E3FDAF02600341DF29 - 8872BE286BC1EA39707AFA6419D5A2202F83E74380C883D5021A0D73D7E346A3 - 1E3F78E69B489D930247B71307DEF9580182CB97DBB7381C3D7FF832007134F7 - 0BA2F494ACE1101F6B4656BC0F732CE3B09A791875324472ABC7CF6060C288F6 - E128740C6AE1F54E41AF9566BC120886B0A2380BDF5B5F8ADFED3B8A977EB20E - 474FD4E2A393B5049819AFACACB0DF0B400645EC3819362F26D68255760F8A13 - 5D88B725C2146B87C69C044617465B44C8C1318426AEC0E36A419B730A7FBFFA - 102E748A80E023B269542F994D9C1227F294803FEEDE80831F36A0ACBC590D49 - 7D7DDDFA2F02502C3FC70B4CC6FC0C2B36E5B6213BD10073E626B0519960345A - C892A0D00A924C618086EE26DF0B531086CEC1DD7E0CA77A5270AC2E0281A949 - C54A8ABF043E24E1575B164267B6E2B7FBCB2189210A234B002E6CBE1D8086E6 - DFC8F235F6F9B3F1C385E7911C1B0EA3FD456828759A1D22AE793420C354F215 - A6F230734A9C152611109D19D24407BC4D7B503698834395B3C0FB271122BC1B - 4B6D5856908C1D7B9BE0A330190D3A088218AAAAAA58C19496AE515D45F35951 - 940FC6C55BB1BDA41369BA361873B781E1ACD02288CFDA67C1311E01032B4224 - 721526B8919B14002FDE229E863523D47F0ABEDE933836B00A7F39A34141860E - AF6F5F884FEAFCE8EC19414B970703435E0C0D0D5636355D5CCBE4E717107B35 - E6A8A8E866B0E6B4CDAB24AC8CFA94DC351BBAF4F58A79D03012DA5D61180B18 - 31EC35C0E531C0C28DE3E9FC6BE40D8AF50C021DE4C93EF08E0F302E5AF04A4D - 31A6A6043C5A10A7440D1CC7A2B27114DDCE71345EACFBB1DBED7E8BD1EBF588 - 8B8B5B3F37D3FE6E669A053B1757221A2E30FA30B0B615605813794702AB91C1 - E944B40E46E2484B32B990C7A6050EA4C70AAA17981B00C4894E88A3F5F4A084 - F29102BC713A1641BF173733D4C8E9303939DE535B5B53425E77AACB0B16E4BF - 1F13F7D0D31B96C978D2F6992A9732B15C634E80262243BD4C3141A79531E4D1 - 615F7506A67816453627BEF3F02802218DCA03884188D79B2841FCAAFC8DF251 - 78B972097A9C93D0B1D308585687E6E6C657FBFB9DBB542122361A962C296E8B - B6C6A5EE5CD98B1C632318AD7EDAADF4B0C6685179408B30E9451CA88C468533 - 0D0612244E1EC32F4ABB1161A444080520FB06200B816952D2F11089C581D665 - 38D940DE632525D42442018F42BE502854AF02309BCDC9458B96B627265A4D2F - 9534205ED74BABBADB845C525D6B301AD03164C42F4FCE87DE14AD7A64CA17C2 - F78B9AF18D6C377D0F4E8BBEE2094C678A4CE9F651DF221CAC88849EE1A1D3E9 - 70F5EA950F3A3A2E6FA42D82BA2F2C2C2CBBA070496366BA95DDB5B41A167644 - B5F6F6A1643C47ECFFD9311BCE0F6722D512443817428B2B02B931DD78EDDB0E - 08127B8B8CEA1905630865AE3CEC3F1307AD1C5016C4EAEAAA755EAFF7F8CC3E - 05402101C8488FB901C07D1700935E467927879F7F9A05D61085AD4BDB616405 - BC7ACE0E569AC09E275A30CF16425060EE02F00F572EF69DB141AF1194D43B7F - F162C36AFAC733B38F42904221684D4A8CA110D4C3A673DE118269F64AD8FA5E - 323A3D69C8B47AF1C6130D18F3EBF1E2F185182652AEB7B7E285E56E7883B780 - DF0CC1C7BD853848BC51F4A3AEEEFC0B947A6FDEE15D62BC69C9D2475A2DD6B8 - 949D8F75C16E6EA130EA67DC19669070B4DE88D7CA73603499F0D3925694660C - 931831D85D361FA7AFC623DE3088031B3A10499D829F57C8379D968A0CFFB9B5 - 18279BF4084E5DEFABA9A95652CF716778D5345C782CC696FAD4A64702F856FC - 594AC3E9782AB2EB0BCAF8D1BBE918E293B138D98DDF3CDEA23EAE5854E9B010 - 885C88C4FC67165CC2D098041BF173D3121EFEA084EB41135EAE5A8ADE411E1D - 979BF7F4F5F56DFF62E55301D86CF1DFCDCEC97F675E6A38763C5C812876420D - 8362FD818A701C6AB0233A9CC5AF57372327DE4379AF55C185A8F0ED3A9107E7 - 7818BC93E3F0F21C526679F1F6C6AB30698328776560EFD964F0BE715F7575E5 - 63C160B0F69E00480BA2480B9A4C1131C99B974F6265ECE7249B7A38DC1A3C7F - 641E021A1B9ECCEEC3B647AFC02F686F1E839974E17063320E5D9843592223DA - 2460EE2C379E2BEC22D594F14A55212E39240C3ABB4EB4B5B5AEA323C17B0250 - 466242E2D6ACECBC3767CF8EC08E920E6484F7E3D250241A5C5698382D4A5287 - 610DE311923433C754659C34128054E42578A8405D872D22A0880D8E74CCC3E1 - 9A704A046FB0A6A66A9DCFE73B817B8C1900D4C57054984E455BE24BEC734CD8 - B2A81D49E113D4824D133240960B92A270CCF42995E6D37D2129377542B21A92 - 50C087B37D09F853790C756A3CDADA2EBDD5D7D7BB8D4EF0F705A00C83C19051 - 54B4E834678C4A9A9F66C2B3454ECC891CA5326B80ACD1DDD87E03C08DEF37B1 - 2875C017E471BA2B0E876B23C0533BD6EFEC296B6D6D798EFE75E24BC65D2D2D - E9C262F2C47B9C3132D932CB88B5797E14278F20C6A474315AA57ADC925BF28D - D221F979115D6E033EA19EA1B6430B860468A0BFF72C3DFE3CA55D1BEE33EED9 - 53731C97939565FFBD35366E9944D9906065919714C2DCD800628907D4D0A81D - AF27C0A07F5C8F9601035AFBB5540F04305250E8EABAF2576ABD77D35557F080 - 71BFA63ED266B36D494949DB6C0E8B4C97C972C5039C9E514BAB4C0002216ACB - 69529347BF7969D47DEDF3EEEEAEB73D1ECF87747EEC418F3F08C04D72A6582C - 96353131D695111111597ABDC14A65D500E55951F005027ED7D8D858D3C8C8B5 - B2C9C9C9725AEF03EEA84BFF1E80DB23433396A47B360130290BA2284E499244 - E51354C1E0FB1A77FD4B00FE23E37F0EE09F19A8E321D9E34DB9000000004945 - 4E44AE426082} - Transparent = True - end - object lblTitle5: TLabel - Left = 12 - Top = 8 - Width = 223 - Height = 14 - Caption = 'Installing Metamod:Source (version)' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -12 - Font.Name = 'Tahoma' - Font.Style = [fsBold] - ParentFont = False - end - object lblSubTitle5: TLabel - Left = 22 - Top = 28 - Width = 296 - Height = 13 - Caption = 'Please wait while Metamod:Source (version) is being installed.' - end - object bvlSpacer5: TBevel - Left = 0 - Top = 46 - Width = 527 - Height = 3 - Align = alBottom - Shape = bsBottomLine - end - end - object rtfDetails: TmxFlatRichEdit - Left = 8 - Top = 166 - Width = 509 - Height = 139 - ReadOnly = True - ScrollBars = ssVertical - TabOrder = 1 - Activate = True - BorderColor = clBtnShadow - Flat = True - ShowBorder = True - Version = '1.26' - end - end - end - object pnlButtons: TPanel - Left = 0 - Top = 317 - Width = 527 - Height = 38 - Align = alBottom - BevelOuter = bvNone - TabOrder = 1 - object cmdNext: TFlatButton - Left = 438 - Top = 7 - Width = 85 - Height = 25 - ColorFocused = 16245198 - ColorDown = 16245198 - ColorBorder = clBtnShadow - ColorHighLight = clBtnShadow - ColorShadow = clBtnShadow - Caption = '&Next >' - TabOrder = 0 - OnClick = cmdNextClick - end - object cmdCancel: TFlatButton - Left = 4 - Top = 7 - Width = 85 - Height = 25 - Color = clBtnFace - ColorFocused = 16245198 - ColorDown = 16245198 - ColorBorder = clBtnShadow - ColorHighLight = clBtnShadow - ColorShadow = clBtnShadow - Caption = '&Cancel' - ParentColor = False - TabOrder = 1 - OnClick = cmdCancelClick - end - object cmdBack: TFlatButton - Left = 348 - Top = 7 - Width = 85 - Height = 25 - ColorFocused = 16245198 - ColorDown = 16245198 - ColorBorder = clBtnShadow - ColorHighLight = clBtnShadow - ColorShadow = clBtnShadow - Caption = '< &Back' - TabOrder = 2 - Visible = False - OnClick = cmdBackClick - end - end - object ilImages: TImageList - Left = 154 - Top = 324 - Bitmap = { - 494C010102000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 - 0000000000003600000028000000400000001000000001002000000000000010 - 00000000000000000000000000000000000000000000008CBD00008CBD00008C - BD00008CBD00008CBD00008CBD00008CBD00008CBD00008CBD00008CBD00008C - BD00008CBD00008CBD00000000000000000000000000008CBD00008CBD00008C - BD00008CBD00008CBD00008CBD00008CBD00008CBD00008CBD00008CBD00008C - BD00008CBD000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD0063CEF700008CBD00A5F7 - FF0063CEF70063CEF70063CEF70063CEF70063CEF70063CEF70063CEF70063CE - F70039ADDE00ADF7FF00008CBD0000000000008CBD0021A5CE005ACEEF0084E7 - FF0063CEF70063CEF70063CEF70063CEF70063CEF70063CEF70063CEF70063CE - F70039ADDE001094C60000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD006BD6F700008CBD00ADF7 - FF006BD6FF006BD6FF006BD6FF006BD6FF006BD6FF006BD6FF006BD6FF006BD6 - FF0039ADDE00BDEFF700008CBD0000000000008CBD004ABDE70031ADD60094EF - FF006BD6FF006BD6FF006BD6FF006BD6FF006BD6FF006BD6FF006BD6FF006BD6 - FF0039B5DE00CEF7FF00008CBD00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD0073D6FF00008CBD00ADF7 - FF007BDEFF007BDEFF007BDEFF007BDEFF007BDEFF007BDEFF007BDEFF007BDE - FF0042B5DE00BDEFF700008CBD0000000000008CBD0073D6FF00008CBD00ADFF - FF007BDEFF007BDEFF007BDEFF007BDEFF007BDEFF007BDEFF007BDEFF007BDE - FF0042B5DE00CEF7FF00008CBD00000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD007BDEFF00008CBD00B5F7 - FF0084E7FF0084E7FF0084E7FF0084E7FF0084E7FF0084E7FF0084E7FF0084E7 - FF0042B5DE00C6F7F700008CBD0000000000008CBD007BDEFF001094C60094EF - FF0094EFFF0084E7FF0084E7FF0084E7FF0084E7FF0084E7FF0084E7FF0084E7 - FF004ABDE700CEF7FF001094C600000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD0084E7FF00008CBD00BDF7 - FF008CEFFF008CEFFF008CEFFF008CEFFF008CEFFF008CEFFF008CEFFF008CEF - FF004ABDE700BDF7FF00008CBD0000000000008CBD0084E7FF0042B5DE005AC6 - EF00ADFFFF008CEFFF008CEFFF008CEFFF008CEFFF008CEFFF008CEFFF008CEF - FF004ABDE700CEF7FF00CEF7FF00008CBD000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD008CEFFF00008CBD00D6F7 - FF00CEF7FF00CEF7FF00CEF7FF00CEF7FF00CEF7FF00CEF7FF00CEF7FF00CEF7 - FF00BDDEDE00D6F7FF00008CBD0000000000008CBD008CE7FF007BDEFF0021A5 - CE00E7FFFF00CEF7FF00CEF7FF00CEF7FF00CEF7FF00CEF7FF00CEF7FF00CEF7 - FF0094EFFF00E7FFFF00CEF7FF00008CBD000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD0094F7FF00008CBD00008C - BD00008CBD00008CBD00008CBD00008CBD00008CBD00008CBD00008CBD00008C - BD00008CBD00008CBD00008CBD0000000000008CBD0094F7FF0094F7FF001094 - C600008CBD00008CBD00008CBD00008CBD00008CBD00008CBD00008CBD00008C - BD00008CBD00008CBD00008CBD00008CBD000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD009CF7FF009CF7FF009CF7 - FF009CF7FF009CF7FF009CF7FF009CF7FF009CF7FF009CF7FF009CF7FF009CF7 - FF00008CBD00000000000000000000000000008CBD009CF7FF009CF7FF009CF7 - FF009CF7FF009CF7FF009CF7FF009CF7FF009CF7FF009CF7FF009CF7FF009CF7 - FF00088CBD000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000008CBD00D6F7FF00A5F7FF00A5F7 - FF00A5F7FF00A5F7FF00A5F7FF00A5F7FF00A5F7FF00A5F7FF00A5F7FF00A5F7 - FF00008CBD00000000000000000000000000008CBD00E7FFFF00A5FFFF00A5FF - FF00A5FFFF00A5FFFF00A5FFFF00A5FFFF00A5FFFF00A5FFFF00A5FFFF00A5FF - FF00088CBD000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000008CBD00D6F7FF00A5F7 - FF00A5F7FF00A5F7FF00008CBD00008CBD00008CBD00008CBD00008CBD00008C - BD000000000000000000000000000000000000000000008CBD00E7FFFF00A5FF - FF00A5FFFF00A5FFFF00008CBD00008CBD00008CBD00008CBD00008CBD00008C - BD00000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008CBD00008C - BD00008CBD00008CBD0000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000008CBD00008C - BD00008CBD00008CBD0000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000424D3E000000000000003E000000 - 2800000040000000100000000100010000000000800000000000000000000000 - 000000000000000000000000FFFFFF0080038007000000000001000300000000 - 0001000100000000000100010000000000010001000000000001000000000000 - 0001000000000000000100000000000000070007000000000007000700000000 - 800F800F00000000C3FFC3FF00000000FFFFFFFF00000000FFFFFFFF00000000 - FFFFFFFF00000000FFFFFFFF0000000000000000000000000000000000000000 - 000000000000} - end - object IdFTP: TIdFTP - Intercept = IdLogFile - MaxLineAction = maException - ReadTimeout = 0 - RecvBufferSize = 1024 - SendBufferSize = 1024 - OnWork = IdFTPWork - ProxySettings.ProxyType = fpcmNone - ProxySettings.Port = 0 - Left = 274 - Top = 324 - end - object IdAntiFreeze: TIdAntiFreeze - IdleTimeOut = 150 - Left = 244 - Top = 324 - end - object tmrSpeed: TTimer - Enabled = False - OnTimer = tmrSpeedTimer - Left = 214 - Top = 324 - end - object IdLogFile: TIdLogFile - LogTime = False - Left = 184 - Top = 324 - end -end diff --git a/installer/UnitfrmMain.pas b/installer/UnitfrmMain.pas deleted file mode 100644 index e335bc5..0000000 --- a/installer/UnitfrmMain.pas +++ /dev/null @@ -1,804 +0,0 @@ -unit UnitfrmMain; - -interface - -uses - Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, TFlatRadioButtonUnit, StdCtrls, ComCtrls, mxFlatControls, JvPageList, - ExtCtrls, JvExControls, JvComponent, TFlatButtonUnit, jpeg, TFlatEditUnit, - TFlatGaugeUnit, ImgList, FileCtrl, Registry, CheckLst, TFlatComboBoxUnit, - TFlatCheckBoxUnit, IdBaseComponent, IdComponent, IdTCPConnection, - IdTCPClient, IdFTP, IdException, IdAntiFreezeBase, IdAntiFreeze, - IdIntercept, IdLogBase, IdLogFile, pngimage; - -type - TfrmMain = class(TForm) - jplWizard: TJvPageList; - jspWelcome: TJvStandardPage; - pnlButtons: TPanel; - bvlSpace: TBevel; - cmdNext: TFlatButton; - cmdCancel: TFlatButton; - imgInstall: TImage; - lblWelcome: TLabel; - lblInfo1: TLabel; - lblInfo2: TLabel; - lblInfo3: TLabel; - jspLicense: TJvStandardPage; - pnlLicense: TPanel; - imgIcon1: TImage; - lblTitle1: TLabel; - lblSubTitle1: TLabel; - freLicense: TmxFlatRichEdit; - frbAgree: TFlatRadioButton; - ftbDontAgree: TFlatRadioButton; - jspInstallMethod: TJvStandardPage; - pnlHeader2: TPanel; - imgIcon2: TImage; - lblTitle2: TLabel; - lblSubTitle2: TLabel; - lblInstallMethod: TLabel; - pnlInstallMethod: TPanel; - frbDedicatedServer: TFlatRadioButton; - frbListenServer: TFlatRadioButton; - frbSelectMod: TFlatRadioButton; - frbFTP: TFlatRadioButton; - cmdBack: TFlatButton; - jspFTP: TJvStandardPage; - pnlHeader3: TPanel; - imgIcon3: TImage; - lblTitle3: TLabel; - lblSubTitle3: TLabel; - lblStep1: TLabel; - pnlFTPData: TPanel; - lblHost: TLabel; - txtHost: TFlatEdit; - lblUserName: TLabel; - txtUserName: TFlatEdit; - txtPassword: TFlatEdit; - lblPassword: TLabel; - txtPort: TFlatEdit; - lblPort: TLabel; - lblStep2: TLabel; - cmdConnect: TFlatButton; - pnlDirectory: TPanel; - trvDirectories: TTreeView; - lblStep4: TLabel; - jspInstallProgress: TJvStandardPage; - pnlHeader5: TPanel; - imgIcon4: TImage; - lblTitle5: TLabel; - lblSubTitle5: TLabel; - ggeAll: TFlatGauge; - lblProgress: TLabel; - ggeItem: TFlatGauge; - rtfDetails: TmxFlatRichEdit; - lblDetails: TLabel; - bvlSpace2: TBevel; - ilImages: TImageList; - bvlSpacer1: TBevel; - bvlSpacer2: TBevel; - bvlSpacer3: TBevel; - bvlSpacer5: TBevel; - jspSelectMod: TJvStandardPage; - pnlSelectMod: TPanel; - imgIcon5: TImage; - lblSelectMod: TLabel; - lblSelectModInfo: TLabel; - bvlSelectMod: TBevel; - lblInfo: TLabel; - chkPassive: TFlatCheckBox; - lblStep3: TLabel; - pnlOS: TPanel; - optWindows: TFlatRadioButton; - optLinux: TFlatRadioButton; - IdFTP: TIdFTP; - cmdProxySettings: TFlatButton; - IdAntiFreeze: TIdAntiFreeze; - frbStandaloneServer: TFlatRadioButton; - tmrSpeed: TTimer; - IdLogFile: TIdLogFile; - shpMods: TShape; - trvMods: TTreeView; - FlatRadioButton1: TFlatRadioButton; - procedure jvwStepsCancelButtonClick(Sender: TObject); - procedure cmdCancelClick(Sender: TObject); - procedure cmdNextClick(Sender: TObject); - procedure CheckNext(Sender: TObject); - procedure cmdBackClick(Sender: TObject); - procedure cmdConnectClick(Sender: TObject); - procedure jplWizardChange(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure cmdProxySettingsClick(Sender: TObject); - procedure txtPortChange(Sender: TObject); - procedure trvDirectoriesExpanded(Sender: TObject; Node: TTreeNode); - procedure trvDirectoriesChange(Sender: TObject; Node: TTreeNode); - procedure IdFTPWork(Sender: TObject; AWorkMode: TWorkMode; - const AWorkCount: Integer); - procedure FormClose(Sender: TObject; var Action: TCloseAction); - procedure tmrSpeedTimer(Sender: TObject); - procedure trvDirectoriesExpanding(Sender: TObject; Node: TTreeNode; - var AllowExpansion: Boolean); - procedure trvDirectoriesCollapsing(Sender: TObject; Node: TTreeNode; - var AllowCollapse: Boolean); - procedure trvModsClick(Sender: TObject); - procedure trvDirectoriesMouseDown(Sender: TObject; - Button: TMouseButton; Shift: TShiftState; X, Y: Integer); - private - OldProgress: Integer; - CurrProgress: Integer; - public - procedure ExceptionHandler(Sender: TObject; E: Exception); - end; - -var - frmMain: TfrmMain; - -var VERSION: String = ''; - -implementation - -uses UnitFunctions, UnitfrmProxy, UnitInstall, UnitSelectModPath; - -{$R *.dfm} - -procedure TfrmMain.jvwStepsCancelButtonClick(Sender: TObject); -begin - Close; -end; - -procedure TfrmMain.cmdCancelClick(Sender: TObject); -begin - Close; -end; - -procedure TfrmMain.cmdNextClick(Sender: TObject); -var ePath: String; - eRegistry: TRegistry; - eStr: TStringList; - CurNode: TTreeNode; - eOS: TOS; - i: integer; - Source: Boolean; -begin - { FTP } - if jplWizard.ActivePage = jspFTP then begin - if not IdFTP.Connected then - IdFTP.Connect; - eStr := TStringList.Create; - ePath := '/'; - CurNode := trvDirectories.Selected; - if (Assigned(CurNode)) then begin - repeat - ePath := '/' + CurNode.Text + ePath; - CurNode := CurNode.Parent; - until (not Assigned(CurNode)); - end; - IdFTP.ChangeDir(ePath); - IdFTP.List(eStr, '', False); - eStr.CaseSensitive := False; - // check if gameinfo.txt is in the directory -> valid installation - if (eStr.IndexOf('gameinfo.txt') = -1) then begin - MessageBox(Handle, 'Invalid directory. Please select your mod directory and try again.', PChar(Application.Title), MB_ICONWARNING); - eStr.Free; - exit; - end - else - eStr.Free; - // check for orangebox directory - Source := True; - if (AnsiSameText(ExtractFileName(trvDirectories.Selected.Text), 'tf')) then begin - case MessageBox(Handle, 'It looks like your server is using the OrangeBox engine. Would you like to install the appropriate binaries for it?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNOCANCEL) of - mrYes: Source := False; - mrNo: Source := True; - mrCancel: begin - eStr.Free; - exit; - end; - end; - end; - // design stuff - trvDirectories.Enabled := False; - cmdConnect.Enabled := False; - optWindows.Enabled := False; - optLinux.Enabled := False; - Screen.Cursor := crHourGlass; - - if optWindows.Checked then - eOS := osWindows - else - eOS := osLinux; - - jspInstallProgress.Show; - // installation - Screen.Cursor := crAppStart; - InstallFTP(eOS, Source); - end - else if jplWizard.ActivePage = jspInstallProgress then - Close - else if jplWizard.ActivePage = jspSelectMod then begin - { Dedicated Server } - if frbDedicatedServer.Checked then begin - Source := True; - ePath := trvMods.Selected.Text; - if ePath = 'Counter-Strike:Source' then - ePath := trvMods.Selected.Parent.Text + '\source dedicated server\cstrike' - else if ePath = 'Day of Defeat:Source' then - ePath := trvMods.Selected.Parent.Text + '\source dedicated server\dod' - else if ePath = 'Half-Life 2 Deathmatch' then - ePath := trvMods.Selected.Parent.Text + '\source dedicated server\hl2mp' - else begin - { get games } - if ePath = 'Team Fortress 2' then - ePath := trvMods.Selected.Parent.Text + '\source 2007 dedicated server\tf'; - { ask user, just in case } - case MessageBox(Handle, 'It looks like your server is using the OrangeBox engine. Would you like to install the appropriate binaries for it?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNOCANCEL) of - mrYes: Source := False; - mrNo: Source := True; - mrCancel: exit; - end; - end; - SteamPath := IncludeTrailingPathDelimiter(SteamPath) + 'steamapps\'; - // install it - if DirectoryExists(SteamPath + ePath) then begin - jspInstallProgress.Show; - InstallDedicated(IncludeTrailingPathDelimiter(SteamPath + ePath), True, Source); - end - else begin - MessageBox(Handle, 'Error: The directory of the mod you selected doesn''t exist any more. Run Dedicated Server with the chosen mod and try again.', PChar(Application.Title), MB_ICONERROR); - jspSelectMod.Show; - exit; - end; - end; - { Standalone Server } - if frbStandaloneServer.Checked then begin - Source := True; - ePath := trvMods.Selected.Text; - if ePath = 'Counter-Strike:Source' then - ePath := 'cstrike' - else if ePath = 'Day of Defeat:Source' then - ePath := 'dod' - else if ePath = 'Half-Life 2 Deathmatch' then - ePath := 'hl2mp' - else begin - { get games } - if ePath = 'Team Fortress 2' then - ePath := 'orangebox\tf'; - { ask user, just in case } - case MessageBox(Handle, 'It looks like your server is using the OrangeBox engine. Would you like to install the appropriate binaries for it?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNOCANCEL) of - mrYes: Source := False; - mrNo: Source := True; - mrCancel: exit; - end; - end; - // install it - if DirectoryExists(StandaloneServer + ePath) then begin - jspInstallProgress.Show; - InstallDedicated(IncludeTrailingPathDelimiter(StandaloneServer + ePath), False, Source) - end - else begin - MessageBox(Handle, 'Error: The directory of the mod you selected doesn''t exist (any more). Run Half-Life Dedicated Server with the chosen mod again and restart.', PChar(Application.Title), MB_ICONERROR); - jspSelectMod.Show; - exit; - end; - end; - { Listen Server } - if frbListenServer.Checked then begin - Source := True; - ePath := trvMods.Selected.Text; - if ePath = 'Counter-Strike:Source' then - ePath := SteamPath + 'SteamApps\' + trvMods.Selected.Parent.Text + '\counter-strike source\cstrike' - else if ePath = 'Half-Life 2 Deathmatch' then - ePath := SteamPath + 'SteamApps\' + trvMods.Selected.Parent.Text + '\half-life 2 deathmatch\hl2mp' - else if ePath = 'Day of Defeat:Source' then - ePath := SteamPath + 'SteamApps\' + trvMods.Selected.Parent.Text + '\day of defeat source\dod' - else begin - { get games } - if ePath = 'Team Fortress 2' then - ePath := SteamPath + 'SteamApps\' + trvMods.Selected.Parent.Text + '\team fortress 2\tf'; - { ask user, just in case } - case MessageBox(Handle, 'It looks like your server is using the OrangeBox engine. Would you like to install the appropriate binaries for it?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNOCANCEL) of - mrYes: Source := False; - mrNo: Source := True; - mrCancel: exit; - end; - end; - - if Pos(SteamPath, ePath) = 0 then - MessageBox(Handle, 'An error occured. Please report this bug to the Metamod:Source team and post a new thread on the forums of www.amxmodx.org.', PChar(Application.Title), MB_ICONSTOP) - else begin - if not FileExists(ePath + '\gameinfo.txt') then begin - MessageBox(Handle, 'You have to play this game once before installing Metamod:Source. Do that and try again.', PChar(Application.Title), MB_ICONWARNING); - exit; - end; - - jspInstallProgress.Show; - InstallListen(IncludeTrailingPathDelimiter(ePath), Source); - end; - end; - { Custom mod below } - end - else if jplWizard.ActivePage <> jspInstallMethod then - jplWizard.NextPage - else begin - if frbDedicatedServer.Checked then begin // Dedicated Server - eRegistry := TRegistry.Create(KEY_READ); - try - eRegistry.RootKey := HKEY_CURRENT_USER; - if eRegistry.OpenKey('Software\Valve\Steam', False) then begin - ePath := eRegistry.ReadString('SteamPath'); - ePath := IncludeTrailingPathDelimiter(StringReplace(ePath, '/', '\', [rfReplaceAll])); - SteamPath := ePath; - - ePath := ePath + 'SteamApps\'; - if DirectoryExists(ePath) then begin - trvMods.Items.Clear; - // Check Mods - eStr := GetAllFiles(ePath + '*.*', faDirectory, False, True, False); - for i := 0 to eStr.Count -1 do begin - CurNode := trvMods.Items.Add(nil, eStr[i]); - - if DirectoryExists(ePath + eStr[i] + '\source dedicated server\cstrike') then - trvMods.Items.AddChild(CurNode, 'Counter-Strike:Source'); - if DirectoryExists(ePath + eStr[i] + '\source dedicated server\dod') then - trvMods.Items.AddChild(CurNode, 'Day of Defeat:Source'); - if DirectoryExists(ePath + eStr[i] + '\source dedicated server\hl2mp') then - trvMods.Items.AddChild(CurNode, 'Half-Life 2 Deatmatch'); - if DirectoryExists(ePath + eStr[i] + '\source 2007 dedicated server\tf') then - trvMods.Items.AddChild(CurNode, 'Team Fortress 2'); - - if CurNode.Count = 0 then - CurNode.Free - else - CurNode.Expand(False); - end; - // Misc - jspSelectMod.Show; - trvMods.Selected := nil; - cmdNext.Enabled := False; - end - else - MessageBox(Handle, 'You have to run Dedicated Server once before installing Metamod:Source!', 'Error', MB_ICONWARNING); - end - else - MessageBox(Handle, 'You haven''t installed Steam yet! Download it at www.steampowered.com, install Dedicated Server and try again.', 'Error', MB_ICONWARNING); - finally - eRegistry.Free; - end; - end - else if frbListenServer.Checked then begin // Listen Server - eRegistry := TRegistry.Create(KEY_READ); - try - eRegistry.RootKey := HKEY_CURRENT_USER; - if eRegistry.OpenKey('Software\Valve\Steam', False) then begin - ePath := eRegistry.ReadString('SteamPath'); - ePath := IncludeTrailingPathDelimiter(StringReplace(ePath, '/', '\', [rfReplaceAll])); - SteamPath := ePath; - - ePath := ePath + 'SteamApps\'; - if DirectoryExists(ePath) then begin - trvMods.Items.Clear; - // Check Mods - eStr := GetAllFiles(ePath + '*.*', faDirectory, False, True, False); - for i := 0 to eStr.Count -1 do begin - CurNode := trvMods.Items.Add(nil, eStr[i]); - - if DirectoryExists(ePath + eStr[i] + '\counter-strike source') then - trvMods.Items.AddChild(CurNode, 'Counter-Strike:Source'); - if DirectoryExists(ePath + eStr[i] + '\day of defeat source') then - trvMods.Items.AddChild(CurNode, 'Day of Defeat:Source'); - if DirectoryExists(ePath + eStr[i] + '\half-life 2 deathmatch') then - trvMods.Items.AddChild(CurNode, 'Half-Life 2 Deatmatch'); - if DirectoryExists(ePath + eStr[i] + '\team fortress 2') then - trvMods.Items.AddChild(CurNode, 'Team Fortress 2'); - - if CurNode.Count = 0 then - CurNode.Free - else - CurNode.Expand(False); - end; - // Misc - jspSelectMod.Show; - trvMods.Selected := nil; - cmdNext.Enabled := False; - end - else - MessageBox(Handle, 'You haven''t installed Steam yet! Download it at www.steampowered.com, install Dedicated Server and try again.', 'Error', MB_ICONWARNING); - end - else - MessageBox(Handle, 'You haven''t installed Steam yet! Download it at www.steampowered.com, install Dedicated Server and try again.', 'Error', MB_ICONWARNING); - finally - eRegistry.Free; - end; - end - else if frbStandaloneServer.Checked then begin // Standalone Server - eRegistry := TRegistry.Create; - try - eRegistry.RootKey := HKEY_CURRENT_USER; - if eRegistry.OpenKey('Software\Valve\HLServer', False) then begin - StandaloneServer := IncludeTrailingPathDelimiter(eRegistry.ReadString('InstallPath')); - if DirectoryExists(StandaloneServer + 'cstrike') then - trvMods.Items.Add(nil, 'Counter-Strike:Source'); - if DirectoryExists(StandaloneServer + 'dod') then - trvMods.Items.Add(nil, 'Day of Defeat:Source'); - if DirectoryExists(StandaloneServer + 'hl2mp') then - trvMods.Items.Add(nil, 'Half-Life 2 Deatmatch'); - if DirectoryExists(StandaloneServer + 'orangebox\tf') then - trvMods.Items.Add(nil, 'Team Fortress 2'); - jspSelectMod.Show; - cmdNext.Enabled := False; - end - else - MessageBox(Handle, 'You haven''t installed Half-Life Dedicated Server yet!', 'Error', MB_ICONWARNING); - finally - eRegistry.Free; - end; - end - else if frbSelectMod.Checked then begin - { Custom mod } - if frmSelectModPath.ShowModal = mrOk then begin - ePath := frmSelectModPath.trvDirectory.SelectedFolder.PathName; - { check if this is an orangebox game } - Source := True; - if (AnsiSameText(ExtractFileName(ePath), 'tf')) then begin - case MessageBox(Handle, 'It looks like your server is using the OrangeBox engine. Would you like to install the appropriate binaries for it?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNOCANCEL) of - mrYes: Source := False; - mrNo: Source := True; - mrCancel: exit; - end; - end; - { install now } - jspInstallProgress.Show; - InstallCustom(IncludeTrailingPathDelimiter(ePath), osWindows, Source); - end; - end - else if frbFTP.Checked then // FTP - jspFTP.Show; - end; -end; - -procedure TfrmMain.CheckNext(Sender: TObject); -begin - cmdNext.Enabled := frbAgree.Checked; -end; - -procedure TfrmMain.cmdBackClick(Sender: TObject); -begin - if jplWizard.ActivePage = jspFTP then - jspInstallMethod.Show - else begin - jplWizard.PrevPage; - cmdBack.Visible := jplWizard.ActivePageIndex <> 0; - end; -end; - -procedure TfrmMain.cmdConnectClick(Sender: TObject); -var i: integer; - eStr: TStringList; - CurNode: TTreeNode; - Path: String; -begin - if (Trim(txtHost.Text) = '') or (Trim(txtUsername.Text) = '') then - MessageBox(Handle, 'Please fill in each field!', PChar(Application.Title), MB_ICONWARNING) - else if cmdConnect.Caption = 'Connect' then begin - // ... design stuff ... - Screen.Cursor := crHourGlass; - cmdConnect.Enabled := False; - cmdProxySettings.Enabled := False; - txtHost.Enabled := False; - txtPort.Enabled := False; - txtUsername.Enabled := False; - txtPassword.Enabled := False; - chkPassive.Enabled := False; - cmdConnect.Caption := 'Connecting...'; - // ... set values ... - IdFTP.Host := txtHost.Text; - IdFTP.Port := StrToInt(txtPort.Text); - IdFTP.Username := txtUsername.Text; - IdFTP.Passive := chkPassive.Checked; - IdFTP.Password := txtPassword.Text; - // ... connect and check values etc ... - try - IdFTP.Connect(True, 15000); - // ... get initial directory ... - Path := IdFTP.RetrieveCurrentDir; - // ... "fix" path ... - eStr := TStringList.Create; - eStr.Text := StringReplace(Path, '/', #13, [rfReplaceAll]); - for i := eStr.Count -1 downto 0 do begin - if eStr[i] = '' then - eStr.Delete(i); - end; - if (Copy(Path, Length(Path) -1, 1) <> '/') then - Path := Path + '/'; - // ... connect successful, change captions ... - trvDirectories.Enabled := True; - cmdConnect.Enabled := True; - cmdConnect.Caption := 'Disconnect'; - // ... change to / and create all the directories ... - CurNode := nil; - if (Path <> '/') then begin - try - IdFTP.ChangeDir('/'); - with GetAllDirs do begin - for i := 0 to Count -1 do begin - if (Assigned(CurNode)) then - trvDirectories.Items.AddChild(trvDirectories.Items.Add(nil, Strings[i]), 'Scanning...') - else begin - CurNode := trvDirectories.Items.Add(nil, Strings[i]); - trvDirectories.Items.AddChild(CurNode, 'Scanning...'); - if (Pos('/' + CurNode.Text + '/', Path) = 0) then - CurNode := nil; - end - end; - Free; - end; - IdFTP.ChangeDir(Path); - except - if (IdFTP.Connected) then - IdFTP.ChangeDir(Path) - else - IdFTP.Connect; - end; - end; - // ... find directories in start path ... - if eStr.Count <> 0 then begin - for i := 0 to eStr.Count -1 do begin - if (not ((i = 0) and (Assigned(CurNode)))) then - CurNode := trvDirectories.Items.AddChild(CurNode, eStr[i]); - end; - end; - trvDirectories.Selected := CurNode; - eStr.Free; - // ... scan for directories ... - with GetAllDirs do begin - for i := 0 to Count -1 do - trvDirectories.Items.AddChild(trvDirectories.Items.AddChild(CurNode, Strings[i]), 'Scanning...'); - Free; - end; - - if Assigned(CurNode) then - CurNode.Expand(False); - except - on E: Exception do begin - // reset button properties - cmdConnect.Enabled := True; - txtHost.Enabled := True; - txtPort.Enabled := True; - txtUsername.Enabled := True; - txtPassword.Enabled := True; - chkPassive.Enabled := True; - cmdProxySettings.Enabled := True; - cmdNext.Enabled := False; - cmdConnect.Caption := 'Connect'; - // analyze messages - if Pos('Login incorrect.', E.Message) <> 0 then begin // login failed - MessageBox(Handle, 'Login incorrect. Check your FTP settings and try again.', PChar(Application.Title), MB_ICONWARNING); - txtUsername.SetFocus; - txtUsername.SelectAll; - end - else if Pos('Host not found.', E.Message) <> 0 then begin // host not found - MessageBox(Handle, 'The entered host couldn''t be found. Check your settings and try again.', PChar(Application.Title), MB_ICONWARNING); - txtHost.SetFocus; - txtHost.SelectAll; - end - else if Pos('Connection refused.', E.Message) <> 0 then begin // wrong port (?) - MessageBox(Handle, 'The host refused the connection. Check your port and try again.', PChar(Application.Title), MB_ICONWARNING); - txtPort.SetFocus; - txtPort.SelectAll; - end - else if E is EIdProtocolReplyError then begin // wrong port - MessageBox(Handle, 'The port you entered is definitely wrong. Check it and try again.', PChar(Application.Title), MB_ICONWARNING); - txtPort.SetFocus; - txtPort.SelectAll; - end - else - MessageBox(Handle, PChar(E.Message), PChar(Application.Title), MB_ICONWARNING); // unknown error - // ... connect failed, leave procedure ... - Screen.Cursor := crDefault; - exit; - end; - end; - - Screen.Cursor := crDefault; - end - else begin - Screen.Cursor := crHourGlass; - IdFTP.Quit; - trvDirectories.Items.Clear; - trvDirectories.Enabled := False; - cmdConnect.Enabled := True; - cmdProxySettings.Enabled := True; - txtHost.Enabled := True; - txtPort.Enabled := True; - txtUsername.Enabled := True; - txtPassword.Enabled := True; - chkPassive.Enabled := True; - cmdConnect.Caption := 'Connect'; - cmdNext.Enabled := False; - Screen.Cursor := crDefault; - end; -end; - -procedure TfrmMain.jplWizardChange(Sender: TObject); -begin - if (jplWizard.ActivePage = jspInstallProgress) then begin - cmdNext.Caption := '&Finish'; - cmdNext.Enabled := False; - cmdBack.Visible := False; - end - else begin - cmdNext.Caption := '&Next >'; - cmdNext.Enabled := True; - cmdBack.Visible := jplWizard.ActivePageIndex <> 0; - end; - - if (jplWizard.ActivePage = jspLicense) then - cmdNext.Enabled := frbAgree.Checked; - - if (jplWizard.ActivePage = jspFTP) then - cmdNext.Enabled := False; -end; - -procedure TfrmMain.FormCreate(Sender: TObject); -begin - if LowerCase(ParamStr(1)) = '-logftp' then begin - MessageBox(Handle, 'FTP installation will be logged to FTP.log!', PChar(Application.Title), MB_ICONINFORMATION); - IdLogFile.Filename := ExtractFilePath(ParamStr(0)) + 'FTP.log'; - IdLogFile.Active := True; - end; - - rtfDetails.Clear; -end; - -procedure TfrmMain.cmdProxySettingsClick(Sender: TObject); -begin - frmProxy.ShowModal; - // Apply Proxy Settings - case frmProxy.cboProxy.ItemIndex of - 0: IdFTP.ProxySettings.ProxyType := fpcmNone; // none - 1: IdFTP.ProxySettings.ProxyType := fpcmHttpProxyWithFtp; // HTTP Proxy with FTP - 2: IdFTP.ProxySettings.ProxyType := fpcmOpen; // Open - 3: IdFTP.ProxySettings.ProxyType := fpcmSite; // Site - 4: IdFTP.ProxySettings.ProxyType := fpcmTransparent; // Transparent - 5: IdFTP.ProxySettings.ProxyType := fpcmUserPass; // User (Password) - 6: IdFTP.ProxySettings.ProxyType := fpcmUserSite; // User (Site) - end; - - IdFTP.ProxySettings.Host := frmProxy.txtHost.Text; - IdFTP.ProxySettings.UserName := frmProxy.txtPort.Text; - IdFTP.ProxySettings.Password := frmProxy.txtPassword.Text; - IdFTP.ProxySettings.Port := StrToInt(frmProxy.txtPort.Text); -end; - -procedure TfrmMain.txtPortChange(Sender: TObject); -var i: integer; -begin - if txtPort.Text = '' then - txtPort.Text := '21' - else begin - // check if value is numeric... - for i := Length(txtPort.Text) downto 1 do begin - if Pos(txtPort.Text[i], '0123456789') = 0 then begin - txtPort.Text := '21'; - txtPort.SelStart := 4; - exit; - end; - end; - end; -end; - -procedure TfrmMain.trvDirectoriesExpanded(Sender: TObject; - Node: TTreeNode); -var ePath: String; - CurNode: TTreeNode; - i: integer; -begin - if Node.Item[0].Text = 'Scanning...' then begin // no directories added yet - Screen.Cursor := crHourGlass; - // get complete path - ePath := '/'; - CurNode := Node; - repeat - ePath := '/' + CurNode.Text + ePath; - CurNode := CurNode.Parent; - until (not Assigned(CurNode)); - // change dir and add directories in it - try - Repaint; - IdFTP.ChangeDir(ePath); - with GetAllDirs do begin - Node.Item[0].Free; - for i := 0 to Count -1 do begin - trvDirectories.Items.AddChild(trvDirectories.Items.AddChild(Node, Strings[i]), 'Scanning...'); - end; - Free; - end; - finally - Application.ProcessMessages; - end; - Screen.Cursor := crDefault; - end; -end; - -procedure TfrmMain.trvDirectoriesChange(Sender: TObject; Node: TTreeNode); -begin - cmdNext.Enabled := Assigned(trvDirectories.Selected); -end; - -procedure TfrmMain.IdFTPWork(Sender: TObject; AWorkMode: TWorkMode; - const AWorkCount: Integer); -begin - if AWorkCount > 15 then begin - ggeItem.Progress := AWorkCount; - CurrProgress := AWorkCount; - end; - - if Cancel then - IdFTP.Abort; - - Application.ProcessMessages; -end; - -procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction); -begin - if (jplWizard.ActivePage = jspFTP) and (IdFTP.Connected) then - IdFTP.Quit; - if (jplWizard.ActivePage = jspInstallProgress) and (ggeAll.Progress <> ggeAll.MaxValue) and (not Cancel) then begin - if MessageBox(Handle, 'Do you really want to cancel the installation?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then begin - Screen.Cursor := crDefault; - Application.OnException := ExceptionHandler; - Cancel := True; - if IdFTP.Connected then - IdFTP.Quit; - end - else - Action := caNone; - end; -end; - -procedure TfrmMain.ExceptionHandler(Sender: TObject; E: Exception); -begin - // IF any exceptions were raised after close, nobody would want them so leave this empty -end; - -procedure TfrmMain.tmrSpeedTimer(Sender: TObject); -begin - Caption := CalcSpeed(OldProgress, CurrProgress); - OldProgress := CurrProgress; -end; - -procedure TfrmMain.trvDirectoriesExpanding(Sender: TObject; - Node: TTreeNode; var AllowExpansion: Boolean); -begin - Node.ImageIndex := 1; - Node.SelectedIndex := 1; -end; - -procedure TfrmMain.trvDirectoriesCollapsing(Sender: TObject; - Node: TTreeNode; var AllowCollapse: Boolean); -begin - Node.ImageIndex := 0; - Node.SelectedIndex := 0; -end; - -procedure TfrmMain.trvModsClick(Sender: TObject); -begin - if Assigned(trvMods.Selected) then - cmdNext.Enabled := Assigned(trvMods.Selected.Parent) - else - cmdNext.Enabled := False; -end; - -procedure TfrmMain.trvDirectoriesMouseDown(Sender: TObject; - Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -var Node: TTreeNode; -begin - Node := trvDirectories.GetNodeAt(X, Y); - if (Assigned(Node)) then begin - if (Node.DisplayRect(True).Right < X) then - trvDirectories.Selected := nil; - end; -end; - -end. diff --git a/installer/UnitfrmProxy.dfm b/installer/UnitfrmProxy.dfm deleted file mode 100644 index 7ba9c06c5cae79c3827a3d1d98e81d212d147e8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1584 zcmb7EO>fgc5Z&00KjI`*DjSGp8wQ9=#K`$X!!aK*xPz!0uToNo)ez2 zS-|M>!Y+RpeRRh4&lNqSbN#F4wkeAd8}kc{EPIl5Qi$o)^5C4Ol$cG~{B(>sPsuc^ zdpJde_fR@bxc&vWDn3nPp6EY7)uWg)%ZYHC6CXyX?o+~dy#%rhaqCW}>mQ!8@$ zSt`g|TXQ;qDe)!JzfDT73QEtfLpf#rKi~qGWs6)k3T`f$m2l5)fGg`a;oQ*2khjk{ zr^JqCv4?3^@Ovqx`5qJmPfEo5btx~OM&}udjc-4H14sVTp$j5ISB6T_mMc{_PGByo zrcCs5)%JyQFXdE|s=Jg}y>L~Ma|bkrc!aWZ%(aRg!im(IRt3P3%XH(ETRa!kmB)Xf z7STU|a+7VvTU@}ha^WW_M=J%akt+Z+B(g_m6WXRrJDSi9X=?KFcMJIMEBJd=W#?v; zbr_wC^Yqh<7w)u6r`3))nw4^Hh#=b?b0&OVF^ywNkh$Fp!=NQcwiYQ*T7DRq#&C{^ zX^eByrW-OyvN>eAzf4!?ruA4n_f8pzsvWT22^hk23f>Vjk4TJ`8nA~X|4fi6vYO?R zD!zK%wI@C*PZa0X4sUf`X8@OdM5a8^s%utS!D@eRe{apCkw2ywcb$lvXG)W7n(D03 lY;-Fw>-qZTmIA!Ai~=X}q5luOUP6ekuUUDr9%cXl{sJ)8?-l?6 diff --git a/installer/UnitfrmProxy.pas b/installer/UnitfrmProxy.pas deleted file mode 100644 index 1556226..0000000 --- a/installer/UnitfrmProxy.pas +++ /dev/null @@ -1,72 +0,0 @@ -unit UnitfrmProxy; - -interface - -uses - SysUtils, Windows, Messages, Classes, Graphics, Controls, - StdCtrls, ExtCtrls, Forms, TFlatButtonUnit, TFlatComboBoxUnit, - TFlatEditUnit; - -type - TfrmProxy = class(TForm) - cmdClose: TFlatButton; - lblProxy: TLabel; - txtHost: TFlatEdit; - cboProxy: TFlatComboBox; - lblHost: TLabel; - txtPort: TFlatEdit; - lblPort: TLabel; - lblUsername: TLabel; - txtUsername: TFlatEdit; - txtPassword: TFlatEdit; - lblPassword: TLabel; - procedure cboProxyChange(Sender: TObject); - procedure txtPortChange(Sender: TObject); - public - procedure EnableControls(Enable: Boolean); - end; - -var - frmProxy: TfrmProxy; - -implementation - -{$R *.DFM} - -{ TfrmProxy } - -procedure TfrmProxy.EnableControls(Enable: Boolean); -begin - lblHost.Enabled := Enable; - lblPassword.Enabled := Enable; - lblPort.Enabled := Enable; - lblUsername.Enabled := Enable; - txtHost.Enabled := Enable; - txtPassword.Enabled := Enable; - txtPort.Enabled := Enable; - txtUsername.Enabled := Enable; -end; - -procedure TfrmProxy.cboProxyChange(Sender: TObject); -begin - EnableControls(cboProxy.ItemIndex <> 0); // 0 = None -end; - -procedure TfrmProxy.txtPortChange(Sender: TObject); -var i: integer; -begin - if txtPort.Text = '' then - txtPort.Text := '8080' - else begin - // check if value is numeric... - for i := Length(txtPort.Text) downto 1 do begin - if Pos(txtPort.Text[i], '0123456789') = 0 then begin - txtPort.Text := '8080'; - txtPort.SelStart := 4; - exit; - end; - end; - end; -end; - -end. diff --git a/installer/del.bat b/installer/del.bat deleted file mode 100644 index 74a143b..0000000 --- a/installer/del.bat +++ /dev/null @@ -1,15 +0,0 @@ -del .\*.~pas -del .\*.dcu -del .\*.~ddp -del .\*.ddp -del .\*.~dpr -del .\*.~dfm -del .\*.~dpr -del .\*.map -del .\*.drc -del .\*.~xfm -del .\*.log -del .\*.dof -upx MMS_Installer.exe -upx Attach.exe -upx hl2launch.exe \ No newline at end of file diff --git a/installer/files/Readme.txt b/installer/files/Readme.txt deleted file mode 100644 index 8074221..0000000 --- a/installer/files/Readme.txt +++ /dev/null @@ -1,8 +0,0 @@ -This folder will be used by the attach binary. Make sure you have both the Source and OrangeBox binary in it. -Here are some instructions on how to prepare an upcoming release: - -1) Copy the latest MM:S dlls (Source+OrangeBox) and "hl2launch.exe" into this directory -2) Attach .source and .orangebox to the particular binaries. -3) Run Attach.exe -4) Test MMS_Installer.exe once (should work but nobody wants a buggy installer) -5) If everything worked fine, release it, otherwise pm me (Basic-Master) \ No newline at end of file diff --git a/installer/install.bmp b/installer/install.bmp deleted file mode 100644 index 39b905be4507286639395912964881258552398f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154542 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 diff --git a/installer/upx.exe b/installer/upx.exe deleted file mode 100644 index d47856823e48792f97d19f20ed08d40bc7cb0d4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126464 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 z 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 | cut -b1) - -CFLAGS += -DORANGEBOX_BUILD -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Wno-non-virtual-dtor -Werror -fPIC -fno-exceptions -fno-rtti -msse - -ifeq "$(GCC_VERSION)" "4" - CFLAGS += $(GCC4_FLAGS) -endif - -OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) - -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< - -all: - mkdir -p $(BIN_DIR) - ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so - ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so - $(MAKE) -f Makefile.ep2 sample_mm - rm -rf $(BINARY) - ln -sf $(BIN_DIR)/$(BINARY) $(BINARY) - -sample_mm: $(OBJ_LINUX) - $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) - -debug: - $(MAKE) -f Makefile.ep2 all DEBUG=true - -default: all - -clean: - rm -rf Release/*.o - rm -rf Release/$(BINARY) - rm -rf Debug/*.o - rm -rf Debug/$(BINARY) - diff --git a/sample_mm/engine_wrappers.h b/sample_mm/engine_wrappers.h deleted file mode 100644 index 05b6ee5..0000000 --- a/sample_mm/engine_wrappers.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source Sample Plugin - * Written by AlliedModders LLC. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * This sample plugin is public domain. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCE_ENGINE_WRAPPERS_ -#define _INCLUDE_SOURCE_ENGINE_WRAPPERS_ - -#include - -extern IVEngineServer *engine; - -#if !defined ORANGEBOX_BUILD -class CCommand -{ -public: - const char *ArgS() - { - return engine->Cmd_Args(); - } - int ArgC() - { - return engine->Cmd_Argc(); - } - - const char *Arg(int index) - { - return engine->Cmd_Argv(index); - } -}; -#endif - -#endif //_INCLUDE_SOURCE_ENGINE_WRAPPERS_ diff --git a/sample_mm/msvc8/sample_mm.sln b/sample_mm/msvc8/sample_mm.sln deleted file mode 100644 index 37c4ebc..0000000 --- a/sample_mm/msvc8/sample_mm.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample plugin", "sample_mm.vcproj", "{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug - Orange Box|Win32 = Debug - Orange Box|Win32 - Debug|Win32 = Debug|Win32 - Release - Orange Box|Win32 = Release - Orange Box|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug|Win32.ActiveCfg = Debug|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug|Win32.Build.0 = Debug|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release|Win32.ActiveCfg = Release|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/sample_mm/msvc8/sample_mm.vcproj b/sample_mm/msvc8/sample_mm.vcproj deleted file mode 100644 index e294cbd..0000000 --- a/sample_mm/msvc8/sample_mm.vcproj +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sample_mm/sample_mm.cpp b/sample_mm/sample_mm.cpp deleted file mode 100644 index 6178dfa..0000000 --- a/sample_mm/sample_mm.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source Sample Plugin - * Written by AlliedModders LLC. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * This sample plugin is public domain. - * - * Version: $Id$ - */ - -#include -#include "sample_mm.h" - -SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, 0, bool, char const *, char const *, char const *, char const *, bool, bool); -SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int); -SH_DECL_HOOK1_void(IServerGameDLL, GameFrame, SH_NOATTRIB, 0, bool); -SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, 0); -SH_DECL_HOOK2_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, edict_t *, bool); -SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *); -SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, char const *); -SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, 0, int); -SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *); -SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char*, const char *, char *, int); -SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *, bool); - -#if defined ORANGEBOX_BUILD -SH_DECL_HOOK2_void(IServerGameClients, NetworkIDValidated, SH_NOATTRIB, 0, const char *, const char *); -SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &); -#else -SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *); -#endif - -StubPlugin g_StubPlugin; -IServerGameDLL *server = NULL; -IServerGameClients *gameclients = NULL; -IVEngineServer *engine = NULL; -IServerPluginHelpers *helpers = NULL; -IGameEventManager2 *gameevents = NULL; -IServerPluginCallbacks *vsp_callbacks = NULL; -IPlayerInfoManager *playerinfomanager = NULL; - -PLUGIN_EXPOSE(StubPlugin, g_StubPlugin); -bool StubPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) -{ - PLUGIN_SAVEVARS(); - - GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); - GET_V_IFACE_CURRENT(GetEngineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2); - GET_V_IFACE_CURRENT(GetEngineFactory, helpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS); - GET_V_IFACE_ANY(GetServerFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); - GET_V_IFACE_ANY(GetServerFactory, gameclients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS); - GET_V_IFACE_ANY(GetServerFactory, playerinfomanager, IPlayerInfoManager, INTERFACEVERSION_PLAYERINFOMANAGER); - - META_LOG(g_PLAPI, "Starting plugin."); - - /* Load the VSP listener. Most people won't need this. */ - if ((vsp_callbacks = ismm->GetVSPInfo(NULL)) == NULL) - { - ismm->AddListener(this, this); - ismm->EnableVSPListener(); - } - - m_hooks.push_back(SH_ADD_HOOK(IServerGameDLL, LevelInit, server, SH_MEMBER(this, &StubPlugin::Hook_LevelInit), true)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameDLL, ServerActivate, server, SH_MEMBER(this, &StubPlugin::Hook_ServerActivate), true)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameDLL, GameFrame, server, SH_MEMBER(this, &StubPlugin::Hook_GameFrame), true)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameDLL, LevelShutdown, server, SH_MEMBER(this, &StubPlugin::Hook_LevelShutdown), false)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientActive, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientActive), true)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientDisconnect, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientDisconnect), true)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientPutInServer, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientPutInServer), true)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, SetCommandClient, gameclients, SH_MEMBER(this, &StubPlugin::Hook_SetCommandClient), true)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientSettingsChanged, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientSettingsChanged), false)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientConnect, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientConnect), false)); - m_hooks.push_back(SH_ADD_HOOK(IServerGameClients, ClientCommand, gameclients, SH_MEMBER(this, &StubPlugin::Hook_ClientCommand), false)); - - SH_CALL(engine, &IVEngineServer::LogPrint)("All hooks started!\n"); - - return true; -} - -bool StubPlugin::Unload(char *error, size_t maxlen) -{ - for (size_t i = 0; i < m_hooks.size(); i++) - { - if (m_hooks[i] != 0) - { - SH_REMOVE_HOOK_ID(m_hooks[i]); - } - } - m_hooks.clear(); - - return true; -} - -void StubPlugin::OnVSPListening(IServerPluginCallbacks *iface) -{ - vsp_callbacks = iface; -} - -void StubPlugin::Hook_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) -{ - META_LOG(g_PLAPI, "ServerActivate() called: edictCount = %d, clientMax = %d", edictCount, clientMax); -} - -void StubPlugin::AllPluginsLoaded() -{ - /* This is where we'd do stuff that relies on the mod or other plugins - * being initialized (for example, cvars added and events registered). - */ -} - -void StubPlugin::Hook_ClientActive(edict_t *pEntity, bool bLoadGame) -{ - META_LOG(g_PLAPI, "Hook_ClientActive(%d, %d)", engine->IndexOfEdict(pEntity), bLoadGame); -} - -#if defined ORANGEBOX_BUILD -void StubPlugin::Hook_ClientCommand(edict_t *pEntity, const CCommand &args) -#else -void StubPlugin::Hook_ClientCommand(edict_t *pEntity) -#endif -{ -#if !defined ORANGEBOX_BUILD - CCommand args; -#endif - - if (!pEntity || !pEntity->IsFree()) - { - return; - } - - const char *cmd = args.Arg(0); - if (strcmp(cmd, "menu") == 0) - { - KeyValues *kv = new KeyValues("menu"); - kv->SetString("title", "You've got options, hit ESC"); - kv->SetInt("level", 1); - kv->SetColor("color", Color(255, 0, 0, 255)); - kv->SetInt("time", 20); - kv->SetString("msg", "Pick an option\nOr don't."); - - for (int i = 1; i < 9; i++) - { - char num[10], msg[10], cmd[10]; - g_SMAPI->Format( num, sizeof(num), "%i", i ); - g_SMAPI->Format( msg, sizeof(msg), "Option %i", i ); - g_SMAPI->Format( cmd, sizeof(cmd), "option %i", i ); - - KeyValues *item1 = kv->FindKey(num, true); - item1->SetString("msg", msg); - item1->SetString("command", cmd); - } - - helpers->CreateMessage(pEntity, DIALOG_MENU, kv, vsp_callbacks); - kv->deleteThis(); - RETURN_META(MRES_SUPERCEDE); - } - else if (strcmp(cmd, "rich") == 0) - { - KeyValues *kv = new KeyValues("menu"); - kv->SetString("title", "A rich message"); - kv->SetInt("level", 1); - kv->SetInt("time", 20); - kv->SetString("msg", "This is a long long long text string.\n\nIt also has line breaks."); - - helpers->CreateMessage(pEntity, DIALOG_TEXT, kv, vsp_callbacks); - kv->deleteThis(); - RETURN_META(MRES_SUPERCEDE); - } - else if (strcmp(cmd, "msg") == 0) - { - KeyValues *kv = new KeyValues("menu"); - kv->SetString("title", "Just a simple hello"); - kv->SetInt("level", 1); - kv->SetInt("time", 20); - - helpers->CreateMessage(pEntity, DIALOG_MSG, kv, vsp_callbacks); - kv->deleteThis(); - RETURN_META(MRES_SUPERCEDE); - } - else if (strcmp(cmd, "entry") == 0) - { - KeyValues *kv = new KeyValues("entry"); - kv->SetString("title", "Stuff"); - kv->SetString("msg", "Enter something"); - kv->SetString("command", "say"); // anything they enter into the dialog turns into a say command - kv->SetInt("level", 1); - kv->SetInt("time", 20); - - helpers->CreateMessage(pEntity, DIALOG_ENTRY, kv, vsp_callbacks); - kv->deleteThis(); - RETURN_META(MRES_SUPERCEDE); - } -} - -void StubPlugin::Hook_ClientSettingsChanged(edict_t *pEdict) -{ - if (playerinfomanager) - { - IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo(pEdict); - - const char *name = engine->GetClientConVarValue(engine->IndexOfEdict(pEdict), "name"); - - if (playerinfo != NULL - && name != NULL - && playerinfo->GetName() != NULL - && strcmp(name, playerinfo->GetName()) == 0) - { - char msg[128]; - g_SMAPI->Format(msg, sizeof(msg), "Your name changed to \"%s\" (from \"%s\")\n", name, playerinfo->GetName()); - engine->ClientPrintf(pEdict, msg); - } - } -} - -bool StubPlugin::Hook_ClientConnect(edict_t *pEntity, - const char *pszName, - const char *pszAddress, - char *reject, - int maxrejectlen) -{ - META_LOG(g_PLAPI, "Hook_ClientConnect(%d, \"%s\", \"%s\")", engine->IndexOfEdict(pEntity), pszName, pszAddress); - - return true; -} - -void StubPlugin::Hook_ClientPutInServer(edict_t *pEntity, char const *playername) -{ - KeyValues *kv = new KeyValues( "msg" ); - kv->SetString( "title", "Hello" ); - kv->SetString( "msg", "Hello there" ); - kv->SetColor( "color", Color( 255, 0, 0, 255 )); - kv->SetInt( "level", 5); - kv->SetInt( "time", 10); - helpers->CreateMessage(pEntity, DIALOG_MSG, kv, vsp_callbacks); - kv->deleteThis(); -} - -void StubPlugin::Hook_ClientDisconnect(edict_t *pEntity) -{ - META_LOG(g_PLAPI, "Hook_ClientDisconnect(%d)", engine->IndexOfEdict(pEntity)); -} - -void StubPlugin::Hook_GameFrame(bool simulating) -{ - /** - * simulating: - * *********** - * true | game is ticking - * false | game is not ticking - */ -} - -bool StubPlugin::Hook_LevelInit(const char *pMapName, - char const *pMapEntities, - char const *pOldLevel, - char const *pLandmarkName, - bool loadGame, - bool background) -{ - META_LOG(g_PLAPI, "Hook_LevelInit(%s)", pMapName); - - return true; -} - -void StubPlugin::Hook_LevelShutdown() -{ - META_LOG(g_PLAPI, "Hook_LevelShutdown()"); -} - -void StubPlugin::Hook_SetCommandClient(int index) -{ - META_LOG(g_PLAPI, "Hook_SetCommandClient(%d)", index); -} - -bool StubPlugin::Pause(char *error, size_t maxlen) -{ - return true; -} - -bool StubPlugin::Unpause(char *error, size_t maxlen) -{ - return true; -} - -const char *StubPlugin::GetLicense() -{ - return "Public Domain"; -} - -const char *StubPlugin::GetVersion() -{ - return "1.0.0.0"; -} - -const char *StubPlugin::GetDate() -{ - return __DATE__; -} - -const char *StubPlugin::GetLogTag() -{ - return "SAMPLE"; -} - -const char *StubPlugin::GetAuthor() -{ - return "AlliedModders LLC"; -} - -const char *StubPlugin::GetDescription() -{ - return "Sample basic plugin"; -} - -const char *StubPlugin::GetName() -{ - return "Sample Plugin"; -} - -const char *StubPlugin::GetURL() -{ - return "http://www.sourcemm.net/"; -} diff --git a/sample_mm/sample_mm.h b/sample_mm/sample_mm.h deleted file mode 100644 index 4a0c0b9..0000000 --- a/sample_mm/sample_mm.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source Sample Plugin - * Written by AlliedModders LLC. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * This sample plugin is public domain. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ -#define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ - -#include -#include -#include -#include -#include "engine_wrappers.h" - -class StubPlugin : public ISmmPlugin, public IMetamodListener -{ -public: - bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); - bool Unload(char *error, size_t maxlen); - bool Pause(char *error, size_t maxlen); - bool Unpause(char *error, size_t maxlen); - void AllPluginsLoaded(); -public: //IMetamodListener stuff - void OnVSPListening(IServerPluginCallbacks *iface); -public: //hooks - void Hook_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); - bool Hook_LevelInit(const char *pMapName, - char const *pMapEntities, - char const *pOldLevel, - char const *pLandmarkName, - bool loadGame, - bool background); - void Hook_GameFrame(bool simulating); - void Hook_LevelShutdown(void); - void Hook_ClientActive(edict_t *pEntity, bool bLoadGame); - void Hook_ClientDisconnect(edict_t *pEntity); - void Hook_ClientPutInServer(edict_t *pEntity, char const *playername); - void Hook_SetCommandClient(int index); - void Hook_ClientSettingsChanged(edict_t *pEdict); - bool Hook_ClientConnect(edict_t *pEntity, - const char *pszName, - const char *pszAddress, - char *reject, - int maxrejectlen); -#if defined ORANGEBOX_BUILD - void Hook_ClientCommand(edict_t *pEntity, const CCommand &args); -#else - void Hook_ClientCommand(edict_t *pEntity); -#endif -public: - const char *GetAuthor(); - const char *GetName(); - const char *GetDescription(); - const char *GetURL(); - const char *GetLicense(); - const char *GetVersion(); - const char *GetDate(); - const char *GetLogTag(); -private: - SourceHook::CVector m_hooks; -}; - -extern StubPlugin g_StubPlugin; - -PLUGIN_GLOBALVARS(); - -#endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ diff --git a/sourcehook/FastDelegate.h b/sourcehook/FastDelegate.h deleted file mode 100644 index 59d63ff..0000000 --- a/sourcehook/FastDelegate.h +++ /dev/null @@ -1,3259 +0,0 @@ -// FastDelegate.h -// Efficient delegates in C++ that generate only two lines of asm code! -// Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp -// -// - Don Clugston, Mar 2004. -// Major contributions were made by Jody Hagins. -// History: -// 24-Apr-04 1.0 * Submitted to CodeProject. -// 28-Apr-04 1.1 * Prevent most unsafe uses of evil static function hack. -// * Improved syntax for horrible_cast (thanks Paul Bludov). -// * Tested on Metrowerks MWCC and Intel ICL (IA32) -// * Compiled, but not run, on Comeau C++ and Intel Itanium ICL. -// 27-Jun-04 1.2 * Now works on Borland C++ Builder 5.5 -// * Now works on /clr "managed C++" code on VC7, VC7.1 -// * Comeau C++ now compiles without warnings. -// * Prevent the virtual inheritance case from being used on -// VC6 and earlier, which generate incorrect code. -// * Improved warning and error messages. Non-standard hacks -// now have compile-time checks to make them safer. -// * implicit_cast used instead of static_cast in many cases. -// * If calling a const member function, a const class pointer can be used. -// * MakeDelegate() global helper function added to simplify pass-by-value. -// * Added fastdelegate.clear() -// 16-Jul-04 1.2.1* Workaround for gcc bug (const member function pointers in templates) -// 30-Oct-04 1.3 * Support for (non-void) return values. -// * No more workarounds in client code! -// MSVC and Intel now use a clever hack invented by John Dlugosz: -// - The FASTDELEGATEDECLARE workaround is no longer necessary. -// - No more warning messages for VC6 -// * Less use of macros. Error messages should be more comprehensible. -// * Added include guards -// * Added FastDelegate::empty() to test if invocation is safe (Thanks Neville Franks). -// * Now tested on VS 2005 Express Beta, PGI C++ -// 24-Dec-04 1.4 * Added DelegateMemento, to allow collections of disparate delegates. -// * <,>,<=,>= comparison operators to allow storage in ordered containers. -// * Substantial reduction of code size, especially the 'Closure' class. -// * Standardised all the compiler-specific workarounds. -// * MFP conversion now works for CodePlay (but not yet supported in the full code). -// * Now compiles without warnings on _any_ supported compiler, including BCC 5.5.1 -// * New syntax: FastDelegate< int (char *, double) >. -// 14-Feb-05 1.4.1* Now treats =0 as equivalent to .clear(), ==0 as equivalent to .empty(). (Thanks elfric). -// * Now tested on Intel ICL for AMD64, VS2005 Beta for AMD64 and Itanium. -// 30-Mar-05 1.5 * Safebool idiom: "if (dg)" is now equivalent to "if (!dg.empty())" -// * Fully supported by CodePlay VectorC -// * Bugfix for Metrowerks: empty() was buggy because a valid MFP can be 0 on MWCC! -// * More optimal assignment,== and != operators for static function pointers. - -#ifndef FASTDELEGATE_H -#define FASTDELEGATE_H - -#ifdef _MSC_VER -# if _MSC_VER > 1000 -# pragma once -# endif // _MSC_VER > 1000 -#endif // #ifdef _MSC_VER - -#include // to allow <,> comparisons - -//////////////////////////////////////////////////////////////////////////////// -// Configuration options -// -//////////////////////////////////////////////////////////////////////////////// - -// Uncomment the following #define for optimally-sized delegates. -// In this case, the generated asm code is almost identical to the code you'd get -// if the compiler had native support for delegates. -// It will not work on systems where sizeof(dataptr) < sizeof(codeptr). -// Thus, it will not work for DOS compilers using the medium model. -// It will also probably fail on some DSP systems. -#define FASTDELEGATE_USESTATICFUNCTIONHACK - -// Uncomment the next line to allow function declarator syntax. -// It is automatically enabled for those compilers where it is known to work. -//#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -//////////////////////////////////////////////////////////////////////////////// -// Compiler identification for workarounds -// -//////////////////////////////////////////////////////////////////////////////// - -// Compiler identification. It's not easy to identify Visual C++ because -// many vendors fraudulently define Microsoft's identifiers. -#if defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__VECTOR_C) && !defined(__ICL) && !defined(__BORLANDC__) -#define FASTDLGT_ISMSVC - -#if (_MSC_VER <1300) // Many workarounds are required for VC6. -#define FASTDLGT_VC6 -#pragma warning(disable:4786) // disable this ridiculous warning -#endif - -#endif - -// Does the compiler uses Microsoft's member function pointer structure? -// If so, it needs special treatment. -// Metrowerks CodeWarrior, Intel, and CodePlay fraudulently define Microsoft's -// identifier, _MSC_VER. We need to filter Metrowerks out. -#if defined(_MSC_VER) && !defined(__MWERKS__) -#define FASTDLGT_MICROSOFT_MFP - -#if !defined(__VECTOR_C) -// CodePlay doesn't have the __single/multi/virtual_inheritance keywords -#define FASTDLGT_HASINHERITANCE_KEYWORDS -#endif -#endif - -// Does it allow function declarator syntax? The following compilers are known to work: -#if defined(FASTDLGT_ISMSVC) && (_MSC_VER >=1310) // VC 7.1 -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -// Gcc(2.95+), and versions of Digital Mars, Intel and Comeau in common use. -#if defined (__DMC__) || defined(__GNUC__) || defined(__ICL) || defined(__COMO__) -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -// It works on Metrowerks MWCC 3.2.2. From boost.Config it should work on earlier ones too. -#if defined (__MWERKS__) -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -#ifdef __GNUC__ // Workaround GCC bug #8271 - // At present, GCC doesn't recognize constness of MFPs in templates -#define FASTDELEGATE_GCC_BUG_8271 -#endif - - - -//////////////////////////////////////////////////////////////////////////////// -// General tricks used in this code -// -// (a) Error messages are generated by typdefing an array of negative size to -// generate compile-time errors. -// (b) Warning messages on MSVC are generated by declaring unused variables, and -// enabling the "variable XXX is never used" warning. -// (c) Unions are used in a few compiler-specific cases to perform illegal casts. -// (d) For Microsoft and Intel, when adjusting the 'this' pointer, it's cast to -// (char *) first to ensure that the correct number of *bytes* are added. -// -//////////////////////////////////////////////////////////////////////////////// -// Helper templates -// -//////////////////////////////////////////////////////////////////////////////// - - -namespace fastdelegate { -namespace detail { // we'll hide the implementation details in a nested namespace. - -// implicit_cast< > -// I believe this was originally going to be in the C++ standard but -// was left out by accident. It's even milder than static_cast. -// I use it instead of static_cast<> to emphasize that I'm not doing -// anything nasty. -// Usage is identical to static_cast<> -template -inline OutputClass implicit_cast(InputClass input){ - return input; -} - -// horrible_cast< > -// This is truly evil. It completely subverts C++'s type system, allowing you -// to cast from any class to any other class. Technically, using a union -// to perform the cast is undefined behaviour (even in C). But we can see if -// it is OK by checking that the union is the same size as each of its members. -// horrible_cast<> should only be used for compiler-specific workarounds. -// Usage is identical to reinterpret_cast<>. - -// This union is declared outside the horrible_cast because BCC 5.5.1 -// can't inline a function with a nested class, and gives a warning. -template -union horrible_union{ - OutputClass out; - InputClass in; -}; - -template -inline OutputClass horrible_cast(const InputClass input){ - horrible_union u; - // Cause a compile-time error if in, out and u are not the same size. - // If the compile fails here, it means the compiler has peculiar - // unions which would prevent the cast from working. - typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u) - && sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1]; - u.in = input; - return u.out; -} - -//////////////////////////////////////////////////////////////////////////////// -// Workarounds -// -//////////////////////////////////////////////////////////////////////////////// - -// Backwards compatibility: This macro used to be necessary in the virtual inheritance -// case for Intel and Microsoft. Now it just forward-declares the class. -#define FASTDELEGATEDECLARE(CLASSNAME) class CLASSNAME; - -// Prevent use of the static function hack with the DOS medium model. -#ifdef __MEDIUM__ -#undef FASTDELEGATE_USESTATICFUNCTIONHACK -#endif - -// DefaultVoid - a workaround for 'void' templates in VC6. -// -// (1) VC6 and earlier do not allow 'void' as a default template argument. -// (2) They also doesn't allow you to return 'void' from a function. -// -// Workaround for (1): Declare a dummy type 'DefaultVoid' which we use -// when we'd like to use 'void'. We convert it into 'void' and back -// using the templates DefaultVoidToVoid<> and VoidToDefaultVoid<>. -// Workaround for (2): On VC6, the code for calling a void function is -// identical to the code for calling a non-void function in which the -// return value is never used, provided the return value is returned -// in the EAX register, rather than on the stack. -// This is true for most fundamental types such as int, enum, void *. -// Const void * is the safest option since it doesn't participate -// in any automatic conversions. But on a 16-bit compiler it might -// cause extra code to be generated, so we disable it for all compilers -// except for VC6 (and VC5). -#ifdef FASTDLGT_VC6 -// VC6 workaround -typedef const void * DefaultVoid; -#else -// On any other compiler, just use a normal void. -typedef void DefaultVoid; -#endif - -// Translate from 'DefaultVoid' to 'void'. -// Everything else is unchanged -template -struct DefaultVoidToVoid { typedef T type; }; - -template <> -struct DefaultVoidToVoid { typedef void type; }; - -// Translate from 'void' into 'DefaultVoid' -// Everything else is unchanged -template -struct VoidToDefaultVoid { typedef T type; }; - -template <> -struct VoidToDefaultVoid { typedef DefaultVoid type; }; - - - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 1: -// -// Conversion of member function pointer to a standard form -// -//////////////////////////////////////////////////////////////////////////////// - -// GenericClass is a fake class, ONLY used to provide a type. -// It is vitally important that it is never defined, so that the compiler doesn't -// think it can optimize the invocation. For example, Borland generates simpler -// code if it knows the class only uses single inheritance. - -// Compilers using Microsoft's structure need to be treated as a special case. -#ifdef FASTDLGT_MICROSOFT_MFP - -#ifdef FASTDLGT_HASINHERITANCE_KEYWORDS - // For Microsoft and Intel, we want to ensure that it's the most efficient type of MFP - // (4 bytes), even when the /vmg option is used. Declaring an empty class - // would give 16 byte pointers in this case.... - class __single_inheritance GenericClass; -#endif - // ...but for Codeplay, an empty class *always* gives 4 byte pointers. - // If compiled with the /clr option ("managed C++"), the JIT compiler thinks - // it needs to load GenericClass before it can call any of its functions, - // (compiles OK but crashes at runtime!), so we need to declare an - // empty class to make it happy. - // Codeplay and VC4 can't cope with the unknown_inheritance case either. - class GenericClass {}; -#else - class GenericClass; -#endif - -// The size of a single inheritance member function pointer. -const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)()); - -// SimplifyMemFunc< >::Convert() -// -// A template function that converts an arbitrary member function pointer into the -// simplest possible form of member function pointer, using a supplied 'this' pointer. -// According to the standard, this can be done legally with reinterpret_cast<>. -// For (non-standard) compilers which use member function pointers which vary in size -// depending on the class, we need to use knowledge of the internal structure of a -// member function pointer, as used by the compiler. Template specialization is used -// to distinguish between the sizes. Because some compilers don't support partial -// template specialisation, I use full specialisation of a wrapper struct. - -// general case -- don't know how to convert it. Force a compile failure -template -struct SimplifyMemFunc { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // Unsupported member function type -- force a compile failure. - // (it's illegal to have a array with negative size). - typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100]; - return 0; - } -}; - -// For compilers where all member func ptrs are the same size, everything goes here. -// For non-standard compilers, only single_inheritance classes go here. -template <> -struct SimplifyMemFunc { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { -#if defined __DMC__ - // Digital Mars doesn't allow you to cast between abitrary PMF's, - // even though the standard says you can. The 32-bit compiler lets you - // static_cast through an int, but the DOS compiler doesn't. - bound_func = horrible_cast(function_to_bind); -#else - bound_func = reinterpret_cast(function_to_bind); -#endif - return reinterpret_cast(pthis); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 1b: -// -// Workarounds for Microsoft and Intel -// -//////////////////////////////////////////////////////////////////////////////// - - -// Compilers with member function pointers which violate the standard (MSVC, Intel, Codeplay), -// need to be treated as a special case. -#ifdef FASTDLGT_MICROSOFT_MFP - -// We use unions to perform horrible_casts. I would like to use #pragma pack(push, 1) -// at the start of each function for extra safety, but VC6 seems to ICE -// intermittently if you do this inside a template. - -// __multiple_inheritance classes go here -// Nasty hack for Microsoft and Intel (IA32 and Itanium) -template<> -struct SimplifyMemFunc< SINGLE_MEMFUNCPTR_SIZE + sizeof(int) > { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // We need to use a horrible_cast to do this conversion. - // In MSVC, a multiple inheritance member pointer is internally defined as: - union { - XFuncType func; - struct { - GenericMemFuncType funcaddress; // points to the actual member function - int delta; // #BYTES to be added to the 'this' pointer - }s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)? 1 : -1]; - u.func = function_to_bind; - bound_func = u.s.funcaddress; - return reinterpret_cast(reinterpret_cast(pthis) + u.s.delta); - } -}; - -// virtual inheritance is a real nuisance. It's inefficient and complicated. -// On MSVC and Intel, there isn't enough information in the pointer itself to -// enable conversion to a closure pointer. Earlier versions of this code didn't -// work for all cases, and generated a compile-time error instead. -// But a very clever hack invented by John M. Dlugosz solves this problem. -// My code is somewhat different to his: I have no asm code, and I make no -// assumptions about the calling convention that is used. - -// In VC++ and ICL, a virtual_inheritance member pointer -// is internally defined as: -struct MicrosoftVirtualMFP { - void (GenericClass::*codeptr)(); // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtable_index; // or 0 if no virtual inheritance -}; -// The CRUCIAL feature of Microsoft/Intel MFPs which we exploit is that the -// m_codeptr member is *always* called, regardless of the values of the other -// members. (This is *not* true for other compilers, eg GCC, which obtain the -// function address from the vtable if a virtual function is being called). -// Dlugosz's trick is to make the codeptr point to a probe function which -// returns the 'this' pointer that was used. - -// Define a generic class that uses virtual inheritance. -// It has a trival member function that returns the value of the 'this' pointer. -struct GenericVirtualClass : virtual public GenericClass -{ - typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)(); - GenericVirtualClass * GetThis() { return this; } -}; - -// __virtual_inheritance classes go here -template <> -struct SimplifyMemFunc -{ - - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - union { - XFuncType func; - GenericClass* (X::*ProbeFunc)(); - MicrosoftVirtualMFP s; - } u; - u.func = function_to_bind; - bound_func = reinterpret_cast(u.s.codeptr); - union { - GenericVirtualClass::ProbePtrType virtfunc; - MicrosoftVirtualMFP s; - } u2; - // Check that the horrible_cast<>s will work - typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s) - && sizeof(function_to_bind)==sizeof(u.ProbeFunc) - && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1]; - // Unfortunately, taking the address of a MF prevents it from being inlined, so - // this next line can't be completely optimised away by the compiler. - u2.virtfunc = &GenericVirtualClass::GetThis; - u.s.codeptr = u2.s.codeptr; - return (pthis->*u.ProbeFunc)(); - } -}; - -#if (_MSC_VER <1300) - -// Nasty hack for Microsoft Visual C++ 6.0 -// unknown_inheritance classes go here -// There is a compiler bug in MSVC6 which generates incorrect code in this case!! -template <> -struct SimplifyMemFunc -{ - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // There is an apalling but obscure compiler bug in MSVC6 and earlier: - // vtable_index and 'vtordisp' are always set to 0 in the - // unknown_inheritance case! - // This means that an incorrect function could be called!!! - // Compiling with the /vmg option leads to potentially incorrect code. - // This is probably the reason that the IDE has a user interface for specifying - // the /vmg option, but it is disabled - you can only specify /vmg on - // the command line. In VC1.5 and earlier, the compiler would ICE if it ever - // encountered this situation. - // It is OK to use the /vmg option if /vmm or /vms is specified. - - // Fortunately, the wrong function is only called in very obscure cases. - // It only occurs when a derived class overrides a virtual function declared - // in a virtual base class, and the member function - // points to the *Derived* version of that function. The problem can be - // completely averted in 100% of cases by using the *Base class* for the - // member fpointer. Ie, if you use the base class as an interface, you'll - // stay out of trouble. - // Occasionally, you might want to point directly to a derived class function - // that isn't an override of a base class. In this case, both vtable_index - // and 'vtordisp' are zero, but a virtual_inheritance pointer will be generated. - // We can generate correct code in this case. To prevent an incorrect call from - // ever being made, on MSVC6 we generate a warning, and call a function to - // make the program crash instantly. - typedef char ERROR_VC6CompilerBug[-100]; - return 0; - } -}; - - -#else - -// Nasty hack for Microsoft and Intel (IA32 and Itanium) -// unknown_inheritance classes go here -// This is probably the ugliest bit of code I've ever written. Look at the casts! -// There is a compiler bug in MSVC6 which prevents it from using this code. -template <> -struct SimplifyMemFunc -{ - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // The member function pointer is 16 bytes long. We can't use a normal cast, but - // we can use a union to do the conversion. - union { - XFuncType func; - // In VC++ and ICL, an unknown_inheritance member pointer - // is internally defined as: - struct { - GenericMemFuncType m_funcaddress; // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtordisp; // #bytes to add to 'this' to find the vtable - int vtable_index; // or 0 if no virtual inheritance - } s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(XFuncType)==sizeof(u.s)? 1 : -1]; - u.func = function_to_bind; - bound_func = u.s.funcaddress; - int virtual_delta = 0; - if (u.s.vtable_index) { // Virtual inheritance is used - // First, get to the vtable. - // It is 'vtordisp' bytes from the start of the class. - const int * vtable = *reinterpret_cast( - reinterpret_cast(pthis) + u.s.vtordisp ); - - // 'vtable_index' tells us where in the table we should be looking. - virtual_delta = u.s.vtordisp + *reinterpret_cast( - reinterpret_cast(vtable) + u.s.vtable_index); - } - // The int at 'virtual_delta' gives us the amount to add to 'this'. - // Finally we can add the three components together. Phew! - return reinterpret_cast( - reinterpret_cast(pthis) + u.s.delta + virtual_delta); - }; -}; -#endif // MSVC 7 and greater - -#endif // MS/Intel hacks - -} // namespace detail - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 2: -// -// Define the delegate storage, and cope with static functions -// -//////////////////////////////////////////////////////////////////////////////// - -// DelegateMemento -- an opaque structure which can hold an arbitary delegate. -// It knows nothing about the calling convention or number of arguments used by -// the function pointed to. -// It supplies comparison operators so that it can be stored in STL collections. -// It cannot be set to anything other than null, nor invoked directly: -// it must be converted to a specific delegate. - -// Implementation: -// There are two possible implementations: the Safe method and the Evil method. -// DelegateMemento - Safe version -// -// This implementation is standard-compliant, but a bit tricky. -// A static function pointer is stored inside the class. -// Here are the valid values: -// +-- Static pointer --+--pThis --+-- pMemFunc-+-- Meaning------+ -// | 0 | 0 | 0 | Empty | -// | !=0 |(dontcare)| Invoker | Static function| -// | 0 | !=0 | !=0* | Method call | -// +--------------------+----------+------------+----------------+ -// * For Metrowerks, this can be 0. (first virtual function in a -// single_inheritance class). -// When stored stored inside a specific delegate, the 'dontcare' entries are replaced -// with a reference to the delegate itself. This complicates the = and == operators -// for the delegate class. - -// DelegateMemento - Evil version -// -// For compilers where data pointers are at least as big as code pointers, it is -// possible to store the function pointer in the this pointer, using another -// horrible_cast. In this case the DelegateMemento implementation is simple: -// +--pThis --+-- pMemFunc-+-- Meaning---------------------+ -// | 0 | 0 | Empty | -// | !=0 | !=0* | Static function or method call| -// +----------+------------+-------------------------------+ -// * For Metrowerks, this can be 0. (first virtual function in a -// single_inheritance class). -// Note that the Sun C++ and MSVC documentation explicitly state that they -// support static_cast between void * and function pointers. - -class DelegateMemento { -protected: - // the data is protected, not private, because many - // compilers have problems with template friends. - typedef void (detail::GenericClass::*GenericMemFuncType)(); // arbitrary MFP. - detail::GenericClass *m_pthis; - GenericMemFuncType m_pFunction; - -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - typedef void (*GenericFuncPtr)(); // arbitrary code pointer - GenericFuncPtr m_pStaticFunction; -#endif - -public: -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - DelegateMemento() : m_pthis(0), m_pFunction(0), m_pStaticFunction(0) {}; - void clear() { - m_pthis=0; m_pFunction=0; m_pStaticFunction=0; - } -#else - DelegateMemento() : m_pthis(0), m_pFunction(0) {}; - void clear() { m_pthis=0; m_pFunction=0; } -#endif -public: -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - inline bool IsEqual (const DelegateMemento &x) const{ - // We have to cope with the static function pointers as a special case - if (m_pFunction!=x.m_pFunction) return false; - // the static function ptrs must either both be equal, or both be 0. - if (m_pStaticFunction!=x.m_pStaticFunction) return false; - if (m_pStaticFunction!=0) return m_pthis==x.m_pthis; - else return true; - } -#else // Evil Method - inline bool IsEqual (const DelegateMemento &x) const{ - return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction; - } -#endif - // Provide a strict weak ordering for DelegateMementos. - inline bool IsLess(const DelegateMemento &right) const { - // deal with static function pointers first -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - if (m_pStaticFunction !=0 || right.m_pStaticFunction!=0) - return m_pStaticFunction < right.m_pStaticFunction; -#endif - if (m_pthis !=right.m_pthis) return m_pthis < right.m_pthis; - // There are no ordering operators for member function pointers, - // but we can fake one by comparing each byte. The resulting ordering is - // arbitrary (and compiler-dependent), but it permits storage in ordered STL containers. - return memcmp(&m_pFunction, &right.m_pFunction, sizeof(m_pFunction)) < 0; - - } - // BUGFIX (Mar 2005): - // We can't just compare m_pFunction because on Metrowerks, - // m_pFunction can be zero even if the delegate is not empty! - inline bool operator ! () const // Is it bound to anything? - { return m_pthis==0 && m_pFunction==0; } - inline bool empty() const // Is it bound to anything? - { return m_pthis==0 && m_pFunction==0; } -public: - DelegateMemento & operator = (const DelegateMemento &right) { - SetMementoFrom(right); - return *this; - } - inline bool operator <(const DelegateMemento &right) { - return IsLess(right); - } - inline bool operator >(const DelegateMemento &right) { - return right.IsLess(*this); - } - DelegateMemento (const DelegateMemento &right) : - m_pthis(right.m_pthis), m_pFunction(right.m_pFunction) -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - , m_pStaticFunction (right.m_pStaticFunction) -#endif - {} -protected: - void SetMementoFrom(const DelegateMemento &right) { - m_pFunction = right.m_pFunction; - m_pthis = right.m_pthis; -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = right.m_pStaticFunction; -#endif - } -}; - - -// ClosurePtr<> -// -// A private wrapper class that adds function signatures to DelegateMemento. -// It's the class that does most of the actual work. -// The signatures are specified by: -// GenericMemFunc: must be a type of GenericClass member function pointer. -// StaticFuncPtr: must be a type of function pointer with the same signature -// as GenericMemFunc. -// UnvoidStaticFuncPtr: is the same as StaticFuncPtr, except on VC6 -// where it never returns void (returns DefaultVoid instead). - -// An outer class, FastDelegateN<>, handles the invoking and creates the -// necessary typedefs. -// This class does everything else. - -namespace detail { - -template < class GenericMemFunc, class StaticFuncPtr, class UnvoidStaticFuncPtr> -class ClosurePtr : public DelegateMemento { -public: - // These functions are for setting the delegate to a member function. - - // Here's the clever bit: we convert an arbitrary member function into a - // standard form. XMemFunc should be a member function of class X, but I can't - // enforce that here. It needs to be enforced by the wrapper class. - template < class X, class XMemFunc > - inline void bindmemfunc(X *pthis, XMemFunc function_to_bind ) { - m_pthis = SimplifyMemFunc< sizeof(function_to_bind) > - ::Convert(pthis, function_to_bind, m_pFunction); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } - // For const member functions, we only need a const class pointer. - // Since we know that the member function is const, it's safe to - // remove the const qualifier from the 'this' pointer with a const_cast. - // VC6 has problems if we just overload 'bindmemfunc', so we give it a different name. - template < class X, class XMemFunc> - inline void bindconstmemfunc(const X *pthis, XMemFunc function_to_bind) { - m_pthis= SimplifyMemFunc< sizeof(function_to_bind) > - ::Convert(const_cast(pthis), function_to_bind, m_pFunction); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } -#ifdef FASTDELEGATE_GCC_BUG_8271 // At present, GCC doesn't recognize constness of MFPs in templates - template < class X, class XMemFunc> - inline void bindmemfunc(const X *pthis, XMemFunc function_to_bind) { - bindconstmemfunc(pthis, function_to_bind); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } -#endif - // These functions are required for invoking the stored function - inline GenericClass *GetClosureThis() const { return m_pthis; } - inline GenericMemFunc GetClosureMemPtr() const { return reinterpret_cast(m_pFunction); } - -// There are a few ways of dealing with static function pointers. -// There's a standard-compliant, but tricky method. -// There's also a straightforward hack, that won't work on DOS compilers using the -// medium memory model. It's so evil that I can't recommend it, but I've -// implemented it anyway because it produces very nice asm code. - -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - -// ClosurePtr<> - Safe version -// -// This implementation is standard-compliant, but a bit tricky. -// I store the function pointer inside the class, and the delegate then -// points to itself. Whenever the delegate is copied, these self-references -// must be transformed, and this complicates the = and == operators. -public: - // The next two functions are for operator ==, =, and the copy constructor. - // We may need to convert the m_pthis pointers, so that - // they remain as self-references. - template< class DerivedClass > - inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &x) { - SetMementoFrom(x); - if (m_pStaticFunction!=0) { - // transform self references... - m_pthis=reinterpret_cast(pParent); - } - } - // For static functions, the 'static_function_invoker' class in the parent - // will be called. The parent then needs to call GetStaticFunction() to find out - // the actual function to invoke. - template < class DerivedClass, class ParentInvokerSig > - inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, - StaticFuncPtr function_to_bind ) { - if (function_to_bind==0) { // cope with assignment to 0 - m_pFunction=0; - } else { - bindmemfunc(pParent, static_function_invoker); - } - m_pStaticFunction=reinterpret_cast(function_to_bind); - } - inline UnvoidStaticFuncPtr GetStaticFunction() const { - return reinterpret_cast(m_pStaticFunction); - } -#else - -// ClosurePtr<> - Evil version -// -// For compilers where data pointers are at least as big as code pointers, it is -// possible to store the function pointer in the this pointer, using another -// horrible_cast. Invocation isn't any faster, but it saves 4 bytes, and -// speeds up comparison and assignment. If C++ provided direct language support -// for delegates, they would produce asm code that was almost identical to this. -// Note that the Sun C++ and MSVC documentation explicitly state that they -// support static_cast between void * and function pointers. - - template< class DerivedClass > - inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &right) { - SetMementoFrom(right); - } - // For static functions, the 'static_function_invoker' class in the parent - // will be called. The parent then needs to call GetStaticFunction() to find out - // the actual function to invoke. - // ******** EVIL, EVIL CODE! ******* - template < class DerivedClass, class ParentInvokerSig> - inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, - StaticFuncPtr function_to_bind) { - if (function_to_bind==0) { // cope with assignment to 0 - m_pFunction=0; - } else { - // We'll be ignoring the 'this' pointer, but we need to make sure we pass - // a valid value to bindmemfunc(). - bindmemfunc(pParent, static_function_invoker); - } - - // WARNING! Evil hack. We store the function in the 'this' pointer! - // Ensure that there's a compilation failure if function pointers - // and data pointers have different sizes. - // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK. - typedef int ERROR_CantUseEvilMethod[sizeof(GenericClass *)==sizeof(function_to_bind) ? 1 : -1]; - m_pthis = horrible_cast(function_to_bind); - // MSVC, SunC++ and DMC accept the following (non-standard) code: -// m_pthis = static_cast(static_cast(function_to_bind)); - // BCC32, Comeau and DMC accept this method. MSVC7.1 needs __int64 instead of long -// m_pthis = reinterpret_cast(reinterpret_cast(function_to_bind)); - } - // ******** EVIL, EVIL CODE! ******* - // This function will be called with an invalid 'this' pointer!! - // We're just returning the 'this' pointer, converted into - // a function pointer! - inline UnvoidStaticFuncPtr GetStaticFunction() const { - // Ensure that there's a compilation failure if function pointers - // and data pointers have different sizes. - // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK. - typedef int ERROR_CantUseEvilMethod[sizeof(UnvoidStaticFuncPtr)==sizeof(this) ? 1 : -1]; - return horrible_cast(this); - } -#endif // !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - - // Does the closure contain this static function? - inline bool IsEqualToStaticFuncPtr(StaticFuncPtr funcptr){ - if (funcptr==0) return empty(); - // For the Evil method, if it doesn't actually contain a static function, this will return an arbitrary - // value that is not equal to any valid function pointer. - else return funcptr==reinterpret_cast(GetStaticFunction()); - } -}; - - -} // namespace detail - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 3: -// -// Wrapper classes to ensure type safety -// -//////////////////////////////////////////////////////////////////////////////// - - -// Once we have the member function conversion templates, it's easy to make the -// wrapper classes. So that they will work with as many compilers as possible, -// the classes are of the form -// FastDelegate3 -// They can cope with any combination of parameters. The max number of parameters -// allowed is 8, but it is trivial to increase this limit. -// Note that we need to treat const member functions seperately. -// All this class does is to enforce type safety, and invoke the delegate with -// the correct list of parameters. - -// Because of the weird rule about the class of derived member function pointers, -// you sometimes need to apply a downcast to the 'this' pointer. -// This is the reason for the use of "implicit_cast(pthis)" in the code below. -// If CDerivedClass is derived from CBaseClass, but doesn't override SimpleVirtualFunction, -// without this trick you'd need to write: -// MyDelegate(static_cast(&d), &CDerivedClass::SimpleVirtualFunction); -// but with the trick you can write -// MyDelegate(&d, &CDerivedClass::SimpleVirtualFunction); - -// RetType is the type the compiler uses in compiling the template. For VC6, -// it cannot be void. DesiredRetType is the real type which is returned from -// all of the functions. It can be void. - -// Implicit conversion to "bool" is achieved using the safe_bool idiom, -// using member data pointers (MDP). This allows "if (dg)..." syntax -// Because some compilers (eg codeplay) don't have a unique value for a zero -// MDP, an extra padding member is added to the SafeBool struct. -// Some compilers (eg VC6) won't implicitly convert from 0 to an MDP, so -// in that case the static function constructor is not made explicit; this -// allows "if (dg==0) ..." to compile. - -//N=0 -template -class FastDelegate0 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(); - typedef RetType (*UnvoidStaticFunctionPtr)(); - typedef RetType (detail::GenericClass::*GenericMemFn)(); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate0 type; - - // Construction and comparison functions - FastDelegate0() { clear(); } - FastDelegate0(const FastDelegate0 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate0 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate0 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate0 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate0 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate0 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate0(Y *pthis, DesiredRetType (X::* function_to_bind)() ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)()) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate0(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate0(DesiredRetType (*function_to_bind)() ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)() ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)()) { - m_Closure.bindstaticfunc(this, &FastDelegate0::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() () const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction() const { - return (*(m_Closure.GetStaticFunction()))(); } -}; - -//N=1 -template -class FastDelegate1 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate1 type; - - // Construction and comparison functions - FastDelegate1() { clear(); } - FastDelegate1(const FastDelegate1 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate1 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate1 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate1 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate1 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate1 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate1(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate1(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate1(DesiredRetType (*function_to_bind)(Param1 p1) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1)) { - m_Closure.bindstaticfunc(this, &FastDelegate1::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1) const { - return (*(m_Closure.GetStaticFunction()))(p1); } -}; - -//N=2 -template -class FastDelegate2 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate2 type; - - // Construction and comparison functions - FastDelegate2() { clear(); } - FastDelegate2(const FastDelegate2 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate2 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate2 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate2 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate2 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate2 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate2(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate2(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate2(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2)) { - m_Closure.bindstaticfunc(this, &FastDelegate2::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2); } -}; - -//N=3 -template -class FastDelegate3 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate3 type; - - // Construction and comparison functions - FastDelegate3() { clear(); } - FastDelegate3(const FastDelegate3 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate3 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate3 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate3 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate3 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate3 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate3(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate3(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate3(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) { - m_Closure.bindstaticfunc(this, &FastDelegate3::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3); } -}; - -//N=4 -template -class FastDelegate4 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate4 type; - - // Construction and comparison functions - FastDelegate4() { clear(); } - FastDelegate4(const FastDelegate4 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate4 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate4 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate4 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate4 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate4 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate4(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate4(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate4(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { - m_Closure.bindstaticfunc(this, &FastDelegate4::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4); } -}; - -//N=5 -template -class FastDelegate5 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate5 type; - - // Construction and comparison functions - FastDelegate5() { clear(); } - FastDelegate5(const FastDelegate5 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate5 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate5 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate5 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate5 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate5 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate5(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate5(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate5(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { - m_Closure.bindstaticfunc(this, &FastDelegate5::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5); } -}; - -//N=6 -template -class FastDelegate6 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate6 type; - - // Construction and comparison functions - FastDelegate6() { clear(); } - FastDelegate6(const FastDelegate6 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate6 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate6 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate6 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate6 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate6 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate6(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate6(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate6(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { - m_Closure.bindstaticfunc(this, &FastDelegate6::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6); } -}; - -//N=7 -template -class FastDelegate7 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate7 type; - - // Construction and comparison functions - FastDelegate7() { clear(); } - FastDelegate7(const FastDelegate7 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate7 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate7 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate7 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate7 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate7 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate7(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate7(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate7(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { - m_Closure.bindstaticfunc(this, &FastDelegate7::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7); } -}; - -//N=8 -template -class FastDelegate8 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate8 type; - - // Construction and comparison functions - FastDelegate8() { clear(); } - FastDelegate8(const FastDelegate8 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate8 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate8 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate8 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate8 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate8 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate8(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate8(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate8(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { - m_Closure.bindstaticfunc(this, &FastDelegate8::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8); } -}; - -//N=9 -template -class FastDelegate9 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate9 type; - - // Construction and comparison functions - FastDelegate9() { clear(); } - FastDelegate9(const FastDelegate9 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate9 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate9 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate9 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate9 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate9 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate9(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate9(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate9(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9)) { - m_Closure.bindstaticfunc(this, &FastDelegate9::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9); } -}; - -//N=10 -template -class FastDelegate10 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate10 type; - - // Construction and comparison functions - FastDelegate10() { clear(); } - FastDelegate10(const FastDelegate10 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate10 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate10 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate10 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate10 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate10 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate10(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate10(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate10(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10)) { - m_Closure.bindstaticfunc(this, &FastDelegate10::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } -}; - -//N=11 -template -class FastDelegate11 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate11 type; - - // Construction and comparison functions - FastDelegate11() { clear(); } - FastDelegate11(const FastDelegate11 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate11 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate11 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate11 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate11 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate11 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate11(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate11(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate11(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { - m_Closure.bindstaticfunc(this, &FastDelegate11::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } -}; - -//N=12 -template -class FastDelegate12 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate12 type; - - // Construction and comparison functions - FastDelegate12() { clear(); } - FastDelegate12(const FastDelegate12 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate12 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate12 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate12 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate12 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate12 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate12(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate12(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate12(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { - m_Closure.bindstaticfunc(this, &FastDelegate12::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } -}; - -//N=13 -template -class FastDelegate13 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate13 type; - - // Construction and comparison functions - FastDelegate13() { clear(); } - FastDelegate13(const FastDelegate13 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate13 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate13 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate13 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate13 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate13 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate13(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate13(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate13(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { - m_Closure.bindstaticfunc(this, &FastDelegate13::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } -}; - -//N=14 -template -class FastDelegate14 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate14 type; - - // Construction and comparison functions - FastDelegate14() { clear(); } - FastDelegate14(const FastDelegate14 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate14 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate14 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate14 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate14 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate14 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate14(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate14(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate14(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)) { - m_Closure.bindstaticfunc(this, &FastDelegate14::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } -}; - -//N=15 -template -class FastDelegate15 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate15 type; - - // Construction and comparison functions - FastDelegate15() { clear(); } - FastDelegate15(const FastDelegate15 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate15 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate15 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate15 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate15 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate15 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate15(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate15(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate15(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)) { - m_Closure.bindstaticfunc(this, &FastDelegate15::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } -}; - -//N=16 -template -class FastDelegate16 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate16 type; - - // Construction and comparison functions - FastDelegate16() { clear(); } - FastDelegate16(const FastDelegate16 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate16 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate16 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate16 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate16 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate16 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate16(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate16(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate16(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)) { - m_Closure.bindstaticfunc(this, &FastDelegate16::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); } -}; - - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 4: -// -// FastDelegate<> class (Original author: Jody Hagins) -// Allows boost::function style syntax like: -// FastDelegate< double (int, long) > -// instead of: -// FastDelegate2< int, long, double > -// -//////////////////////////////////////////////////////////////////////////////// - -#ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -// Declare FastDelegate as a class template. It will be specialized -// later for all number of arguments. -template -class FastDelegate; - -//N=0 -// Specialization to allow use of -// FastDelegate< R ( ) > -// instead of -// FastDelegate0 < R > -template -class FastDelegate< R ( ) > - // Inherit from FastDelegate0 so that it can be treated just like a FastDelegate0 - : public FastDelegate0 < R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate0 < R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=1 -// Specialization to allow use of -// FastDelegate< R ( Param1 ) > -// instead of -// FastDelegate1 < Param1, R > -template -class FastDelegate< R ( Param1 ) > - // Inherit from FastDelegate1 so that it can be treated just like a FastDelegate1 - : public FastDelegate1 < Param1, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate1 < Param1, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=2 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2 ) > -// instead of -// FastDelegate2 < Param1, Param2, R > -template -class FastDelegate< R ( Param1, Param2 ) > - // Inherit from FastDelegate2 so that it can be treated just like a FastDelegate2 - : public FastDelegate2 < Param1, Param2, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate2 < Param1, Param2, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=3 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3 ) > -// instead of -// FastDelegate3 < Param1, Param2, Param3, R > -template -class FastDelegate< R ( Param1, Param2, Param3 ) > - // Inherit from FastDelegate3 so that it can be treated just like a FastDelegate3 - : public FastDelegate3 < Param1, Param2, Param3, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate3 < Param1, Param2, Param3, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=4 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4 ) > -// instead of -// FastDelegate4 < Param1, Param2, Param3, Param4, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4 ) > - // Inherit from FastDelegate4 so that it can be treated just like a FastDelegate4 - : public FastDelegate4 < Param1, Param2, Param3, Param4, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate4 < Param1, Param2, Param3, Param4, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=5 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) > -// instead of -// FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) > - // Inherit from FastDelegate5 so that it can be treated just like a FastDelegate5 - : public FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=6 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) > -// instead of -// FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) > - // Inherit from FastDelegate6 so that it can be treated just like a FastDelegate6 - : public FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=7 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) > -// instead of -// FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) > - // Inherit from FastDelegate7 so that it can be treated just like a FastDelegate7 - : public FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=8 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) > -// instead of -// FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) > - // Inherit from FastDelegate8 so that it can be treated just like a FastDelegate8 - : public FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=9 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9 ) > -// instead of -// FastDelegate9 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9 ) > - // Inherit from FastDelegate9 so that it can be treated just like a FastDelegate9 - : public FastDelegate9 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate9 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=10 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10 ) > -// instead of -// FastDelegate10 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10 ) > - // Inherit from FastDelegate10 so that it can be treated just like a FastDelegate10 - : public FastDelegate10 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate10 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=11 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11 ) > -// instead of -// FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11 ) > - // Inherit from FastDelegate11 so that it can be treated just like a FastDelegate11 - : public FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=12 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12 ) > -// instead of -// FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12 ) > - // Inherit from FastDelegate12 so that it can be treated just like a FastDelegate12 - : public FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=13 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13 ) > -// instead of -// FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13 ) > - // Inherit from FastDelegate13 so that it can be treated just like a FastDelegate13 - : public FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=14 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14 ) > -// instead of -// FastDelegate14 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14 ) > - // Inherit from FastDelegate14 so that it can be treated just like a FastDelegate14 - : public FastDelegate14 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate14 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=15 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15 ) > -// instead of -// FastDelegate15 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15 ) > - // Inherit from FastDelegate15 so that it can be treated just like a FastDelegate15 - : public FastDelegate15 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate15 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=16 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16 ) > -// instead of -// FastDelegate16 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16 ) > - // Inherit from FastDelegate16 so that it can be treated just like a FastDelegate16 - : public FastDelegate16 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate16 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - - -#endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 5: -// -// MakeDelegate() helper function -// -// MakeDelegate(&x, &X::func) returns a fastdelegate of the type -// necessary for calling x.func() with the correct number of arguments. -// This makes it possible to eliminate many typedefs from user code. -// -//////////////////////////////////////////////////////////////////////////////// - -// Also declare overloads of a MakeDelegate() global function to -// reduce the need for typedefs. -// We need seperate overloads for const and non-const member functions. -// Also, because of the weird rule about the class of derived member function pointers, -// implicit downcasts may need to be applied later to the 'this' pointer. -// That's why two classes (X and Y) appear in the definitions. Y must be implicitly -// castable to X. - -// Workaround for VC6. VC6 needs void return types converted into DefaultVoid. -// GCC 3.2 and later won't compile this unless it's preceded by 'typename', -// but VC6 doesn't allow 'typename' in this context. -// So, I have to use a macro. - -#ifdef FASTDLGT_VC6 -#define FASTDLGT_RETTYPE detail::VoidToDefaultVoid::type -#else -#define FASTDLGT_RETTYPE RetType -#endif - -//N=0 -template -FastDelegate0 MakeDelegate(Y* x, RetType (X::*func)()) { - return FastDelegate0(x, func); -} - -template -FastDelegate0 MakeDelegate(Y* x, RetType (X::*func)() const) { - return FastDelegate0(x, func); -} - -template -FastDelegate0 MakeDelegate(RetType (*func)()) { - return FastDelegate0(func); -} - -//N=1 -template -FastDelegate1 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1)) { - return FastDelegate1(x, func); -} - -template -FastDelegate1 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1) const) { - return FastDelegate1(x, func); -} - -template -FastDelegate1 MakeDelegate(RetType (*func)(Param1 p1)) { - return FastDelegate1(func); -} - -//N=2 -template -FastDelegate2 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2)) { - return FastDelegate2(x, func); -} - -template -FastDelegate2 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2) const) { - return FastDelegate2(x, func); -} - -template -FastDelegate2 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2)) { - return FastDelegate2(func); -} - -//N=3 -template -FastDelegate3 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3)) { - return FastDelegate3(x, func); -} - -template -FastDelegate3 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3) const) { - return FastDelegate3(x, func); -} - -template -FastDelegate3 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3)) { - return FastDelegate3(func); -} - -//N=4 -template -FastDelegate4 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { - return FastDelegate4(x, func); -} - -template -FastDelegate4 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { - return FastDelegate4(x, func); -} - -template -FastDelegate4 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { - return FastDelegate4(func); -} - -//N=5 -template -FastDelegate5 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { - return FastDelegate5(x, func); -} - -template -FastDelegate5 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { - return FastDelegate5(x, func); -} - -template -FastDelegate5 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { - return FastDelegate5(func); -} - -//N=6 -template -FastDelegate6 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { - return FastDelegate6(x, func); -} - -template -FastDelegate6 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { - return FastDelegate6(x, func); -} - -template -FastDelegate6 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { - return FastDelegate6(func); -} - -//N=7 -template -FastDelegate7 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { - return FastDelegate7(x, func); -} - -template -FastDelegate7 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { - return FastDelegate7(x, func); -} - -template -FastDelegate7 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { - return FastDelegate7(func); -} - -//N=8 -template -FastDelegate8 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { - return FastDelegate8(x, func); -} - -template -FastDelegate8 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { - return FastDelegate8(x, func); -} - -template -FastDelegate8 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { - return FastDelegate8(func); -} - -//N=9 -template -FastDelegate9 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9)) { - return FastDelegate9(x, func); -} - -template -FastDelegate9 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const) { - return FastDelegate9(x, func); -} - -template -FastDelegate9 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9)) { - return FastDelegate9(func); -} - -//N=10 -template -FastDelegate10 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10)) { - return FastDelegate10(x, func); -} - -template -FastDelegate10 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const) { - return FastDelegate10(x, func); -} - -template -FastDelegate10 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10)) { - return FastDelegate10(func); -} - -//N=11 -template -FastDelegate11 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { - return FastDelegate11(x, func); -} - -template -FastDelegate11 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { - return FastDelegate11(x, func); -} - -template -FastDelegate11 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { - return FastDelegate11(func); -} - -//N=12 -template -FastDelegate12 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { - return FastDelegate12(x, func); -} - -template -FastDelegate12 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { - return FastDelegate12(x, func); -} - -template -FastDelegate12 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { - return FastDelegate12(func); -} - -//N=13 -template -FastDelegate13 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { - return FastDelegate13(x, func); -} - -template -FastDelegate13 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { - return FastDelegate13(x, func); -} - -template -FastDelegate13 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { - return FastDelegate13(func); -} - -//N=14 -template -FastDelegate14 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)) { - return FastDelegate14(x, func); -} - -template -FastDelegate14 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const) { - return FastDelegate14(x, func); -} - -template -FastDelegate14 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)) { - return FastDelegate14(func); -} - -//N=15 -template -FastDelegate15 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)) { - return FastDelegate15(x, func); -} - -template -FastDelegate15 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const) { - return FastDelegate15(x, func); -} - -template -FastDelegate15 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)) { - return FastDelegate15(func); -} - -//N=16 -template -FastDelegate16 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)) { - return FastDelegate16(x, func); -} - -template -FastDelegate16 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const) { - return FastDelegate16(x, func); -} - -template -FastDelegate16 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)) { - return FastDelegate16(func); -} - - - // clean up after ourselves... -#undef FASTDLGT_RETTYPE - -} // namespace fastdelegate - -#endif // !defined(FASTDELEGATE_H) diff --git a/sourcehook/generate/FastDelegate.h b/sourcehook/generate/FastDelegate.h deleted file mode 100644 index 59d63ff..0000000 --- a/sourcehook/generate/FastDelegate.h +++ /dev/null @@ -1,3259 +0,0 @@ -// FastDelegate.h -// Efficient delegates in C++ that generate only two lines of asm code! -// Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp -// -// - Don Clugston, Mar 2004. -// Major contributions were made by Jody Hagins. -// History: -// 24-Apr-04 1.0 * Submitted to CodeProject. -// 28-Apr-04 1.1 * Prevent most unsafe uses of evil static function hack. -// * Improved syntax for horrible_cast (thanks Paul Bludov). -// * Tested on Metrowerks MWCC and Intel ICL (IA32) -// * Compiled, but not run, on Comeau C++ and Intel Itanium ICL. -// 27-Jun-04 1.2 * Now works on Borland C++ Builder 5.5 -// * Now works on /clr "managed C++" code on VC7, VC7.1 -// * Comeau C++ now compiles without warnings. -// * Prevent the virtual inheritance case from being used on -// VC6 and earlier, which generate incorrect code. -// * Improved warning and error messages. Non-standard hacks -// now have compile-time checks to make them safer. -// * implicit_cast used instead of static_cast in many cases. -// * If calling a const member function, a const class pointer can be used. -// * MakeDelegate() global helper function added to simplify pass-by-value. -// * Added fastdelegate.clear() -// 16-Jul-04 1.2.1* Workaround for gcc bug (const member function pointers in templates) -// 30-Oct-04 1.3 * Support for (non-void) return values. -// * No more workarounds in client code! -// MSVC and Intel now use a clever hack invented by John Dlugosz: -// - The FASTDELEGATEDECLARE workaround is no longer necessary. -// - No more warning messages for VC6 -// * Less use of macros. Error messages should be more comprehensible. -// * Added include guards -// * Added FastDelegate::empty() to test if invocation is safe (Thanks Neville Franks). -// * Now tested on VS 2005 Express Beta, PGI C++ -// 24-Dec-04 1.4 * Added DelegateMemento, to allow collections of disparate delegates. -// * <,>,<=,>= comparison operators to allow storage in ordered containers. -// * Substantial reduction of code size, especially the 'Closure' class. -// * Standardised all the compiler-specific workarounds. -// * MFP conversion now works for CodePlay (but not yet supported in the full code). -// * Now compiles without warnings on _any_ supported compiler, including BCC 5.5.1 -// * New syntax: FastDelegate< int (char *, double) >. -// 14-Feb-05 1.4.1* Now treats =0 as equivalent to .clear(), ==0 as equivalent to .empty(). (Thanks elfric). -// * Now tested on Intel ICL for AMD64, VS2005 Beta for AMD64 and Itanium. -// 30-Mar-05 1.5 * Safebool idiom: "if (dg)" is now equivalent to "if (!dg.empty())" -// * Fully supported by CodePlay VectorC -// * Bugfix for Metrowerks: empty() was buggy because a valid MFP can be 0 on MWCC! -// * More optimal assignment,== and != operators for static function pointers. - -#ifndef FASTDELEGATE_H -#define FASTDELEGATE_H - -#ifdef _MSC_VER -# if _MSC_VER > 1000 -# pragma once -# endif // _MSC_VER > 1000 -#endif // #ifdef _MSC_VER - -#include // to allow <,> comparisons - -//////////////////////////////////////////////////////////////////////////////// -// Configuration options -// -//////////////////////////////////////////////////////////////////////////////// - -// Uncomment the following #define for optimally-sized delegates. -// In this case, the generated asm code is almost identical to the code you'd get -// if the compiler had native support for delegates. -// It will not work on systems where sizeof(dataptr) < sizeof(codeptr). -// Thus, it will not work for DOS compilers using the medium model. -// It will also probably fail on some DSP systems. -#define FASTDELEGATE_USESTATICFUNCTIONHACK - -// Uncomment the next line to allow function declarator syntax. -// It is automatically enabled for those compilers where it is known to work. -//#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -//////////////////////////////////////////////////////////////////////////////// -// Compiler identification for workarounds -// -//////////////////////////////////////////////////////////////////////////////// - -// Compiler identification. It's not easy to identify Visual C++ because -// many vendors fraudulently define Microsoft's identifiers. -#if defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__VECTOR_C) && !defined(__ICL) && !defined(__BORLANDC__) -#define FASTDLGT_ISMSVC - -#if (_MSC_VER <1300) // Many workarounds are required for VC6. -#define FASTDLGT_VC6 -#pragma warning(disable:4786) // disable this ridiculous warning -#endif - -#endif - -// Does the compiler uses Microsoft's member function pointer structure? -// If so, it needs special treatment. -// Metrowerks CodeWarrior, Intel, and CodePlay fraudulently define Microsoft's -// identifier, _MSC_VER. We need to filter Metrowerks out. -#if defined(_MSC_VER) && !defined(__MWERKS__) -#define FASTDLGT_MICROSOFT_MFP - -#if !defined(__VECTOR_C) -// CodePlay doesn't have the __single/multi/virtual_inheritance keywords -#define FASTDLGT_HASINHERITANCE_KEYWORDS -#endif -#endif - -// Does it allow function declarator syntax? The following compilers are known to work: -#if defined(FASTDLGT_ISMSVC) && (_MSC_VER >=1310) // VC 7.1 -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -// Gcc(2.95+), and versions of Digital Mars, Intel and Comeau in common use. -#if defined (__DMC__) || defined(__GNUC__) || defined(__ICL) || defined(__COMO__) -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -// It works on Metrowerks MWCC 3.2.2. From boost.Config it should work on earlier ones too. -#if defined (__MWERKS__) -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -#ifdef __GNUC__ // Workaround GCC bug #8271 - // At present, GCC doesn't recognize constness of MFPs in templates -#define FASTDELEGATE_GCC_BUG_8271 -#endif - - - -//////////////////////////////////////////////////////////////////////////////// -// General tricks used in this code -// -// (a) Error messages are generated by typdefing an array of negative size to -// generate compile-time errors. -// (b) Warning messages on MSVC are generated by declaring unused variables, and -// enabling the "variable XXX is never used" warning. -// (c) Unions are used in a few compiler-specific cases to perform illegal casts. -// (d) For Microsoft and Intel, when adjusting the 'this' pointer, it's cast to -// (char *) first to ensure that the correct number of *bytes* are added. -// -//////////////////////////////////////////////////////////////////////////////// -// Helper templates -// -//////////////////////////////////////////////////////////////////////////////// - - -namespace fastdelegate { -namespace detail { // we'll hide the implementation details in a nested namespace. - -// implicit_cast< > -// I believe this was originally going to be in the C++ standard but -// was left out by accident. It's even milder than static_cast. -// I use it instead of static_cast<> to emphasize that I'm not doing -// anything nasty. -// Usage is identical to static_cast<> -template -inline OutputClass implicit_cast(InputClass input){ - return input; -} - -// horrible_cast< > -// This is truly evil. It completely subverts C++'s type system, allowing you -// to cast from any class to any other class. Technically, using a union -// to perform the cast is undefined behaviour (even in C). But we can see if -// it is OK by checking that the union is the same size as each of its members. -// horrible_cast<> should only be used for compiler-specific workarounds. -// Usage is identical to reinterpret_cast<>. - -// This union is declared outside the horrible_cast because BCC 5.5.1 -// can't inline a function with a nested class, and gives a warning. -template -union horrible_union{ - OutputClass out; - InputClass in; -}; - -template -inline OutputClass horrible_cast(const InputClass input){ - horrible_union u; - // Cause a compile-time error if in, out and u are not the same size. - // If the compile fails here, it means the compiler has peculiar - // unions which would prevent the cast from working. - typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u) - && sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1]; - u.in = input; - return u.out; -} - -//////////////////////////////////////////////////////////////////////////////// -// Workarounds -// -//////////////////////////////////////////////////////////////////////////////// - -// Backwards compatibility: This macro used to be necessary in the virtual inheritance -// case for Intel and Microsoft. Now it just forward-declares the class. -#define FASTDELEGATEDECLARE(CLASSNAME) class CLASSNAME; - -// Prevent use of the static function hack with the DOS medium model. -#ifdef __MEDIUM__ -#undef FASTDELEGATE_USESTATICFUNCTIONHACK -#endif - -// DefaultVoid - a workaround for 'void' templates in VC6. -// -// (1) VC6 and earlier do not allow 'void' as a default template argument. -// (2) They also doesn't allow you to return 'void' from a function. -// -// Workaround for (1): Declare a dummy type 'DefaultVoid' which we use -// when we'd like to use 'void'. We convert it into 'void' and back -// using the templates DefaultVoidToVoid<> and VoidToDefaultVoid<>. -// Workaround for (2): On VC6, the code for calling a void function is -// identical to the code for calling a non-void function in which the -// return value is never used, provided the return value is returned -// in the EAX register, rather than on the stack. -// This is true for most fundamental types such as int, enum, void *. -// Const void * is the safest option since it doesn't participate -// in any automatic conversions. But on a 16-bit compiler it might -// cause extra code to be generated, so we disable it for all compilers -// except for VC6 (and VC5). -#ifdef FASTDLGT_VC6 -// VC6 workaround -typedef const void * DefaultVoid; -#else -// On any other compiler, just use a normal void. -typedef void DefaultVoid; -#endif - -// Translate from 'DefaultVoid' to 'void'. -// Everything else is unchanged -template -struct DefaultVoidToVoid { typedef T type; }; - -template <> -struct DefaultVoidToVoid { typedef void type; }; - -// Translate from 'void' into 'DefaultVoid' -// Everything else is unchanged -template -struct VoidToDefaultVoid { typedef T type; }; - -template <> -struct VoidToDefaultVoid { typedef DefaultVoid type; }; - - - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 1: -// -// Conversion of member function pointer to a standard form -// -//////////////////////////////////////////////////////////////////////////////// - -// GenericClass is a fake class, ONLY used to provide a type. -// It is vitally important that it is never defined, so that the compiler doesn't -// think it can optimize the invocation. For example, Borland generates simpler -// code if it knows the class only uses single inheritance. - -// Compilers using Microsoft's structure need to be treated as a special case. -#ifdef FASTDLGT_MICROSOFT_MFP - -#ifdef FASTDLGT_HASINHERITANCE_KEYWORDS - // For Microsoft and Intel, we want to ensure that it's the most efficient type of MFP - // (4 bytes), even when the /vmg option is used. Declaring an empty class - // would give 16 byte pointers in this case.... - class __single_inheritance GenericClass; -#endif - // ...but for Codeplay, an empty class *always* gives 4 byte pointers. - // If compiled with the /clr option ("managed C++"), the JIT compiler thinks - // it needs to load GenericClass before it can call any of its functions, - // (compiles OK but crashes at runtime!), so we need to declare an - // empty class to make it happy. - // Codeplay and VC4 can't cope with the unknown_inheritance case either. - class GenericClass {}; -#else - class GenericClass; -#endif - -// The size of a single inheritance member function pointer. -const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)()); - -// SimplifyMemFunc< >::Convert() -// -// A template function that converts an arbitrary member function pointer into the -// simplest possible form of member function pointer, using a supplied 'this' pointer. -// According to the standard, this can be done legally with reinterpret_cast<>. -// For (non-standard) compilers which use member function pointers which vary in size -// depending on the class, we need to use knowledge of the internal structure of a -// member function pointer, as used by the compiler. Template specialization is used -// to distinguish between the sizes. Because some compilers don't support partial -// template specialisation, I use full specialisation of a wrapper struct. - -// general case -- don't know how to convert it. Force a compile failure -template -struct SimplifyMemFunc { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // Unsupported member function type -- force a compile failure. - // (it's illegal to have a array with negative size). - typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100]; - return 0; - } -}; - -// For compilers where all member func ptrs are the same size, everything goes here. -// For non-standard compilers, only single_inheritance classes go here. -template <> -struct SimplifyMemFunc { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { -#if defined __DMC__ - // Digital Mars doesn't allow you to cast between abitrary PMF's, - // even though the standard says you can. The 32-bit compiler lets you - // static_cast through an int, but the DOS compiler doesn't. - bound_func = horrible_cast(function_to_bind); -#else - bound_func = reinterpret_cast(function_to_bind); -#endif - return reinterpret_cast(pthis); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 1b: -// -// Workarounds for Microsoft and Intel -// -//////////////////////////////////////////////////////////////////////////////// - - -// Compilers with member function pointers which violate the standard (MSVC, Intel, Codeplay), -// need to be treated as a special case. -#ifdef FASTDLGT_MICROSOFT_MFP - -// We use unions to perform horrible_casts. I would like to use #pragma pack(push, 1) -// at the start of each function for extra safety, but VC6 seems to ICE -// intermittently if you do this inside a template. - -// __multiple_inheritance classes go here -// Nasty hack for Microsoft and Intel (IA32 and Itanium) -template<> -struct SimplifyMemFunc< SINGLE_MEMFUNCPTR_SIZE + sizeof(int) > { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // We need to use a horrible_cast to do this conversion. - // In MSVC, a multiple inheritance member pointer is internally defined as: - union { - XFuncType func; - struct { - GenericMemFuncType funcaddress; // points to the actual member function - int delta; // #BYTES to be added to the 'this' pointer - }s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)? 1 : -1]; - u.func = function_to_bind; - bound_func = u.s.funcaddress; - return reinterpret_cast(reinterpret_cast(pthis) + u.s.delta); - } -}; - -// virtual inheritance is a real nuisance. It's inefficient and complicated. -// On MSVC and Intel, there isn't enough information in the pointer itself to -// enable conversion to a closure pointer. Earlier versions of this code didn't -// work for all cases, and generated a compile-time error instead. -// But a very clever hack invented by John M. Dlugosz solves this problem. -// My code is somewhat different to his: I have no asm code, and I make no -// assumptions about the calling convention that is used. - -// In VC++ and ICL, a virtual_inheritance member pointer -// is internally defined as: -struct MicrosoftVirtualMFP { - void (GenericClass::*codeptr)(); // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtable_index; // or 0 if no virtual inheritance -}; -// The CRUCIAL feature of Microsoft/Intel MFPs which we exploit is that the -// m_codeptr member is *always* called, regardless of the values of the other -// members. (This is *not* true for other compilers, eg GCC, which obtain the -// function address from the vtable if a virtual function is being called). -// Dlugosz's trick is to make the codeptr point to a probe function which -// returns the 'this' pointer that was used. - -// Define a generic class that uses virtual inheritance. -// It has a trival member function that returns the value of the 'this' pointer. -struct GenericVirtualClass : virtual public GenericClass -{ - typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)(); - GenericVirtualClass * GetThis() { return this; } -}; - -// __virtual_inheritance classes go here -template <> -struct SimplifyMemFunc -{ - - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - union { - XFuncType func; - GenericClass* (X::*ProbeFunc)(); - MicrosoftVirtualMFP s; - } u; - u.func = function_to_bind; - bound_func = reinterpret_cast(u.s.codeptr); - union { - GenericVirtualClass::ProbePtrType virtfunc; - MicrosoftVirtualMFP s; - } u2; - // Check that the horrible_cast<>s will work - typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s) - && sizeof(function_to_bind)==sizeof(u.ProbeFunc) - && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1]; - // Unfortunately, taking the address of a MF prevents it from being inlined, so - // this next line can't be completely optimised away by the compiler. - u2.virtfunc = &GenericVirtualClass::GetThis; - u.s.codeptr = u2.s.codeptr; - return (pthis->*u.ProbeFunc)(); - } -}; - -#if (_MSC_VER <1300) - -// Nasty hack for Microsoft Visual C++ 6.0 -// unknown_inheritance classes go here -// There is a compiler bug in MSVC6 which generates incorrect code in this case!! -template <> -struct SimplifyMemFunc -{ - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // There is an apalling but obscure compiler bug in MSVC6 and earlier: - // vtable_index and 'vtordisp' are always set to 0 in the - // unknown_inheritance case! - // This means that an incorrect function could be called!!! - // Compiling with the /vmg option leads to potentially incorrect code. - // This is probably the reason that the IDE has a user interface for specifying - // the /vmg option, but it is disabled - you can only specify /vmg on - // the command line. In VC1.5 and earlier, the compiler would ICE if it ever - // encountered this situation. - // It is OK to use the /vmg option if /vmm or /vms is specified. - - // Fortunately, the wrong function is only called in very obscure cases. - // It only occurs when a derived class overrides a virtual function declared - // in a virtual base class, and the member function - // points to the *Derived* version of that function. The problem can be - // completely averted in 100% of cases by using the *Base class* for the - // member fpointer. Ie, if you use the base class as an interface, you'll - // stay out of trouble. - // Occasionally, you might want to point directly to a derived class function - // that isn't an override of a base class. In this case, both vtable_index - // and 'vtordisp' are zero, but a virtual_inheritance pointer will be generated. - // We can generate correct code in this case. To prevent an incorrect call from - // ever being made, on MSVC6 we generate a warning, and call a function to - // make the program crash instantly. - typedef char ERROR_VC6CompilerBug[-100]; - return 0; - } -}; - - -#else - -// Nasty hack for Microsoft and Intel (IA32 and Itanium) -// unknown_inheritance classes go here -// This is probably the ugliest bit of code I've ever written. Look at the casts! -// There is a compiler bug in MSVC6 which prevents it from using this code. -template <> -struct SimplifyMemFunc -{ - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // The member function pointer is 16 bytes long. We can't use a normal cast, but - // we can use a union to do the conversion. - union { - XFuncType func; - // In VC++ and ICL, an unknown_inheritance member pointer - // is internally defined as: - struct { - GenericMemFuncType m_funcaddress; // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtordisp; // #bytes to add to 'this' to find the vtable - int vtable_index; // or 0 if no virtual inheritance - } s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(XFuncType)==sizeof(u.s)? 1 : -1]; - u.func = function_to_bind; - bound_func = u.s.funcaddress; - int virtual_delta = 0; - if (u.s.vtable_index) { // Virtual inheritance is used - // First, get to the vtable. - // It is 'vtordisp' bytes from the start of the class. - const int * vtable = *reinterpret_cast( - reinterpret_cast(pthis) + u.s.vtordisp ); - - // 'vtable_index' tells us where in the table we should be looking. - virtual_delta = u.s.vtordisp + *reinterpret_cast( - reinterpret_cast(vtable) + u.s.vtable_index); - } - // The int at 'virtual_delta' gives us the amount to add to 'this'. - // Finally we can add the three components together. Phew! - return reinterpret_cast( - reinterpret_cast(pthis) + u.s.delta + virtual_delta); - }; -}; -#endif // MSVC 7 and greater - -#endif // MS/Intel hacks - -} // namespace detail - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 2: -// -// Define the delegate storage, and cope with static functions -// -//////////////////////////////////////////////////////////////////////////////// - -// DelegateMemento -- an opaque structure which can hold an arbitary delegate. -// It knows nothing about the calling convention or number of arguments used by -// the function pointed to. -// It supplies comparison operators so that it can be stored in STL collections. -// It cannot be set to anything other than null, nor invoked directly: -// it must be converted to a specific delegate. - -// Implementation: -// There are two possible implementations: the Safe method and the Evil method. -// DelegateMemento - Safe version -// -// This implementation is standard-compliant, but a bit tricky. -// A static function pointer is stored inside the class. -// Here are the valid values: -// +-- Static pointer --+--pThis --+-- pMemFunc-+-- Meaning------+ -// | 0 | 0 | 0 | Empty | -// | !=0 |(dontcare)| Invoker | Static function| -// | 0 | !=0 | !=0* | Method call | -// +--------------------+----------+------------+----------------+ -// * For Metrowerks, this can be 0. (first virtual function in a -// single_inheritance class). -// When stored stored inside a specific delegate, the 'dontcare' entries are replaced -// with a reference to the delegate itself. This complicates the = and == operators -// for the delegate class. - -// DelegateMemento - Evil version -// -// For compilers where data pointers are at least as big as code pointers, it is -// possible to store the function pointer in the this pointer, using another -// horrible_cast. In this case the DelegateMemento implementation is simple: -// +--pThis --+-- pMemFunc-+-- Meaning---------------------+ -// | 0 | 0 | Empty | -// | !=0 | !=0* | Static function or method call| -// +----------+------------+-------------------------------+ -// * For Metrowerks, this can be 0. (first virtual function in a -// single_inheritance class). -// Note that the Sun C++ and MSVC documentation explicitly state that they -// support static_cast between void * and function pointers. - -class DelegateMemento { -protected: - // the data is protected, not private, because many - // compilers have problems with template friends. - typedef void (detail::GenericClass::*GenericMemFuncType)(); // arbitrary MFP. - detail::GenericClass *m_pthis; - GenericMemFuncType m_pFunction; - -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - typedef void (*GenericFuncPtr)(); // arbitrary code pointer - GenericFuncPtr m_pStaticFunction; -#endif - -public: -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - DelegateMemento() : m_pthis(0), m_pFunction(0), m_pStaticFunction(0) {}; - void clear() { - m_pthis=0; m_pFunction=0; m_pStaticFunction=0; - } -#else - DelegateMemento() : m_pthis(0), m_pFunction(0) {}; - void clear() { m_pthis=0; m_pFunction=0; } -#endif -public: -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - inline bool IsEqual (const DelegateMemento &x) const{ - // We have to cope with the static function pointers as a special case - if (m_pFunction!=x.m_pFunction) return false; - // the static function ptrs must either both be equal, or both be 0. - if (m_pStaticFunction!=x.m_pStaticFunction) return false; - if (m_pStaticFunction!=0) return m_pthis==x.m_pthis; - else return true; - } -#else // Evil Method - inline bool IsEqual (const DelegateMemento &x) const{ - return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction; - } -#endif - // Provide a strict weak ordering for DelegateMementos. - inline bool IsLess(const DelegateMemento &right) const { - // deal with static function pointers first -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - if (m_pStaticFunction !=0 || right.m_pStaticFunction!=0) - return m_pStaticFunction < right.m_pStaticFunction; -#endif - if (m_pthis !=right.m_pthis) return m_pthis < right.m_pthis; - // There are no ordering operators for member function pointers, - // but we can fake one by comparing each byte. The resulting ordering is - // arbitrary (and compiler-dependent), but it permits storage in ordered STL containers. - return memcmp(&m_pFunction, &right.m_pFunction, sizeof(m_pFunction)) < 0; - - } - // BUGFIX (Mar 2005): - // We can't just compare m_pFunction because on Metrowerks, - // m_pFunction can be zero even if the delegate is not empty! - inline bool operator ! () const // Is it bound to anything? - { return m_pthis==0 && m_pFunction==0; } - inline bool empty() const // Is it bound to anything? - { return m_pthis==0 && m_pFunction==0; } -public: - DelegateMemento & operator = (const DelegateMemento &right) { - SetMementoFrom(right); - return *this; - } - inline bool operator <(const DelegateMemento &right) { - return IsLess(right); - } - inline bool operator >(const DelegateMemento &right) { - return right.IsLess(*this); - } - DelegateMemento (const DelegateMemento &right) : - m_pthis(right.m_pthis), m_pFunction(right.m_pFunction) -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - , m_pStaticFunction (right.m_pStaticFunction) -#endif - {} -protected: - void SetMementoFrom(const DelegateMemento &right) { - m_pFunction = right.m_pFunction; - m_pthis = right.m_pthis; -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = right.m_pStaticFunction; -#endif - } -}; - - -// ClosurePtr<> -// -// A private wrapper class that adds function signatures to DelegateMemento. -// It's the class that does most of the actual work. -// The signatures are specified by: -// GenericMemFunc: must be a type of GenericClass member function pointer. -// StaticFuncPtr: must be a type of function pointer with the same signature -// as GenericMemFunc. -// UnvoidStaticFuncPtr: is the same as StaticFuncPtr, except on VC6 -// where it never returns void (returns DefaultVoid instead). - -// An outer class, FastDelegateN<>, handles the invoking and creates the -// necessary typedefs. -// This class does everything else. - -namespace detail { - -template < class GenericMemFunc, class StaticFuncPtr, class UnvoidStaticFuncPtr> -class ClosurePtr : public DelegateMemento { -public: - // These functions are for setting the delegate to a member function. - - // Here's the clever bit: we convert an arbitrary member function into a - // standard form. XMemFunc should be a member function of class X, but I can't - // enforce that here. It needs to be enforced by the wrapper class. - template < class X, class XMemFunc > - inline void bindmemfunc(X *pthis, XMemFunc function_to_bind ) { - m_pthis = SimplifyMemFunc< sizeof(function_to_bind) > - ::Convert(pthis, function_to_bind, m_pFunction); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } - // For const member functions, we only need a const class pointer. - // Since we know that the member function is const, it's safe to - // remove the const qualifier from the 'this' pointer with a const_cast. - // VC6 has problems if we just overload 'bindmemfunc', so we give it a different name. - template < class X, class XMemFunc> - inline void bindconstmemfunc(const X *pthis, XMemFunc function_to_bind) { - m_pthis= SimplifyMemFunc< sizeof(function_to_bind) > - ::Convert(const_cast(pthis), function_to_bind, m_pFunction); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } -#ifdef FASTDELEGATE_GCC_BUG_8271 // At present, GCC doesn't recognize constness of MFPs in templates - template < class X, class XMemFunc> - inline void bindmemfunc(const X *pthis, XMemFunc function_to_bind) { - bindconstmemfunc(pthis, function_to_bind); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } -#endif - // These functions are required for invoking the stored function - inline GenericClass *GetClosureThis() const { return m_pthis; } - inline GenericMemFunc GetClosureMemPtr() const { return reinterpret_cast(m_pFunction); } - -// There are a few ways of dealing with static function pointers. -// There's a standard-compliant, but tricky method. -// There's also a straightforward hack, that won't work on DOS compilers using the -// medium memory model. It's so evil that I can't recommend it, but I've -// implemented it anyway because it produces very nice asm code. - -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - -// ClosurePtr<> - Safe version -// -// This implementation is standard-compliant, but a bit tricky. -// I store the function pointer inside the class, and the delegate then -// points to itself. Whenever the delegate is copied, these self-references -// must be transformed, and this complicates the = and == operators. -public: - // The next two functions are for operator ==, =, and the copy constructor. - // We may need to convert the m_pthis pointers, so that - // they remain as self-references. - template< class DerivedClass > - inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &x) { - SetMementoFrom(x); - if (m_pStaticFunction!=0) { - // transform self references... - m_pthis=reinterpret_cast(pParent); - } - } - // For static functions, the 'static_function_invoker' class in the parent - // will be called. The parent then needs to call GetStaticFunction() to find out - // the actual function to invoke. - template < class DerivedClass, class ParentInvokerSig > - inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, - StaticFuncPtr function_to_bind ) { - if (function_to_bind==0) { // cope with assignment to 0 - m_pFunction=0; - } else { - bindmemfunc(pParent, static_function_invoker); - } - m_pStaticFunction=reinterpret_cast(function_to_bind); - } - inline UnvoidStaticFuncPtr GetStaticFunction() const { - return reinterpret_cast(m_pStaticFunction); - } -#else - -// ClosurePtr<> - Evil version -// -// For compilers where data pointers are at least as big as code pointers, it is -// possible to store the function pointer in the this pointer, using another -// horrible_cast. Invocation isn't any faster, but it saves 4 bytes, and -// speeds up comparison and assignment. If C++ provided direct language support -// for delegates, they would produce asm code that was almost identical to this. -// Note that the Sun C++ and MSVC documentation explicitly state that they -// support static_cast between void * and function pointers. - - template< class DerivedClass > - inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &right) { - SetMementoFrom(right); - } - // For static functions, the 'static_function_invoker' class in the parent - // will be called. The parent then needs to call GetStaticFunction() to find out - // the actual function to invoke. - // ******** EVIL, EVIL CODE! ******* - template < class DerivedClass, class ParentInvokerSig> - inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, - StaticFuncPtr function_to_bind) { - if (function_to_bind==0) { // cope with assignment to 0 - m_pFunction=0; - } else { - // We'll be ignoring the 'this' pointer, but we need to make sure we pass - // a valid value to bindmemfunc(). - bindmemfunc(pParent, static_function_invoker); - } - - // WARNING! Evil hack. We store the function in the 'this' pointer! - // Ensure that there's a compilation failure if function pointers - // and data pointers have different sizes. - // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK. - typedef int ERROR_CantUseEvilMethod[sizeof(GenericClass *)==sizeof(function_to_bind) ? 1 : -1]; - m_pthis = horrible_cast(function_to_bind); - // MSVC, SunC++ and DMC accept the following (non-standard) code: -// m_pthis = static_cast(static_cast(function_to_bind)); - // BCC32, Comeau and DMC accept this method. MSVC7.1 needs __int64 instead of long -// m_pthis = reinterpret_cast(reinterpret_cast(function_to_bind)); - } - // ******** EVIL, EVIL CODE! ******* - // This function will be called with an invalid 'this' pointer!! - // We're just returning the 'this' pointer, converted into - // a function pointer! - inline UnvoidStaticFuncPtr GetStaticFunction() const { - // Ensure that there's a compilation failure if function pointers - // and data pointers have different sizes. - // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK. - typedef int ERROR_CantUseEvilMethod[sizeof(UnvoidStaticFuncPtr)==sizeof(this) ? 1 : -1]; - return horrible_cast(this); - } -#endif // !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - - // Does the closure contain this static function? - inline bool IsEqualToStaticFuncPtr(StaticFuncPtr funcptr){ - if (funcptr==0) return empty(); - // For the Evil method, if it doesn't actually contain a static function, this will return an arbitrary - // value that is not equal to any valid function pointer. - else return funcptr==reinterpret_cast(GetStaticFunction()); - } -}; - - -} // namespace detail - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 3: -// -// Wrapper classes to ensure type safety -// -//////////////////////////////////////////////////////////////////////////////// - - -// Once we have the member function conversion templates, it's easy to make the -// wrapper classes. So that they will work with as many compilers as possible, -// the classes are of the form -// FastDelegate3 -// They can cope with any combination of parameters. The max number of parameters -// allowed is 8, but it is trivial to increase this limit. -// Note that we need to treat const member functions seperately. -// All this class does is to enforce type safety, and invoke the delegate with -// the correct list of parameters. - -// Because of the weird rule about the class of derived member function pointers, -// you sometimes need to apply a downcast to the 'this' pointer. -// This is the reason for the use of "implicit_cast(pthis)" in the code below. -// If CDerivedClass is derived from CBaseClass, but doesn't override SimpleVirtualFunction, -// without this trick you'd need to write: -// MyDelegate(static_cast(&d), &CDerivedClass::SimpleVirtualFunction); -// but with the trick you can write -// MyDelegate(&d, &CDerivedClass::SimpleVirtualFunction); - -// RetType is the type the compiler uses in compiling the template. For VC6, -// it cannot be void. DesiredRetType is the real type which is returned from -// all of the functions. It can be void. - -// Implicit conversion to "bool" is achieved using the safe_bool idiom, -// using member data pointers (MDP). This allows "if (dg)..." syntax -// Because some compilers (eg codeplay) don't have a unique value for a zero -// MDP, an extra padding member is added to the SafeBool struct. -// Some compilers (eg VC6) won't implicitly convert from 0 to an MDP, so -// in that case the static function constructor is not made explicit; this -// allows "if (dg==0) ..." to compile. - -//N=0 -template -class FastDelegate0 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(); - typedef RetType (*UnvoidStaticFunctionPtr)(); - typedef RetType (detail::GenericClass::*GenericMemFn)(); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate0 type; - - // Construction and comparison functions - FastDelegate0() { clear(); } - FastDelegate0(const FastDelegate0 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate0 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate0 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate0 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate0 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate0 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate0(Y *pthis, DesiredRetType (X::* function_to_bind)() ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)()) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate0(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate0(DesiredRetType (*function_to_bind)() ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)() ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)()) { - m_Closure.bindstaticfunc(this, &FastDelegate0::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() () const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction() const { - return (*(m_Closure.GetStaticFunction()))(); } -}; - -//N=1 -template -class FastDelegate1 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate1 type; - - // Construction and comparison functions - FastDelegate1() { clear(); } - FastDelegate1(const FastDelegate1 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate1 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate1 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate1 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate1 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate1 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate1(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate1(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate1(DesiredRetType (*function_to_bind)(Param1 p1) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1)) { - m_Closure.bindstaticfunc(this, &FastDelegate1::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1) const { - return (*(m_Closure.GetStaticFunction()))(p1); } -}; - -//N=2 -template -class FastDelegate2 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate2 type; - - // Construction and comparison functions - FastDelegate2() { clear(); } - FastDelegate2(const FastDelegate2 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate2 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate2 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate2 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate2 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate2 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate2(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate2(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate2(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2)) { - m_Closure.bindstaticfunc(this, &FastDelegate2::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2); } -}; - -//N=3 -template -class FastDelegate3 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate3 type; - - // Construction and comparison functions - FastDelegate3() { clear(); } - FastDelegate3(const FastDelegate3 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate3 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate3 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate3 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate3 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate3 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate3(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate3(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate3(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) { - m_Closure.bindstaticfunc(this, &FastDelegate3::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3); } -}; - -//N=4 -template -class FastDelegate4 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate4 type; - - // Construction and comparison functions - FastDelegate4() { clear(); } - FastDelegate4(const FastDelegate4 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate4 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate4 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate4 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate4 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate4 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate4(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate4(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate4(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { - m_Closure.bindstaticfunc(this, &FastDelegate4::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4); } -}; - -//N=5 -template -class FastDelegate5 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate5 type; - - // Construction and comparison functions - FastDelegate5() { clear(); } - FastDelegate5(const FastDelegate5 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate5 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate5 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate5 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate5 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate5 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate5(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate5(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate5(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { - m_Closure.bindstaticfunc(this, &FastDelegate5::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5); } -}; - -//N=6 -template -class FastDelegate6 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate6 type; - - // Construction and comparison functions - FastDelegate6() { clear(); } - FastDelegate6(const FastDelegate6 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate6 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate6 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate6 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate6 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate6 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate6(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate6(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate6(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { - m_Closure.bindstaticfunc(this, &FastDelegate6::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6); } -}; - -//N=7 -template -class FastDelegate7 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate7 type; - - // Construction and comparison functions - FastDelegate7() { clear(); } - FastDelegate7(const FastDelegate7 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate7 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate7 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate7 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate7 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate7 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate7(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate7(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate7(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { - m_Closure.bindstaticfunc(this, &FastDelegate7::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7); } -}; - -//N=8 -template -class FastDelegate8 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate8 type; - - // Construction and comparison functions - FastDelegate8() { clear(); } - FastDelegate8(const FastDelegate8 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate8 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate8 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate8 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate8 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate8 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate8(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate8(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate8(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { - m_Closure.bindstaticfunc(this, &FastDelegate8::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8); } -}; - -//N=9 -template -class FastDelegate9 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate9 type; - - // Construction and comparison functions - FastDelegate9() { clear(); } - FastDelegate9(const FastDelegate9 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate9 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate9 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate9 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate9 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate9 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate9(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate9(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate9(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9)) { - m_Closure.bindstaticfunc(this, &FastDelegate9::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9); } -}; - -//N=10 -template -class FastDelegate10 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate10 type; - - // Construction and comparison functions - FastDelegate10() { clear(); } - FastDelegate10(const FastDelegate10 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate10 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate10 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate10 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate10 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate10 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate10(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate10(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate10(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10)) { - m_Closure.bindstaticfunc(this, &FastDelegate10::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } -}; - -//N=11 -template -class FastDelegate11 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate11 type; - - // Construction and comparison functions - FastDelegate11() { clear(); } - FastDelegate11(const FastDelegate11 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate11 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate11 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate11 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate11 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate11 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate11(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate11(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate11(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { - m_Closure.bindstaticfunc(this, &FastDelegate11::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } -}; - -//N=12 -template -class FastDelegate12 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate12 type; - - // Construction and comparison functions - FastDelegate12() { clear(); } - FastDelegate12(const FastDelegate12 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate12 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate12 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate12 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate12 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate12 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate12(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate12(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate12(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { - m_Closure.bindstaticfunc(this, &FastDelegate12::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } -}; - -//N=13 -template -class FastDelegate13 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate13 type; - - // Construction and comparison functions - FastDelegate13() { clear(); } - FastDelegate13(const FastDelegate13 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate13 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate13 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate13 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate13 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate13 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate13(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate13(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate13(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { - m_Closure.bindstaticfunc(this, &FastDelegate13::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } -}; - -//N=14 -template -class FastDelegate14 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate14 type; - - // Construction and comparison functions - FastDelegate14() { clear(); } - FastDelegate14(const FastDelegate14 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate14 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate14 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate14 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate14 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate14 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate14(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate14(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate14(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)) { - m_Closure.bindstaticfunc(this, &FastDelegate14::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } -}; - -//N=15 -template -class FastDelegate15 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate15 type; - - // Construction and comparison functions - FastDelegate15() { clear(); } - FastDelegate15(const FastDelegate15 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate15 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate15 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate15 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate15 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate15 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate15(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate15(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate15(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)) { - m_Closure.bindstaticfunc(this, &FastDelegate15::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } -}; - -//N=16 -template -class FastDelegate16 { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16); - typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16); - typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate16 type; - - // Construction and comparison functions - FastDelegate16() { clear(); } - FastDelegate16(const FastDelegate16 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate16 &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate16 &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate16 &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate16 &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate16 &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate16(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate16(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate16(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)) { - m_Closure.bindstaticfunc(this, &FastDelegate16::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const { - return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16); } -}; - - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 4: -// -// FastDelegate<> class (Original author: Jody Hagins) -// Allows boost::function style syntax like: -// FastDelegate< double (int, long) > -// instead of: -// FastDelegate2< int, long, double > -// -//////////////////////////////////////////////////////////////////////////////// - -#ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -// Declare FastDelegate as a class template. It will be specialized -// later for all number of arguments. -template -class FastDelegate; - -//N=0 -// Specialization to allow use of -// FastDelegate< R ( ) > -// instead of -// FastDelegate0 < R > -template -class FastDelegate< R ( ) > - // Inherit from FastDelegate0 so that it can be treated just like a FastDelegate0 - : public FastDelegate0 < R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate0 < R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=1 -// Specialization to allow use of -// FastDelegate< R ( Param1 ) > -// instead of -// FastDelegate1 < Param1, R > -template -class FastDelegate< R ( Param1 ) > - // Inherit from FastDelegate1 so that it can be treated just like a FastDelegate1 - : public FastDelegate1 < Param1, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate1 < Param1, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=2 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2 ) > -// instead of -// FastDelegate2 < Param1, Param2, R > -template -class FastDelegate< R ( Param1, Param2 ) > - // Inherit from FastDelegate2 so that it can be treated just like a FastDelegate2 - : public FastDelegate2 < Param1, Param2, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate2 < Param1, Param2, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=3 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3 ) > -// instead of -// FastDelegate3 < Param1, Param2, Param3, R > -template -class FastDelegate< R ( Param1, Param2, Param3 ) > - // Inherit from FastDelegate3 so that it can be treated just like a FastDelegate3 - : public FastDelegate3 < Param1, Param2, Param3, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate3 < Param1, Param2, Param3, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=4 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4 ) > -// instead of -// FastDelegate4 < Param1, Param2, Param3, Param4, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4 ) > - // Inherit from FastDelegate4 so that it can be treated just like a FastDelegate4 - : public FastDelegate4 < Param1, Param2, Param3, Param4, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate4 < Param1, Param2, Param3, Param4, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=5 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) > -// instead of -// FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) > - // Inherit from FastDelegate5 so that it can be treated just like a FastDelegate5 - : public FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=6 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) > -// instead of -// FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) > - // Inherit from FastDelegate6 so that it can be treated just like a FastDelegate6 - : public FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=7 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) > -// instead of -// FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) > - // Inherit from FastDelegate7 so that it can be treated just like a FastDelegate7 - : public FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=8 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) > -// instead of -// FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) > - // Inherit from FastDelegate8 so that it can be treated just like a FastDelegate8 - : public FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=9 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9 ) > -// instead of -// FastDelegate9 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9 ) > - // Inherit from FastDelegate9 so that it can be treated just like a FastDelegate9 - : public FastDelegate9 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate9 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=10 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10 ) > -// instead of -// FastDelegate10 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10 ) > - // Inherit from FastDelegate10 so that it can be treated just like a FastDelegate10 - : public FastDelegate10 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate10 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=11 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11 ) > -// instead of -// FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11 ) > - // Inherit from FastDelegate11 so that it can be treated just like a FastDelegate11 - : public FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=12 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12 ) > -// instead of -// FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12 ) > - // Inherit from FastDelegate12 so that it can be treated just like a FastDelegate12 - : public FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=13 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13 ) > -// instead of -// FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13 ) > - // Inherit from FastDelegate13 so that it can be treated just like a FastDelegate13 - : public FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=14 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14 ) > -// instead of -// FastDelegate14 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14 ) > - // Inherit from FastDelegate14 so that it can be treated just like a FastDelegate14 - : public FastDelegate14 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate14 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=15 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15 ) > -// instead of -// FastDelegate15 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15 ) > - // Inherit from FastDelegate15 so that it can be treated just like a FastDelegate15 - : public FastDelegate15 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate15 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -//N=16 -// Specialization to allow use of -// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16 ) > -// instead of -// FastDelegate16 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, R > -template -class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16 ) > - // Inherit from FastDelegate16 so that it can be treated just like a FastDelegate16 - : public FastDelegate16 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate16 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16 )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16 ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16 )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - - -#endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 5: -// -// MakeDelegate() helper function -// -// MakeDelegate(&x, &X::func) returns a fastdelegate of the type -// necessary for calling x.func() with the correct number of arguments. -// This makes it possible to eliminate many typedefs from user code. -// -//////////////////////////////////////////////////////////////////////////////// - -// Also declare overloads of a MakeDelegate() global function to -// reduce the need for typedefs. -// We need seperate overloads for const and non-const member functions. -// Also, because of the weird rule about the class of derived member function pointers, -// implicit downcasts may need to be applied later to the 'this' pointer. -// That's why two classes (X and Y) appear in the definitions. Y must be implicitly -// castable to X. - -// Workaround for VC6. VC6 needs void return types converted into DefaultVoid. -// GCC 3.2 and later won't compile this unless it's preceded by 'typename', -// but VC6 doesn't allow 'typename' in this context. -// So, I have to use a macro. - -#ifdef FASTDLGT_VC6 -#define FASTDLGT_RETTYPE detail::VoidToDefaultVoid::type -#else -#define FASTDLGT_RETTYPE RetType -#endif - -//N=0 -template -FastDelegate0 MakeDelegate(Y* x, RetType (X::*func)()) { - return FastDelegate0(x, func); -} - -template -FastDelegate0 MakeDelegate(Y* x, RetType (X::*func)() const) { - return FastDelegate0(x, func); -} - -template -FastDelegate0 MakeDelegate(RetType (*func)()) { - return FastDelegate0(func); -} - -//N=1 -template -FastDelegate1 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1)) { - return FastDelegate1(x, func); -} - -template -FastDelegate1 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1) const) { - return FastDelegate1(x, func); -} - -template -FastDelegate1 MakeDelegate(RetType (*func)(Param1 p1)) { - return FastDelegate1(func); -} - -//N=2 -template -FastDelegate2 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2)) { - return FastDelegate2(x, func); -} - -template -FastDelegate2 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2) const) { - return FastDelegate2(x, func); -} - -template -FastDelegate2 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2)) { - return FastDelegate2(func); -} - -//N=3 -template -FastDelegate3 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3)) { - return FastDelegate3(x, func); -} - -template -FastDelegate3 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3) const) { - return FastDelegate3(x, func); -} - -template -FastDelegate3 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3)) { - return FastDelegate3(func); -} - -//N=4 -template -FastDelegate4 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { - return FastDelegate4(x, func); -} - -template -FastDelegate4 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { - return FastDelegate4(x, func); -} - -template -FastDelegate4 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { - return FastDelegate4(func); -} - -//N=5 -template -FastDelegate5 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { - return FastDelegate5(x, func); -} - -template -FastDelegate5 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { - return FastDelegate5(x, func); -} - -template -FastDelegate5 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { - return FastDelegate5(func); -} - -//N=6 -template -FastDelegate6 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { - return FastDelegate6(x, func); -} - -template -FastDelegate6 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { - return FastDelegate6(x, func); -} - -template -FastDelegate6 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { - return FastDelegate6(func); -} - -//N=7 -template -FastDelegate7 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { - return FastDelegate7(x, func); -} - -template -FastDelegate7 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { - return FastDelegate7(x, func); -} - -template -FastDelegate7 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { - return FastDelegate7(func); -} - -//N=8 -template -FastDelegate8 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { - return FastDelegate8(x, func); -} - -template -FastDelegate8 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { - return FastDelegate8(x, func); -} - -template -FastDelegate8 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { - return FastDelegate8(func); -} - -//N=9 -template -FastDelegate9 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9)) { - return FastDelegate9(x, func); -} - -template -FastDelegate9 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const) { - return FastDelegate9(x, func); -} - -template -FastDelegate9 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9)) { - return FastDelegate9(func); -} - -//N=10 -template -FastDelegate10 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10)) { - return FastDelegate10(x, func); -} - -template -FastDelegate10 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const) { - return FastDelegate10(x, func); -} - -template -FastDelegate10 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10)) { - return FastDelegate10(func); -} - -//N=11 -template -FastDelegate11 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { - return FastDelegate11(x, func); -} - -template -FastDelegate11 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { - return FastDelegate11(x, func); -} - -template -FastDelegate11 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { - return FastDelegate11(func); -} - -//N=12 -template -FastDelegate12 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { - return FastDelegate12(x, func); -} - -template -FastDelegate12 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { - return FastDelegate12(x, func); -} - -template -FastDelegate12 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { - return FastDelegate12(func); -} - -//N=13 -template -FastDelegate13 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { - return FastDelegate13(x, func); -} - -template -FastDelegate13 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { - return FastDelegate13(x, func); -} - -template -FastDelegate13 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { - return FastDelegate13(func); -} - -//N=14 -template -FastDelegate14 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)) { - return FastDelegate14(x, func); -} - -template -FastDelegate14 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const) { - return FastDelegate14(x, func); -} - -template -FastDelegate14 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14)) { - return FastDelegate14(func); -} - -//N=15 -template -FastDelegate15 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)) { - return FastDelegate15(x, func); -} - -template -FastDelegate15 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const) { - return FastDelegate15(x, func); -} - -template -FastDelegate15 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15)) { - return FastDelegate15(func); -} - -//N=16 -template -FastDelegate16 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)) { - return FastDelegate16(x, func); -} - -template -FastDelegate16 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const) { - return FastDelegate16(x, func); -} - -template -FastDelegate16 MakeDelegate(RetType (*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16)) { - return FastDelegate16(func); -} - - - // clean up after ourselves... -#undef FASTDLGT_RETTYPE - -} // namespace fastdelegate - -#endif // !defined(FASTDELEGATE_H) diff --git a/sourcehook/generate/FastDelegate.hxx b/sourcehook/generate/FastDelegate.hxx deleted file mode 100644 index 6f2fe49..0000000 --- a/sourcehook/generate/FastDelegate.hxx +++ /dev/null @@ -1,1054 +0,0 @@ -// FastDelegate.h -// Efficient delegates in C++ that generate only two lines of asm code! -// Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp -// -// - Don Clugston, Mar 2004. -// Major contributions were made by Jody Hagins. -// History: -// 24-Apr-04 1.0 * Submitted to CodeProject. -// 28-Apr-04 1.1 * Prevent most unsafe uses of evil static function hack. -// * Improved syntax for horrible_cast (thanks Paul Bludov). -// * Tested on Metrowerks MWCC and Intel ICL (IA32) -// * Compiled, but not run, on Comeau C++ and Intel Itanium ICL. -// 27-Jun-04 1.2 * Now works on Borland C++ Builder 5.5 -// * Now works on /clr "managed C++" code on VC7, VC7.1 -// * Comeau C++ now compiles without warnings. -// * Prevent the virtual inheritance case from being used on -// VC6 and earlier, which generate incorrect code. -// * Improved warning and error messages. Non-standard hacks -// now have compile-time checks to make them safer. -// * implicit_cast used instead of static_cast in many cases. -// * If calling a const member function, a const class pointer can be used. -// * MakeDelegate() global helper function added to simplify pass-by-value. -// * Added fastdelegate.clear() -// 16-Jul-04 1.2.1* Workaround for gcc bug (const member function pointers in templates) -// 30-Oct-04 1.3 * Support for (non-void) return values. -// * No more workarounds in client code! -// MSVC and Intel now use a clever hack invented by John Dlugosz: -// - The FASTDELEGATEDECLARE workaround is no longer necessary. -// - No more warning messages for VC6 -// * Less use of macros. Error messages should be more comprehensible. -// * Added include guards -// * Added FastDelegate::empty() to test if invocation is safe (Thanks Neville Franks). -// * Now tested on VS 2005 Express Beta, PGI C++ -// 24-Dec-04 1.4 * Added DelegateMemento, to allow collections of disparate delegates. -// * <,>,<=,>= comparison operators to allow storage in ordered containers. -// * Substantial reduction of code size, especially the 'Closure' class. -// * Standardised all the compiler-specific workarounds. -// * MFP conversion now works for CodePlay (but not yet supported in the full code). -// * Now compiles without warnings on _any_ supported compiler, including BCC 5.5.1 -// * New syntax: FastDelegate< int (char *, double) >. -// 14-Feb-05 1.4.1* Now treats =0 as equivalent to .clear(), ==0 as equivalent to .empty(). (Thanks elfric). -// * Now tested on Intel ICL for AMD64, VS2005 Beta for AMD64 and Itanium. -// 30-Mar-05 1.5 * Safebool idiom: "if (dg)" is now equivalent to "if (!dg.empty())" -// * Fully supported by CodePlay VectorC -// * Bugfix for Metrowerks: empty() was buggy because a valid MFP can be 0 on MWCC! -// * More optimal assignment,== and != operators for static function pointers. - -#ifndef FASTDELEGATE_H -#define FASTDELEGATE_H - -#ifdef _MSC_VER -# if _MSC_VER > 1000 -# pragma once -# endif // _MSC_VER > 1000 -#endif // #ifdef _MSC_VER - -#include // to allow <,> comparisons - -//////////////////////////////////////////////////////////////////////////////// -// Configuration options -// -//////////////////////////////////////////////////////////////////////////////// - -// Uncomment the following #define for optimally-sized delegates. -// In this case, the generated asm code is almost identical to the code you'd get -// if the compiler had native support for delegates. -// It will not work on systems where sizeof(dataptr) < sizeof(codeptr). -// Thus, it will not work for DOS compilers using the medium model. -// It will also probably fail on some DSP systems. -#define FASTDELEGATE_USESTATICFUNCTIONHACK - -// Uncomment the next line to allow function declarator syntax. -// It is automatically enabled for those compilers where it is known to work. -//#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -//////////////////////////////////////////////////////////////////////////////// -// Compiler identification for workarounds -// -//////////////////////////////////////////////////////////////////////////////// - -// Compiler identification. It's not easy to identify Visual C++ because -// many vendors fraudulently define Microsoft's identifiers. -#if defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__VECTOR_C) && !defined(__ICL) && !defined(__BORLANDC__) -#define FASTDLGT_ISMSVC - -#if (_MSC_VER <1300) // Many workarounds are required for VC6. -#define FASTDLGT_VC6 -#pragma warning(disable:4786) // disable this ridiculous warning -#endif - -#endif - -// Does the compiler uses Microsoft's member function pointer structure? -// If so, it needs special treatment. -// Metrowerks CodeWarrior, Intel, and CodePlay fraudulently define Microsoft's -// identifier, _MSC_VER. We need to filter Metrowerks out. -#if defined(_MSC_VER) && !defined(__MWERKS__) -#define FASTDLGT_MICROSOFT_MFP - -#if !defined(__VECTOR_C) -// CodePlay doesn't have the __single/multi/virtual_inheritance keywords -#define FASTDLGT_HASINHERITANCE_KEYWORDS -#endif -#endif - -// Does it allow function declarator syntax? The following compilers are known to work: -#if defined(FASTDLGT_ISMSVC) && (_MSC_VER >=1310) // VC 7.1 -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -// Gcc(2.95+), and versions of Digital Mars, Intel and Comeau in common use. -#if defined (__DMC__) || defined(__GNUC__) || defined(__ICL) || defined(__COMO__) -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -// It works on Metrowerks MWCC 3.2.2. From boost.Config it should work on earlier ones too. -#if defined (__MWERKS__) -#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX -#endif - -#ifdef __GNUC__ // Workaround GCC bug #8271 - // At present, GCC doesn't recognize constness of MFPs in templates -#define FASTDELEGATE_GCC_BUG_8271 -#endif - - - -//////////////////////////////////////////////////////////////////////////////// -// General tricks used in this code -// -// (a) Error messages are generated by typdefing an array of negative size to -// generate compile-time errors. -// (b) Warning messages on MSVC are generated by declaring unused variables, and -// enabling the "variable XXX is never used" warning. -// (c) Unions are used in a few compiler-specific cases to perform illegal casts. -// (d) For Microsoft and Intel, when adjusting the 'this' pointer, it's cast to -// (char *) first to ensure that the correct number of *bytes* are added. -// -//////////////////////////////////////////////////////////////////////////////// -// Helper templates -// -//////////////////////////////////////////////////////////////////////////////// - - -namespace fastdelegate { -namespace detail { // we'll hide the implementation details in a nested namespace. - -// implicit_cast< > -// I believe this was originally going to be in the C++ standard but -// was left out by accident. It's even milder than static_cast. -// I use it instead of static_cast<> to emphasize that I'm not doing -// anything nasty. -// Usage is identical to static_cast<> -template -inline OutputClass implicit_cast(InputClass input){ - return input; -} - -// horrible_cast< > -// This is truly evil. It completely subverts C++'s type system, allowing you -// to cast from any class to any other class. Technically, using a union -// to perform the cast is undefined behaviour (even in C). But we can see if -// it is OK by checking that the union is the same size as each of its members. -// horrible_cast<> should only be used for compiler-specific workarounds. -// Usage is identical to reinterpret_cast<>. - -// This union is declared outside the horrible_cast because BCC 5.5.1 -// can't inline a function with a nested class, and gives a warning. -template -union horrible_union{ - OutputClass out; - InputClass in; -}; - -template -inline OutputClass horrible_cast(const InputClass input){ - horrible_union u; - // Cause a compile-time error if in, out and u are not the same size. - // If the compile fails here, it means the compiler has peculiar - // unions which would prevent the cast from working. - typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u) - && sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1]; - u.in = input; - return u.out; -} - -//////////////////////////////////////////////////////////////////////////////// -// Workarounds -// -//////////////////////////////////////////////////////////////////////////////// - -// Backwards compatibility: This macro used to be necessary in the virtual inheritance -// case for Intel and Microsoft. Now it just forward-declares the class. -#define FASTDELEGATEDECLARE(CLASSNAME) class CLASSNAME; - -// Prevent use of the static function hack with the DOS medium model. -#ifdef __MEDIUM__ -#undef FASTDELEGATE_USESTATICFUNCTIONHACK -#endif - -// DefaultVoid - a workaround for 'void' templates in VC6. -// -// (1) VC6 and earlier do not allow 'void' as a default template argument. -// (2) They also doesn't allow you to return 'void' from a function. -// -// Workaround for (1): Declare a dummy type 'DefaultVoid' which we use -// when we'd like to use 'void'. We convert it into 'void' and back -// using the templates DefaultVoidToVoid<> and VoidToDefaultVoid<>. -// Workaround for (2): On VC6, the code for calling a void function is -// identical to the code for calling a non-void function in which the -// return value is never used, provided the return value is returned -// in the EAX register, rather than on the stack. -// This is true for most fundamental types such as int, enum, void *. -// Const void * is the safest option since it doesn't participate -// in any automatic conversions. But on a 16-bit compiler it might -// cause extra code to be generated, so we disable it for all compilers -// except for VC6 (and VC5). -#ifdef FASTDLGT_VC6 -// VC6 workaround -typedef const void * DefaultVoid; -#else -// On any other compiler, just use a normal void. -typedef void DefaultVoid; -#endif - -// Translate from 'DefaultVoid' to 'void'. -// Everything else is unchanged -template -struct DefaultVoidToVoid { typedef T type; }; - -template <> -struct DefaultVoidToVoid { typedef void type; }; - -// Translate from 'void' into 'DefaultVoid' -// Everything else is unchanged -template -struct VoidToDefaultVoid { typedef T type; }; - -template <> -struct VoidToDefaultVoid { typedef DefaultVoid type; }; - - - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 1: -// -// Conversion of member function pointer to a standard form -// -//////////////////////////////////////////////////////////////////////////////// - -// GenericClass is a fake class, ONLY used to provide a type. -// It is vitally important that it is never defined, so that the compiler doesn't -// think it can optimize the invocation. For example, Borland generates simpler -// code if it knows the class only uses single inheritance. - -// Compilers using Microsoft's structure need to be treated as a special case. -#ifdef FASTDLGT_MICROSOFT_MFP - -#ifdef FASTDLGT_HASINHERITANCE_KEYWORDS - // For Microsoft and Intel, we want to ensure that it's the most efficient type of MFP - // (4 bytes), even when the /vmg option is used. Declaring an empty class - // would give 16 byte pointers in this case.... - class __single_inheritance GenericClass; -#endif - // ...but for Codeplay, an empty class *always* gives 4 byte pointers. - // If compiled with the /clr option ("managed C++"), the JIT compiler thinks - // it needs to load GenericClass before it can call any of its functions, - // (compiles OK but crashes at runtime!), so we need to declare an - // empty class to make it happy. - // Codeplay and VC4 can't cope with the unknown_inheritance case either. - class GenericClass {}; -#else - class GenericClass; -#endif - -// The size of a single inheritance member function pointer. -const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)()); - -// SimplifyMemFunc< >::Convert() -// -// A template function that converts an arbitrary member function pointer into the -// simplest possible form of member function pointer, using a supplied 'this' pointer. -// According to the standard, this can be done legally with reinterpret_cast<>. -// For (non-standard) compilers which use member function pointers which vary in size -// depending on the class, we need to use knowledge of the internal structure of a -// member function pointer, as used by the compiler. Template specialization is used -// to distinguish between the sizes. Because some compilers don't support partial -// template specialisation, I use full specialisation of a wrapper struct. - -// general case -- don't know how to convert it. Force a compile failure -template -struct SimplifyMemFunc { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // Unsupported member function type -- force a compile failure. - // (it's illegal to have a array with negative size). - typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100]; - return 0; - } -}; - -// For compilers where all member func ptrs are the same size, everything goes here. -// For non-standard compilers, only single_inheritance classes go here. -template <> -struct SimplifyMemFunc { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { -#if defined __DMC__ - // Digital Mars doesn't allow you to cast between abitrary PMF's, - // even though the standard says you can. The 32-bit compiler lets you - // static_cast through an int, but the DOS compiler doesn't. - bound_func = horrible_cast(function_to_bind); -#else - bound_func = reinterpret_cast(function_to_bind); -#endif - return reinterpret_cast(pthis); - } -}; - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 1b: -// -// Workarounds for Microsoft and Intel -// -//////////////////////////////////////////////////////////////////////////////// - - -// Compilers with member function pointers which violate the standard (MSVC, Intel, Codeplay), -// need to be treated as a special case. -#ifdef FASTDLGT_MICROSOFT_MFP - -// We use unions to perform horrible_casts. I would like to use #pragma pack(push, 1) -// at the start of each function for extra safety, but VC6 seems to ICE -// intermittently if you do this inside a template. - -// __multiple_inheritance classes go here -// Nasty hack for Microsoft and Intel (IA32 and Itanium) -template<> -struct SimplifyMemFunc< SINGLE_MEMFUNCPTR_SIZE + sizeof(int) > { - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // We need to use a horrible_cast to do this conversion. - // In MSVC, a multiple inheritance member pointer is internally defined as: - union { - XFuncType func; - struct { - GenericMemFuncType funcaddress; // points to the actual member function - int delta; // #BYTES to be added to the 'this' pointer - }s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)? 1 : -1]; - u.func = function_to_bind; - bound_func = u.s.funcaddress; - return reinterpret_cast(reinterpret_cast(pthis) + u.s.delta); - } -}; - -// virtual inheritance is a real nuisance. It's inefficient and complicated. -// On MSVC and Intel, there isn't enough information in the pointer itself to -// enable conversion to a closure pointer. Earlier versions of this code didn't -// work for all cases, and generated a compile-time error instead. -// But a very clever hack invented by John M. Dlugosz solves this problem. -// My code is somewhat different to his: I have no asm code, and I make no -// assumptions about the calling convention that is used. - -// In VC++ and ICL, a virtual_inheritance member pointer -// is internally defined as: -struct MicrosoftVirtualMFP { - void (GenericClass::*codeptr)(); // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtable_index; // or 0 if no virtual inheritance -}; -// The CRUCIAL feature of Microsoft/Intel MFPs which we exploit is that the -// m_codeptr member is *always* called, regardless of the values of the other -// members. (This is *not* true for other compilers, eg GCC, which obtain the -// function address from the vtable if a virtual function is being called). -// Dlugosz's trick is to make the codeptr point to a probe function which -// returns the 'this' pointer that was used. - -// Define a generic class that uses virtual inheritance. -// It has a trival member function that returns the value of the 'this' pointer. -struct GenericVirtualClass : virtual public GenericClass -{ - typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)(); - GenericVirtualClass * GetThis() { return this; } -}; - -// __virtual_inheritance classes go here -template <> -struct SimplifyMemFunc -{ - - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - union { - XFuncType func; - GenericClass* (X::*ProbeFunc)(); - MicrosoftVirtualMFP s; - } u; - u.func = function_to_bind; - bound_func = reinterpret_cast(u.s.codeptr); - union { - GenericVirtualClass::ProbePtrType virtfunc; - MicrosoftVirtualMFP s; - } u2; - // Check that the horrible_cast<>s will work - typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s) - && sizeof(function_to_bind)==sizeof(u.ProbeFunc) - && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1]; - // Unfortunately, taking the address of a MF prevents it from being inlined, so - // this next line can't be completely optimised away by the compiler. - u2.virtfunc = &GenericVirtualClass::GetThis; - u.s.codeptr = u2.s.codeptr; - return (pthis->*u.ProbeFunc)(); - } -}; - -#if (_MSC_VER <1300) - -// Nasty hack for Microsoft Visual C++ 6.0 -// unknown_inheritance classes go here -// There is a compiler bug in MSVC6 which generates incorrect code in this case!! -template <> -struct SimplifyMemFunc -{ - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // There is an apalling but obscure compiler bug in MSVC6 and earlier: - // vtable_index and 'vtordisp' are always set to 0 in the - // unknown_inheritance case! - // This means that an incorrect function could be called!!! - // Compiling with the /vmg option leads to potentially incorrect code. - // This is probably the reason that the IDE has a user interface for specifying - // the /vmg option, but it is disabled - you can only specify /vmg on - // the command line. In VC1.5 and earlier, the compiler would ICE if it ever - // encountered this situation. - // It is OK to use the /vmg option if /vmm or /vms is specified. - - // Fortunately, the wrong function is only called in very obscure cases. - // It only occurs when a derived class overrides a virtual function declared - // in a virtual base class, and the member function - // points to the *Derived* version of that function. The problem can be - // completely averted in 100% of cases by using the *Base class* for the - // member fpointer. Ie, if you use the base class as an interface, you'll - // stay out of trouble. - // Occasionally, you might want to point directly to a derived class function - // that isn't an override of a base class. In this case, both vtable_index - // and 'vtordisp' are zero, but a virtual_inheritance pointer will be generated. - // We can generate correct code in this case. To prevent an incorrect call from - // ever being made, on MSVC6 we generate a warning, and call a function to - // make the program crash instantly. - typedef char ERROR_VC6CompilerBug[-100]; - return 0; - } -}; - - -#else - -// Nasty hack for Microsoft and Intel (IA32 and Itanium) -// unknown_inheritance classes go here -// This is probably the ugliest bit of code I've ever written. Look at the casts! -// There is a compiler bug in MSVC6 which prevents it from using this code. -template <> -struct SimplifyMemFunc -{ - template - inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, - GenericMemFuncType &bound_func) { - // The member function pointer is 16 bytes long. We can't use a normal cast, but - // we can use a union to do the conversion. - union { - XFuncType func; - // In VC++ and ICL, an unknown_inheritance member pointer - // is internally defined as: - struct { - GenericMemFuncType m_funcaddress; // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtordisp; // #bytes to add to 'this' to find the vtable - int vtable_index; // or 0 if no virtual inheritance - } s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(XFuncType)==sizeof(u.s)? 1 : -1]; - u.func = function_to_bind; - bound_func = u.s.funcaddress; - int virtual_delta = 0; - if (u.s.vtable_index) { // Virtual inheritance is used - // First, get to the vtable. - // It is 'vtordisp' bytes from the start of the class. - const int * vtable = *reinterpret_cast( - reinterpret_cast(pthis) + u.s.vtordisp ); - - // 'vtable_index' tells us where in the table we should be looking. - virtual_delta = u.s.vtordisp + *reinterpret_cast( - reinterpret_cast(vtable) + u.s.vtable_index); - } - // The int at 'virtual_delta' gives us the amount to add to 'this'. - // Finally we can add the three components together. Phew! - return reinterpret_cast( - reinterpret_cast(pthis) + u.s.delta + virtual_delta); - }; -}; -#endif // MSVC 7 and greater - -#endif // MS/Intel hacks - -} // namespace detail - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 2: -// -// Define the delegate storage, and cope with static functions -// -//////////////////////////////////////////////////////////////////////////////// - -// DelegateMemento -- an opaque structure which can hold an arbitary delegate. -// It knows nothing about the calling convention or number of arguments used by -// the function pointed to. -// It supplies comparison operators so that it can be stored in STL collections. -// It cannot be set to anything other than null, nor invoked directly: -// it must be converted to a specific delegate. - -// Implementation: -// There are two possible implementations: the Safe method and the Evil method. -// DelegateMemento - Safe version -// -// This implementation is standard-compliant, but a bit tricky. -// A static function pointer is stored inside the class. -// Here are the valid values: -// +-- Static pointer --+--pThis --+-- pMemFunc-+-- Meaning------+ -// | 0 | 0 | 0 | Empty | -// | !=0 |(dontcare)| Invoker | Static function| -// | 0 | !=0 | !=0* | Method call | -// +--------------------+----------+------------+----------------+ -// * For Metrowerks, this can be 0. (first virtual function in a -// single_inheritance class). -// When stored stored inside a specific delegate, the 'dontcare' entries are replaced -// with a reference to the delegate itself. This complicates the = and == operators -// for the delegate class. - -// DelegateMemento - Evil version -// -// For compilers where data pointers are at least as big as code pointers, it is -// possible to store the function pointer in the this pointer, using another -// horrible_cast. In this case the DelegateMemento implementation is simple: -// +--pThis --+-- pMemFunc-+-- Meaning---------------------+ -// | 0 | 0 | Empty | -// | !=0 | !=0* | Static function or method call| -// +----------+------------+-------------------------------+ -// * For Metrowerks, this can be 0. (first virtual function in a -// single_inheritance class). -// Note that the Sun C++ and MSVC documentation explicitly state that they -// support static_cast between void * and function pointers. - -class DelegateMemento { -protected: - // the data is protected, not private, because many - // compilers have problems with template friends. - typedef void (detail::GenericClass::*GenericMemFuncType)(); // arbitrary MFP. - detail::GenericClass *m_pthis; - GenericMemFuncType m_pFunction; - -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - typedef void (*GenericFuncPtr)(); // arbitrary code pointer - GenericFuncPtr m_pStaticFunction; -#endif - -public: -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - DelegateMemento() : m_pthis(0), m_pFunction(0), m_pStaticFunction(0) {}; - void clear() { - m_pthis=0; m_pFunction=0; m_pStaticFunction=0; - } -#else - DelegateMemento() : m_pthis(0), m_pFunction(0) {}; - void clear() { m_pthis=0; m_pFunction=0; } -#endif -public: -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - inline bool IsEqual (const DelegateMemento &x) const{ - // We have to cope with the static function pointers as a special case - if (m_pFunction!=x.m_pFunction) return false; - // the static function ptrs must either both be equal, or both be 0. - if (m_pStaticFunction!=x.m_pStaticFunction) return false; - if (m_pStaticFunction!=0) return m_pthis==x.m_pthis; - else return true; - } -#else // Evil Method - inline bool IsEqual (const DelegateMemento &x) const{ - return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction; - } -#endif - // Provide a strict weak ordering for DelegateMementos. - inline bool IsLess(const DelegateMemento &right) const { - // deal with static function pointers first -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - if (m_pStaticFunction !=0 || right.m_pStaticFunction!=0) - return m_pStaticFunction < right.m_pStaticFunction; -#endif - if (m_pthis !=right.m_pthis) return m_pthis < right.m_pthis; - // There are no ordering operators for member function pointers, - // but we can fake one by comparing each byte. The resulting ordering is - // arbitrary (and compiler-dependent), but it permits storage in ordered STL containers. - return memcmp(&m_pFunction, &right.m_pFunction, sizeof(m_pFunction)) < 0; - - } - // BUGFIX (Mar 2005): - // We can't just compare m_pFunction because on Metrowerks, - // m_pFunction can be zero even if the delegate is not empty! - inline bool operator ! () const // Is it bound to anything? - { return m_pthis==0 && m_pFunction==0; } - inline bool empty() const // Is it bound to anything? - { return m_pthis==0 && m_pFunction==0; } -public: - DelegateMemento & operator = (const DelegateMemento &right) { - SetMementoFrom(right); - return *this; - } - inline bool operator <(const DelegateMemento &right) { - return IsLess(right); - } - inline bool operator >(const DelegateMemento &right) { - return right.IsLess(*this); - } - DelegateMemento (const DelegateMemento &right) : - m_pthis(right.m_pthis), m_pFunction(right.m_pFunction) -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - , m_pStaticFunction (right.m_pStaticFunction) -#endif - {} -protected: - void SetMementoFrom(const DelegateMemento &right) { - m_pFunction = right.m_pFunction; - m_pthis = right.m_pthis; -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = right.m_pStaticFunction; -#endif - } -}; - - -// ClosurePtr<> -// -// A private wrapper class that adds function signatures to DelegateMemento. -// It's the class that does most of the actual work. -// The signatures are specified by: -// GenericMemFunc: must be a type of GenericClass member function pointer. -// StaticFuncPtr: must be a type of function pointer with the same signature -// as GenericMemFunc. -// UnvoidStaticFuncPtr: is the same as StaticFuncPtr, except on VC6 -// where it never returns void (returns DefaultVoid instead). - -// An outer class, FastDelegateN<>, handles the invoking and creates the -// necessary typedefs. -// This class does everything else. - -namespace detail { - -template < class GenericMemFunc, class StaticFuncPtr, class UnvoidStaticFuncPtr> -class ClosurePtr : public DelegateMemento { -public: - // These functions are for setting the delegate to a member function. - - // Here's the clever bit: we convert an arbitrary member function into a - // standard form. XMemFunc should be a member function of class X, but I can't - // enforce that here. It needs to be enforced by the wrapper class. - template < class X, class XMemFunc > - inline void bindmemfunc(X *pthis, XMemFunc function_to_bind ) { - m_pthis = SimplifyMemFunc< sizeof(function_to_bind) > - ::Convert(pthis, function_to_bind, m_pFunction); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } - // For const member functions, we only need a const class pointer. - // Since we know that the member function is const, it's safe to - // remove the const qualifier from the 'this' pointer with a const_cast. - // VC6 has problems if we just overload 'bindmemfunc', so we give it a different name. - template < class X, class XMemFunc> - inline void bindconstmemfunc(const X *pthis, XMemFunc function_to_bind) { - m_pthis= SimplifyMemFunc< sizeof(function_to_bind) > - ::Convert(const_cast(pthis), function_to_bind, m_pFunction); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } -#ifdef FASTDELEGATE_GCC_BUG_8271 // At present, GCC doesn't recognize constness of MFPs in templates - template < class X, class XMemFunc> - inline void bindmemfunc(const X *pthis, XMemFunc function_to_bind) { - bindconstmemfunc(pthis, function_to_bind); -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - m_pStaticFunction = 0; -#endif - } -#endif - // These functions are required for invoking the stored function - inline GenericClass *GetClosureThis() const { return m_pthis; } - inline GenericMemFunc GetClosureMemPtr() const { return reinterpret_cast(m_pFunction); } - -// There are a few ways of dealing with static function pointers. -// There's a standard-compliant, but tricky method. -// There's also a straightforward hack, that won't work on DOS compilers using the -// medium memory model. It's so evil that I can't recommend it, but I've -// implemented it anyway because it produces very nice asm code. - -#if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - -// ClosurePtr<> - Safe version -// -// This implementation is standard-compliant, but a bit tricky. -// I store the function pointer inside the class, and the delegate then -// points to itself. Whenever the delegate is copied, these self-references -// must be transformed, and this complicates the = and == operators. -public: - // The next two functions are for operator ==, =, and the copy constructor. - // We may need to convert the m_pthis pointers, so that - // they remain as self-references. - template< class DerivedClass > - inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &x) { - SetMementoFrom(x); - if (m_pStaticFunction!=0) { - // transform self references... - m_pthis=reinterpret_cast(pParent); - } - } - // For static functions, the 'static_function_invoker' class in the parent - // will be called. The parent then needs to call GetStaticFunction() to find out - // the actual function to invoke. - template < class DerivedClass, class ParentInvokerSig > - inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, - StaticFuncPtr function_to_bind ) { - if (function_to_bind==0) { // cope with assignment to 0 - m_pFunction=0; - } else { - bindmemfunc(pParent, static_function_invoker); - } - m_pStaticFunction=reinterpret_cast(function_to_bind); - } - inline UnvoidStaticFuncPtr GetStaticFunction() const { - return reinterpret_cast(m_pStaticFunction); - } -#else - -// ClosurePtr<> - Evil version -// -// For compilers where data pointers are at least as big as code pointers, it is -// possible to store the function pointer in the this pointer, using another -// horrible_cast. Invocation isn't any faster, but it saves 4 bytes, and -// speeds up comparison and assignment. If C++ provided direct language support -// for delegates, they would produce asm code that was almost identical to this. -// Note that the Sun C++ and MSVC documentation explicitly state that they -// support static_cast between void * and function pointers. - - template< class DerivedClass > - inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &right) { - SetMementoFrom(right); - } - // For static functions, the 'static_function_invoker' class in the parent - // will be called. The parent then needs to call GetStaticFunction() to find out - // the actual function to invoke. - // ******** EVIL, EVIL CODE! ******* - template < class DerivedClass, class ParentInvokerSig> - inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, - StaticFuncPtr function_to_bind) { - if (function_to_bind==0) { // cope with assignment to 0 - m_pFunction=0; - } else { - // We'll be ignoring the 'this' pointer, but we need to make sure we pass - // a valid value to bindmemfunc(). - bindmemfunc(pParent, static_function_invoker); - } - - // WARNING! Evil hack. We store the function in the 'this' pointer! - // Ensure that there's a compilation failure if function pointers - // and data pointers have different sizes. - // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK. - typedef int ERROR_CantUseEvilMethod[sizeof(GenericClass *)==sizeof(function_to_bind) ? 1 : -1]; - m_pthis = horrible_cast(function_to_bind); - // MSVC, SunC++ and DMC accept the following (non-standard) code: -// m_pthis = static_cast(static_cast(function_to_bind)); - // BCC32, Comeau and DMC accept this method. MSVC7.1 needs __int64 instead of long -// m_pthis = reinterpret_cast(reinterpret_cast(function_to_bind)); - } - // ******** EVIL, EVIL CODE! ******* - // This function will be called with an invalid 'this' pointer!! - // We're just returning the 'this' pointer, converted into - // a function pointer! - inline UnvoidStaticFuncPtr GetStaticFunction() const { - // Ensure that there's a compilation failure if function pointers - // and data pointers have different sizes. - // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK. - typedef int ERROR_CantUseEvilMethod[sizeof(UnvoidStaticFuncPtr)==sizeof(this) ? 1 : -1]; - return horrible_cast(this); - } -#endif // !defined(FASTDELEGATE_USESTATICFUNCTIONHACK) - - // Does the closure contain this static function? - inline bool IsEqualToStaticFuncPtr(StaticFuncPtr funcptr){ - if (funcptr==0) return empty(); - // For the Evil method, if it doesn't actually contain a static function, this will return an arbitrary - // value that is not equal to any valid function pointer. - else return funcptr==reinterpret_cast(GetStaticFunction()); - } -}; - - -} // namespace detail - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 3: -// -// Wrapper classes to ensure type safety -// -//////////////////////////////////////////////////////////////////////////////// - - -// Once we have the member function conversion templates, it's easy to make the -// wrapper classes. So that they will work with as many compilers as possible, -// the classes are of the form -// FastDelegate3 -// They can cope with any combination of parameters. The max number of parameters -// allowed is 8, but it is trivial to increase this limit. -// Note that we need to treat const member functions seperately. -// All this class does is to enforce type safety, and invoke the delegate with -// the correct list of parameters. - -// Because of the weird rule about the class of derived member function pointers, -// you sometimes need to apply a downcast to the 'this' pointer. -// This is the reason for the use of "implicit_cast(pthis)" in the code below. -// If CDerivedClass is derived from CBaseClass, but doesn't override SimpleVirtualFunction, -// without this trick you'd need to write: -// MyDelegate(static_cast(&d), &CDerivedClass::SimpleVirtualFunction); -// but with the trick you can write -// MyDelegate(&d, &CDerivedClass::SimpleVirtualFunction); - -// RetType is the type the compiler uses in compiling the template. For VC6, -// it cannot be void. DesiredRetType is the real type which is returned from -// all of the functions. It can be void. - -// Implicit conversion to "bool" is achieved using the safe_bool idiom, -// using member data pointers (MDP). This allows "if (dg)..." syntax -// Because some compilers (eg codeplay) don't have a unique value for a zero -// MDP, an extra padding member is added to the SafeBool struct. -// Some compilers (eg VC6) won't implicitly convert from 0 to an MDP, so -// in that case the static function constructor is not made explicit; this -// allows "if (dg==0) ..." to compile. - -@VARARGS -template<@CLASSARGS, class RetType=detail::DefaultVoid> -class FastDelegate@NUM { -private: - typedef typename detail::DefaultVoidToVoid::type DesiredRetType; - typedef DesiredRetType (*StaticFunctionPtr)(@FUNCARGS); - typedef RetType (*UnvoidStaticFunctionPtr)(@FUNCARGS); - typedef RetType (detail::GenericClass::*GenericMemFn)(@FUNCARGS); - typedef detail::ClosurePtr ClosureType; - ClosureType m_Closure; -public: - // Typedefs to aid generic programming - typedef FastDelegate@NUM type; - - // Construction and comparison functions - FastDelegate@NUM() { clear(); } - FastDelegate@NUM(const FastDelegate@NUM &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - void operator = (const FastDelegate@NUM &x) { - m_Closure.CopyFrom(this, x.m_Closure); } - bool operator ==(const FastDelegate@NUM &x) const { - return m_Closure.IsEqual(x.m_Closure); } - bool operator !=(const FastDelegate@NUM &x) const { - return !m_Closure.IsEqual(x.m_Closure); } - bool operator <(const FastDelegate@NUM &x) const { - return m_Closure.IsLess(x.m_Closure); } - bool operator >(const FastDelegate@NUM &x) const { - return x.m_Closure.IsLess(m_Closure); } - // Binding to non-const member functions - template < class X, class Y > - FastDelegate@NUM(Y *pthis, DesiredRetType (X::* function_to_bind)(@FUNCARGS) ) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(@FUNCARGS)) { - m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Binding to const member functions. - template < class X, class Y > - FastDelegate@NUM(const Y *pthis, DesiredRetType (X::* function_to_bind)(@FUNCARGS) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - template < class X, class Y > - inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(@FUNCARGS) const) { - m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } - // Static functions. We convert them into a member function call. - // This constructor also provides implicit conversion - FastDelegate@NUM(DesiredRetType (*function_to_bind)(@FUNCARGS) ) { - bind(function_to_bind); } - // for efficiency, prevent creation of a temporary - void operator = (DesiredRetType (*function_to_bind)(@FUNCARGS) ) { - bind(function_to_bind); } - inline void bind(DesiredRetType (*function_to_bind)(@FUNCARGS)) { - m_Closure.bindstaticfunc(this, &FastDelegate@NUM::InvokeStaticFunction, - function_to_bind); } - // Invoke the delegate - RetType operator() (@FUNCARGS) const { - return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(@INVOKEARGS); } - // Implicit conversion to "bool" using the safe_bool idiom -private: - typedef struct SafeBoolStruct { - int a_data_pointer_to_this_is_0_on_buggy_compilers; - StaticFunctionPtr m_nonzero; - } UselessTypedef; - typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; -public: - operator unspecified_bool_type() const { - return empty()? 0: &SafeBoolStruct::m_nonzero; - } - // necessary to allow ==0 to work despite the safe_bool idiom - inline bool operator==(StaticFunctionPtr funcptr) { - return m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator!=(StaticFunctionPtr funcptr) { - return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } - inline bool operator ! () const { // Is it bound to anything? - return !m_Closure; } - inline bool empty() const { - return !m_Closure; } - void clear() { m_Closure.clear();} - // Conversion to and from the DelegateMemento storage class - const DelegateMemento & GetMemento() { return m_Closure; } - void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } - -private: // Invoker for static functions - RetType InvokeStaticFunction(@FUNCARGS) const { - return (*(m_Closure.GetStaticFunction()))(@INVOKEARGS); } -}; - -@ENDVAR - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 4: -// -// FastDelegate<> class (Original author: Jody Hagins) -// Allows boost::function style syntax like: -// FastDelegate< double (int, long) > -// instead of: -// FastDelegate2< int, long, double > -// -//////////////////////////////////////////////////////////////////////////////// - -#ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -// Declare FastDelegate as a class template. It will be specialized -// later for all number of arguments. -template -class FastDelegate; - -@VARARGS -// Specialization to allow use of -// FastDelegate< R ( @SELARGS ) > -// instead of -// FastDelegate@NUM < @SELARGS, R > -template -class FastDelegate< R ( @SELARGS ) > - // Inherit from FastDelegate@NUM so that it can be treated just like a FastDelegate@NUM - : public FastDelegate@NUM < @SELARGS, R > -{ -public: - // Make using the base type a bit easier via typedef. - typedef FastDelegate@NUM < @SELARGS, R > BaseType; - - // Allow users access to the specific type of this delegate. - typedef FastDelegate SelfType; - - // Mimic the base class constructors. - FastDelegate() : BaseType() { } - - template < class X, class Y > - FastDelegate(Y * pthis, - R (X::* function_to_bind)( @FUNCARGS )) - : BaseType(pthis, function_to_bind) { } - - template < class X, class Y > - FastDelegate(const Y *pthis, - R (X::* function_to_bind)( @FUNCARGS ) const) - : BaseType(pthis, function_to_bind) - { } - - FastDelegate(R (*function_to_bind)( @FUNCARGS )) - : BaseType(function_to_bind) { } - void operator = (const BaseType &x) { - *static_cast(this) = x; } -}; - -@ENDVAR - -#endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX - -//////////////////////////////////////////////////////////////////////////////// -// Fast Delegates, part 5: -// -// MakeDelegate() helper function -// -// MakeDelegate(&x, &X::func) returns a fastdelegate of the type -// necessary for calling x.func() with the correct number of arguments. -// This makes it possible to eliminate many typedefs from user code. -// -//////////////////////////////////////////////////////////////////////////////// - -// Also declare overloads of a MakeDelegate() global function to -// reduce the need for typedefs. -// We need seperate overloads for const and non-const member functions. -// Also, because of the weird rule about the class of derived member function pointers, -// implicit downcasts may need to be applied later to the 'this' pointer. -// That's why two classes (X and Y) appear in the definitions. Y must be implicitly -// castable to X. - -// Workaround for VC6. VC6 needs void return types converted into DefaultVoid. -// GCC 3.2 and later won't compile this unless it's preceded by 'typename', -// but VC6 doesn't allow 'typename' in this context. -// So, I have to use a macro. - -#ifdef FASTDLGT_VC6 -#define FASTDLGT_RETTYPE detail::VoidToDefaultVoid::type -#else -#define FASTDLGT_RETTYPE RetType -#endif - -@VARARGS -template -FastDelegate@NUM<@SELARGS, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(@FUNCARGS)) { - return FastDelegate@NUM<@SELARGS, FASTDLGT_RETTYPE>(x, func); -} - -template -FastDelegate@NUM<@SELARGS, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(@FUNCARGS) const) { - return FastDelegate@NUM<@SELARGS, FASTDLGT_RETTYPE>(x, func); -} - -template <@CLASSARGS, class RetType> -FastDelegate@NUM<@SELARGS, FASTDLGT_RETTYPE> MakeDelegate(RetType (*func)(@FUNCARGS)) { - return FastDelegate@NUM<@SELARGS, FASTDLGT_RETTYPE>(func); -} - -@ENDVAR - - // clean up after ourselves... -#undef FASTDLGT_RETTYPE - -} // namespace fastdelegate - -#endif // !defined(FASTDELEGATE_H) diff --git a/sourcehook/generate/generate b/sourcehook/generate/generate deleted file mode 100755 index f537ff3..0000000 --- a/sourcehook/generate/generate +++ /dev/null @@ -1,7 +0,0 @@ -#/bin/sh - -./shworker.bin iter sourcehook.hxx sourcehook.h $1 -./shworker.bin iter sh_memfuncinfo.hxx sh_memfuncinfo.h $1 -./shworker.bin hopter FastDelegate.hxx FastDelegate.h $1 - -cp *.h .. diff --git a/sourcehook/generate/generate.bat b/sourcehook/generate/generate.bat deleted file mode 100644 index 53c863a..0000000 --- a/sourcehook/generate/generate.bat +++ /dev/null @@ -1,10 +0,0 @@ -:: Generates everything -:: Usage: -:: generate.bat - - -shworker iter sourcehook.hxx sourcehook.h %1 -shworker iter sh_memfuncinfo.hxx sh_memfuncinfo.h %1 -shworker hopter FastDelegate.hxx FastDelegate.h %1 - -copy *.h .. \ No newline at end of file diff --git a/sourcehook/generate/sh_memfuncinfo.h b/sourcehook/generate/sh_memfuncinfo.h deleted file mode 100644 index 77cda0f..0000000 --- a/sourcehook/generate/sh_memfuncinfo.h +++ /dev/null @@ -1,796 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -/** - * @brief This file provides a way for getting information about a member function. - * @file sh_memfuncinfo.h - */ - -#ifndef __SHINT_MEMFUNC_INFO_H__ -#define __SHINT_MEMFUNC_INFO_H__ - -namespace SourceHook -{ - - // Don Clugston: - // implicit_cast< > - // I believe this was originally going to be in the C++ standard but - // was left out by accident. It's even milder than static_cast. - // I use it instead of static_cast<> to emphasize that I'm not doing - // anything nasty. - // Usage is identical to static_cast<> - template - inline OutputClass implicit_cast(InputClass input){ - return input; - } - - - struct MemFuncInfo - { - bool isVirtual; // Is the function virtual? - int thisptroffs; // The this pointer the function expects to be called with - // If -1, you need to call the GetFuncInfo_GetThisPtr function - int vtblindex; // The function's index in the vtable (0-based, 1=second entry, 2=third entry, ...) - int vtbloffs; // The vtable pointer - }; - - // Ideas by Don Clugston. - // Check out his excellent paper: http://www.codeproject.com/cpp/FastDelegate.asp - - template struct MFI_Impl - { - template static inline void GetFuncInfo(MFP *mfp, MemFuncInfo &out) - { - static char weird_memfunc_pointer_exclamation_mark_arrow_error[N-1000]; - } - }; - -# if SH_COMP == SH_COMP_GCC - - template<> struct MFI_Impl<2*SH_PTRSIZE> // All of these have size==8/16 - { - struct GCC_MemFunPtr - { - union - { - void *funcadr; // always even - intptr_t vtable_index_plus1; // = vindex+1, always odd - }; - intptr_t delta; - }; - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - GCC_MemFunPtr *mfp_detail = (GCC_MemFunPtr*)&mfp; - out.thisptroffs = mfp_detail->delta; - if (mfp_detail->vtable_index_plus1 & 1) - { - out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / SH_PTRSIZE; - out.vtbloffs = 0; - out.isVirtual = true; - } - else - out.isVirtual = false; - } - }; - -# elif SH_COMP == SH_COMP_MSVC - - namespace - { - int MFI_GetVtblOffset(void *mfp) - { - unsigned char *addr = (unsigned char*)mfp; - if (*addr == 0xE9) // Jmp - { - // May or may not be! - // Check where it'd jump - addr += 5 /*size of the instruction*/ + *(unsigned long*)(addr + 1); - } - - // Check whether it's a virtual function call - // They look like this: - // 004125A0 8B 01 mov eax,dword ptr [ecx] - // 004125A2 FF 60 04 jmp dword ptr [eax+4] - // ==OR== - // 00411B80 8B 01 mov eax,dword ptr [ecx] - // 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h] - - // However, for vararg functions, they look like this: - // 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4] - // 0048F0B4 8B 00 mov eax,dword ptr [eax] - // 0048F0B6 FF 60 08 jmp dword ptr [eax+8] - // ==OR== - // 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4] - // 0048F0B4 8B 00 mov eax,dword ptr [eax] - // 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h] - - // With varargs, the this pointer is passed as if it was the first argument - - bool ok = false; - if (addr[0] == 0x8B && addr[1] == 0x44 && addr[2] == 0x24 && addr[3] == 0x04 && - addr[4] == 0x8B && addr[5] == 0x00) - { - addr += 6; - ok = true; - } - else if (addr[0] == 0x8B && addr[1] == 0x01) - { - addr += 2; - ok = true; - } - if (!ok) - return -1; - - if (*addr++ == 0xFF) - { - if (*addr == 0x60) - { - return *++addr / 4; - } - else if (*addr == 0xA0) - { - return *((unsigned int*)++addr) / 4; - } - else if (*addr == 0x20) - return 0; - else - return -1; - } - return -1; - } - } - - template<> struct MFI_Impl<1*SH_PTRSIZE> // simple ones - { - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - out.thisptroffs = 0; - out.vtbloffs = 0; - } - }; - - template<> struct MFI_Impl<2*SH_PTRSIZE> // more complicated ones! - { - struct MSVC_MemFunPtr2 - { - void *funcadr; - int delta; - }; - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - out.thisptroffs = reinterpret_cast(&mfp)->delta; - out.vtbloffs = 0; - } - }; - - // By Don Clugston, adapted - template<> struct MFI_Impl<3*SH_PTRSIZE> // WOW IT"S GETTING BIGGER OMGOMOGMG - { - class __single_inheritance GenericClass; - class GenericClass {}; - - struct MicrosoftVirtualMFP { - void (GenericClass::*codeptr)(); // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtable_index; // or 0 if no virtual inheritance - }; - - struct GenericVirtualClass : virtual public GenericClass - { - typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)(); - GenericVirtualClass * GetThis() { return this; } - }; - - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - // This pointer - /* - union { - MFP func; - GenericClass* (T::*ProbeFunc)(); - MicrosoftVirtualMFP s; - } u; - u.func = mfp; - union { - GenericVirtualClass::ProbePtrType virtfunc; - MicrosoftVirtualMFP s; - } u2; - - // Check that the horrible_cast<>s will work - typedef int ERROR_CantUsehorrible_cast[sizeof(mfp)==sizeof(u.s) - && sizeof(mfp)==sizeof(u.ProbeFunc) - && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1]; - // Unfortunately, taking the address of a MF prevents it from being inlined, so - // this next line can't be completely optimised away by the compiler. - u2.virtfunc = &GenericVirtualClass::GetThis; - u.s.codeptr = u2.s.codeptr; - out.thisptroffs = (reinterpret_cast(NULL)->*u.ProbeFunc)(); - */ - out.thisptroffs = -1; - out.vtbloffs = 0; - } - }; - - // Don: Nasty hack for Microsoft and Intel (IA32 and Itanium) - // unknown_inheritance classes go here - // This is probably the ugliest bit of code I've ever written. Look at the casts! - // There is a compiler bug in MSVC6 which prevents it from using this code. - template<> struct MFI_Impl<4*SH_PTRSIZE> // THE BIGGEST ONE!!!1GABEN - { - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - - // The member function pointer is 16 bytes long. We can't use a normal cast, but - // we can use a union to do the conversion. - union { - MFP func; - // In VC++ and ICL, an unknown_inheritance member pointer - // is internally defined as: - struct { - void *m_funcaddress; // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtordisp; // #bytes to add to 'this' to find the vtable - int vtable_index; // or 0 if no virtual inheritance - } s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(u.func)==sizeof(u.s)? 1 : -1]; - u.func = mfp; - int virtual_delta = 0; - if (u.s.vtable_index) { // Virtual inheritance is used - /* - // First, get to the vtable. - // It is 'vtordisp' bytes from the start of the class. - int * vtable = *reinterpret_cast( - reinterpret_cast(thisptr) + u.s.vtordisp ); - - // 'vtable_index' tells us where in the table we should be looking. - virtual_delta = u.s.vtordisp + *reinterpret_cast( - reinterpret_cast(vtable) + u.s.vtable_index); - // The int at 'virtual_delta' gives us the amount to add to 'this'. - // Finally we can add the three components together. Phew! - out.thisptr = reinterpret_cast( - reinterpret_cast(thisptr) + u.s.delta + virtual_delta); - */ - out.vtbloffs = u.s.vtordisp; - out.thisptroffs = -1; - } - else - { - out.vtbloffs = out.vtblindex < 0 ? 0 : u.s.delta; - out.thisptroffs = u.s.delta; - } - }; - }; -# else -# error Unsupported compiler -# endif - - // This version does not take a this pointer - // Useful for hookdecls, as they ensure that mfp is correct through a static_cast - template inline void GetFuncInfo(X mfp, MemFuncInfo &out) - { - MFI_Impl::GetFuncInfo(mfp, out); - } - - // Versions which do take a this - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(), MemFuncInfo &out) - { - RetType(Y::*mfp2)() = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)() const, MemFuncInfo &out) - { - RetType(Y::*mfp2)() const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - // GCC & MSVC 7.1 need this, MSVC 7.0 doesn't like it -#if SH_COMP != SH_COMP_MSVC || _MSC_VER > 1300 - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - -#endif - -} - -#endif diff --git a/sourcehook/generate/sh_memfuncinfo.hxx b/sourcehook/generate/sh_memfuncinfo.hxx deleted file mode 100644 index 5ed37ab..0000000 --- a/sourcehook/generate/sh_memfuncinfo.hxx +++ /dev/null @@ -1,332 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -/** - * @brief This file provides a way for getting information about a member function. - * @file sh_memfuncinfo.h - */ - -#ifndef __SHINT_MEMFUNC_INFO_H__ -#define __SHINT_MEMFUNC_INFO_H__ - -namespace SourceHook -{ - - // Don Clugston: - // implicit_cast< > - // I believe this was originally going to be in the C++ standard but - // was left out by accident. It's even milder than static_cast. - // I use it instead of static_cast<> to emphasize that I'm not doing - // anything nasty. - // Usage is identical to static_cast<> - template - inline OutputClass implicit_cast(InputClass input){ - return input; - } - - - struct MemFuncInfo - { - bool isVirtual; // Is the function virtual? - int thisptroffs; // The this pointer the function expects to be called with - // If -1, you need to call the GetFuncInfo_GetThisPtr function - int vtblindex; // The function's index in the vtable (0-based, 1=second entry, 2=third entry, ...) - int vtbloffs; // The vtable pointer - }; - - // Ideas by Don Clugston. - // Check out his excellent paper: http://www.codeproject.com/cpp/FastDelegate.asp - - template struct MFI_Impl - { - template static inline void GetFuncInfo(MFP *mfp, MemFuncInfo &out) - { - static char weird_memfunc_pointer_exclamation_mark_arrow_error[N-1000]; - } - }; - -# if SH_COMP == SH_COMP_GCC - - template<> struct MFI_Impl<2*SH_PTRSIZE> // All of these have size==8/16 - { - struct GCC_MemFunPtr - { - union - { - void *funcadr; // always even - intptr_t vtable_index_plus1; // = vindex+1, always odd - }; - intptr_t delta; - }; - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - GCC_MemFunPtr *mfp_detail = (GCC_MemFunPtr*)&mfp; - out.thisptroffs = mfp_detail->delta; - if (mfp_detail->vtable_index_plus1 & 1) - { - out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / SH_PTRSIZE; - out.vtbloffs = 0; - out.isVirtual = true; - } - else - out.isVirtual = false; - } - }; - -# elif SH_COMP == SH_COMP_MSVC - - namespace - { - int MFI_GetVtblOffset(void *mfp) - { - unsigned char *addr = (unsigned char*)mfp; - if (*addr == 0xE9) // Jmp - { - // May or may not be! - // Check where it'd jump - addr += 5 /*size of the instruction*/ + *(unsigned long*)(addr + 1); - } - - // Check whether it's a virtual function call - // They look like this: - // 004125A0 8B 01 mov eax,dword ptr [ecx] - // 004125A2 FF 60 04 jmp dword ptr [eax+4] - // ==OR== - // 00411B80 8B 01 mov eax,dword ptr [ecx] - // 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h] - - // However, for vararg functions, they look like this: - // 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4] - // 0048F0B4 8B 00 mov eax,dword ptr [eax] - // 0048F0B6 FF 60 08 jmp dword ptr [eax+8] - // ==OR== - // 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4] - // 0048F0B4 8B 00 mov eax,dword ptr [eax] - // 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h] - - // With varargs, the this pointer is passed as if it was the first argument - - bool ok = false; - if (addr[0] == 0x8B && addr[1] == 0x44 && addr[2] == 0x24 && addr[3] == 0x04 && - addr[4] == 0x8B && addr[5] == 0x00) - { - addr += 6; - ok = true; - } - else if (addr[0] == 0x8B && addr[1] == 0x01) - { - addr += 2; - ok = true; - } - if (!ok) - return -1; - - if (*addr++ == 0xFF) - { - if (*addr == 0x60) - { - return *++addr / 4; - } - else if (*addr == 0xA0) - { - return *((unsigned int*)++addr) / 4; - } - else if (*addr == 0x20) - return 0; - else - return -1; - } - return -1; - } - } - - template<> struct MFI_Impl<1*SH_PTRSIZE> // simple ones - { - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - out.thisptroffs = 0; - out.vtbloffs = 0; - } - }; - - template<> struct MFI_Impl<2*SH_PTRSIZE> // more complicated ones! - { - struct MSVC_MemFunPtr2 - { - void *funcadr; - int delta; - }; - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - out.thisptroffs = reinterpret_cast(&mfp)->delta; - out.vtbloffs = 0; - } - }; - - // By Don Clugston, adapted - template<> struct MFI_Impl<3*SH_PTRSIZE> // WOW IT"S GETTING BIGGER OMGOMOGMG - { - class __single_inheritance GenericClass; - class GenericClass {}; - - struct MicrosoftVirtualMFP { - void (GenericClass::*codeptr)(); // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtable_index; // or 0 if no virtual inheritance - }; - - struct GenericVirtualClass : virtual public GenericClass - { - typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)(); - GenericVirtualClass * GetThis() { return this; } - }; - - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - // This pointer - /* - union { - MFP func; - GenericClass* (T::*ProbeFunc)(); - MicrosoftVirtualMFP s; - } u; - u.func = mfp; - union { - GenericVirtualClass::ProbePtrType virtfunc; - MicrosoftVirtualMFP s; - } u2; - - // Check that the horrible_cast<>s will work - typedef int ERROR_CantUsehorrible_cast[sizeof(mfp)==sizeof(u.s) - && sizeof(mfp)==sizeof(u.ProbeFunc) - && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1]; - // Unfortunately, taking the address of a MF prevents it from being inlined, so - // this next line can't be completely optimised away by the compiler. - u2.virtfunc = &GenericVirtualClass::GetThis; - u.s.codeptr = u2.s.codeptr; - out.thisptroffs = (reinterpret_cast(NULL)->*u.ProbeFunc)(); - */ - out.thisptroffs = -1; - out.vtbloffs = 0; - } - }; - - // Don: Nasty hack for Microsoft and Intel (IA32 and Itanium) - // unknown_inheritance classes go here - // This is probably the ugliest bit of code I've ever written. Look at the casts! - // There is a compiler bug in MSVC6 which prevents it from using this code. - template<> struct MFI_Impl<4*SH_PTRSIZE> // THE BIGGEST ONE!!!1GABEN - { - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - - // The member function pointer is 16 bytes long. We can't use a normal cast, but - // we can use a union to do the conversion. - union { - MFP func; - // In VC++ and ICL, an unknown_inheritance member pointer - // is internally defined as: - struct { - void *m_funcaddress; // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtordisp; // #bytes to add to 'this' to find the vtable - int vtable_index; // or 0 if no virtual inheritance - } s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(u.func)==sizeof(u.s)? 1 : -1]; - u.func = mfp; - int virtual_delta = 0; - if (u.s.vtable_index) { // Virtual inheritance is used - /* - // First, get to the vtable. - // It is 'vtordisp' bytes from the start of the class. - int * vtable = *reinterpret_cast( - reinterpret_cast(thisptr) + u.s.vtordisp ); - - // 'vtable_index' tells us where in the table we should be looking. - virtual_delta = u.s.vtordisp + *reinterpret_cast( - reinterpret_cast(vtable) + u.s.vtable_index); - // The int at 'virtual_delta' gives us the amount to add to 'this'. - // Finally we can add the three components together. Phew! - out.thisptr = reinterpret_cast( - reinterpret_cast(thisptr) + u.s.delta + virtual_delta); - */ - out.vtbloffs = u.s.vtordisp; - out.thisptroffs = -1; - } - else - { - out.vtbloffs = out.vtblindex < 0 ? 0 : u.s.delta; - out.thisptroffs = u.s.delta; - } - }; - }; -# else -# error Unsupported compiler -# endif - - // This version does not take a this pointer - // Useful for hookdecls, as they ensure that mfp is correct through a static_cast - template inline void GetFuncInfo(X mfp, MemFuncInfo &out) - { - MFI_Impl::GetFuncInfo(mfp, out); - } - - // Versions which do take a this -@[$1,0,$a: - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(@[$2,1,$1|, :Param$2@]), MemFuncInfo &out) - { - RetType(Y::*mfp2)(@[$2,1,$1|, :Param$2@]) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(@[$2,1,$1|, :Param$2@]) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(@[$2,1,$1|, :Param$2@]) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } -@] - - // GCC & MSVC 7.1 need this, MSVC 7.0 doesn't like it -#if SH_COMP != SH_COMP_MSVC || _MSC_VER > 1300 - -@[$1,0,$a: - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(@[$2,1,$1|, :Param$2@]@[$1!=0:, @]...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(@[$2,1,$1|, :Param$2@]@[$1!=0:, @]...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(@[$2,1,$1|, :Param$2@]@[$1!=0:, @]...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(@[$2,1,$1|, :Param$2@]@[$1!=0:, @]...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - -@] - -#endif - -} - -#endif diff --git a/sourcehook/generate/shworker.bin b/sourcehook/generate/shworker.bin deleted file mode 100755 index 96105b3c726572527d301d27612a2893d65a2beb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50608 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 diff --git a/sourcehook/generate/shworker/Makefile b/sourcehook/generate/shworker/Makefile deleted file mode 100644 index 86ac5bf..0000000 --- a/sourcehook/generate/shworker/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -default: shworker - -bin: - mkdir bin - -fd_hopter.o: fd_hopter.cpp bin - gcc -fPIC -O2 -o bin/$@ -c $< - -main.o: shworker.cpp bin - gcc -fPIC -O2 -o bin/$@ -c $< - -shworker: fd_hopter.o main.o bin - gcc -ldl -lstdc++ bin/fd_hopter.o bin/main.o -o bin/shworker.bin diff --git a/sourcehook/generate/shworker/fd_hopter.cpp b/sourcehook/generate/shworker/fd_hopter.cpp deleted file mode 100644 index 7fc149d..0000000 --- a/sourcehook/generate/shworker/fd_hopter.cpp +++ /dev/null @@ -1,370 +0,0 @@ -// From fastdelegate -// http://www.codeproject.com/cpp/FastDelegate.asp - -// Modified to be run from shworker by PM - - -// HOPTER.EXE -- A simple header generator for vararg templates -/* MOTIVATION - C++ doesn't have a vararg feature for templates. This can be a - nuisance when writing class libraries. There are a few options: - (a) manually repeat code. This is tedious and error prone. - (b) Use macros. Messy, can't cope with template - arguments, and users get hard-to-interpret error messages. - (c) Use the boost preprocessor library. This slows compilation, - and introduces a dependency on boost. - (d) Write a program to automatically generate the code. - I've never seen a general program to do this job, so this is - a very simple command-line program to do it. - - Why is it called Hopter? - I wanted a word that started with h, to be reminiscent of header - files. At the time, my 2yo son kept talking about 'Hopter Copters' - (he couldn't pronounce 'helicopter'). - It also reflects the level of sophistication of this program -- - it was named by a two year old. - - IMPLEMENTATION - - When you analyze the problem, you find that the requirements - are very simple. - Varargs are needed in two places: templates and functions. - You want to use them in two ways: when declaring the template - or function, and when invoking the function / selecting the - template. - - It's a brain-dead implementation, which just does a search-and-replace - of specific strings. It could be done with a few lines using sed on - a *NIX platform. Because I use Windows, I've done a quick and dirty - implementation using CString. - -In a file, @VARARGS at the start of a line indicates the start of the code -to be expanded. @ENDVAR at the start of a line marks the end of the -expansion. - - declare template -- template <@CLASSARGS> class SomeClass - template - class SomeClass - - declare function -- somefunc(@FUNCARGS) - somefunc(Param1 p1, Param2 p2) - - select template -- SomeClass<@SELARGS> - SomeClass - - invoke function -- somefunc(@INVOKEARGS) - somefunc(p1, p2) - - I also provide @NUM which is the number of arguments. - The case where @NUM is zero is a special case: for template declarations, - the entire template<> bit needs to disappear. When other arguments are - involved, either at the beginning or end of the list, there a commas - which might need to be removed. - - I've used .hxx as the extension for these files. This enables C++ - I wanted to use an unusual file extension (.HOH) for these files, because they - aren't real header files. But I also like to use the C++ syntax highlighting - in Visual Studio. I chose .hxx because MSVC treats it as C++, but it - seems to very rarely used. - - Installation (for VC6, if you want to use .HOH as the extension instead): - Go into the registry and change - HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Text Editor\Tabs/Language Settings\C/C++\FileExtensions from cpp;cxx;c;h;hxx;hpp;inl;tlh;tli;rc;rc2 - to cpp;cxx;c;h;hxx;hpp;inl;tlh;tli;rc;rc2;hoh by adding “;hoh” to the end. - Then add this as a custom build step to the main file of your project: - hopter $(InputDir)\*.hoh $(InputDir)\*.h - -*/ - -#include -#include -#include - -// This is a quick-n-dirty implementation of a CString replacement. -// It promises nothing more than to provide enough functionality to get -// this program to run. -// Note that I have really never used CString, so the information to -// implement the members that are used in this program come from -// online documentation at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_cstring.asp -// Also, I have only used VC++ a few times, a long time ago, so -// I really do not know what all their alphabet soup is suppoed to -// mean, so I just made a guess... - - -class CString -{ -public: - enum { MAX_FORMAT_STRING_SIZE = 8 * 1044 }; - CString() - : str_() - { - } - - CString( - CString const & rhs) - : str_(rhs.str_) - { - } - - CString( - char ch, - int repeat = 1) - : str_(repeat, ch) - { - } - - CString( - char const * s) - : str_(s) - { - } - - CString & operator=( - CString const & rhs) - { - str_ = rhs.str_; - return *this; - } - - CString & operator=( - char const * s) - { - str_ = s; - return *this; - } - - CString & operator=( - char ch) - { - str_ = ch; - return *this; - } - - void Format( - char const * fmt, - ...) - { - char buffer[ MAX_FORMAT_STRING_SIZE ]; - va_list ap; - va_start(ap, fmt); - vsprintf(buffer, fmt, ap); - va_end(ap); - str_ = buffer; - } - - char operator[]( - int x) const - { - return str_[x]; - } - - CString & operator+=( - CString const & x) - { - str_ += x.str_; return *this; - } - - int Replace( - CString const & lhs, - CString const & rhs) - { - int rval = 0; - std::string::size_type pos = 0; - while (pos < str_.length()) - { - pos = str_.find(lhs.str_, pos); - if (pos != std::string::npos) - { - str_.replace(pos, lhs.GetLength(), rhs.str_); - pos += rhs.GetLength(); - ++rval; - } - } - return rval; - } - - int GetLength() const - { - return str_.length(); - } - - operator char const * () const - { - return str_.c_str(); - } - -private: - std::string str_; -}; - - -CString operator+( - CString const & x, - CString const & y) -{ - CString result(x); - result += y; - return result; -} - - -/* Example: This is an excerpt from boost::function_template.hpp - -#define BOOST_FUNCTION_FUNCTION_INVOKER \ - BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS) -#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \ - BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS) - - template< - typename FunctionPtr, - typename R BOOST_FUNCTION_COMMA - BOOST_FUNCTION_TEMPLATE_PARMS - > - struct BOOST_FUNCTION_GET_FUNCTION_INVOKER - { - typedef typename ct_if<(is_void::value), - BOOST_FUNCTION_VOID_FUNCTION_INVOKER< - FunctionPtr, - R BOOST_FUNCTION_COMMA - BOOST_FUNCTION_TEMPLATE_ARGS - >, - BOOST_FUNCTION_FUNCTION_INVOKER< - FunctionPtr, - R BOOST_FUNCTION_COMMA - BOOST_FUNCTION_TEMPLATE_ARGS - > - >::type type; - }; - -Using HOPTER, this can be written as: - - template< typename FunctionPtr, typename R, @CLASSARGS> - struct get_function_invoker@NUM - { - typedef typename ct_if<(is_void::value), - void_function_invoker@NUM, - function_invoker@NUM - >::type type; - }; -*/ - -int MaxNumArgs; - -/// Makes the necessary subsititutions in 'bigblock', and writes to fout. -void PrintVarArgs(FILE *fout, CString bigblock, int num) { - CString numstr; - CString invokelist; - CString funclist; - CString selectlist; - CString classlist; - CString commastr; - numstr.Format("%d", num); - if (num==0) { - invokelist=""; - funclist=""; - selectlist=""; - commastr=""; - classlist=""; - }else { - invokelist="p1"; - funclist="Param1 p1"; - selectlist = "Param1"; - classlist = "class Param1"; - commastr=", "; - CString str; - for (int k=2; k<=num; k++) { - str.Format(", p%d", k); - invokelist+=str; - str.Format(", Param%d p%d", k, k); - funclist+=str; - str.Format(", Param%d", k); - selectlist += str; - str.Format(", class Param%d", k); - classlist += str; - } - } - - // Simple replacement of number of arguments - bigblock.Replace("@NUM", numstr); - - // Template declarations - if (num==0) bigblock.Replace("template<@CLASSARGS>", ""); - else bigblock.Replace("template<@CLASSARGS>", - (CString)"template<" + classlist+">"); - if (num==0) bigblock.Replace("template <@CLASSARGS>", ""); - else bigblock.Replace("template <@CLASSARGS>", - (CString)"template<" + classlist+">"); - bigblock.Replace(",@CLASSARGS", commastr + classlist); - bigblock.Replace(", @CLASSARGS", commastr + classlist); - bigblock.Replace("@CLASSARGS, ", classlist + commastr); - bigblock.Replace("@CLASSARGS,", classlist + commastr); - bigblock.Replace("@CLASSARGS", classlist); - - // Template selections - CString selargstr; - if (num==0) selargstr = ""; - else selargstr = (CString)"<"+selectlist+">"; - - bigblock.Replace("<@SELARGS>", selargstr); - bigblock.Replace("< @SELARGS >", selargstr); - bigblock.Replace(",@SELARGS", commastr + selectlist); - bigblock.Replace(", @SELARGS", commastr + selectlist); - bigblock.Replace("@SELARGS, ", selectlist + commastr); - bigblock.Replace("@SELARGS,", selectlist + commastr); - bigblock.Replace("@SELARGS", selectlist); - - // Function declarations - bigblock.Replace(",@FUNCARGS", commastr + funclist); - bigblock.Replace(", @FUNCARGS", commastr + funclist); - bigblock.Replace("@FUNCARGS, ", funclist + commastr); - bigblock.Replace("@FUNCARGS,", funclist + commastr); - bigblock.Replace("@FUNCARGS", funclist); - - // Function invocation - bigblock.Replace(",@INVOKEARGS", commastr + invokelist); - bigblock.Replace(", @INVOKEARGS", commastr + invokelist); - bigblock.Replace("@INVOKEARGS, ", invokelist + commastr); - bigblock.Replace("@INVOKEARGS,", invokelist + commastr); - bigblock.Replace("@INVOKEARGS", invokelist); - - fprintf(fout, bigblock); -} - -int action_hopter(int numargs, const char *filenamein, const char *filenameout) -{ - - MaxNumArgs = numargs; - - FILE * fin; - FILE *fout; - - fin =fopen(filenamein,"rt"); - if (!fin) { printf("Error, can't open %s\n", filenamein); return 1; }; - fout = fopen (filenameout, "wt"); - if (!fout) { printf("Error, can't open %s\n", filenameout); return 1; }; - char buf[5000]; - for (;;) { - if (!fgets(buf, 5000, fin)) break; - if (!strncmp(buf, "@VARARGS", 8)) { - // found a match... - CString bigblock; - for (;;) { - if (feof(fin)) { printf("No matching @ENDVAR !!??\n"); return 1; }; - fgets(buf, 5000, fin); - if (!strncmp(buf, "@ENDVAR", 7)) break; - bigblock+=buf; - } -// fprintf(fout, "// Auto-generated code [[[\n"); - for (int k=0; k<=MaxNumArgs; k++) { - fprintf(fout, "//N=%d\n", k); - PrintVarArgs(fout, bigblock, k); - } -// fprintf(fout, "// ]]] End auto-generated code\n"); - } else { - fprintf(fout, "%s", buf); - } - } - fclose(fin); - fclose(fout); - return 0; -} diff --git a/sourcehook/generate/shworker/msvc7/shworker.vcproj b/sourcehook/generate/shworker/msvc7/shworker.vcproj deleted file mode 100644 index 159bd19..0000000 --- a/sourcehook/generate/shworker/msvc7/shworker.vcproj +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sourcehook/generate/shworker/msvc8/shworker.vcproj b/sourcehook/generate/shworker/msvc8/shworker.vcproj deleted file mode 100644 index 997949d..0000000 --- a/sourcehook/generate/shworker/msvc8/shworker.vcproj +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sourcehook/generate/shworker/shworker.cpp b/sourcehook/generate/shworker/shworker.cpp deleted file mode 100644 index 5e0047c..0000000 --- a/sourcehook/generate/shworker/shworker.cpp +++ /dev/null @@ -1,767 +0,0 @@ -// SHWorker -// Inspired by "Hopter" that comes with FastDelegate (http://www.codeproject.com/cpp/FastDelegate.asp) -// Much more powerful (and ugly) though - -/* - - INPUT FILE DIRECTIVES - - $a is the first additional argument, $b the second, ... - - --- - ITERATION - - @[variable,min,max:code|separator@] - - variable: this will be replaced in code by its current value. - vars are always $ and a number. - min: first value to be used for variable - max: last value to be used for variable - code: the code that will be inserted on each iteration. - separator: optional. this will be inserted between iterations. - If you don't use a separator, you may leave out the | - IMPORTANT: iterations will only be performed if max >= min - - --- ARITHMETIC EXPRESSION - - @(expr) - - expr may contain: - variables - constants - operators (currently only + and * are supported) - - --- CONDITION - - @[expr operator expr:code@] - - Example: @[$1!=0:hello@] - - Currently only != and == are supported operators. - - - Yes, error handling in here is weird, some stuff uses return values, other code uses exceptions. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "stdio.h" - -#ifdef __linux__ -# define stricmp strcasecmp -#endif - -// Ensure that the template version is being used! -#ifdef min -#undef min -#endif - -using namespace std; - -extern int action_hopter(int numargs, const char *filenamein, const char *filenameout); - -typedef map varmap; - -struct MyError -{ - const char *m_desc; - - MyError(const char *desc) : m_desc(desc) - { - } - - void Print() - { - cout << m_desc << endl; - } -}; - -struct SyntaxError : MyError -{ - SyntaxError() : MyError("Syntax error in expression") - { - } -}; -struct OtherError : MyError -{ - OtherError() : MyError("WTF") - { - } -}; - -void trim_string(std::string &str) -{ - size_t first = str.find_first_not_of(" \t\v\n\r"); - if (first == std::string::npos) - { - str.clear(); - return; - } - - size_t last = str.length(); - for (std::string::reverse_iterator riter = str.rbegin(); riter != str.rend(); ++riter) - { - char ch = *riter; - if (ch != ' ' && - ch != '\t' && - ch != '\v' && - ch != '\n' && - ch != '\r') - break; - --last; - } - str = str.substr(first, last - first); -} - -// unused -bool ExtractToken(std::string &strin, std::string &strout) -{ - trim_string(strin); - if (strin.begin() == strin.end()) - { - strout.clear(); - return false; - } - size_t first = strin.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFHIJKLMNOPQRSTUVWXYZ_0123456789"); - if (first == 0) - { - if (strin.size() > 1 && strin.at(0) == '/' && strin.at(1) == '/') - { - // One-line comment, find its end - first = strin.find('\n') + 1; - } - else if (strin.size() > 1 && strin.at(0) == '/' && strin.at(1) == '*') - { - // Multi-line comment, find its end - first = strin.find("*/") + 2; - } - strin = strin.substr(1); - strout.clear(); - return true; - } - strout = strin.substr(0, first); - strin = strin.substr(first); - return true; -} - -// Returns the number of occurencies replaced -int DoReplace(string &str, const string &what, const string &with) -{ - int cnt=0; - size_t where = str.find(what); - - while (where != string::npos) - { - str.replace(where, what.size(), with); - ++cnt; - where = str.find(what, where); - } - return cnt; -} - -int DoReplace(string &str, const char *what, const char *with) -{ - int cnt=0; - size_t where = str.find(what); - size_t whatsize = strlen(what); - while (where != string::npos) - { - str.replace(where, whatsize, with); - ++cnt; - where = str.find(what, where); - } - return cnt; -} - - -class ExprParser -{ - // grammar: - /* - expr -> expr + term { do_add } - | expr - term { do_sub } - | term - - term -> term * factor { do_mul } - | term / factor { do_div } - | term % factor { do_mod } - - factor -> (expr) - | numeric constant { push } - - - equivalent to: - - expr -> term moreterms - moreterms -> + term { do_add } moreterms - moreterms -> - term { do_sub } moreterms - moreterms -> epsilon - - term -> factor morefactors - morefactors -> * factor { do_mul } morefactors - morefactors -> / factor { do_div } morefactors - morefactors -> % factor { do_mod } morefactors - morefactors -> epsilon - - factor -> (expr) - factor -> numeric constant { push } - - */ - - string::const_iterator m_begin; - string::const_iterator m_end; - string::const_iterator m_iter; - - int m_lookahead; - int m_tokenval; - - stack m_stack; - static const int DONE = 256; - static const int NUM = 257; - - int lexan() - { - while (1) - { - if (m_iter == m_end) - return DONE; - - int t = *m_iter++; - - if (t == ' ' || t == '\t') - ; // Remove whitespace - else if (isdigit(t)) - { - --m_iter; - - m_tokenval = 0; - while (m_iter != m_end && isdigit(*m_iter)) - { - m_tokenval *= 10; - m_tokenval += *m_iter - '0'; - ++m_iter; - } - return NUM; - } - else - return t; - } - } - - void match(int t) - { - if (m_lookahead == t) - m_lookahead = lexan(); - else - throw SyntaxError(); - } - void factor() - { - switch (m_lookahead) - { - case '(': - match('('); expr(); match(')'); - break; - case NUM: - m_stack.push(m_tokenval); match(NUM); - break; - default: - throw SyntaxError(); - } - } - void term() - { - factor(); - while (1) - { - switch (m_lookahead) - { - case '*': - match('*'); factor(); do_mul(); - continue; - case '/': - match('/'); factor(); do_div(); - continue; - case '%': - match('%'); factor(); do_mod(); - continue; - default: - return; - } - - } - } - - void expr() - { - term(); - while (1) - { - switch (m_lookahead) - { - case '+': - match('+'); term(); do_add(); - continue; - case '-': - match('-'); term(); do_sub(); - continue; - default: - return; - } - } - } - - void do_add() - { - int a2 = m_stack.top(); m_stack.pop(); - int a1 = m_stack.top(); m_stack.pop(); - m_stack.push(a1 + a2); - } - - void do_sub() - { - int a2 = m_stack.top(); m_stack.pop(); - int a1 = m_stack.top(); m_stack.pop(); - m_stack.push(a1 - a2); - } - - void do_mul() - { - int a2 = m_stack.top(); m_stack.pop(); - int a1 = m_stack.top(); m_stack.pop(); - m_stack.push(a1 * a2); - } - - void do_div() - { - int a2 = m_stack.top(); m_stack.pop(); - int a1 = m_stack.top(); m_stack.pop(); - m_stack.push(a1 / a2); - } - - void do_mod() - { - int a2 = m_stack.top(); m_stack.pop(); - int a1 = m_stack.top(); m_stack.pop(); - m_stack.push(a1 % a2); - } - -public: - ExprParser(string::const_iterator begin, string::const_iterator end) : - m_begin(begin), m_end(end), m_iter(begin) - { - m_lookahead = lexan(); - expr(); - } - - operator int() - { - if (m_stack.size() != 1) - throw OtherError(); - - return m_stack.top(); - } -}; - -int parse_expr(string::const_iterator begin, string::const_iterator end) -{ - return ExprParser(begin, end); -} - -size_t find_first_directive(const string &buf, size_t begin=0) -{ - for (;;) - { - if (begin >= buf.size()) - return string::npos; - - size_t firstdirpos = buf.find('@', begin); - if (firstdirpos == string::npos) - return firstdirpos; - - if (buf.size() > firstdirpos+1) - { - if (buf[firstdirpos+1] == '[' || buf[firstdirpos+1] == '(') - return firstdirpos; - } - begin = firstdirpos+1; - } -} - -// buf begins with a section. Find its end! -size_t find_section_end(const string &buf) -{ - int starttype = buf[1]; - int endtype = (buf[1] == '(') ? ')' : ']'; - - int nestlevel = 0; - - if (starttype == '(') - { - for (string::const_iterator iter = buf.begin(); iter != buf.end(); ++iter) - { - if (*iter == starttype) - ++nestlevel; - if (*iter == endtype) - { - if (--nestlevel == 0) - return iter - buf.begin() + 1; - } - } - return string::npos; - } - else if (starttype == '[') - { - int lastchar = 0; - for (string::const_iterator iter = buf.begin(); iter != buf.end(); ++iter) - { - if (lastchar == '@' && *iter == starttype) - ++nestlevel; - if (lastchar == '@' && *iter == endtype) - { - if (--nestlevel == 0) - return iter - buf.begin() + 1; - } - lastchar = *iter; - } - return string::npos; - } - - return string::npos; -} - -// replaces variables and additional arguments -void replace_vars(string &buf, int argc, int *argv, const varmap &vars) -{ - char varname[] = "$ "; - char value[32]; - - for (int i = 0; i < argc; ++i) - { - varname[1] = 'a' + i; - sprintf(value, "%d", argv[i]); - DoReplace(buf, varname, value); - } - - for (varmap::const_iterator iter = vars.begin(); iter != vars.end(); ++iter) - { - varname[1] = '0' + iter->first; - sprintf(value, "%d", iter->second); - DoReplace(buf, varname, value); - } -} - -// do_input -// params: -// argc: number of additional arguments -// argv: additional arguments -// outfile: output file -// buf: string to be processed. IMPORTANT: buf is modified! -// curvars: variables buffer. -// retval: -// 0 on success, non-zero on error - -int do_input(int argc, int *argv, ofstream &outfile, string &buf, varmap &curvars) -{ - for (;;) - { - // Find the next directive. - size_t firstdirpos = find_first_directive(buf); - - // Output everything that came before, and remove it from buf - outfile << buf.substr(0, firstdirpos); - if (firstdirpos == string::npos) - return 0; - buf = buf.substr(firstdirpos); - - // Now find the matching end. - size_t sectionend = find_section_end(buf); - if (sectionend == string::npos) - { - cout << "ERROR: Section not closed!" << endl; - return 1; - } - - // Place the section in its own buffer and remove it from the input string. - string sect(buf.begin(), buf.begin() + sectionend); - buf = buf.substr(sectionend); - - // CASE1: Arithmetic expression - if (sect[1] == '(') - { - replace_vars(sect, argc, argv, curvars); - outfile << parse_expr(sect.begin()+1, sect.end()); - } - else if (sect[1] == '[') - { - int is_iter = 0; // 0 -> no; 1 -> maybe (only used in check); 2 -> yes - char lastchar = 0; - // This could be an iteration OR a conditional thing. - // Pretty braindead check: iterations begin with a variable, then a comma. - for (string::iterator iter = sect.begin() + 2; iter != sect.end(); ++iter) - { - if (*iter == ' ' || *iter == '\t') - ; - else if (is_iter == 0 && lastchar == '$' && isdigit(*iter)) - is_iter = 1; - else if (is_iter == 1 && *iter == ',') - { - is_iter = 2; - break; - } - else if (*iter == '$') - ; - else - break; - lastchar = *iter; - } - if (is_iter == 2) - { - // CASE2: iteration - // Looks like: @[var,min,max:code|sep@] - // Replace known variables / additional arguments - replace_vars(sect, argc, argv, curvars); - - // get the parts! - string varname; - int varnum; - int expr_min; - int expr_max; - - // varname - size_t comma = sect.find(','); - if (comma == string::npos) - { - cout << "Invalid iteration syntax" << endl; - return 1; - } - varname.assign(sect.begin() + 2, sect.begin() + comma); - trim_string(varname); - if (varname.size() != 2 || varname[0] != '$' || !isdigit(varname[1])) - { - cout << "Invalid variable name" << endl; - return 1; - } - varnum = varname[1] - '0'; - - // min - ++comma; - size_t nextcomma = sect.find(',', comma); - if (nextcomma == string::npos) - { - cout << "Invalid iteration syntax" << endl; - return 1; - } - expr_min = parse_expr(sect.begin() + comma, sect.begin() + nextcomma); - - // max - comma = nextcomma + 1; - nextcomma = sect.find(':', comma); - if (nextcomma == string::npos) - { - cout << "Invalid iteration syntax" << endl; - return 1; - } - - expr_max = parse_expr(sect.begin() + comma, sect.begin() + nextcomma); - - // separator - size_t sepbegin = sect.find('|'); - size_t sepend = string::npos; - if (sepbegin != string::npos && sepbegin < nextcomma) - { - // There's a separator! - ++sepbegin; - sepend = nextcomma; - } - else - sepbegin = string::npos; - - - ++nextcomma; // nextcomma is now where code begins! - - size_t codeend = sect.size() - 2; - - // Check whether the var is already taken - if (curvars.find(varnum) != curvars.end()) - { - cout << "Variable $" << varnum << "already taken!" << endl; - return 1; - } - - // Do iterations!! - for (int i = expr_min; i <= expr_max; ++i) - { - curvars[varnum] = i; - - string code(sect.begin() + nextcomma, sect.begin() + codeend); - replace_vars(code, argc, argv, curvars); - - // Feed it through the input routine (RECURSE!!!!!! YEAH!) - do_input(argc, argv, outfile, code, curvars); - - // Add separator if required - if (sepbegin != string::npos && i != expr_max) - { - string tmp(sect.begin() + sepbegin, sect.begin() + sepend); - do_input(argc, argv, outfile, tmp, curvars); - } - } - // Remove the var! - curvars.erase(varnum); - } - else - { - // CASE3: conditional thing. - // Looks like: @[expr1 operator expr2:code@] - - // Find the operator position - - enum OP_TYPE - { - OP_EQ, - OP_NEQ - }; - - OP_TYPE op; - size_t oppos = sect.find("=="); - if (oppos != string::npos) - op = OP_EQ; - else - { - oppos = sect.find("!="); - if (oppos != string::npos) - op = OP_NEQ; - else - { - cout << "Conditional expression without operator!?" << endl; - return 1; - } - } - size_t colon = sect.find(':'); - - // Now we've got everything. Parse first expr: - int expr1 = parse_expr(sect.begin() + 2, sect.begin() + oppos); - int expr2 = parse_expr(sect.begin() + oppos + 2, sect.begin() + colon); - if ((op == OP_EQ && expr1 == expr2) || - (op == OP_NEQ && expr1 != expr2)) - { - // Condition is true, process it! - // The text may still contain arithmetic exprs or other cond. exprs - // so send it through do_input - string tmp(sect.substr(colon+1, sect.size() - colon - 3)); - do_input(argc, argv, outfile, tmp, curvars); - } - } - } - else - { - cout << "WTF" << endl; - return 1; - } - } - - return 0; -} - - - -// action_iter -// params: -// filenamein: input file name -// filenameout: output file name -// argc: number of additional arguments -// argv: additional arguments -// retval: 0 on success, non-zero on error - -// Convert additional arguments -// Read whole input file to memory and open output file -// Pass to do_input() -int action_iter(const char *filenamein, const char *filenameout, int argc, const char *argv[]) -{ - // Convert additional arguments - const int MAX_ARGC = 10; - int converted_argv[MAX_ARGC]; - - int i; - for (i = 0; i < argc && i < MAX_ARGC; ++i) - converted_argv[i] = atoi(argv[i]); - - if (argc != i) - cout << "WARNING: Not all additional arguments processed!" << endl; - - - // Read whole input file to memory and open output file - ifstream fin(filenamein); - ofstream fout(filenameout); - - if (!fin) - { - cout << "Could not open file \"" << filenamein << "\"." << endl; - return 1; - } - if (!fout) - { - cout << "Could not open file \"" << filenameout << "\"." << endl; - return 1; - } - string input_str( - istreambuf_iterator (fin.rdbuf()), - istreambuf_iterator ()); - - - // Begin processing input - varmap vars; - try - { - return do_input(argc, converted_argv, fout, input_str, vars); - } - catch (MyError err) - { - err.Print(); - return 1; - } -} - -// MAIN -// Prints usage if required -// Calls action_hopter OR action_iter -int main(int argc, const char **argv) -{ - if (argc < 4) - { - cout << "Usage:" << endl << " shworker [iter/hopter] ..." << endl; - cout << " shworker iter filename.in filename.out [param1, param2, ...]" << endl; - cout << " shworker hopter filename.in filename.out [num-of-args]" << endl; - return 1; - } - - const char *action = argv[1]; - - if (stricmp(action, "hopter") == 0) - { - const char *filenamein = argv[2]; - const char *filenameout = argv[3]; - int argsnum = atoi(argv[4]); - - return action_hopter(argsnum, filenamein, filenameout); - } - else if (stricmp(action, "iter") == 0) - { - const char *filenamein = argv[2]; - const char *filenameout = argv[3]; - int additional_argc = argc - 4; - const char ** additional_argv = argv + 4; - return action_iter(filenamein, filenameout, additional_argc, additional_argv); - } - else - { - cout << "Unrecognized action: " << argv[1] << endl; - return 1; - } -} diff --git a/sourcehook/generate/sourcehook.h b/sourcehook/generate/sourcehook.h deleted file mode 100644 index df5a477..0000000 --- a/sourcehook/generate/sourcehook.h +++ /dev/null @@ -1,6043 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -/** -* @file sourcehook.h -* @brief Contains the public SourceHook API -*/ - -#ifndef __SOURCEHOOK_H__ -#define __SOURCEHOOK_H__ - -// Interface revisions: -// 1 - Initial revision -// 2 - Changed to virtual functions for iterators and all queries -// 3 - Added "hook loop status variable" -// 4 - Reentrant -// 5 - New "V2" interface -#define SH_IFACE_VERSION 5 - -// Impl versions: -// ??? -// 4 - addition of hook ids and vp hooks (with them, AddHookNew and RemoveHookNew) -// This is not a SH_IFACE_VERSION change so that old plugins continue working! -// 5 - implementation of the new "V2" interface -#define SH_IMPL_VERSION 5 - -// Hookman version: -// 1 - standard -#define SH_HOOKMAN_VERSION 1 - -// Hookmanautogen versions -// 1 - initial -#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1 -#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1 - -// The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook -// It's used in various macros -#ifndef SH_GLOB_SHPTR -#define SH_GLOB_SHPTR g_SHPtr -#endif - -// Used to identify the current plugin -#ifndef SH_GLOB_PLUGPTR -#define SH_GLOB_PLUGPTR g_PLID -#endif - -#ifdef SH_DEBUG -# include -# include - -# define SH_ASSERT(x, info) \ - do { \ - if (!(x)) \ - { \ - printf("SOURCEHOOK DEBUG ASSERTION FAILED: %s:%u(%s): %s: ", __FILE__, __LINE__, __FUNCTION__, #x); \ - printf info; \ - putchar('\n'); \ - abort(); \ - } \ - } while(0) - -#else -# define SH_ASSERT(x, info) -#endif - -// System -#define SH_SYS_WIN32 1 -#define SH_SYS_LINUX 2 - -#ifdef _WIN32 -# define SH_SYS SH_SYS_WIN32 -#elif defined __linux__ -# define SH_SYS SH_SYS_LINUX -#else -# error Unsupported system -#endif - -// Compiler -#define SH_COMP_GCC 1 -#define SH_COMP_MSVC 2 - -#ifdef _MSC_VER -# define SH_COMP SH_COMP_MSVC -#elif defined __GNUC__ -# define SH_COMP SH_COMP_GCC -#else -# error Unsupported compiler -#endif - -#if SH_COMP==SH_COMP_MSVC -# define vsnprintf _vsnprintf -#endif - -#if SH_SYS != SH_SYS_WIN32 -# include -#endif - -#define SH_PTRSIZE sizeof(void*) - -#include "sh_memfuncinfo.h" -#include "FastDelegate.h" - -// Good old metamod! - -// Flags returned by a plugin's api function. -// NOTE: order is crucial, as greater/less comparisons are made. -enum META_RES -{ - MRES_IGNORED=0, // plugin didn't take any action - MRES_HANDLED, // plugin did something, but real function should still be called - MRES_OVERRIDE, // call real function, but use my return value - MRES_SUPERCEDE // skip real function; use my return value -}; - - -namespace SourceHook -{ - /** - * @brief Specifies the size (in bytes) for the internal buffer of vafmt(printf-like) function handlers - */ - const int STRBUF_LEN=4096; - - /** - * @brief An empty class. No inheritance used. Used for original-function-call hacks - */ - class EmptyClass - { - }; - - /** - * @brief Implicit cast. - */ - template - inline Out implicit_cast(In input) - { - return input; - } - - /** - * @brief A plugin typedef - * - * SourceHook doesn't really care what this is. As long as the ==, != and = operators work on it and every - * plugin has a unique identifier, everything is ok. - * It should also be possible to set it to 0. - */ - typedef int Plugin; - - - template class CallClass : public T - { - }; - typedef void ManualCallClass; - - /** - * @brief Describes the way a parameter/retval is passed. - */ - struct PassInfo - { - enum PassType - { - PassType_Unknown=0, /**< Unknown -- no extra info available */ - PassType_Basic, /**< Plain old register data (pointers, integers) */ - PassType_Float, /**< Floating point data */ - PassType_Object, /**< Object or structure */ - }; - - enum PassFlags - { - PassFlag_ByVal = (1<<0), /**< Passing by value */ - PassFlag_ByRef = (1<<1), /**< Passing by reference */ - PassFlag_ODtor = (1<<2), /**< Object has a destructor */ - PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */ - PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */ - PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */ - - // The following two flags are only relevant for byval return types. - // SH tries to auto-detect these - // If you want to override SH's auto-detection, pass them in yourself - PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */ - PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */ - }; - - size_t size; //!< Size of the data being passed - - // Extra info: - // (might be used in future versions for automatic hookfunc generation) - int type; //!< PassType value - unsigned int flags; //!< Pass/return flags - - struct V2Info - { - void *pNormalCtor; - void *pCopyCtor; - void *pDtor; - void *pAssignOperator; - }; - }; - - struct ProtoInfo - { - enum CallConvention - { - CallConv_Unknown, /**< Unknown -- no extra info available (0)*/ - CallConv_ThisCall, /**< This call (object pointer required) (1)*/ - CallConv_Cdecl, /**< C call (2)*/ - CallConv_StdCall, /**< Windows "stdcall" (3)*/ - - CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */ - CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */ - }; - - int numOfParams; //!< number of parameters - PassInfo retPassInfo; //!< PassInfo for the return value. size=0 -> no retval - const PassInfo *paramsPassInfo; //!< PassInfos for the parameters - - // paramsPassInfo[0] is basically a dummy parameter. - // However, paramsPassInfo[0].size stores the version of the ProtoInfo structure. - - // Extra info: - int convention; - - // Version2: - PassInfo::V2Info retPassInfo2; - const PassInfo::V2Info *paramsPassInfo2; - }; - - struct IHookManagerInfo; - - /** - * @brief Pointer to hook manager interface function - * - * The hook manager should store hi for later use if store==true. It should then call hi->SetInfo(...) if hi - * is non-null. The hook manager can return 0 for success or a non-zero value if it doesn't want to be used. - * - * @param hi A pointer to IHookManagerInfo - */ - typedef int (*HookManagerPubFunc)(bool store, IHookManagerInfo *hi); - - class ISHDelegate - { - public: - virtual bool IsEqual(ISHDelegate *pOtherDeleg) = 0; // pOtherDeleg is from the same plugin and hookman - virtual void DeleteThis() = 0; - }; - - struct IHookManagerInfo - { - virtual void SetInfo(int hookman_version, int vtbloffs, int vtblidx, - ProtoInfo *proto, void *hookfunc_vfnptr) = 0; - }; - - // I'm adding support for functions which return references. - - // How it works: - // SH_SETUPCALLS doesn't use plain rettype to store the temporary return values (plugin ret, orig ret, - // override ret) anymore; instead, it uses SourceHook::ReferenceCarrier::type - // this is typedefed to the original rettype normally, but if the rettype is a reference, it's a special class - // which stores the reference as a pointer, and implements constructors, operator= and a conversion operator. - // special cases were needed for getoverrideret / getorigret; these are implemented through the - // SourceHook::MacroRefHelpers structs. - // Furthermore, SetOverrideRet had to be changed a bit; see SourceHook::OverrideFunctor somewhere down in this file. - template struct ReferenceCarrier - { - typedef T type; - }; - - template struct ReferenceCarrier - { - class type - { - T *m_StoredRef; - public: - type() : m_StoredRef(NULL) - { - } - type(T& ref) : m_StoredRef(&ref) - { - } - - T& operator= (T& ref) - { - m_StoredRef = &ref; - return ref; - } - - operator T& () const - { - return *m_StoredRef; - } - }; - }; - - struct IHookContext - { - virtual ISHDelegate *GetNext() = 0; - virtual void *GetOverrideRetPtr() = 0; - virtual const void *GetOrigRetPtr() = 0; - virtual bool ShouldCallOrig() = 0; - }; - - /** - * @brief The main SourceHook interface - */ - class ISourceHook - { - public: - /** - * @brief Return interface version - */ - virtual int GetIfaceVersion() = 0; - - /** - * @brief Return implementation version - */ - virtual int GetImplVersion() = 0; - - /** - * @brief Modes for the new AddHook - */ - enum AddHookMode - { - Hook_Normal, - Hook_VP, - Hook_DVP - }; - - /** - * @brief Add a (VP) hook. - * - * @return non-zero hook id on success, 0 otherwise - * - * @param plug The unique identifier of the plugin that calls this function - * @param mode Can be either Hook_Normal or Hook_VP (vtable-wide hook) - * @param iface The interface pointer - * @param ifacesize The size of the class iface points to - * @param myHookMan A hook manager function that should be capable of handling the function - * @param handler A pointer to the hook handler something - * @param post Set to true if you want a post handler - */ - virtual int AddHook(Plugin plug, AddHookMode mode, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post) = 0; - - // Source backwarts compat (only for normal hooks) - virtual bool RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post) = 0; - - /** - * @brief Remove a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool RemoveHookByID(int hookid) = 0; - - /** - * @brief Pause a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool PauseHookByID(int hookid) = 0; - - /** - * @brief Unpause a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool UnpauseHookByID(int hookid) = 0; - - /** - * @brief Checks whether a plugin has (a) hook manager(s) that is/are currently used by other plugins - * - * @param plug The unique identifier of the plugin in question - */ - - virtual void SetRes(META_RES res) = 0; //!< Sets the meta result - virtual META_RES GetPrevRes() = 0; //!< Gets the meta result of the - //!< previously calledhandler - virtual META_RES GetStatus() = 0; //!< Gets the highest meta result - virtual const void *GetOrigRet() = 0; //!< Gets the original result. - //!< If not in post function, undefined - virtual const void *GetOverrideRet() = 0; //!< Gets the override result. - //!< If none is specified, NULL - virtual void *GetIfacePtr() = 0; //!< Gets the interface pointer - - virtual void *GetOverrideRetPtr() = 0; //!< Used for setting the override return value - - /** - * @brief Remove a hook manager. Auto-removes all hooks attached to it from plugin plug. - * - * @param plug The owner of the hook manager - * @param pubFunc The hook manager's info function - */ - virtual void RemoveHookManager(Plugin plug, HookManagerPubFunc pubFunc) = 0; - - // For SH_CALL: - - /** - * @brief Makes sure that hooks are going to be ignored on the next call of vfnptr - * - * @param plug The unique identifier of the plugin that calls this function - * @param vfnptr The virtual function pointer of the function in question - */ - virtual void SetIgnoreHooks(void *vfnptr) = 0; - - /** - * @brief Reverses SetIgnoreHooks' effect - * - * @param plug The unique identifier of the plugin that calls this function - * @param vfnptr The virtual function pointer of the function in question - */ - virtual void ResetIgnoreHooks(void *vfnptr) = 0; - - /** - * @brief Finds the original entry of a virtual function pointer - * - * @param vfnptr The virtual function pointer - * @return The original entry if the virtual function pointer has been patched; NULL otherwise. - */ - virtual void *GetOrigVfnPtrEntry(void *vfnptr) = 0; - - ////////////////////////////////////////////////////////////////////////// - - // For hook managers - - // Returns the current iface ptr - virtual void DoRecall() = 0; //!< Initiates a recall sequence - - /* - HOW RECALLS WORK: - - The problem: - Users want the ability to change parameters of the called function - from inside their handler. - The solution: - 1) Mark as "recall" - 2) Recall the function - 3) => SH's hook func gets called: - 4) The first iterator points at the first hook the last hookfunc didn't execute yet - 5) does all iteration and returns normally - 6) The user's handler returns immediately - 7) The hook func returns immediately as well - - Also note that the recalled hookfunc starts with the status the recalling hookfunc - ended with. The last handler (doing the recall) is also able to specify its own - META_RES. - */ - - /** - * @brief Set up the hook loop. - * - * @param statusPtr pointer to status variable - * @param prevResPtr pointer to previous result variable - * @param curResPtr pointer to current result variable - * @param ifacePtrPtr pointer to interface this pointer variable - * @param origRetPr pointer to original return value variable. NULL for void funcs - * @param overrideRetPtr pointer to override return value variable. NULL for void funcs - * - * @return Override Return Pointer the hookfunc should use (may differ from overrideRetPtr - * when the hook func is being called as part of a recall - */ - virtual IHookContext *SetupHookLoop(IHookManagerInfo *hi, void *vfnptr, void *thisptr, void **origentry, - META_RES *statusPtr, META_RES *prevResPtr, META_RES *curResPtr, - const void *origRetPtr, void *overrideRetPtr) = 0; - - virtual void EndContext(IHookContext *pCtx) = 0; - }; - - - class IHookManagerAutoGen - { - public: - virtual int GetIfaceVersion() = 0; - virtual int GetImplVersion() = 0; - - virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0; - virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0; - }; - - // For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET: - // These have to be able to return references. If T is a reference, the pointers returned - // from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier::type. - template struct MacroRefHelpers - { - inline static const T* GetOrigRet(ISourceHook *shptr) - { - return reinterpret_cast(shptr->GetOrigRet()); - } - inline static const T* GetOverrideRet(ISourceHook *shptr) - { - return reinterpret_cast(shptr->GetOverrideRet()); - } - }; - - template struct MacroRefHelpers - { - inline static T* GetOrigRet(ISourceHook *shptr) - { - T &ref = *reinterpret_cast::type *>(shptr->GetOrigRet()); - return &ref; - } - inline static T* GetOverrideRet(ISourceHook *shptr) - { - T &ref = *reinterpret_cast::type *>(shptr->GetOverrideRet()); - return &ref; - } - }; - - template - void *GetOrigVfnPtrEntry(X *pInstance, MFP mfp, ISourceHook *pSH) - { - SourceHook::MemFuncInfo info = {true, -1, 0, 0}; - SourceHook::GetFuncInfo(pInstance, mfp, info); - - void *vfnptr = reinterpret_cast( - *reinterpret_cast(reinterpret_cast(pInstance) + info.thisptroffs + info.vtbloffs) + info.vtblindex); - - void *origentry = pSH->GetOrigVfnPtrEntry(vfnptr); - - return origentry ? origentry : *reinterpret_cast(vfnptr); - } - - template struct GetPassInfo - { - static const int type = 0; - static const unsigned int flags = PassInfo::PassFlag_ByVal; - }; - - template struct GetPassInfo - { - static const int type = 0; - static const unsigned int flags = PassInfo::PassFlag_ByRef; - }; -} - -/************************************************************************/ -/* High level interface */ -/************************************************************************/ -#define META_RESULT_STATUS SH_GLOB_SHPTR->GetStatus() -#define META_RESULT_PREVIOUS SH_GLOB_SHPTR->GetPrevRes() -#define META_RESULT_ORIG_RET(type) *SourceHook::MacroRefHelpers::GetOrigRet(SH_GLOB_SHPTR) -#define META_RESULT_OVERRIDE_RET(type) *SourceHook::MacroRefHelpers::GetOverrideRet(SH_GLOB_SHPTR) -#define META_IFACEPTR(type) reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()) - -#define SET_META_RESULT(result) SH_GLOB_SHPTR->SetRes(result) -#define RETURN_META(result) do { SET_META_RESULT(result); return; } while(0) -#define RETURN_META_VALUE(result, value) do { SET_META_RESULT(result); return (value); } while(0) - - -template -SourceHook::CallClass *SH_GET_CALLCLASS(T *p) -{ - return static_cast< SourceHook::CallClass *>(p); -} -#define SH_RELEASE_CALLCLASS(p) - -#define SH_GET_MCALLCLASS(p, size) reinterpret_cast(p) - -// only call these from the hook handlers directly! - -// If a hook on a function which returns a reference does not want to specify a return value, -// it can use this macro. -// ONLY USE THIS WITH MRES_IGNORED AND MRES_HANDLED !!! -#define RETURN_META_NOREF(result, rettype) do { SET_META_RESULT(result); return reinterpret_cast(*SH_GLOB_SHPTR); } while(0) - -// Why take a memfuncptr instead of iface and func when we have to deduce the iface anyway now? -// Well, without it, there'd be no way to specify which overloaded version we want in _VALUE - -// SourceHook::SetOverrideRet is defined later. -#define RETURN_META_NEWPARAMS(result, memfuncptr, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - (SourceHook::RecallGetIface(SH_GLOB_SHPTR, memfuncptr)->*(memfuncptr)) newparams; \ - RETURN_META(MRES_SUPERCEDE); \ - } while (0) - -#define RETURN_META_VALUE_NEWPARAMS(result, value, memfuncptr, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - if ((result) >= MRES_OVERRIDE) \ - { \ - /* meh, set the override result here because we don't get a chance to return */ \ - /* before continuing the hook loop through the recall */ \ - SourceHook::SetOverrideResult(memfuncptr)(SH_GLOB_SHPTR, value); \ - } \ - RETURN_META_VALUE(MRES_SUPERCEDE, \ - (SourceHook::RecallGetIface(SH_GLOB_SHPTR, memfuncptr)->*(memfuncptr)) newparams); \ - } while (0) - -// :TODO: thisptroffs in MNEWPARAMS ?? - -#if SH_COMP == SH_COMP_MSVC - -#define SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname) \ - union \ - { \ - SH_MFHCls(hookname)::ECMFP mfp; \ - void *addr; \ - } u; \ - SourceHook::EmptyClass *thisptr = reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()); \ - u.addr = (*reinterpret_cast(reinterpret_cast(thisptr) + SH_MFHCls(hookname)::ms_MFI.vtbloffs))[ \ - SH_MFHCls(hookname)::ms_MFI.vtblindex]; - -#elif SH_COMP == SH_COMP_GCC - -#define SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname) \ - union \ - { \ - SH_MFHCls(hookname)::ECMFP mfp; \ - struct \ - { \ - void *addr; \ - intptr_t adjustor; \ - } s; \ - } u; \ - SourceHook::EmptyClass *thisptr = reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()); \ - u.s.addr = (*reinterpret_cast(reinterpret_cast(thisptr) + SH_MFHCls(hookname)::ms_MFI.vtbloffs))[ \ - SH_MFHCls(hookname)::ms_MFI.vtblindex]; \ - u.s.adjustor = 0; - -#endif - -#define RETURN_META_MNEWPARAMS(result, hookname, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname); \ - (thisptr->*(u.mfp)) newparams; \ - RETURN_META(MRES_SUPERCEDE); \ - } while (0) - -#define RETURN_META_VALUE_MNEWPARAMS(result, value, hookname, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - if ((result) >= MRES_OVERRIDE) \ - { \ - /* see RETURN_META_VALUE_NEWPARAMS */ \ - SourceHook::SetOverrideResult(SH_GLOB_SHPTR, value); \ - } \ - SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname); \ - RETURN_META_VALUE(MRES_SUPERCEDE, (thisptr->*(u.mfp)) newparams); \ - } while (0) - - -#define SH_MANUALHOOK_RECONFIGURE(hookname, pvtblindex, pvtbloffs, pthisptroffs) \ - do { \ - SH_GLOB_SHPTR->RemoveHookManager(SH_GLOB_PLUGPTR, SH_MFHCls(hookname)::HookManPubFunc); \ - SH_MFHCls(hookname)::ms_MFI.thisptroffs = pthisptroffs; \ - SH_MFHCls(hookname)::ms_MFI.vtblindex = pvtblindex; \ - SH_MFHCls(hookname)::ms_MFI.vtbloffs = pvtbloffs; \ - } while (0) - -#define SH_GET_ORIG_VFNPTR_ENTRY(inst, mfp) (SourceHook::GetOrigVfnPtrEntry(inst, mfp, SH_GLOB_SHPTR)) - -// New ADD / REMOVE macros. -#define SH_STATIC(func) fastdelegate::MakeDelegate(func) -#define SH_MEMBER(inst, func) fastdelegate::MakeDelegate(inst, func) - -#define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_Normal, post, handler) - -#define SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHRemove##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - post, handler) - -#define SH_ADD_MANUALHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_Normal, post, handler) - -#define SH_REMOVE_MANUALHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMRemove##hookname(reinterpret_cast(ifaceptr), post, handler) - -#define SH_ADD_VPHOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_VP, post, handler) - -#define SH_ADD_DVPHOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_DVP, post, handler) - -#define SH_ADD_MANUALVPHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), SourceHook::ISourceHook::Hook_VP, post, handler) - -#define SH_ADD_MANUALDVPHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), SourceHook::ISourceHook::Hook_DVP, post, handler) - -#define SH_REMOVE_HOOK_ID(hookid) \ - (SH_GLOB_SHPTR->RemoveHookByID(hookid)) - -// Old macros -// !! These are now deprecated. Instead, use one of these: -// SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -// SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_ADD_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \ - SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -#define SH_ADD_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \ - SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -// SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_REMOVE_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \ - SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -#define SH_REMOVE_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \ - SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -// SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_ADD_MANUALHOOK_STATICFUNC(hookname, ifaceptr, handler, post) \ - SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -#define SH_ADD_MANUALHOOK_MEMFUNC(hookname, ifaceptr, handler_inst, handler_func, post) \ - SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -// SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_REMOVE_MANUALHOOK_STATICFUNC(hookname, ifaceptr, handler, post) \ - SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -#define SH_REMOVE_MANUALHOOK_MEMFUNC(hookname, ifaceptr, handler_inst, handler_func, post) \ - SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -#define SH_NOATTRIB - - - - -#if SH_COMP == SH_COMP_MSVC -# define SH_SETUP_MFP(mfp) \ - reinterpret_cast(&mfp)[0] = vfnptr_origentry; -#elif SH_COMP == SH_COMP_GCC -# define SH_SETUP_MFP(mfp) \ - reinterpret_cast(&mfp)[0] = vfnptr_origentry; \ - reinterpret_cast(&mfp)[1] = 0; -#else -# error Not supported yet. -#endif - -////////////////////////////////////////////////////////////////////////// -#define SH_FHCls(ift, iff, ov) __SourceHook_FHCls_##ift##iff##ov -#define SH_MFHCls(hookname) __SourceHook_MFHCls_##hookname - -#define SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) \ - static int HookManPubFunc(bool store, ::SourceHook::IHookManagerInfo *hi) \ - { \ - using namespace ::SourceHook; \ - GetFuncInfo(funcptr, ms_MFI); \ - /* Verify interface version */ \ - if (SH_GLOB_SHPTR->GetIfaceVersion() != SH_IFACE_VERSION) \ - return 1; \ - if (SH_GLOB_SHPTR->GetImplVersion() < SH_IMPL_VERSION) \ - return 1; \ - if (store) \ - ms_HI = hi; \ - if (hi) \ - { \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(&SH_FHCls(ifacetype,ifacefunc,overload)::Func, mfi); \ - hi->SetInfo(SH_HOOKMAN_VERSION, ms_MFI.vtbloffs, ms_MFI.vtblindex, &ms_Proto, \ - reinterpret_cast(reinterpret_cast(&ms_Inst) + mfi.vtbloffs)[mfi.vtblindex] ); \ - } \ - return 0; \ - } - -// It has to be possible to use the macros in namespaces -// -> So we need to access and extend the global SourceHook namespace -// We use a namespace alias for this -#define SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, funcptr) \ - struct SH_FHCls(ifacetype,ifacefunc,overload) \ - { \ - static SH_FHCls(ifacetype,ifacefunc,overload) ms_Inst; \ - static ::SourceHook::MemFuncInfo ms_MFI; \ - static ::SourceHook::IHookManagerInfo *ms_HI; \ - static ::SourceHook::ProtoInfo ms_Proto; \ - SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) - -#define SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, funcptr) \ - }; \ - SH_FHCls(ifacetype,ifacefunc,overload) SH_FHCls(ifacetype,ifacefunc,overload)::ms_Inst; \ - ::SourceHook::MemFuncInfo SH_FHCls(ifacetype,ifacefunc,overload)::ms_MFI; \ - ::SourceHook::IHookManagerInfo *SH_FHCls(ifacetype,ifacefunc,overload)::ms_HI; \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ - { \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(funcptr, mfi); \ - if (mfi.thisptroffs < 0 || !mfi.isVirtual) \ - return false; /* No non-virtual functions / virtual inheritance supported */ \ - \ - return SH_GLOB_SHPTR->AddHook(SH_GLOB_PLUGPTR, mode, \ - iface, mfi.thisptroffs, SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, \ - new SH_FHCls(ifacetype,ifacefunc,overload)::CMyDelegateImpl(handler), post); \ - } \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ - { \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(funcptr, mfi); \ - SH_FHCls(ifacetype,ifacefunc,overload)::CMyDelegateImpl tmp(handler); \ - return SH_GLOB_SHPTR->RemoveHook(SH_GLOB_PLUGPTR, iface, mfi.thisptroffs, \ - SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, &tmp, post); \ - } \ - -#define SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, pvtbloffs, pvtblidx, pthisptroffs) \ - struct SH_MFHCls(hookname) \ - { \ - static SH_MFHCls(hookname) ms_Inst; \ - static ::SourceHook::MemFuncInfo ms_MFI; \ - static ::SourceHook::IHookManagerInfo *ms_HI; \ - static ::SourceHook::ProtoInfo ms_Proto; \ - \ - SH_MFHCls(hookname)() \ - { \ - ms_MFI.isVirtual = true; \ - ms_MFI.thisptroffs = pthisptroffs; \ - ms_MFI.vtblindex = pvtblidx; \ - ms_MFI.vtbloffs = pvtbloffs; \ - } \ - static int HookManPubFunc(bool store, ::SourceHook::IHookManagerInfo *hi) \ - { \ - using namespace ::SourceHook; \ - /* Verify interface version */ \ - if (SH_GLOB_SHPTR->GetIfaceVersion() != SH_IFACE_VERSION) \ - return 1; \ - if (SH_GLOB_SHPTR->GetImplVersion() < SH_IMPL_VERSION) \ - return 1; \ - if (store) \ - ms_HI = hi; \ - if (hi) \ - { \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(&SH_MFHCls(hookname)::Func, mfi); \ - hi->SetInfo(SH_HOOKMAN_VERSION, ms_MFI.vtbloffs, ms_MFI.vtblindex, &ms_Proto, \ - reinterpret_cast(reinterpret_cast(&ms_Inst) + mfi.vtbloffs)[mfi.vtblindex] ); \ - } \ - return 0; \ - } - -#define SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, pvtbloffs, pvtblidx, pthisptroffs) \ - }; \ - SH_MFHCls(hookname) SH_MFHCls(hookname)::ms_Inst; \ - ::SourceHook::MemFuncInfo SH_MFHCls(hookname)::ms_MFI; \ - ::SourceHook::IHookManagerInfo *SH_MFHCls(hookname)::ms_HI; \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - SH_MFHCls(hookname)::FD handler) \ - { \ - return SH_GLOB_SHPTR->AddHook(SH_GLOB_PLUGPTR, mode, \ - iface, pthisptroffs, SH_MFHCls(hookname)::HookManPubFunc, \ - new SH_MFHCls(hookname)::CMyDelegateImpl(handler), post); \ - } \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - SH_MFHCls(hookname)::FD handler) \ - { \ - SH_MFHCls(hookname)::CMyDelegateImpl tmp(handler); \ - return SH_GLOB_SHPTR->RemoveHook(SH_GLOB_PLUGPTR, iface, pthisptroffs, \ - SH_MFHCls(hookname)::HookManPubFunc, &tmp, post); \ - } \ - -#define SH_SETUPCALLS(rettype, paramtypes, params) \ - /* 1) Set up */ \ - using namespace ::SourceHook; \ - void *ourvfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(this) + ms_MFI.vtbloffs) + ms_MFI.vtblindex); \ - void *vfnptr_origentry; \ - \ - META_RES status = MRES_IGNORED; \ - META_RES prev_res; \ - META_RES cur_res; \ - \ - typedef ReferenceCarrier< rettype >::type my_rettype; \ - my_rettype orig_ret; \ - my_rettype override_ret; \ - my_rettype plugin_ret; \ - IMyDelegate *iter; \ - IHookContext *pContext = SH_GLOB_SHPTR->SetupHookLoop(ms_HI, ourvfnptr, reinterpret_cast(this), \ - &vfnptr_origentry, &status, &prev_res, &cur_res, &orig_ret, &override_ret); - -#define SH_CALL_HOOKS(post, params) \ - prev_res = MRES_IGNORED; \ - while ( (iter = static_cast(pContext->GetNext())) ) \ - { \ - cur_res = MRES_IGNORED; \ - plugin_ret = iter->Call params; \ - prev_res = cur_res; \ - if (cur_res > status) \ - status = cur_res; \ - if (cur_res >= MRES_OVERRIDE) \ - *reinterpret_cast(pContext->GetOverrideRetPtr()) = plugin_ret; \ - } - -#define SH_CALL_ORIG(rettype, paramtypes, params) \ - if (status != MRES_SUPERCEDE && pContext->ShouldCallOrig()) \ - { \ - rettype (EmptyClass::*mfp)paramtypes; \ - SH_SETUP_MFP(mfp); \ - orig_ret = (reinterpret_cast(this)->*mfp)params; \ - } \ - else \ - orig_ret = override_ret; /* :TODO: ??? : use pContext->GetOverrideRetPtr() or not? */ - -#define SH_RETURN() \ - const my_rettype *retptr = reinterpret_cast( \ - (status >= MRES_OVERRIDE) ? pContext->GetOverrideRetPtr() : pContext->GetOrigRetPtr()); \ - SH_GLOB_SHPTR->EndContext(pContext); \ - return *retptr; - -#define SH_HANDLEFUNC(paramtypes, params, rettype) \ - SH_SETUPCALLS(rettype, paramtypes, params) \ - SH_CALL_HOOKS(pre, params) \ - SH_CALL_ORIG(rettype, paramtypes, params) \ - SH_CALL_HOOKS(post, params) \ - SH_RETURN() - -////////////////////////////////////////////////////////////////////////// -#define SH_SETUPCALLS_void(paramtypes, params) \ - /* 1) Set up */ \ - using namespace ::SourceHook; \ - void *ourvfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(this) + ms_MFI.vtbloffs) + ms_MFI.vtblindex); \ - void *vfnptr_origentry; \ - \ - META_RES status = MRES_IGNORED; \ - META_RES prev_res; \ - META_RES cur_res; \ - \ - IMyDelegate *iter; \ - IHookContext *pContext = SH_GLOB_SHPTR->SetupHookLoop(ms_HI, ourvfnptr, reinterpret_cast(this), \ - &vfnptr_origentry, &status, &prev_res, &cur_res, NULL, NULL); - -#define SH_CALL_HOOKS_void(post, params) \ - prev_res = MRES_IGNORED; \ - while ( (iter = static_cast(pContext->GetNext())) ) \ - { \ - cur_res = MRES_IGNORED; \ - iter->Call params; \ - prev_res = cur_res; \ - if (cur_res > status) \ - status = cur_res; \ - } - -#define SH_CALL_ORIG_void(paramtypes, params) \ - if (status != MRES_SUPERCEDE && pContext->ShouldCallOrig()) \ - { \ - void (EmptyClass::*mfp)paramtypes; \ - SH_SETUP_MFP(mfp); \ - (reinterpret_cast(this)->*mfp)params; \ - } - -#define SH_RETURN_void() \ - SH_GLOB_SHPTR->EndContext(pContext); - -#define SH_HANDLEFUNC_void(paramtypes, params) \ - SH_SETUPCALLS_void(paramtypes, params) \ - SH_CALL_HOOKS_void(pre, params) \ - SH_CALL_ORIG_void(paramtypes, params) \ - SH_CALL_HOOKS_void(post, params) \ - SH_RETURN_void() - - -// Special vafmt handlers -// :TODO: what -#define SH_HANDLEFUNC_vafmt(paramtypes, params_orig, params_plug, rettype) \ - SH_SETUPCALLS(rettype, paramtypes, params_orig) \ - SH_CALL_HOOKS(pre, params_plug) \ - SH_CALL_ORIG(rettype, paramtypes, params_orig) \ - SH_CALL_HOOKS(post, params_plug) \ - SH_RETURN() - -#define SH_HANDLEFUNC_void_vafmt(paramtypes, params_orig, params_plug) \ - SH_SETUPCALLS_void(paramtypes, params_orig) \ - SH_CALL_HOOKS_void(pre, params_plug) \ - SH_CALL_ORIG_void(paramtypes, params_orig) \ - SH_CALL_HOOKS_void(post, params_plug) \ - SH_RETURN_void() - -////////////////////////////////////////////////////////////////////////// - -#define MAKE_DELEG(ret_type, params_decl, params_pass) \ - struct IMyDelegate : ::SourceHook::ISHDelegate { virtual ret_type Call params_decl = 0; }; \ - struct CMyDelegateImpl : IMyDelegate \ - { \ - FD m_Deleg; \ - CMyDelegateImpl(FD deleg) : m_Deleg(deleg) {} \ - ret_type Call params_decl { return m_Deleg params_pass; } \ - void DeleteThis() { delete this; } \ - bool IsEqual(ISHDelegate *pOtherDeleg) { return m_Deleg == static_cast(pOtherDeleg)->m_Deleg; } \ - }; - -#define MAKE_DELEG_void(params_decl, params_pass) \ - struct IMyDelegate : ::SourceHook::ISHDelegate { virtual void Call params_decl = 0; }; \ - struct CMyDelegateImpl : IMyDelegate \ - { \ - FD m_Deleg; \ - CMyDelegateImpl(FD deleg) : m_Deleg(deleg) {} \ - void Call params_decl { m_Deleg params_pass; } \ - void DeleteThis() { delete this; } \ - bool IsEqual(ISHDelegate *pOtherDeleg) { return m_Deleg == static_cast(pOtherDeleg)->m_Deleg; } \ - }; - -// GetPassInfo -> easier access. __SH_GPI generates a SourceHook::PassInfo instance. -#define __SH_GPI(tt) { sizeof(tt), ::SourceHook::GetPassInfo< tt >::type, ::SourceHook::GetPassInfo< tt >::flags } -// Extra pass info V2 -#define __SH_EPI { 0, 0, 0, 0 } - - -// ********* Support for 0 arguments ********* -#define SH_DECL_HOOK0(ifacetype, ifacefunc, attr, overload, rettype) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate0 FD; \ - MAKE_DELEG(rettype, (), ()); \ - virtual rettype Func() \ - { SH_HANDLEFUNC((), (), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 0, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN0(ifacetype, ifacefunc, attr, overload, rettype) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate0 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate0 handler); - -#define SH_DECL_HOOK0_void(ifacetype, ifacefunc, attr, overload) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate0<> FD; \ - MAKE_DELEG_void((), ()); \ - virtual void Func() \ - { SH_HANDLEFUNC_void((), ()); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 0, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN0_void(ifacetype, ifacefunc, attr, overload) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate0<> handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate0<> handler); - -#define SH_DECL_HOOK0_vafmt(ifacetype, ifacefunc, attr, overload, rettype) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG(rettype, (const char *px), (px)); \ - virtual rettype Func( const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((...), ("%s", buf), (buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 0, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN0_vafmt(ifacetype, ifacefunc, attr, overload, rettype) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_HOOK0_void_vafmt(ifacetype, ifacefunc, attr, overload) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG_void((const char *px), (px)); \ - virtual void Func(const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((...), ("%s", buf), (buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 0, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN0_void_vafmt(ifacetype, ifacefunc, attr, overload) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_MANUALHOOK0(hookname, vtblidx, vtbloffs, thisptroffs, rettype) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate0 FD; \ - MAKE_DELEG(rettype, (), ()); \ - virtual rettype Func() \ - { SH_HANDLEFUNC((), (), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 0, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN0(hookname, rettype) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate0 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate0 handler); - -#define SH_DECL_MANUALHOOK0_void(hookname, vtblidx, vtbloffs, thisptroffs) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate0<> FD; \ - MAKE_DELEG_void((), ()); \ - virtual void Func() \ - { SH_HANDLEFUNC_void((), ()); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 0, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN0_void(hookname) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate0<> handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate0<> handler); - -// ********* Support for 1 arguments ********* -#define SH_DECL_HOOK1(ifacetype, ifacefunc, attr, overload, rettype, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG(rettype, (param1 p1), (p1)); \ - virtual rettype Func(param1 p1) \ - { SH_HANDLEFUNC((param1), (p1), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 1, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN1(ifacetype, ifacefunc, attr, overload, rettype, param1) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_HOOK1_void(ifacetype, ifacefunc, attr, overload, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG_void((param1 p1), (p1)); \ - virtual void Func(param1 p1) \ - { SH_HANDLEFUNC_void((param1), (p1)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 1, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN1_void(ifacetype, ifacefunc, attr, overload, param1) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_HOOK1_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG(rettype, (param1 p1, const char *px), (p1, px)); \ - virtual rettype Func(param1 p1 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, ...), (p1, "%s", buf), (p1, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 1, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN1_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_HOOK1_void_vafmt(ifacetype, ifacefunc, attr, overload, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG_void((param1 p1, const char *px), (p1, px)); \ - virtual void Func(param1 p1, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, ...), (p1, "%s", buf), (p1, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 1, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN1_void_vafmt(ifacetype, ifacefunc, attr, overload, param1) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_MANUALHOOK1(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG(rettype, (param1 p1), (p1)); \ - virtual rettype Func(param1 p1) \ - { SH_HANDLEFUNC((param1), (p1), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 1, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN1(hookname, rettype, param1) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_MANUALHOOK1_void(hookname, vtblidx, vtbloffs, thisptroffs, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG_void((param1 p1), (p1)); \ - virtual void Func(param1 p1) \ - { SH_HANDLEFUNC_void((param1), (p1)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 1, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN1_void(hookname, param1) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -// ********* Support for 2 arguments ********* -#define SH_DECL_HOOK2(ifacetype, ifacefunc, attr, overload, rettype, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2), (p1, p2)); \ - virtual rettype Func(param1 p1, param2 p2) \ - { SH_HANDLEFUNC((param1, param2), (p1, p2), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 2, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN2(ifacetype, ifacefunc, attr, overload, rettype, param1, param2) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_HOOK2_void(ifacetype, ifacefunc, attr, overload, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2), (p1, p2)); \ - virtual void Func(param1 p1, param2 p2) \ - { SH_HANDLEFUNC_void((param1, param2), (p1, p2)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 2, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN2_void(ifacetype, ifacefunc, attr, overload, param1, param2) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_HOOK2_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, const char *px), (p1, p2, px)); \ - virtual rettype Func(param1 p1, param2 p2 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, ...), (p1, p2, "%s", buf), (p1, p2, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 2, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN2_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_HOOK2_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, const char *px), (p1, p2, px)); \ - virtual void Func(param1 p1, param2 p2, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, ...), (p1, p2, "%s", buf), (p1, p2, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 2, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN2_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_MANUALHOOK2(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2), (p1, p2)); \ - virtual rettype Func(param1 p1, param2 p2) \ - { SH_HANDLEFUNC((param1, param2), (p1, p2), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 2, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN2(hookname, rettype, param1, param2) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_MANUALHOOK2_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2), (p1, p2)); \ - virtual void Func(param1 p1, param2 p2) \ - { SH_HANDLEFUNC_void((param1, param2), (p1, p2)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 2, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN2_void(hookname, param1, param2) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -// ********* Support for 3 arguments ********* -#define SH_DECL_HOOK3(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3), (p1, p2, p3)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3) \ - { SH_HANDLEFUNC((param1, param2, param3), (p1, p2, p3), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 3, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN3(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_HOOK3_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3), (p1, p2, p3)); \ - virtual void Func(param1 p1, param2 p2, param3 p3) \ - { SH_HANDLEFUNC_void((param1, param2, param3), (p1, p2, p3)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 3, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN3_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_HOOK3_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, const char *px), (p1, p2, p3, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, ...), (p1, p2, p3, "%s", buf), (p1, p2, p3, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 3, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN3_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_HOOK3_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, const char *px), (p1, p2, p3, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, ...), (p1, p2, p3, "%s", buf), (p1, p2, p3, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 3, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN3_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_MANUALHOOK3(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3), (p1, p2, p3)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3) \ - { SH_HANDLEFUNC((param1, param2, param3), (p1, p2, p3), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 3, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN3(hookname, rettype, param1, param2, param3) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_MANUALHOOK3_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3), (p1, p2, p3)); \ - virtual void Func(param1 p1, param2 p2, param3 p3) \ - { SH_HANDLEFUNC_void((param1, param2, param3), (p1, p2, p3)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 3, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN3_void(hookname, param1, param2, param3) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -// ********* Support for 4 arguments ********* -#define SH_DECL_HOOK4(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4), (p1, p2, p3, p4)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { SH_HANDLEFUNC((param1, param2, param3, param4), (p1, p2, p3, p4), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 4, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN4(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_HOOK4_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4), (p1, p2, p3, p4)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4), (p1, p2, p3, p4)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 4, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN4_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_HOOK4_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, const char *px), (p1, p2, p3, p4, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, ...), (p1, p2, p3, p4, "%s", buf), (p1, p2, p3, p4, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 4, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN4_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_HOOK4_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, const char *px), (p1, p2, p3, p4, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, ...), (p1, p2, p3, p4, "%s", buf), (p1, p2, p3, p4, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 4, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN4_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_MANUALHOOK4(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4), (p1, p2, p3, p4)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { SH_HANDLEFUNC((param1, param2, param3, param4), (p1, p2, p3, p4), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 4, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN4(hookname, rettype, param1, param2, param3, param4) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_MANUALHOOK4_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4), (p1, p2, p3, p4)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4), (p1, p2, p3, p4)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 4, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN4_void(hookname, param1, param2, param3, param4) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -// ********* Support for 5 arguments ********* -#define SH_DECL_HOOK5(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5), (p1, p2, p3, p4, p5)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5), (p1, p2, p3, p4, p5), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 5, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN5(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_HOOK5_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5), (p1, p2, p3, p4, p5)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5), (p1, p2, p3, p4, p5)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 5, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN5_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_HOOK5_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *px), (p1, p2, p3, p4, p5, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, ...), (p1, p2, p3, p4, p5, "%s", buf), (p1, p2, p3, p4, p5, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 5, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN5_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_HOOK5_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *px), (p1, p2, p3, p4, p5, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, ...), (p1, p2, p3, p4, p5, "%s", buf), (p1, p2, p3, p4, p5, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 5, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN5_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_MANUALHOOK5(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5), (p1, p2, p3, p4, p5)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5), (p1, p2, p3, p4, p5), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 5, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN5(hookname, rettype, param1, param2, param3, param4, param5) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_MANUALHOOK5_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5), (p1, p2, p3, p4, p5)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5), (p1, p2, p3, p4, p5)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 5, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN5_void(hookname, param1, param2, param3, param4, param5) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -// ********* Support for 6 arguments ********* -#define SH_DECL_HOOK6(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6), (p1, p2, p3, p4, p5, p6)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6), (p1, p2, p3, p4, p5, p6), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 6, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN6(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_HOOK6_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6), (p1, p2, p3, p4, p5, p6)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6), (p1, p2, p3, p4, p5, p6)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 6, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN6_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_HOOK6_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *px), (p1, p2, p3, p4, p5, p6, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, ...), (p1, p2, p3, p4, p5, p6, "%s", buf), (p1, p2, p3, p4, p5, p6, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 6, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN6_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_HOOK6_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *px), (p1, p2, p3, p4, p5, p6, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, ...), (p1, p2, p3, p4, p5, p6, "%s", buf), (p1, p2, p3, p4, p5, p6, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 6, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN6_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_MANUALHOOK6(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6), (p1, p2, p3, p4, p5, p6)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6), (p1, p2, p3, p4, p5, p6), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 6, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN6(hookname, rettype, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_MANUALHOOK6_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6), (p1, p2, p3, p4, p5, p6)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6), (p1, p2, p3, p4, p5, p6)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 6, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN6_void(hookname, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -// ********* Support for 7 arguments ********* -#define SH_DECL_HOOK7(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7), (p1, p2, p3, p4, p5, p6, p7)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7), (p1, p2, p3, p4, p5, p6, p7), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 7, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN7(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_HOOK7_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7), (p1, p2, p3, p4, p5, p6, p7)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7), (p1, p2, p3, p4, p5, p6, p7)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 7, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN7_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_HOOK7_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, const char *px), (p1, p2, p3, p4, p5, p6, p7, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, ...), (p1, p2, p3, p4, p5, p6, p7, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 7, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN7_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_HOOK7_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, const char *px), (p1, p2, p3, p4, p5, p6, p7, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, ...), (p1, p2, p3, p4, p5, p6, p7, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 7, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN7_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_MANUALHOOK7(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7), (p1, p2, p3, p4, p5, p6, p7)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7), (p1, p2, p3, p4, p5, p6, p7), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 7, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN7(hookname, rettype, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_MANUALHOOK7_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7), (p1, p2, p3, p4, p5, p6, p7)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7), (p1, p2, p3, p4, p5, p6, p7)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 7, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN7_void(hookname, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -// ********* Support for 8 arguments ********* -#define SH_DECL_HOOK8(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8), (p1, p2, p3, p4, p5, p6, p7, p8)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8), (p1, p2, p3, p4, p5, p6, p7, p8), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 8, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN8(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_HOOK8_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8), (p1, p2, p3, p4, p5, p6, p7, p8)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8), (p1, p2, p3, p4, p5, p6, p7, p8)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 8, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN8_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_HOOK8_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, ...), (p1, p2, p3, p4, p5, p6, p7, p8, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 8, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN8_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_HOOK8_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, ...), (p1, p2, p3, p4, p5, p6, p7, p8, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 8, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN8_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_MANUALHOOK8(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8), (p1, p2, p3, p4, p5, p6, p7, p8)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8), (p1, p2, p3, p4, p5, p6, p7, p8), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 8, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN8(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_MANUALHOOK8_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8), (p1, p2, p3, p4, p5, p6, p7, p8)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8), (p1, p2, p3, p4, p5, p6, p7, p8)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 8, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN8_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -// ********* Support for 9 arguments ********* -#define SH_DECL_HOOK9(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9), (p1, p2, p3, p4, p5, p6, p7, p8, p9), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 9, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN9(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_HOOK9_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 9, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN9_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_HOOK9_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 9, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN9_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_HOOK9_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 9, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN9_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_MANUALHOOK9(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9), (p1, p2, p3, p4, p5, p6, p7, p8, p9), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 9, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN9(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_MANUALHOOK9_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 9, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN9_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -// ********* Support for 10 arguments ********* -#define SH_DECL_HOOK10(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 10, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN10(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_HOOK10_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 10, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN10_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_HOOK10_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 10, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN10_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_HOOK10_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 10, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN10_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_MANUALHOOK10(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 10, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN10(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_MANUALHOOK10_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 10, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN10_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -// ********* Support for 11 arguments ********* -#define SH_DECL_HOOK11(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 11, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN11(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_HOOK11_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 11, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN11_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_HOOK11_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 11, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN11_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_HOOK11_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 11, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN11_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_MANUALHOOK11(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 11, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN11(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_MANUALHOOK11_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 11, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN11_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -// ********* Support for 12 arguments ********* -#define SH_DECL_HOOK12(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 12, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN12(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_HOOK12_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 12, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN12_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_HOOK12_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 12, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN12_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_HOOK12_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 12, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN12_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_MANUALHOOK12(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 12, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN12(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_MANUALHOOK12_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 12, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN12_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -// ********* Support for 13 arguments ********* -#define SH_DECL_HOOK13(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 13, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN13(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_HOOK13_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12),__SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 13, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN13_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_HOOK13_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 13, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN13_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_HOOK13_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 13, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN13_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_MANUALHOOK13(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 13, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN13(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_MANUALHOOK13_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 13, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN13_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -// ********* Support for 14 arguments ********* -#define SH_DECL_HOOK14(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 14, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN14(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_HOOK14_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12),__SH_GPI(param13),__SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 14, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN14_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_HOOK14_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 14, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN14_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_HOOK14_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 14, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN14_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_MANUALHOOK14(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 14, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN14(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_MANUALHOOK14_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 14, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN14_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -// ********* Support for 15 arguments ********* -#define SH_DECL_HOOK15(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 15, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN15(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_HOOK15_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12),__SH_GPI(param13),__SH_GPI(param14),__SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 15, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN15_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_HOOK15_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 15, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN15_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_HOOK15_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 15, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN15_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_MANUALHOOK15(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 15, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN15(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_MANUALHOOK15_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 15, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN15_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -// ********* Support for 16 arguments ********* -#define SH_DECL_HOOK16(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 16, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN16(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_HOOK16_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12),__SH_GPI(param13),__SH_GPI(param14),__SH_GPI(param15),__SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 16, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN16_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_HOOK16_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate17 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 16, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN16_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate17 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate17 handler); - -#define SH_DECL_HOOK16_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate17 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 16, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN16_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate17 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate17 handler); - -#define SH_DECL_MANUALHOOK16(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 16, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN16(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_MANUALHOOK16_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 16, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN16_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - - - -////////////////////////////////////////////////////////////////////////// -// SH_CALL - -#define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ -{ \ - using namespace ::SourceHook; \ - \ - m_pSH->SetIgnoreHooks(m_VfnPtr); \ - RetType tmpret = (m_ThisPtr->*m_MFP)call; \ - m_pSH->ResetIgnoreHooks(m_VfnPtr); \ - return tmpret; \ -} - -#define SH_MAKE_EXECUTABLECLASS_OB_void(call, prms) \ -{ \ - using namespace ::SourceHook; \ - \ - m_pSH->SetIgnoreHooks(m_VfnPtr); \ - (m_ThisPtr->*m_MFP)call; \ - m_pSH->ResetIgnoreHooks(m_VfnPtr); \ -} - -namespace SourceHook -{ - - // Support for 0 arguments - template class ExecutableClass0 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass0(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()() const - SH_MAKE_EXECUTABLECLASS_OB((), ()) - - - template RetType operator()(Param1 p1) const - SH_MAKE_EXECUTABLECLASS_OB((p1), (Param1)) - - template RetType operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2), (Param1, Param2)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass0 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass0(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()() const - SH_MAKE_EXECUTABLECLASS_OB_void((), ()) - - - template void operator()(Param1 p1) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1), (Param1)) - - template void operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2), (Param1, Param2)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3), (Param1, Param2, Param3)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 1 arguments - template class ExecutableClass1 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass1(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1) const - SH_MAKE_EXECUTABLECLASS_OB((p1), (Param1)) - - - template RetType operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2), (Param1, Param2)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass1 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass1(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1), (Param1)) - - - template void operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2), (Param1, Param2)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3), (Param1, Param2, Param3)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 2 arguments - template class ExecutableClass2 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass2(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2), (Param1, Param2)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass2 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass2(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2), (Param1, Param2)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3), (Param1, Param2, Param3)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 3 arguments - template class ExecutableClass3 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass3(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass3 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass3(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3), (Param1, Param2, Param3)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 4 arguments - template class ExecutableClass4 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass4(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass4 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass4(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 5 arguments - template class ExecutableClass5 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass5(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass5 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass5(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 6 arguments - template class ExecutableClass6 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass6(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass6 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass6(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 7 arguments - template class ExecutableClass7 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass7(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass7 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass7(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 8 arguments - template class ExecutableClass8 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass8(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass8 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass8(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 9 arguments - template class ExecutableClass9 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass9(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass9 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass9(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 10 arguments - template class ExecutableClass10 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass10(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass10 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass10(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 11 arguments - template class ExecutableClass11 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass11(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass11 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass11(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 12 arguments - template class ExecutableClass12 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass12(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass12 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass12(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 13 arguments - template class ExecutableClass13 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass13(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass13 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass13(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 14 arguments - template class ExecutableClass14 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass14(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass14 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass14(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 15 arguments - template class ExecutableClass15 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass15(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass15 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass15(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 16 arguments - template class ExecutableClass16 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass16(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - - }; - - template class ExecutableClass16 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass16(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - - }; - - -} - -#define SH__CALL_GET_VFNPTR_NORMAL \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(ptr, mfp, mfi); \ - void *vfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(ptr) + mfi.thisptroffs + mfi.vtbloffs) + mfi.vtblindex); - -#define SH__CALL_GET_VFNPTR_MANUAL \ - using namespace ::SourceHook; \ - void *vfnptr = reinterpret_cast( \ - *reinterpret_cast( (reinterpret_cast(ptr) + thisptroffs + vtbloffs) ) + vtblidx); \ - /* patch mfp */ \ - *reinterpret_cast(&mfp) = *reinterpret_cast(vfnptr); - -// SH_CALL needs to deduce the return type -> it uses templates and function overloading -// That's why SH_CALL takes two parameters: "mfp2" of type RetType(X::*mfp)(params), and "mfp" of type MFP -// The only purpose of the mfp2 parameter is to extract the return type - - -// Support for 0 arguments -template -SourceHook::ExecutableClass0 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass0(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass0 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)()const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass0(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass0 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass0( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 1 arguments -template -SourceHook::ExecutableClass1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass1 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass1( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 2 arguments -template -SourceHook::ExecutableClass2 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass2(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass2 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass2(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass2 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass2( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 3 arguments -template -SourceHook::ExecutableClass3 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass3(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass3 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass3(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass3 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass3( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 4 arguments -template -SourceHook::ExecutableClass4 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass4(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass4 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass4(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass4 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass4( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 5 arguments -template -SourceHook::ExecutableClass5 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass5(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass5 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass5(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass5 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass5( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 6 arguments -template -SourceHook::ExecutableClass6 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass6(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass6 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass6(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass6 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass6( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 7 arguments -template -SourceHook::ExecutableClass7 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass7(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass7 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass7(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass7 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass7( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 8 arguments -template -SourceHook::ExecutableClass8 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass8(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass8 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass8(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass8 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass8( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 9 arguments -template -SourceHook::ExecutableClass9 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass9(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass9 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass9(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass9 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass9( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 10 arguments -template -SourceHook::ExecutableClass10 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass10(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass10 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass10(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass10 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass10( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 11 arguments -template -SourceHook::ExecutableClass11 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass11(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass11 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass11(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass11 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass11( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 12 arguments -template -SourceHook::ExecutableClass12 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass12(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass12 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass12(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass12 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass12( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 13 arguments -template -SourceHook::ExecutableClass13 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass13(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass13 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass13(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass13 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass13( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 14 arguments -template -SourceHook::ExecutableClass14 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass14(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass14 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass14(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass14 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass14( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 15 arguments -template -SourceHook::ExecutableClass15 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass15(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass15 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass15(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass15 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass15( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 16 arguments -template -SourceHook::ExecutableClass16 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass16(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass16 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass16(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass16 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass16( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - - -#if SH_COMP != SH_COMP_MSVC || _MSC_VER > 1300 -// GCC & MSVC 7.1 need this, MSVC 7.0 doesn't like it - - -// Support for 0 arguments -template -SourceHook::ExecutableClass0 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass0(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass0 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass0(ptr, mfp, vfnptr, shptr); -} - - -// Support for 1 arguments -template -SourceHook::ExecutableClass1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass1(ptr, mfp, vfnptr, shptr); -} - - -// Support for 2 arguments -template -SourceHook::ExecutableClass2 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass2(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass2 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass2(ptr, mfp, vfnptr, shptr); -} - - -// Support for 3 arguments -template -SourceHook::ExecutableClass3 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass3(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass3 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass3(ptr, mfp, vfnptr, shptr); -} - - -// Support for 4 arguments -template -SourceHook::ExecutableClass4 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass4(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass4 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass4(ptr, mfp, vfnptr, shptr); -} - - -// Support for 5 arguments -template -SourceHook::ExecutableClass5 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass5(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass5 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass5(ptr, mfp, vfnptr, shptr); -} - - -// Support for 6 arguments -template -SourceHook::ExecutableClass6 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass6(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass6 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass6(ptr, mfp, vfnptr, shptr); -} - - -// Support for 7 arguments -template -SourceHook::ExecutableClass7 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass7(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass7 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass7(ptr, mfp, vfnptr, shptr); -} - - -// Support for 8 arguments -template -SourceHook::ExecutableClass8 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass8(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass8 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass8(ptr, mfp, vfnptr, shptr); -} - - -// Support for 9 arguments -template -SourceHook::ExecutableClass9 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass9(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass9 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass9(ptr, mfp, vfnptr, shptr); -} - - -// Support for 10 arguments -template -SourceHook::ExecutableClass10 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass10(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass10 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass10(ptr, mfp, vfnptr, shptr); -} - - -// Support for 11 arguments -template -SourceHook::ExecutableClass11 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass11(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass11 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass11(ptr, mfp, vfnptr, shptr); -} - - -// Support for 12 arguments -template -SourceHook::ExecutableClass12 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass12(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass12 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass12(ptr, mfp, vfnptr, shptr); -} - - -// Support for 13 arguments -template -SourceHook::ExecutableClass13 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass13(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass13 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass13(ptr, mfp, vfnptr, shptr); -} - - -// Support for 14 arguments -template -SourceHook::ExecutableClass14 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass14(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass14 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass14(ptr, mfp, vfnptr, shptr); -} - - -// Support for 15 arguments -template -SourceHook::ExecutableClass15 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass15(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass15 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass15(ptr, mfp, vfnptr, shptr); -} - - -// Support for 16 arguments -template -SourceHook::ExecutableClass16 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass16(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass16 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass16(ptr, mfp, vfnptr, shptr); -} - - - -#endif - -#define SH_CALL(ptr, mfp) SH_CALL2((ptr), (mfp), (mfp), SH_GLOB_SHPTR) -#define SH_MCALL2(ptr, mfp, vtblidx, vtbloffs, thisptroffs) SH_MCALL3((ptr), (mfp), (mfp), (vtblidx), (vtbloffs), (thisptroffs), SH_GLOB_SHPTR) -#define SH_MCALL(ptr, mhookname) SH_MCALL2((ptr), SH_MFHCls(mhookname)::ECMFP(), SH_MFHCls(mhookname)::ms_MFI.vtblindex, \ - SH_MFHCls(mhookname)::ms_MFI.vtbloffs, SH_MFHCls(mhookname)::ms_MFI.thisptroffs) - -#undef SH_MAKE_EXECUTABLECLASS_OB -#undef SH_MAKE_EXECUTABLECLASS_OB_void - -////////////////////////////////////////////////////////////////////////// -// SetOverrideRet and RecallGetIface for recalls -// These take a ISourceHook pointer instead of using SH_GLOB_SHPTR directly -// The reason is that the user may want to redefine SH_GLOB_SHPTR - then the macros -// (META_RETURN_VALUE_NEWPARAMS) should obey the new pointer. - -namespace SourceHook -{ - template - void SetOverrideResult(ISourceHook *shptr, const RetType res) - { - *reinterpret_cast(shptr->GetOverrideRetPtr()) = res; - } - - // SetOverrideResult used to be implemented like this: - // SetOverrideResult(shptr, memfuncptr, return); - // normally the compiler can deduce the return type from memfuncptr, but (at least msvc8) failed when it was a reference - // (it thought it was ambigous - the ref and non-ref type) - // so now SetOverrideResult(memfuncptr) deduces the ret type, and returns a functor which does the work - // new syntax: SetOverrideResult(memfuncptr)(shptr, return) - // This also allows us to create a special version for references which respects ReferenceCarrier. - - template struct OverrideFunctor - { - void operator()(ISourceHook *shptr, T res) - { - *reinterpret_cast(shptr->GetOverrideRetPtr()) = res; - } - }; - template struct OverrideFunctor - { - void operator()(ISourceHook *shptr, T &res) - { - // overrideretptr points to ReferenceCarrier - *reinterpret_cast::type *>(shptr->GetOverrideRetPtr()) = res; - } - }; - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)()) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)()) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - -} - -#endif - // The pope is dead. -> :( diff --git a/sourcehook/generate/sourcehook.hxx b/sourcehook/generate/sourcehook.hxx deleted file mode 100755 index 04069b7..0000000 --- a/sourcehook/generate/sourcehook.hxx +++ /dev/null @@ -1,1377 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -/** -* @file sourcehook.h -* @brief Contains the public SourceHook API -*/ - -#ifndef __SOURCEHOOK_H__ -#define __SOURCEHOOK_H__ - -// Interface revisions: -// 1 - Initial revision -// 2 - Changed to virtual functions for iterators and all queries -// 3 - Added "hook loop status variable" -// 4 - Reentrant -// 5 - New "V2" interface -#define SH_IFACE_VERSION 5 - -// Impl versions: -// ??? -// 4 - addition of hook ids and vp hooks (with them, AddHookNew and RemoveHookNew) -// This is not a SH_IFACE_VERSION change so that old plugins continue working! -// 5 - implementation of the new "V2" interface -#define SH_IMPL_VERSION 5 - -// Hookman version: -// 1 - standard -#define SH_HOOKMAN_VERSION 1 - -// Hookmanautogen versions -// 1 - initial -#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1 -#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1 - -// The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook -// It's used in various macros -#ifndef SH_GLOB_SHPTR -#define SH_GLOB_SHPTR g_SHPtr -#endif - -// Used to identify the current plugin -#ifndef SH_GLOB_PLUGPTR -#define SH_GLOB_PLUGPTR g_PLID -#endif - -#ifdef SH_DEBUG -# include -# include - -# define SH_ASSERT(x, info) \ - do { \ - if (!(x)) \ - { \ - printf("SOURCEHOOK DEBUG ASSERTION FAILED: %s:%u(%s): %s: ", __FILE__, __LINE__, __FUNCTION__, #x); \ - printf info; \ - putchar('\n'); \ - abort(); \ - } \ - } while(0) - -#else -# define SH_ASSERT(x, info) -#endif - -// System -#define SH_SYS_WIN32 1 -#define SH_SYS_LINUX 2 - -#ifdef _WIN32 -# define SH_SYS SH_SYS_WIN32 -#elif defined __linux__ -# define SH_SYS SH_SYS_LINUX -#else -# error Unsupported system -#endif - -// Compiler -#define SH_COMP_GCC 1 -#define SH_COMP_MSVC 2 - -#ifdef _MSC_VER -# define SH_COMP SH_COMP_MSVC -#elif defined __GNUC__ -# define SH_COMP SH_COMP_GCC -#else -# error Unsupported compiler -#endif - -#if SH_COMP==SH_COMP_MSVC -# define vsnprintf _vsnprintf -#endif - -#if SH_SYS != SH_SYS_WIN32 -# include -#endif - -#define SH_PTRSIZE sizeof(void*) - -#include "sh_memfuncinfo.h" -#include "FastDelegate.h" - -// Good old metamod! - -// Flags returned by a plugin's api function. -// NOTE: order is crucial, as greater/less comparisons are made. -enum META_RES -{ - MRES_IGNORED=0, // plugin didn't take any action - MRES_HANDLED, // plugin did something, but real function should still be called - MRES_OVERRIDE, // call real function, but use my return value - MRES_SUPERCEDE // skip real function; use my return value -}; - - -namespace SourceHook -{ - /** - * @brief Specifies the size (in bytes) for the internal buffer of vafmt(printf-like) function handlers - */ - const int STRBUF_LEN=4096; - - /** - * @brief An empty class. No inheritance used. Used for original-function-call hacks - */ - class EmptyClass - { - }; - - /** - * @brief Implicit cast. - */ - template - inline Out implicit_cast(In input) - { - return input; - } - - /** - * @brief A plugin typedef - * - * SourceHook doesn't really care what this is. As long as the ==, != and = operators work on it and every - * plugin has a unique identifier, everything is ok. - * It should also be possible to set it to 0. - */ - typedef int Plugin; - - - template class CallClass : public T - { - }; - typedef void ManualCallClass; - - /** - * @brief Describes the way a parameter/retval is passed. - */ - struct PassInfo - { - enum PassType - { - PassType_Unknown=0, /**< Unknown -- no extra info available */ - PassType_Basic, /**< Plain old register data (pointers, integers) */ - PassType_Float, /**< Floating point data */ - PassType_Object, /**< Object or structure */ - }; - - enum PassFlags - { - PassFlag_ByVal = (1<<0), /**< Passing by value */ - PassFlag_ByRef = (1<<1), /**< Passing by reference */ - PassFlag_ODtor = (1<<2), /**< Object has a destructor */ - PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */ - PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */ - PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */ - - // The following two flags are only relevant for byval return types. - // SH tries to auto-detect these - // If you want to override SH's auto-detection, pass them in yourself - PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */ - PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */ - }; - - size_t size; //!< Size of the data being passed - - // Extra info: - // (might be used in future versions for automatic hookfunc generation) - int type; //!< PassType value - unsigned int flags; //!< Pass/return flags - - struct V2Info - { - void *pNormalCtor; - void *pCopyCtor; - void *pDtor; - void *pAssignOperator; - }; - }; - - struct ProtoInfo - { - enum CallConvention - { - CallConv_Unknown, /**< Unknown -- no extra info available (0)*/ - CallConv_ThisCall, /**< This call (object pointer required) (1)*/ - CallConv_Cdecl, /**< C call (2)*/ - CallConv_StdCall, /**< Windows "stdcall" (3)*/ - - CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */ - CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */ - }; - - int numOfParams; //!< number of parameters - PassInfo retPassInfo; //!< PassInfo for the return value. size=0 -> no retval - const PassInfo *paramsPassInfo; //!< PassInfos for the parameters - - // paramsPassInfo[0] is basically a dummy parameter. - // However, paramsPassInfo[0].size stores the version of the ProtoInfo structure. - - // Extra info: - int convention; - - // Version2: - PassInfo::V2Info retPassInfo2; - const PassInfo::V2Info *paramsPassInfo2; - }; - - struct IHookManagerInfo; - - /** - * @brief Pointer to hook manager interface function - * - * The hook manager should store hi for later use if store==true. It should then call hi->SetInfo(...) if hi - * is non-null. The hook manager can return 0 for success or a non-zero value if it doesn't want to be used. - * - * @param hi A pointer to IHookManagerInfo - */ - typedef int (*HookManagerPubFunc)(bool store, IHookManagerInfo *hi); - - class ISHDelegate - { - public: - virtual bool IsEqual(ISHDelegate *pOtherDeleg) = 0; // pOtherDeleg is from the same plugin and hookman - virtual void DeleteThis() = 0; - }; - - struct IHookManagerInfo - { - virtual void SetInfo(int hookman_version, int vtbloffs, int vtblidx, - ProtoInfo *proto, void *hookfunc_vfnptr) = 0; - }; - - // I'm adding support for functions which return references. - - // How it works: - // SH_SETUPCALLS doesn't use plain rettype to store the temporary return values (plugin ret, orig ret, - // override ret) anymore; instead, it uses SourceHook::ReferenceCarrier::type - // this is typedefed to the original rettype normally, but if the rettype is a reference, it's a special class - // which stores the reference as a pointer, and implements constructors, operator= and a conversion operator. - // special cases were needed for getoverrideret / getorigret; these are implemented through the - // SourceHook::MacroRefHelpers structs. - // Furthermore, SetOverrideRet had to be changed a bit; see SourceHook::OverrideFunctor somewhere down in this file. - template struct ReferenceCarrier - { - typedef T type; - }; - - template struct ReferenceCarrier - { - class type - { - T *m_StoredRef; - public: - type() : m_StoredRef(NULL) - { - } - type(T& ref) : m_StoredRef(&ref) - { - } - - T& operator= (T& ref) - { - m_StoredRef = &ref; - return ref; - } - - operator T& () const - { - return *m_StoredRef; - } - }; - }; - - struct IHookContext - { - virtual ISHDelegate *GetNext() = 0; - virtual void *GetOverrideRetPtr() = 0; - virtual const void *GetOrigRetPtr() = 0; - virtual bool ShouldCallOrig() = 0; - }; - - /** - * @brief The main SourceHook interface - */ - class ISourceHook - { - public: - /** - * @brief Return interface version - */ - virtual int GetIfaceVersion() = 0; - - /** - * @brief Return implementation version - */ - virtual int GetImplVersion() = 0; - - /** - * @brief Modes for the new AddHook - */ - enum AddHookMode - { - Hook_Normal, - Hook_VP, - Hook_DVP - }; - - /** - * @brief Add a (VP) hook. - * - * @return non-zero hook id on success, 0 otherwise - * - * @param plug The unique identifier of the plugin that calls this function - * @param mode Can be either Hook_Normal or Hook_VP (vtable-wide hook) - * @param iface The interface pointer - * @param ifacesize The size of the class iface points to - * @param myHookMan A hook manager function that should be capable of handling the function - * @param handler A pointer to the hook handler something - * @param post Set to true if you want a post handler - */ - virtual int AddHook(Plugin plug, AddHookMode mode, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post) = 0; - - // Source backwarts compat (only for normal hooks) - virtual bool RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post) = 0; - - /** - * @brief Remove a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool RemoveHookByID(int hookid) = 0; - - /** - * @brief Pause a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool PauseHookByID(int hookid) = 0; - - /** - * @brief Unpause a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool UnpauseHookByID(int hookid) = 0; - - /** - * @brief Checks whether a plugin has (a) hook manager(s) that is/are currently used by other plugins - * - * @param plug The unique identifier of the plugin in question - */ - - virtual void SetRes(META_RES res) = 0; //!< Sets the meta result - virtual META_RES GetPrevRes() = 0; //!< Gets the meta result of the - //!< previously calledhandler - virtual META_RES GetStatus() = 0; //!< Gets the highest meta result - virtual const void *GetOrigRet() = 0; //!< Gets the original result. - //!< If not in post function, undefined - virtual const void *GetOverrideRet() = 0; //!< Gets the override result. - //!< If none is specified, NULL - virtual void *GetIfacePtr() = 0; //!< Gets the interface pointer - - virtual void *GetOverrideRetPtr() = 0; //!< Used for setting the override return value - - /** - * @brief Remove a hook manager. Auto-removes all hooks attached to it from plugin plug. - * - * @param plug The owner of the hook manager - * @param pubFunc The hook manager's info function - */ - virtual void RemoveHookManager(Plugin plug, HookManagerPubFunc pubFunc) = 0; - - // For SH_CALL: - - /** - * @brief Makes sure that hooks are going to be ignored on the next call of vfnptr - * - * @param plug The unique identifier of the plugin that calls this function - * @param vfnptr The virtual function pointer of the function in question - */ - virtual void SetIgnoreHooks(void *vfnptr) = 0; - - /** - * @brief Reverses SetIgnoreHooks' effect - * - * @param plug The unique identifier of the plugin that calls this function - * @param vfnptr The virtual function pointer of the function in question - */ - virtual void ResetIgnoreHooks(void *vfnptr) = 0; - - /** - * @brief Finds the original entry of a virtual function pointer - * - * @param vfnptr The virtual function pointer - * @return The original entry if the virtual function pointer has been patched; NULL otherwise. - */ - virtual void *GetOrigVfnPtrEntry(void *vfnptr) = 0; - - ////////////////////////////////////////////////////////////////////////// - - // For hook managers - - // Returns the current iface ptr - virtual void DoRecall() = 0; //!< Initiates a recall sequence - - /* - HOW RECALLS WORK: - - The problem: - Users want the ability to change parameters of the called function - from inside their handler. - The solution: - 1) Mark as "recall" - 2) Recall the function - 3) => SH's hook func gets called: - 4) The first iterator points at the first hook the last hookfunc didn't execute yet - 5) does all iteration and returns normally - 6) The user's handler returns immediately - 7) The hook func returns immediately as well - - Also note that the recalled hookfunc starts with the status the recalling hookfunc - ended with. The last handler (doing the recall) is also able to specify its own - META_RES. - */ - - /** - * @brief Set up the hook loop. - * - * @param statusPtr pointer to status variable - * @param prevResPtr pointer to previous result variable - * @param curResPtr pointer to current result variable - * @param ifacePtrPtr pointer to interface this pointer variable - * @param origRetPr pointer to original return value variable. NULL for void funcs - * @param overrideRetPtr pointer to override return value variable. NULL for void funcs - * - * @return Override Return Pointer the hookfunc should use (may differ from overrideRetPtr - * when the hook func is being called as part of a recall - */ - virtual IHookContext *SetupHookLoop(IHookManagerInfo *hi, void *vfnptr, void *thisptr, void **origentry, - META_RES *statusPtr, META_RES *prevResPtr, META_RES *curResPtr, - const void *origRetPtr, void *overrideRetPtr) = 0; - - virtual void EndContext(IHookContext *pCtx) = 0; - }; - - - class IHookManagerAutoGen - { - public: - virtual int GetIfaceVersion() = 0; - virtual int GetImplVersion() = 0; - - virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0; - virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0; - }; - - // For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET: - // These have to be able to return references. If T is a reference, the pointers returned - // from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier::type. - template struct MacroRefHelpers - { - inline static const T* GetOrigRet(ISourceHook *shptr) - { - return reinterpret_cast(shptr->GetOrigRet()); - } - inline static const T* GetOverrideRet(ISourceHook *shptr) - { - return reinterpret_cast(shptr->GetOverrideRet()); - } - }; - - template struct MacroRefHelpers - { - inline static T* GetOrigRet(ISourceHook *shptr) - { - T &ref = *reinterpret_cast::type *>(shptr->GetOrigRet()); - return &ref; - } - inline static T* GetOverrideRet(ISourceHook *shptr) - { - T &ref = *reinterpret_cast::type *>(shptr->GetOverrideRet()); - return &ref; - } - }; - - template - void *GetOrigVfnPtrEntry(X *pInstance, MFP mfp, ISourceHook *pSH) - { - SourceHook::MemFuncInfo info = {true, -1, 0, 0}; - SourceHook::GetFuncInfo(pInstance, mfp, info); - - void *vfnptr = reinterpret_cast( - *reinterpret_cast(reinterpret_cast(pInstance) + info.thisptroffs + info.vtbloffs) + info.vtblindex); - - void *origentry = pSH->GetOrigVfnPtrEntry(vfnptr); - - return origentry ? origentry : *reinterpret_cast(vfnptr); - } - - template struct GetPassInfo - { - static const int type = 0; - static const unsigned int flags = PassInfo::PassFlag_ByVal; - }; - - template struct GetPassInfo - { - static const int type = 0; - static const unsigned int flags = PassInfo::PassFlag_ByRef; - }; -} - -/************************************************************************/ -/* High level interface */ -/************************************************************************/ -#define META_RESULT_STATUS SH_GLOB_SHPTR->GetStatus() -#define META_RESULT_PREVIOUS SH_GLOB_SHPTR->GetPrevRes() -#define META_RESULT_ORIG_RET(type) *SourceHook::MacroRefHelpers::GetOrigRet(SH_GLOB_SHPTR) -#define META_RESULT_OVERRIDE_RET(type) *SourceHook::MacroRefHelpers::GetOverrideRet(SH_GLOB_SHPTR) -#define META_IFACEPTR(type) reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()) - -#define SET_META_RESULT(result) SH_GLOB_SHPTR->SetRes(result) -#define RETURN_META(result) do { SET_META_RESULT(result); return; } while(0) -#define RETURN_META_VALUE(result, value) do { SET_META_RESULT(result); return (value); } while(0) - - -template -SourceHook::CallClass *SH_GET_CALLCLASS(T *p) -{ - return static_cast< SourceHook::CallClass *>(p); -} -#define SH_RELEASE_CALLCLASS(p) - -#define SH_GET_MCALLCLASS(p, size) reinterpret_cast(p) - -// only call these from the hook handlers directly! - -// If a hook on a function which returns a reference does not want to specify a return value, -// it can use this macro. -// ONLY USE THIS WITH MRES_IGNORED AND MRES_HANDLED !!! -#define RETURN_META_NOREF(result, rettype) do { SET_META_RESULT(result); return reinterpret_cast(*SH_GLOB_SHPTR); } while(0) - -// Why take a memfuncptr instead of iface and func when we have to deduce the iface anyway now? -// Well, without it, there'd be no way to specify which overloaded version we want in _VALUE - -// SourceHook::SetOverrideRet is defined later. -#define RETURN_META_NEWPARAMS(result, memfuncptr, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - (SourceHook::RecallGetIface(SH_GLOB_SHPTR, memfuncptr)->*(memfuncptr)) newparams; \ - RETURN_META(MRES_SUPERCEDE); \ - } while (0) - -#define RETURN_META_VALUE_NEWPARAMS(result, value, memfuncptr, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - if ((result) >= MRES_OVERRIDE) \ - { \ - /* meh, set the override result here because we don't get a chance to return */ \ - /* before continuing the hook loop through the recall */ \ - SourceHook::SetOverrideResult(memfuncptr)(SH_GLOB_SHPTR, value); \ - } \ - RETURN_META_VALUE(MRES_SUPERCEDE, \ - (SourceHook::RecallGetIface(SH_GLOB_SHPTR, memfuncptr)->*(memfuncptr)) newparams); \ - } while (0) - -// :TODO: thisptroffs in MNEWPARAMS ?? - -#if SH_COMP == SH_COMP_MSVC - -#define SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname) \ - union \ - { \ - SH_MFHCls(hookname)::ECMFP mfp; \ - void *addr; \ - } u; \ - SourceHook::EmptyClass *thisptr = reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()); \ - u.addr = (*reinterpret_cast(reinterpret_cast(thisptr) + SH_MFHCls(hookname)::ms_MFI.vtbloffs))[ \ - SH_MFHCls(hookname)::ms_MFI.vtblindex]; - -#elif SH_COMP == SH_COMP_GCC - -#define SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname) \ - union \ - { \ - SH_MFHCls(hookname)::ECMFP mfp; \ - struct \ - { \ - void *addr; \ - intptr_t adjustor; \ - } s; \ - } u; \ - SourceHook::EmptyClass *thisptr = reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()); \ - u.s.addr = (*reinterpret_cast(reinterpret_cast(thisptr) + SH_MFHCls(hookname)::ms_MFI.vtbloffs))[ \ - SH_MFHCls(hookname)::ms_MFI.vtblindex]; \ - u.s.adjustor = 0; - -#endif - -#define RETURN_META_MNEWPARAMS(result, hookname, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname); \ - (thisptr->*(u.mfp)) newparams; \ - RETURN_META(MRES_SUPERCEDE); \ - } while (0) - -#define RETURN_META_VALUE_MNEWPARAMS(result, value, hookname, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - if ((result) >= MRES_OVERRIDE) \ - { \ - /* see RETURN_META_VALUE_NEWPARAMS */ \ - SourceHook::SetOverrideResult(SH_GLOB_SHPTR, value); \ - } \ - SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname); \ - RETURN_META_VALUE(MRES_SUPERCEDE, (thisptr->*(u.mfp)) newparams); \ - } while (0) - - -#define SH_MANUALHOOK_RECONFIGURE(hookname, pvtblindex, pvtbloffs, pthisptroffs) \ - do { \ - SH_GLOB_SHPTR->RemoveHookManager(SH_GLOB_PLUGPTR, SH_MFHCls(hookname)::HookManPubFunc); \ - SH_MFHCls(hookname)::ms_MFI.thisptroffs = pthisptroffs; \ - SH_MFHCls(hookname)::ms_MFI.vtblindex = pvtblindex; \ - SH_MFHCls(hookname)::ms_MFI.vtbloffs = pvtbloffs; \ - } while (0) - -#define SH_GET_ORIG_VFNPTR_ENTRY(inst, mfp) (SourceHook::GetOrigVfnPtrEntry(inst, mfp, SH_GLOB_SHPTR)) - -// New ADD / REMOVE macros. -#define SH_STATIC(func) fastdelegate::MakeDelegate(func) -#define SH_MEMBER(inst, func) fastdelegate::MakeDelegate(inst, func) - -#define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_Normal, post, handler) - -#define SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHRemove##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - post, handler) - -#define SH_ADD_MANUALHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_Normal, post, handler) - -#define SH_REMOVE_MANUALHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMRemove##hookname(reinterpret_cast(ifaceptr), post, handler) - -#define SH_ADD_VPHOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_VP, post, handler) - -#define SH_ADD_DVPHOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_DVP, post, handler) - -#define SH_ADD_MANUALVPHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), SourceHook::ISourceHook::Hook_VP, post, handler) - -#define SH_ADD_MANUALDVPHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), SourceHook::ISourceHook::Hook_DVP, post, handler) - -#define SH_REMOVE_HOOK_ID(hookid) \ - (SH_GLOB_SHPTR->RemoveHookByID(hookid)) - -// Old macros -// !! These are now deprecated. Instead, use one of these: -// SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -// SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_ADD_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \ - SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -#define SH_ADD_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \ - SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -// SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_REMOVE_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \ - SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -#define SH_REMOVE_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \ - SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -// SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_ADD_MANUALHOOK_STATICFUNC(hookname, ifaceptr, handler, post) \ - SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -#define SH_ADD_MANUALHOOK_MEMFUNC(hookname, ifaceptr, handler_inst, handler_func, post) \ - SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -// SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_REMOVE_MANUALHOOK_STATICFUNC(hookname, ifaceptr, handler, post) \ - SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -#define SH_REMOVE_MANUALHOOK_MEMFUNC(hookname, ifaceptr, handler_inst, handler_func, post) \ - SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -#define SH_NOATTRIB - - - - -#if SH_COMP == SH_COMP_MSVC -# define SH_SETUP_MFP(mfp) \ - reinterpret_cast(&mfp)[0] = vfnptr_origentry; -#elif SH_COMP == SH_COMP_GCC -# define SH_SETUP_MFP(mfp) \ - reinterpret_cast(&mfp)[0] = vfnptr_origentry; \ - reinterpret_cast(&mfp)[1] = 0; -#else -# error Not supported yet. -#endif - -////////////////////////////////////////////////////////////////////////// -#define SH_FHCls(ift, iff, ov) __SourceHook_FHCls_##ift##iff##ov -#define SH_MFHCls(hookname) __SourceHook_MFHCls_##hookname - -#define SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) \ - static int HookManPubFunc(bool store, ::SourceHook::IHookManagerInfo *hi) \ - { \ - using namespace ::SourceHook; \ - GetFuncInfo(funcptr, ms_MFI); \ - /* Verify interface version */ \ - if (SH_GLOB_SHPTR->GetIfaceVersion() != SH_IFACE_VERSION) \ - return 1; \ - if (SH_GLOB_SHPTR->GetImplVersion() < SH_IMPL_VERSION) \ - return 1; \ - if (store) \ - ms_HI = hi; \ - if (hi) \ - { \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(&SH_FHCls(ifacetype,ifacefunc,overload)::Func, mfi); \ - hi->SetInfo(SH_HOOKMAN_VERSION, ms_MFI.vtbloffs, ms_MFI.vtblindex, &ms_Proto, \ - reinterpret_cast(reinterpret_cast(&ms_Inst) + mfi.vtbloffs)[mfi.vtblindex] ); \ - } \ - return 0; \ - } - -// It has to be possible to use the macros in namespaces -// -> So we need to access and extend the global SourceHook namespace -// We use a namespace alias for this -#define SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, funcptr) \ - struct SH_FHCls(ifacetype,ifacefunc,overload) \ - { \ - static SH_FHCls(ifacetype,ifacefunc,overload) ms_Inst; \ - static ::SourceHook::MemFuncInfo ms_MFI; \ - static ::SourceHook::IHookManagerInfo *ms_HI; \ - static ::SourceHook::ProtoInfo ms_Proto; \ - SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) - -#define SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, funcptr) \ - }; \ - SH_FHCls(ifacetype,ifacefunc,overload) SH_FHCls(ifacetype,ifacefunc,overload)::ms_Inst; \ - ::SourceHook::MemFuncInfo SH_FHCls(ifacetype,ifacefunc,overload)::ms_MFI; \ - ::SourceHook::IHookManagerInfo *SH_FHCls(ifacetype,ifacefunc,overload)::ms_HI; \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ - { \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(funcptr, mfi); \ - if (mfi.thisptroffs < 0 || !mfi.isVirtual) \ - return false; /* No non-virtual functions / virtual inheritance supported */ \ - \ - return SH_GLOB_SHPTR->AddHook(SH_GLOB_PLUGPTR, mode, \ - iface, mfi.thisptroffs, SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, \ - new SH_FHCls(ifacetype,ifacefunc,overload)::CMyDelegateImpl(handler), post); \ - } \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ - { \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(funcptr, mfi); \ - SH_FHCls(ifacetype,ifacefunc,overload)::CMyDelegateImpl tmp(handler); \ - return SH_GLOB_SHPTR->RemoveHook(SH_GLOB_PLUGPTR, iface, mfi.thisptroffs, \ - SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, &tmp, post); \ - } \ - -#define SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, pvtbloffs, pvtblidx, pthisptroffs) \ - struct SH_MFHCls(hookname) \ - { \ - static SH_MFHCls(hookname) ms_Inst; \ - static ::SourceHook::MemFuncInfo ms_MFI; \ - static ::SourceHook::IHookManagerInfo *ms_HI; \ - static ::SourceHook::ProtoInfo ms_Proto; \ - \ - SH_MFHCls(hookname)() \ - { \ - ms_MFI.isVirtual = true; \ - ms_MFI.thisptroffs = pthisptroffs; \ - ms_MFI.vtblindex = pvtblidx; \ - ms_MFI.vtbloffs = pvtbloffs; \ - } \ - static int HookManPubFunc(bool store, ::SourceHook::IHookManagerInfo *hi) \ - { \ - using namespace ::SourceHook; \ - /* Verify interface version */ \ - if (SH_GLOB_SHPTR->GetIfaceVersion() != SH_IFACE_VERSION) \ - return 1; \ - if (SH_GLOB_SHPTR->GetImplVersion() < SH_IMPL_VERSION) \ - return 1; \ - if (store) \ - ms_HI = hi; \ - if (hi) \ - { \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(&SH_MFHCls(hookname)::Func, mfi); \ - hi->SetInfo(SH_HOOKMAN_VERSION, ms_MFI.vtbloffs, ms_MFI.vtblindex, &ms_Proto, \ - reinterpret_cast(reinterpret_cast(&ms_Inst) + mfi.vtbloffs)[mfi.vtblindex] ); \ - } \ - return 0; \ - } - -#define SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, pvtbloffs, pvtblidx, pthisptroffs) \ - }; \ - SH_MFHCls(hookname) SH_MFHCls(hookname)::ms_Inst; \ - ::SourceHook::MemFuncInfo SH_MFHCls(hookname)::ms_MFI; \ - ::SourceHook::IHookManagerInfo *SH_MFHCls(hookname)::ms_HI; \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - SH_MFHCls(hookname)::FD handler) \ - { \ - return SH_GLOB_SHPTR->AddHook(SH_GLOB_PLUGPTR, mode, \ - iface, pthisptroffs, SH_MFHCls(hookname)::HookManPubFunc, \ - new SH_MFHCls(hookname)::CMyDelegateImpl(handler), post); \ - } \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - SH_MFHCls(hookname)::FD handler) \ - { \ - SH_MFHCls(hookname)::CMyDelegateImpl tmp(handler); \ - return SH_GLOB_SHPTR->RemoveHook(SH_GLOB_PLUGPTR, iface, pthisptroffs, \ - SH_MFHCls(hookname)::HookManPubFunc, &tmp, post); \ - } \ - -#define SH_SETUPCALLS(rettype, paramtypes, params) \ - /* 1) Set up */ \ - using namespace ::SourceHook; \ - void *ourvfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(this) + ms_MFI.vtbloffs) + ms_MFI.vtblindex); \ - void *vfnptr_origentry; \ - \ - META_RES status = MRES_IGNORED; \ - META_RES prev_res; \ - META_RES cur_res; \ - \ - typedef ReferenceCarrier< rettype >::type my_rettype; \ - my_rettype orig_ret; \ - my_rettype override_ret; \ - my_rettype plugin_ret; \ - IMyDelegate *iter; \ - IHookContext *pContext = SH_GLOB_SHPTR->SetupHookLoop(ms_HI, ourvfnptr, reinterpret_cast(this), \ - &vfnptr_origentry, &status, &prev_res, &cur_res, &orig_ret, &override_ret); - -#define SH_CALL_HOOKS(post, params) \ - prev_res = MRES_IGNORED; \ - while ( (iter = static_cast(pContext->GetNext())) ) \ - { \ - cur_res = MRES_IGNORED; \ - plugin_ret = iter->Call params; \ - prev_res = cur_res; \ - if (cur_res > status) \ - status = cur_res; \ - if (cur_res >= MRES_OVERRIDE) \ - *reinterpret_cast(pContext->GetOverrideRetPtr()) = plugin_ret; \ - } - -#define SH_CALL_ORIG(rettype, paramtypes, params) \ - if (status != MRES_SUPERCEDE && pContext->ShouldCallOrig()) \ - { \ - rettype (EmptyClass::*mfp)paramtypes; \ - SH_SETUP_MFP(mfp); \ - orig_ret = (reinterpret_cast(this)->*mfp)params; \ - } \ - else \ - orig_ret = override_ret; /* :TODO: ??? : use pContext->GetOverrideRetPtr() or not? */ - -#define SH_RETURN() \ - const my_rettype *retptr = reinterpret_cast( \ - (status >= MRES_OVERRIDE) ? pContext->GetOverrideRetPtr() : pContext->GetOrigRetPtr()); \ - SH_GLOB_SHPTR->EndContext(pContext); \ - return *retptr; - -#define SH_HANDLEFUNC(paramtypes, params, rettype) \ - SH_SETUPCALLS(rettype, paramtypes, params) \ - SH_CALL_HOOKS(pre, params) \ - SH_CALL_ORIG(rettype, paramtypes, params) \ - SH_CALL_HOOKS(post, params) \ - SH_RETURN() - -////////////////////////////////////////////////////////////////////////// -#define SH_SETUPCALLS_void(paramtypes, params) \ - /* 1) Set up */ \ - using namespace ::SourceHook; \ - void *ourvfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(this) + ms_MFI.vtbloffs) + ms_MFI.vtblindex); \ - void *vfnptr_origentry; \ - \ - META_RES status = MRES_IGNORED; \ - META_RES prev_res; \ - META_RES cur_res; \ - \ - IMyDelegate *iter; \ - IHookContext *pContext = SH_GLOB_SHPTR->SetupHookLoop(ms_HI, ourvfnptr, reinterpret_cast(this), \ - &vfnptr_origentry, &status, &prev_res, &cur_res, NULL, NULL); - -#define SH_CALL_HOOKS_void(post, params) \ - prev_res = MRES_IGNORED; \ - while ( (iter = static_cast(pContext->GetNext())) ) \ - { \ - cur_res = MRES_IGNORED; \ - iter->Call params; \ - prev_res = cur_res; \ - if (cur_res > status) \ - status = cur_res; \ - } - -#define SH_CALL_ORIG_void(paramtypes, params) \ - if (status != MRES_SUPERCEDE && pContext->ShouldCallOrig()) \ - { \ - void (EmptyClass::*mfp)paramtypes; \ - SH_SETUP_MFP(mfp); \ - (reinterpret_cast(this)->*mfp)params; \ - } - -#define SH_RETURN_void() \ - SH_GLOB_SHPTR->EndContext(pContext); - -#define SH_HANDLEFUNC_void(paramtypes, params) \ - SH_SETUPCALLS_void(paramtypes, params) \ - SH_CALL_HOOKS_void(pre, params) \ - SH_CALL_ORIG_void(paramtypes, params) \ - SH_CALL_HOOKS_void(post, params) \ - SH_RETURN_void() - - -// Special vafmt handlers -// :TODO: what -#define SH_HANDLEFUNC_vafmt(paramtypes, params_orig, params_plug, rettype) \ - SH_SETUPCALLS(rettype, paramtypes, params_orig) \ - SH_CALL_HOOKS(pre, params_plug) \ - SH_CALL_ORIG(rettype, paramtypes, params_orig) \ - SH_CALL_HOOKS(post, params_plug) \ - SH_RETURN() - -#define SH_HANDLEFUNC_void_vafmt(paramtypes, params_orig, params_plug) \ - SH_SETUPCALLS_void(paramtypes, params_orig) \ - SH_CALL_HOOKS_void(pre, params_plug) \ - SH_CALL_ORIG_void(paramtypes, params_orig) \ - SH_CALL_HOOKS_void(post, params_plug) \ - SH_RETURN_void() - -////////////////////////////////////////////////////////////////////////// - -#define MAKE_DELEG(ret_type, params_decl, params_pass) \ - struct IMyDelegate : ::SourceHook::ISHDelegate { virtual ret_type Call params_decl = 0; }; \ - struct CMyDelegateImpl : IMyDelegate \ - { \ - FD m_Deleg; \ - CMyDelegateImpl(FD deleg) : m_Deleg(deleg) {} \ - ret_type Call params_decl { return m_Deleg params_pass; } \ - void DeleteThis() { delete this; } \ - bool IsEqual(ISHDelegate *pOtherDeleg) { return m_Deleg == static_cast(pOtherDeleg)->m_Deleg; } \ - }; - -#define MAKE_DELEG_void(params_decl, params_pass) \ - struct IMyDelegate : ::SourceHook::ISHDelegate { virtual void Call params_decl = 0; }; \ - struct CMyDelegateImpl : IMyDelegate \ - { \ - FD m_Deleg; \ - CMyDelegateImpl(FD deleg) : m_Deleg(deleg) {} \ - void Call params_decl { m_Deleg params_pass; } \ - void DeleteThis() { delete this; } \ - bool IsEqual(ISHDelegate *pOtherDeleg) { return m_Deleg == static_cast(pOtherDeleg)->m_Deleg; } \ - }; - -// GetPassInfo -> easier access. __SH_GPI generates a SourceHook::PassInfo instance. -#define __SH_GPI(tt) { sizeof(tt), ::SourceHook::GetPassInfo< tt >::type, ::SourceHook::GetPassInfo< tt >::flags } -// Extra pass info V2 -#define __SH_EPI { 0, 0, 0, 0 } - -@[$1,0,$a: -// ********* Support for $1 arguments ********* -#define SH_DECL_HOOK$1(ifacetype, ifacefunc, attr, overload, rettype@[$2,1,$1:, param$2@]) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]@[$1!=0:, @]rettype> FD; \ - MAKE_DELEG(rettype, (@[$2,1,$1|, :param$2 p$2@]), (@[$2,1,$1|, :p$2@])); \ - virtual rettype Func(@[$2,1,$1|, :param$2 p$2@]) \ - { SH_HANDLEFUNC((@[$2,1,$1|, :param$2@]), (@[$2,1,$1|, :p$2@]), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}@[$2,1,$1:, __SH_GPI(param$2)@] }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI@[$2,1,$1:, __SH_EPI@] }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { $1, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN$1(ifacetype, ifacefunc, attr, overload, rettype@[$2,1,$1:, param$2@]) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]@[$1!=0:, @]rettype> handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]@[$1!=0:, @]rettype> handler); - -#define SH_DECL_HOOK$1_void(ifacetype, ifacefunc, attr, overload@[$2,1,$1:, param$2@]) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]> FD; \ - MAKE_DELEG_void((@[$2,1,$1|, :param$2 p$2@]), (@[$2,1,$1|, :p$2@])); \ - virtual void Func(@[$2,1,$1|, :param$2 p$2@]) \ - { SH_HANDLEFUNC_void((@[$2,1,$1|, :param$2@]), (@[$2,1,$1|, :p$2@])); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}@[$2,1,$1:,__SH_GPI(param$2)@] }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI@[$2,1,$1:, __SH_EPI@] }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { $1, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN$1_void(ifacetype, ifacefunc, attr, overload@[$2,1,$1:, param$2@]) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]> handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]> handler); - -#define SH_DECL_HOOK$1_vafmt(ifacetype, ifacefunc, attr, overload, rettype@[$2,1,$1:, param$2@]) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate@($1+1)<@[$2,1,$1|, :param$2@]@[$1!=0:, @]const char *, rettype> FD; \ - MAKE_DELEG(rettype, (@[$2,1,$1|, :param$2 p$2@]@[$1!=0:, @]const char *px), (@[$2,1,$1|, :p$2@]@[$1!=0:, @]px)); \ - virtual rettype Func(@[$2,1,$1|, :param$2 p$2@] @[$1!=0:, @]const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((@[$2,1,$1|, :param$2@]@[$1!=0:, @]...), (@[$2,1,$1|, :p$2@]@[$1!=0:, @]"%s", buf), (@[$2,1,$1|, :p$2@]@[$1!=0:, @]buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}@[$2,1,$1:, __SH_GPI(param$2)@] }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI@[$2,1,$1:, __SH_EPI@] }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { $1, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN$1_vafmt(ifacetype, ifacefunc, attr, overload, rettype@[$2,1,$1:, param$2@]) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate@($1+1)<@[$2,1,$1|, :param$2@]@[$1!=0:, @]const char *, rettype> handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate@($1+1)<@[$2,1,$1|, :param$2@]@[$1!=0:, @]const char *, rettype> handler); - -#define SH_DECL_HOOK$1_void_vafmt(ifacetype, ifacefunc, attr, overload@[$2,1,$1:, param$2@]) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate@($1+1)<@[$2,1,$1|, :param$2@]@[$1!=0:, @]const char *> FD; \ - MAKE_DELEG_void((@[$2,1,$1|, :param$2 p$2@]@[$1!=0:, @]const char *px), (@[$2,1,$1|, :p$2@]@[$1!=0:, @]px)); \ - virtual void Func(@[$2,1,$1|, :param$2 p$2@]@[$1!=0:, @]const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((@[$2,1,$1|, :param$2@]@[$1!=0:, @]...), (@[$2,1,$1|, :p$2@]@[$1!=0:, @]"%s", buf), (@[$2,1,$1|, :p$2@]@[$1!=0:, @]buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}@[$2,1,$1:, __SH_GPI(param$2)@] }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI@[$2,1,$1:, __SH_EPI@] }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { $1, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN$1_void_vafmt(ifacetype, ifacefunc, attr, overload@[$2,1,$1:, param$2@]) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate@($1+1)<@[$2,1,$1|, :param$2@]@[$1!=0:, @]const char *> handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate@($1+1)<@[$2,1,$1|, :param$2@]@[$1!=0:, @]const char *> handler); - -#define SH_DECL_MANUALHOOK$1(hookname, vtblidx, vtbloffs, thisptroffs, rettype@[$2,1,$1:, param$2@]) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]@[$1!=0:, @]rettype> FD; \ - MAKE_DELEG(rettype, (@[$2,1,$1|, :param$2 p$2@]), (@[$2,1,$1|, :p$2@])); \ - virtual rettype Func(@[$2,1,$1|, :param$2 p$2@]) \ - { SH_HANDLEFUNC((@[$2,1,$1|, :param$2@]), (@[$2,1,$1|, :p$2@]), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(@[$2,1,$1|, :param$2@]); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}@[$2,1,$1:, __SH_GPI(param$2)@] }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI@[$2,1,$1:, __SH_EPI@] }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { $1, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN$1(hookname, rettype@[$2,1,$1:, param$2@]) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]@[$1!=0:, @]rettype> handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]@[$1!=0:, @]rettype> handler); - -#define SH_DECL_MANUALHOOK$1_void(hookname, vtblidx, vtbloffs, thisptroffs@[$2,1,$1:, param$2@]) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]> FD; \ - MAKE_DELEG_void((@[$2,1,$1|, :param$2 p$2@]), (@[$2,1,$1|, :p$2@])); \ - virtual void Func(@[$2,1,$1|, :param$2 p$2@]) \ - { SH_HANDLEFUNC_void((@[$2,1,$1|, :param$2@]), (@[$2,1,$1|, :p$2@])); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(@[$2,1,$1|, :param$2@]); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}@[$2,1,$1:, __SH_GPI(param$2)@] }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI@[$2,1,$1:, __SH_EPI@] }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { $1, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN$1_void(hookname@[$2,1,$1:, param$2@]) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]> handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate$1<@[$2,1,$1|, :param$2@]> handler); -@] - - -////////////////////////////////////////////////////////////////////////// -// SH_CALL - -#define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ -{ \ - using namespace ::SourceHook; \ - \ - m_pSH->SetIgnoreHooks(m_VfnPtr); \ - RetType tmpret = (m_ThisPtr->*m_MFP)call; \ - m_pSH->ResetIgnoreHooks(m_VfnPtr); \ - return tmpret; \ -} - -#define SH_MAKE_EXECUTABLECLASS_OB_void(call, prms) \ -{ \ - using namespace ::SourceHook; \ - \ - m_pSH->SetIgnoreHooks(m_VfnPtr); \ - (m_ThisPtr->*m_MFP)call; \ - m_pSH->ResetIgnoreHooks(m_VfnPtr); \ -} - -namespace SourceHook -{ -@[$1,0,$a: - // Support for $1 arguments - template class ExecutableClass$1 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass$1(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(@[$2,1,$1|, :Param$2 p$2@]) const - SH_MAKE_EXECUTABLECLASS_OB((@[$2,1,$1|, :p$2@]), (@[$2,1,$1|, :Param$2@])) - - @[$2,$1+1,$a: - template <@[$3,$1+1,$2|, :class Param$3@]> RetType operator()(@[$3,1,$2|, :Param$3 p$3@]) const - SH_MAKE_EXECUTABLECLASS_OB((@[$3,1,$2|, :p$3@]), (@[$3,1,$2|, :Param$3@])) - @] - }; - - template class ExecutableClass$1 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass$1(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(@[$2,1,$1|, :Param$2 p$2@]) const - SH_MAKE_EXECUTABLECLASS_OB_void((@[$2,1,$1|, :p$2@]), (@[$2,1,$1|, :Param$2@])) - - @[$2,$1+1,$a: - template <@[$3,$1+1,$2|, :class Param$3@]> void operator()(@[$3,1,$2|, :Param$3 p$3@]) const - SH_MAKE_EXECUTABLECLASS_OB_void((@[$3,1,$2|, :p$3@]), (@[$3,1,$2|, :Param$3@])) - @] - }; -@] - -} - -#define SH__CALL_GET_VFNPTR_NORMAL \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(ptr, mfp, mfi); \ - void *vfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(ptr) + mfi.thisptroffs + mfi.vtbloffs) + mfi.vtblindex); - -#define SH__CALL_GET_VFNPTR_MANUAL \ - using namespace ::SourceHook; \ - void *vfnptr = reinterpret_cast( \ - *reinterpret_cast( (reinterpret_cast(ptr) + thisptroffs + vtbloffs) ) + vtblidx); \ - /* patch mfp */ \ - *reinterpret_cast(&mfp) = *reinterpret_cast(vfnptr); - -// SH_CALL needs to deduce the return type -> it uses templates and function overloading -// That's why SH_CALL takes two parameters: "mfp2" of type RetType(X::*mfp)(params), and "mfp" of type MFP -// The only purpose of the mfp2 parameter is to extract the return type - -@[$1,0,$a: -// Support for $1 arguments -template -SourceHook::ExecutableClass$1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(@[$2,1,$1|, :Param$2@]), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass$1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass$1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(@[$2,1,$1|, :Param$2@])const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass$1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass$1 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(@[$2,1,$1|, :Param$2@]), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass$1( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} -@] - -#if SH_COMP != SH_COMP_MSVC || _MSC_VER > 1300 -// GCC & MSVC 7.1 need this, MSVC 7.0 doesn't like it - -@[$1,0,$a: -// Support for $1 arguments -template -SourceHook::ExecutableClass$1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(@[$2,1,$1|, :Param$2@]@[$1!=0:, @]...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass$1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass$1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(@[$2,1,$1|, :Param$2@]@[$1!=0:, @]...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass$1(ptr, mfp, vfnptr, shptr); -} - -@] - -#endif - -#define SH_CALL(ptr, mfp) SH_CALL2((ptr), (mfp), (mfp), SH_GLOB_SHPTR) -#define SH_MCALL2(ptr, mfp, vtblidx, vtbloffs, thisptroffs) SH_MCALL3((ptr), (mfp), (mfp), (vtblidx), (vtbloffs), (thisptroffs), SH_GLOB_SHPTR) -#define SH_MCALL(ptr, mhookname) SH_MCALL2((ptr), SH_MFHCls(mhookname)::ECMFP(), SH_MFHCls(mhookname)::ms_MFI.vtblindex, \ - SH_MFHCls(mhookname)::ms_MFI.vtbloffs, SH_MFHCls(mhookname)::ms_MFI.thisptroffs) - -#undef SH_MAKE_EXECUTABLECLASS_OB -#undef SH_MAKE_EXECUTABLECLASS_OB_void - -////////////////////////////////////////////////////////////////////////// -// SetOverrideRet and RecallGetIface for recalls -// These take a ISourceHook pointer instead of using SH_GLOB_SHPTR directly -// The reason is that the user may want to redefine SH_GLOB_SHPTR - then the macros -// (META_RETURN_VALUE_NEWPARAMS) should obey the new pointer. - -namespace SourceHook -{ - template - void SetOverrideResult(ISourceHook *shptr, const RetType res) - { - *reinterpret_cast(shptr->GetOverrideRetPtr()) = res; - } - - // SetOverrideResult used to be implemented like this: - // SetOverrideResult(shptr, memfuncptr, return); - // normally the compiler can deduce the return type from memfuncptr, but (at least msvc8) failed when it was a reference - // (it thought it was ambigous - the ref and non-ref type) - // so now SetOverrideResult(memfuncptr) deduces the ret type, and returns a functor which does the work - // new syntax: SetOverrideResult(memfuncptr)(shptr, return) - // This also allows us to create a special version for references which respects ReferenceCarrier. - - template struct OverrideFunctor - { - void operator()(ISourceHook *shptr, T res) - { - *reinterpret_cast(shptr->GetOverrideRetPtr()) = res; - } - }; - template struct OverrideFunctor - { - void operator()(ISourceHook *shptr, T &res) - { - // overrideretptr points to ReferenceCarrier - *reinterpret_cast::type *>(shptr->GetOverrideRetPtr()) = res; - } - }; -@[$1,0,$a: - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(@[$2,1,$1|, :Param$2@])) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(@[$2,1,$1:Param$2, @]...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(@[$2,1,$1|, :Param$2@])) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(@[$2,1,$1:Param$2, @]...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } -@] -} - -#endif - // The pope is dead. -> :( diff --git a/sourcehook/sh_list.h b/sourcehook/sh_list.h deleted file mode 100644 index 391df29..0000000 --- a/sourcehook/sh_list.h +++ /dev/null @@ -1,321 +0,0 @@ -/* ======== SourceMM ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): David "BAILOPAN" Anderson -* ============================ -*/ - -#ifndef _INCLUDE_SMM_LIST_H -#define _INCLUDE_SMM_LIST_H - -#include -#include - -namespace SourceHook -{ - - //This class is from CSDM for AMX Mod X - /* - A circular, doubly-linked list with one sentinel node - - Empty: - m_Head = sentinel - m_Head->next = m_Head; - m_Head->prev = m_Head; - One element: - m_Head = sentinel - m_Head->next = node1 - m_Head->prev = node1 - node1->next = m_Head - node1->prev = m_Head - Two elements: - m_Head = sentinel - m_Head->next = node1 - m_Head->prev = node2 - node1->next = node2 - node1->prev = m_Head - node2->next = m_Head - node2->prev = node1 - */ - template - class List - { - public: - class iterator; - friend class iterator; - class ListNode - { - public: - ListNode(const T & o) : obj(o) { }; - ListNode() { }; - T obj; - ListNode *next; - ListNode *prev; - }; - private: - // Initializes the sentinel node. - // BAIL used malloc instead of new in order to bypass the need for a constructor. - ListNode *_Initialize() - { - ListNode *n = (ListNode *)malloc(sizeof(ListNode)); - n->next = n; - n->prev = n; - return n; - } - public: - List() : m_Head(_Initialize()), m_Size(0) - { - } - List(const List &src) : m_Head(_Initialize()), m_Size(0) - { - iterator iter; - for (iter=src.begin(); iter!=src.end(); iter++) - push_back( (*iter) ); - } - ~List() - { - clear(); - - // Don't forget to free the sentinel - if (m_Head) - { - free(m_Head); - m_Head = NULL; - } - } - void push_back(const T &obj) - { - ListNode *node = new ListNode(obj); - - node->prev = m_Head->prev; - node->next = m_Head; - m_Head->prev->next = node; - m_Head->prev = node; - - m_Size++; - } - - void push_front(const T &obj) - { - insert(begin(), obj); - } - - void push_sorted(const T &obj) - { - iterator iter; - for (iter = begin(); iter != end(); ++iter) - { - if (obj < *iter) - { - insert(iter, obj); - return; - } - } - push_back(obj); - } - - size_t size() const - { - return m_Size; - } - - void clear() - { - ListNode *node = m_Head->next; - ListNode *temp; - m_Head->next = m_Head; - m_Head->prev = m_Head; - - // Iterate through the nodes until we find g_Head (the sentinel) again - while (node != m_Head) - { - temp = node->next; - delete node; - node = temp; - } - m_Size = 0; - } - bool empty() const - { - return (m_Size == 0); - } - T & front() - { - return m_Head->next->obj; - } - T & back() - { - return m_Head->prev->obj; - } - private: - ListNode *m_Head; - size_t m_Size; - public: - class iterator - { - friend class List; - public: - iterator() - { - m_This = NULL; - } - iterator(const List &src) - { - m_This = src.m_Head; - } - iterator(ListNode *n) : m_This(n) - { - } - iterator(const iterator &where) - { - m_This = where.m_This; - } - //pre decrement - iterator & operator--() - { - if (m_This) - m_This = m_This->prev; - return *this; - } - //post decrement - iterator operator--(int) - { - iterator old(*this); - if (m_This) - m_This = m_This->prev; - return old; - } - - //pre increment - iterator & operator++() - { - if (m_This) - m_This = m_This->next; - return *this; - } - //post increment - iterator operator++(int) - { - iterator old(*this); - if (m_This) - m_This = m_This->next; - return old; - } - - const T & operator * () const - { - return m_This->obj; - } - T & operator * () - { - return m_This->obj; - } - - T * operator -> () - { - return &(m_This->obj); - } - const T * operator -> () const - { - return &(m_This->obj); - } - - bool operator != (const iterator &where) const - { - return (m_This != where.m_This); - } - bool operator ==(const iterator &where) const - { - return (m_This == where.m_This); - } - - operator bool() - { - return m_This != NULL; - } - private: - ListNode *m_This; - }; - public: - iterator begin() const - { - return iterator(m_Head->next); - } - iterator end() const - { - return iterator(m_Head); - } - iterator erase(iterator &where) - { - ListNode *pNode = where.m_This; - iterator iter(where); - iter++; - - - // Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle... - pNode->prev->next = pNode->next; - pNode->next->prev = pNode->prev; - - delete pNode; - m_Size--; - - return iter; - } - - iterator insert(iterator where, const T &obj) - { - // Insert obj right before where - - ListNode *node = new ListNode(obj); - ListNode *pWhereNode = where.m_This; - - pWhereNode->prev->next = node; - node->prev = pWhereNode->prev; - pWhereNode->prev = node; - node->next = pWhereNode; - - m_Size++; - - return iterator(node); - } - - public: - void remove(const T & obj) - { - iterator b; - for (b=begin(); b!=end(); b++) - { - if ( (*b) == obj ) - { - erase( b ); - break; - } - } - } - template - iterator find(const U & equ) const - { - iterator iter; - for (iter=begin(); iter!=end(); iter++) - { - if ( (*iter) == equ ) - return iter; - } - return end(); - } - List & operator =(const List &src) - { - clear(); - iterator iter; - for (iter=src.begin(); iter!=src.end(); iter++) - push_back( (*iter) ); - return *this; - } - }; - -}; //NAMESPACE - -#endif //_INCLUDE_CSDM_LIST_H diff --git a/sourcehook/sh_memfuncinfo.h b/sourcehook/sh_memfuncinfo.h deleted file mode 100644 index 77cda0f..0000000 --- a/sourcehook/sh_memfuncinfo.h +++ /dev/null @@ -1,796 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -/** - * @brief This file provides a way for getting information about a member function. - * @file sh_memfuncinfo.h - */ - -#ifndef __SHINT_MEMFUNC_INFO_H__ -#define __SHINT_MEMFUNC_INFO_H__ - -namespace SourceHook -{ - - // Don Clugston: - // implicit_cast< > - // I believe this was originally going to be in the C++ standard but - // was left out by accident. It's even milder than static_cast. - // I use it instead of static_cast<> to emphasize that I'm not doing - // anything nasty. - // Usage is identical to static_cast<> - template - inline OutputClass implicit_cast(InputClass input){ - return input; - } - - - struct MemFuncInfo - { - bool isVirtual; // Is the function virtual? - int thisptroffs; // The this pointer the function expects to be called with - // If -1, you need to call the GetFuncInfo_GetThisPtr function - int vtblindex; // The function's index in the vtable (0-based, 1=second entry, 2=third entry, ...) - int vtbloffs; // The vtable pointer - }; - - // Ideas by Don Clugston. - // Check out his excellent paper: http://www.codeproject.com/cpp/FastDelegate.asp - - template struct MFI_Impl - { - template static inline void GetFuncInfo(MFP *mfp, MemFuncInfo &out) - { - static char weird_memfunc_pointer_exclamation_mark_arrow_error[N-1000]; - } - }; - -# if SH_COMP == SH_COMP_GCC - - template<> struct MFI_Impl<2*SH_PTRSIZE> // All of these have size==8/16 - { - struct GCC_MemFunPtr - { - union - { - void *funcadr; // always even - intptr_t vtable_index_plus1; // = vindex+1, always odd - }; - intptr_t delta; - }; - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - GCC_MemFunPtr *mfp_detail = (GCC_MemFunPtr*)&mfp; - out.thisptroffs = mfp_detail->delta; - if (mfp_detail->vtable_index_plus1 & 1) - { - out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / SH_PTRSIZE; - out.vtbloffs = 0; - out.isVirtual = true; - } - else - out.isVirtual = false; - } - }; - -# elif SH_COMP == SH_COMP_MSVC - - namespace - { - int MFI_GetVtblOffset(void *mfp) - { - unsigned char *addr = (unsigned char*)mfp; - if (*addr == 0xE9) // Jmp - { - // May or may not be! - // Check where it'd jump - addr += 5 /*size of the instruction*/ + *(unsigned long*)(addr + 1); - } - - // Check whether it's a virtual function call - // They look like this: - // 004125A0 8B 01 mov eax,dword ptr [ecx] - // 004125A2 FF 60 04 jmp dword ptr [eax+4] - // ==OR== - // 00411B80 8B 01 mov eax,dword ptr [ecx] - // 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h] - - // However, for vararg functions, they look like this: - // 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4] - // 0048F0B4 8B 00 mov eax,dword ptr [eax] - // 0048F0B6 FF 60 08 jmp dword ptr [eax+8] - // ==OR== - // 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4] - // 0048F0B4 8B 00 mov eax,dword ptr [eax] - // 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h] - - // With varargs, the this pointer is passed as if it was the first argument - - bool ok = false; - if (addr[0] == 0x8B && addr[1] == 0x44 && addr[2] == 0x24 && addr[3] == 0x04 && - addr[4] == 0x8B && addr[5] == 0x00) - { - addr += 6; - ok = true; - } - else if (addr[0] == 0x8B && addr[1] == 0x01) - { - addr += 2; - ok = true; - } - if (!ok) - return -1; - - if (*addr++ == 0xFF) - { - if (*addr == 0x60) - { - return *++addr / 4; - } - else if (*addr == 0xA0) - { - return *((unsigned int*)++addr) / 4; - } - else if (*addr == 0x20) - return 0; - else - return -1; - } - return -1; - } - } - - template<> struct MFI_Impl<1*SH_PTRSIZE> // simple ones - { - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - out.thisptroffs = 0; - out.vtbloffs = 0; - } - }; - - template<> struct MFI_Impl<2*SH_PTRSIZE> // more complicated ones! - { - struct MSVC_MemFunPtr2 - { - void *funcadr; - int delta; - }; - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - out.thisptroffs = reinterpret_cast(&mfp)->delta; - out.vtbloffs = 0; - } - }; - - // By Don Clugston, adapted - template<> struct MFI_Impl<3*SH_PTRSIZE> // WOW IT"S GETTING BIGGER OMGOMOGMG - { - class __single_inheritance GenericClass; - class GenericClass {}; - - struct MicrosoftVirtualMFP { - void (GenericClass::*codeptr)(); // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtable_index; // or 0 if no virtual inheritance - }; - - struct GenericVirtualClass : virtual public GenericClass - { - typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)(); - GenericVirtualClass * GetThis() { return this; } - }; - - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - // This pointer - /* - union { - MFP func; - GenericClass* (T::*ProbeFunc)(); - MicrosoftVirtualMFP s; - } u; - u.func = mfp; - union { - GenericVirtualClass::ProbePtrType virtfunc; - MicrosoftVirtualMFP s; - } u2; - - // Check that the horrible_cast<>s will work - typedef int ERROR_CantUsehorrible_cast[sizeof(mfp)==sizeof(u.s) - && sizeof(mfp)==sizeof(u.ProbeFunc) - && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1]; - // Unfortunately, taking the address of a MF prevents it from being inlined, so - // this next line can't be completely optimised away by the compiler. - u2.virtfunc = &GenericVirtualClass::GetThis; - u.s.codeptr = u2.s.codeptr; - out.thisptroffs = (reinterpret_cast(NULL)->*u.ProbeFunc)(); - */ - out.thisptroffs = -1; - out.vtbloffs = 0; - } - }; - - // Don: Nasty hack for Microsoft and Intel (IA32 and Itanium) - // unknown_inheritance classes go here - // This is probably the ugliest bit of code I've ever written. Look at the casts! - // There is a compiler bug in MSVC6 which prevents it from using this code. - template<> struct MFI_Impl<4*SH_PTRSIZE> // THE BIGGEST ONE!!!1GABEN - { - template static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out) - { - out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp); - out.isVirtual = out.vtblindex >= 0 ? true : false; - - // The member function pointer is 16 bytes long. We can't use a normal cast, but - // we can use a union to do the conversion. - union { - MFP func; - // In VC++ and ICL, an unknown_inheritance member pointer - // is internally defined as: - struct { - void *m_funcaddress; // points to the actual member function - int delta; // #bytes to be added to the 'this' pointer - int vtordisp; // #bytes to add to 'this' to find the vtable - int vtable_index; // or 0 if no virtual inheritance - } s; - } u; - // Check that the horrible_cast will work - typedef int ERROR_CantUsehorrible_cast[sizeof(u.func)==sizeof(u.s)? 1 : -1]; - u.func = mfp; - int virtual_delta = 0; - if (u.s.vtable_index) { // Virtual inheritance is used - /* - // First, get to the vtable. - // It is 'vtordisp' bytes from the start of the class. - int * vtable = *reinterpret_cast( - reinterpret_cast(thisptr) + u.s.vtordisp ); - - // 'vtable_index' tells us where in the table we should be looking. - virtual_delta = u.s.vtordisp + *reinterpret_cast( - reinterpret_cast(vtable) + u.s.vtable_index); - // The int at 'virtual_delta' gives us the amount to add to 'this'. - // Finally we can add the three components together. Phew! - out.thisptr = reinterpret_cast( - reinterpret_cast(thisptr) + u.s.delta + virtual_delta); - */ - out.vtbloffs = u.s.vtordisp; - out.thisptroffs = -1; - } - else - { - out.vtbloffs = out.vtblindex < 0 ? 0 : u.s.delta; - out.thisptroffs = u.s.delta; - } - }; - }; -# else -# error Unsupported compiler -# endif - - // This version does not take a this pointer - // Useful for hookdecls, as they ensure that mfp is correct through a static_cast - template inline void GetFuncInfo(X mfp, MemFuncInfo &out) - { - MFI_Impl::GetFuncInfo(mfp, out); - } - - // Versions which do take a this - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(), MemFuncInfo &out) - { - RetType(Y::*mfp2)() = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)() const, MemFuncInfo &out) - { - RetType(Y::*mfp2)() const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - // GCC & MSVC 7.1 need this, MSVC 7.0 doesn't like it -#if SH_COMP != SH_COMP_MSVC || _MSC_VER > 1300 - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...), MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - template - inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const, MemFuncInfo &out) - { - RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const = mfp; - MFI_Impl::GetFuncInfo(mfp2, out); - } - - - -#endif - -} - -#endif diff --git a/sourcehook/sh_memory.h b/sourcehook/sh_memory.h deleted file mode 100644 index 14fc240..0000000 --- a/sourcehook/sh_memory.h +++ /dev/null @@ -1,190 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko, Scott "Damaged Soul" Ehlert -* Contributors: lancevorgin, XAD, theqizmo -* ============================ -*/ - -#ifndef __SHINT_MEMORY_H__ -#define __SHINT_MEMORY_H__ - -// Feb 17 / 2005: -// Unprotect now sets to readwrite -// The vtable doesn't need to be executable anyway - -# if /********/ defined _WIN32 -# include -# define SH_MEM_READ 1 -# define SH_MEM_WRITE 2 -# define SH_MEM_EXEC 4 -# elif /******/ defined __linux__ -# include -# include -namespace LinuxSignal -{ -# include -} -# include -// http://www.die.net/doc/linux/man/man2/mprotect.2.html -# include -# ifndef PAGESIZE -# define PAGESIZE 4096 -# endif -# define SH_MEM_READ PROT_READ -# define SH_MEM_WRITE PROT_WRITE -# define SH_MEM_EXEC PROT_EXEC - -// We need to align addr down to pagesize on linux -// We assume PAGESIZE is a power of two -# define SH_LALIGN(x) (void*)((intptr_t)(x) & ~(PAGESIZE-1)) -# define SH_LALDIF(x) ((intptr_t)(x) % PAGESIZE) -# else -# error Unsupported OS/Compiler -# endif - -#include "sh_list.h" - -namespace SourceHook -{ - inline bool SetMemAccess(void *addr, size_t len, int access) - { -# ifdef __linux__ - return mprotect(SH_LALIGN(addr), len + SH_LALDIF(addr), access)==0 ? true : false; -# else - DWORD tmp; - DWORD prot; - switch (access) - { - case SH_MEM_READ: - prot = PAGE_READONLY; break; - case SH_MEM_READ | SH_MEM_WRITE: - prot = PAGE_READWRITE; break; - case SH_MEM_READ | SH_MEM_EXEC: - prot = PAGE_EXECUTE_READ; break; - default: - case SH_MEM_READ | SH_MEM_WRITE | SH_MEM_EXEC: - prot = PAGE_EXECUTE_READWRITE; break; - } - return VirtualProtect(addr, len, prot, &tmp) ? true : false; -# endif - } - -#ifdef __linux__ - namespace - { - bool g_BadReadCalled; - jmp_buf g_BadReadJmpBuf; - - static void BadReadHandler(int sig) - { - if (g_BadReadCalled) - longjmp(g_BadReadJmpBuf, 1); - } - } -#endif - - /** - * @brief Checks whether the specified memory region is (still) accessible - * - * @param addr The lower boundary - * @param len Length of the region to be checked - */ - namespace - { - bool ModuleInMemory(char *addr, size_t len) - { -#ifdef __linux__ - // On linux, first check /proc/self/maps - long lower = reinterpret_cast(addr); - long upper = lower + len; - - FILE *pF = fopen("/proc/self/maps", "r"); - if (pF) - { - // Linux /proc/self/maps -> parse - // Format: - // lower upper prot stuff path - // 08048000-0804c000 r-xp 00000000 03:03 1010107 /bin/cat - long rlower, rupper; - while (fscanf(pF, "%lx-%lx", &rlower, &rupper) != EOF) - { - // Check whether we're IN THERE! - if (lower >= rlower && upper <= rupper) - { - fclose(pF); - return true; - } - // Read to end of line - int c; - while ((c = fgetc(pF)) != '\n') - { - if (c == EOF) - break; - } - if (c == EOF) - break; - } - fclose(pF); - return false; - } - pF = fopen("/proc/curproc/map", "r"); - if (pF) - { - // FreeBSD /proc/curproc/map -> parse - // 0x804800 0x805500 13 15 0xc6e18960 r-x 21 0x0 COW NC vnode - long rlower, rupper; - while (fscanf(pF, "0x%lx 0x%lx", &rlower, &rupper) != EOF) - { - // Check whether we're IN THERE! - if (lower >= rlower && upper <= rupper) - { - fclose(pF); - return true; - } - // Read to end of line - int c; - while ((c = fgetc(pF)) != '\n') - { - if (c == EOF) - break; - } - if (c == EOF) - break; - } - fclose(pF); - return false; - } - - // Both of the above failed, try to actually read and trap sigsegv (implemented by Damaged Soul) - void(*prevHandler)(int sig); - g_BadReadCalled = true; - - if (setjmp(g_BadReadJmpBuf)) - return true; - - prevHandler = LinuxSignal::signal(SIGSEGV, BadReadHandler); - - volatile const char *p = reinterpret_cast(addr); - char dummy; - - for (size_t i = 0; i < len; i++) - dummy = p[i]; - - g_BadReadCalled = false; - - LinuxSignal::signal(SIGSEGV, prevHandler); - - return false; -#else - // On Win32, simply use IsBadReadPtr - return !IsBadReadPtr(addr, len); -#endif - } - } -} - -#endif diff --git a/sourcehook/sh_pagealloc.h b/sourcehook/sh_pagealloc.h deleted file mode 100644 index afabc3d..0000000 --- a/sourcehook/sh_pagealloc.h +++ /dev/null @@ -1,288 +0,0 @@ -#ifndef __SH_PAGEALLOC_H__ -#define __SH_PAGEALLOC_H__ - -# if /********/ defined _WIN32 -# include -# elif /******/ defined __linux__ -# include -# include -# else -# error Unsupported OS/Compiler -# endif - - -namespace SourceHook -{ - - /* - Class which lets us allocate memory regions in special pages only meant for on the fly code generation. - - If we alloc with malloc and then set the page access type to read/exec only, other regions returned by - malloc that are in the same page would lose their write access as well and the process could crash. - - Allocating one page per code generation session is usually a waste of memory and on some platforms also - a waste of virtual address space (Windows’ VirtualAlloc has a granularity of 64K). - - - IMPORTANT: the memory that Alloc() returns is not a in a defined state! - It could be in read+exec OR read+write mode. - -> call SetRE() or SetRW() before using allocated memory! - */ - class CPageAlloc - { - struct AllocationUnit - { - size_t begin_offset; - size_t size; - - AllocationUnit(size_t p_offs, size_t p_size) : begin_offset(p_offs), size(p_size) - { - } - - bool operator < (const AllocationUnit &other) const - { - return begin_offset < other.begin_offset; - } - }; - - typedef List AUList; - struct AllocatedRegion - { - void *startPtr; - size_t size; - bool isolated; // may contain only one AU - size_t minAlignment; - AUList allocUnits; - - void CheckGap(size_t gap_begin, size_t gap_end, size_t reqsize, - size_t &smallestgap_pos, size_t &smallestgap_size, size_t &outAlignBytes) - { - size_t gapsize = gap_end - gap_begin; - // How many bytes do we actually need here? - // = requested size + alignment bytes - size_t neededSize = reqsize; - size_t alignBytes = minAlignment - ((reinterpret_cast(startPtr) + gap_begin) % minAlignment); - - alignBytes %= minAlignment; - neededSize += alignBytes; - - if (gapsize >= neededSize) - { - if (gapsize < smallestgap_size) - { - smallestgap_size = gapsize; - smallestgap_pos = gap_begin; - outAlignBytes = alignBytes; - } - } - } - - bool TryAlloc(size_t reqsize, void * &outAddr) - { - // Check for isolated - if (isolated && !allocUnits.empty()) - return false; - - // Find the smallest gap where req fits - size_t lastend = 0; - size_t smallestgap_pos = size + 1; - size_t smallestgap_size = size + 1; - size_t alignmentbytes = 0; - - for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) - { - CheckGap(lastend, iter->begin_offset, reqsize, smallestgap_pos, smallestgap_size, alignmentbytes); - lastend = iter->begin_offset + iter->size; - } - - CheckGap(lastend, size, reqsize, smallestgap_pos, smallestgap_size, alignmentbytes); - - if (smallestgap_pos < size) - { - outAddr = reinterpret_cast(reinterpret_cast(startPtr) + smallestgap_pos + alignmentbytes); - allocUnits.push_sorted( AllocationUnit(smallestgap_pos, reqsize + alignmentbytes) ); - return true; - } - else - { - return false; - } - } - - bool TryFree(void *addr) - { - if (addr < startPtr || addr >= reinterpret_cast(reinterpret_cast(startPtr) + size)) - return false; - - intptr_t start = reinterpret_cast(startPtr); - - for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter) - { - size_t AUBegin = start + iter->begin_offset; - void *alignedAUBegin = reinterpret_cast( - AUBegin + ((minAlignment - AUBegin % minAlignment) % minAlignment) - ); - - if (addr == alignedAUBegin) - { - allocUnits.erase(iter); - return true; - } - } - - return false; - } - - bool Contains(void *addr) - { - return addr >= startPtr && addr < reinterpret_cast(reinterpret_cast(startPtr) + size); - } - - void FreeRegion() - { -#ifdef __linux__ - munmap(startPtr, size); -#else - VirtualFree(startPtr, 0, MEM_RELEASE); -#endif - } - }; - - typedef List ARList; - - size_t m_MinAlignment; - size_t m_PageSize; - ARList m_Regions; - - bool AddRegion(size_t minSize, bool isolated) - { - AllocatedRegion newRegion; - newRegion.startPtr = 0; - newRegion.isolated = isolated; - newRegion.minAlignment = m_MinAlignment; - - // Compute real size -> align up to m_PageSize boundary - - newRegion.size = minSize - (minSize % m_PageSize); - if (newRegion.size < minSize) - newRegion.size += m_PageSize; - -#ifdef __linux__ - newRegion.startPtr = mmap(0, newRegion.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -#else - newRegion.startPtr = VirtualAlloc(NULL, newRegion.size, MEM_COMMIT, PAGE_READWRITE); -#endif - - if (newRegion.startPtr) - { - m_Regions.push_back(newRegion); - return true; - } - else - { - return false; - } - - } - - void *AllocPriv(size_t size, bool isolated) - { - void *addr; - - if (!isolated) - { - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - if (iter->TryAlloc(size, addr)) - return addr; - } - } - - if (!AddRegion(size, isolated)) - return NULL; - - bool tmp = m_Regions.back().TryAlloc(size, addr); - SH_ASSERT(tmp, ("TryAlloc fails after AddRegion")); - return addr; - } - - public: - CPageAlloc(size_t minAlignment = 1 /* power of 2 */ ) : m_MinAlignment(minAlignment) - { -#ifdef __linux__ - m_PageSize = sysconf(_SC_PAGESIZE); -#else - SYSTEM_INFO sysInfo; - GetSystemInfo(&sysInfo); - m_PageSize = sysInfo.dwPageSize; -#endif - } - - ~CPageAlloc() - { - // Free all regions - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - iter->FreeRegion(); - } - } - - void *Alloc(size_t size) - { - return AllocPriv(size, false); - } - - void *AllocIsolated(size_t size) - { - return AllocPriv(size, true); - } - - void Free(void *ptr) - { - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - if (iter->TryFree(ptr)) - { - if (iter->allocUnits.empty()) - { - iter->FreeRegion(); - m_Regions.erase(iter); - } - break; - } - } - } - - void SetRE(void *ptr) - { - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - if (iter->Contains(ptr)) - { - SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_EXEC); - break; - } - } - } - - void SetRW(void *ptr) - { - for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter) - { - if (iter->Contains(ptr)) - { - SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_WRITE); - break; - } - } - } - - size_t GetPageSize() - { - return m_PageSize; - } - }; -} - -#endif - diff --git a/sourcehook/sh_stack.h b/sourcehook/sh_stack.h deleted file mode 100644 index c94cfd2..0000000 --- a/sourcehook/sh_stack.h +++ /dev/null @@ -1,232 +0,0 @@ -/* ======== SourceMM ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SH_STACK_H__ -#define __SH_STACK_H__ - -#include -#include "sh_vector.h" - -namespace SourceHook -{ - // May _never_ reallocate used memory! - - template class CStack - { - static const size_t SECTOR_SIZE = 16; - - CVector m_Sectors; // Stores sectors - - size_t m_UsedSize; - - void clear() - { - typename CVector::iterator sect_iter; - for (sect_iter = m_Sectors.begin(); sect_iter != m_Sectors.end(); ++sect_iter) - { - delete [] *sect_iter; - } - m_Sectors.clear(); - } - public: - friend class iterator; - class iterator - { - CStack *m_pParent; - size_t m_Index; - public: - iterator(CStack *pParent, size_t id) : m_pParent(pParent), m_Index(id) - { - } - - iterator(CStack *pParent) : m_pParent(pParent), m_Index(0) - { - } - - iterator() : m_pParent(NULL), m_Index(0) - { - } - - T &operator *() - { - return m_pParent->at(m_Index); - } - const T &operator *() const - { - return m_pParent->at(m_Index); - } - - T * operator->() - { - return &(m_pParent->at(m_Index)); - } - - const T * operator->() const - { - return &(m_pParent->at(m_Index)); - } - - iterator & operator++() // preincrement - { - ++m_Index; - return (*this); - } - - iterator operator++(int) // postincrement - { - iterator tmp = *this; - ++m_Index; - return tmp; - } - - iterator & operator--() // predecrement - { - --m_Index; - return (*this); - } - - iterator operator--(int) // postdecrememnt - { - iterator tmp = *this; - --m_Index; - return tmp; - } - - bool operator==(const iterator & right) const - { - return (m_pParent == right.m_pParent && m_Index == right.m_Index); - } - - bool operator!=(const iterator & right) const - { - return !(*this == right); - } - }; - CStack() : m_UsedSize(0) - { - } - - CStack(const CStack &other) - { - for (typename CVector::iterator sect_iter = other.m_Sectors.begin(); - sect_iter != other.m_Sectors.end(); ++sect_iter) - { - m_Sectors.push_back(new T[SECTOR_SIZE]); - for (size_t i = 0; i < SECTOR_SIZE; ++i) - m_Sectors.back()[i] = (*sect_iter)[i]; - } - m_UsedSize = other.m_UsedSize; - } - - CStack & operator =(const CStack &other) - { - clear(); - for (typename CVector::iterator sect_iter = other.m_Sectors.begin(); - sect_iter != other.m_Sectors.end(); ++sect_iter) - { - m_Sectors.push_back(new T[SECTOR_SIZE]); - for (size_t i = 0; i < SECTOR_SIZE; ++i) - m_Sectors.back()[i] = (*sect_iter)[i]; - } - m_UsedSize = other.m_UsedSize; - return *this; - } - - ~CStack() - { - clear(); - } - - T &at(size_t x) - { - return m_Sectors[x / SECTOR_SIZE][x % SECTOR_SIZE]; - } - - const T &at(size_t x) const - { - return m_Sectors[x / SECTOR_SIZE][x % SECTOR_SIZE]; - } - - bool push(const T &val) - { - if ((m_UsedSize / SECTOR_SIZE) >= m_Sectors.size()) - { - // New sector - m_Sectors.push_back(new T[SECTOR_SIZE]); - } - - at(m_UsedSize) = val; - - ++m_UsedSize; - return true; - } - - T *make_next() - { - if ((m_UsedSize / SECTOR_SIZE) >= m_Sectors.size()) - { - // New sector - m_Sectors.push_back(new T[SECTOR_SIZE]); - } - - return &(at(m_UsedSize++)); - } - - void pop() - { - --m_UsedSize; - } - - void popall() - { - m_UsedSize = 0; - } - - T &front() - { - return at(m_UsedSize-1); - } - - const T &front() const - { - return at(m_UsedSize-1); - } - - T &second() - { - return at(m_UsedSize-2); - } - - const T &second() const - { - return at(m_UsedSize-2); - } - - iterator begin() - { - return iterator(this, 0); - } - iterator end() - { - return iterator(this, m_UsedSize); - } - - size_t size() - { - return m_UsedSize; - } - bool empty() - { - return m_UsedSize == 0 ? true : false; - } - }; -}; //namespace SourceHook - -#endif diff --git a/sourcehook/sh_string.h b/sourcehook/sh_string.h deleted file mode 100755 index 220b4ee..0000000 --- a/sourcehook/sh_string.h +++ /dev/null @@ -1,401 +0,0 @@ -/* ======== SourceMM ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): David "BAILOPAN" Anderson -* ============================ -*/ - -/* AMX Mod X - * - * by the AMX Mod X Development Team - */ - -#ifndef _INCLUDE_CSTRING_H -#define _INCLUDE_CSTRING_H - -#include -#include - -namespace SourceHook -{ -class String -{ -public: - String() - { - v = NULL; - a_size = 0; - //assign(""); - } - - ~String() - { - if (v) - delete [] v; - } - - String(const char *src) - { - v = NULL; - a_size = 0; - assign(src); - } - - String(const String &src) - { - v = NULL; - a_size = 0; - assign(src.c_str()); - } - - bool operator ==(const String &other) - { - return (compare(other.c_str()) == 0); - } - - bool operator ==(const char *other) - { - return (compare(other) == 0); - } - - const char *c_str() { return v?v:""; } - - const char *c_str() const { return v?v:""; } - - void append(const char *t) - { - Grow(size() + strlen(t) + 1); - strcat(v, t); - } - - void append(const char c) - { - size_t len = size(); - Grow(len + 2); - v[len] = c; - v[len + 1] = '\0'; - } - - void append(String &d) - { - append(d.c_str()); - } - - void assign(const String &src) - { - assign(src.c_str()); - } - - void assign(const char *d) - { - if (!d) - { - clear(); - } else { - Grow(strlen(d) + 1, false); - strcpy(v, d); - } - } - - void clear() - { - if (v) - v[0] = '\0'; - } - - int compare (const char *d) const - { - if (!v) - return strcmp("", d); - else - return strcmp(v, d); - } - - //Added this for amxx inclusion - bool empty() const - { - if (!v) - return true; - - if (v[0] == '\0') - return true; - - return false; - } - - size_t size() const - { - if (v) - return strlen(v); - else - return 0; - } - - int find(const char c, int index = 0) const - { - int len = static_cast(size()); - if (len < 1) - return npos; - if (index >= len || index < 0) - return npos; - int i = 0; - for (i=index; i(size()); - if (len < 1) - return npos; - if (index >= len || index < npos) - return npos; - int i; - if (index == npos) - i = len - 1; - else - i = index; - - for (; i>=0; i--) - { - if (v[i] == c) - { - return i; - } - } - - return npos; - } - - bool is_space(int c) const - { - if (c == '\f' || c == '\n' || - c == '\t' || c == '\r' || - c == '\v' || c == ' ') - { - return true; - } - - return false; - } - - void trim() - { - if (!v) - return; - - unsigned int i = 0; - unsigned int j = 0; - size_t len = strlen(v); - - if (len == 1) - { - if (is_space(v[i])) - { - clear(); - return; - } - } - - unsigned char c0 = v[0]; - - if (is_space(c0)) - { - for (i=0; i=0; i--) - { - if (!is_space(v[i]) - || (is_space(v[i]) && i==0)) - { - erase(i+1, j); - break; - } - j++; - } - } - - if (len == 1) - { - if (is_space(v[0])) - { - clear(); - return; - } - } - } - - void erase(unsigned int start, int num = npos) - { - if (!v) - return; - unsigned int i = 0; - size_t len = size(); - //check for bounds - if (num == npos || start+num > len-start) - num = len - start; - //do the erasing - bool copyflag = false; - for (i=0; i=start && i= len || !v) - return ns; - - if (num == npos) - { - num = len - index; - } else if (index+num >= len) { - num = len - index; - } - - unsigned int i = 0; - unsigned int nslen = num + 2; - - ns.Grow(nslen); - - for (i=index; i= 65 && v[i] <= 90) - v[i] &= ~(1<<5); - } - } - - String & operator = (const String &src) - { - assign(src); - return *this; - } - - String & operator = (const char *src) - { - assign(src); - return *this; - - } - - char operator [] (unsigned int index) const - { - if (index > size() || !v) - { - return -1; - } else { - return v[index]; - } - } - - int at(int a) const - { - if (a < 0 || a >= (int)size() || !v) - return -1; - - return v[a]; - } - - bool at(int at, char c) - { - if (at < 0 || at >= (int)size() || !v) - return false; - - v[at] = c; - - return true; - } - -private: - void Grow(unsigned int d, bool copy=true) - { - if (d <= a_size) - return; - char *n = new char[d + 1]; - if (copy && v) - strcpy(n, v); - if (v) - delete [] v; - else - strcpy(n, ""); - v = n; - a_size = d + 1; - } - - char *v; - unsigned int a_size; -public: - static const int npos = -1; -}; - -}; //NAMESPACE - -#endif //_INCLUDE_CSTRING_H diff --git a/sourcehook/sh_tinyhash.h b/sourcehook/sh_tinyhash.h deleted file mode 100644 index 49040a1..0000000 --- a/sourcehook/sh_tinyhash.h +++ /dev/null @@ -1,534 +0,0 @@ -/* ======== SourceMM ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): David "BAILOPAN" Anderson -* ============================ -*/ - -#ifndef _INCLUDE_SH_TINYHASH_H_ -#define _INCLUDE_SH_TINYHASH_H_ - -#include "sh_list.h" - -#define _T_INIT_HASH_SIZE 32 - -namespace SourceHook -{ - template - int HashFunction(const K & k); - - template - int HashAlt(const U &u); - - template - int CompareAlt(const U &k1, const K &k2); - - template - int Compare(const K & k1, const K & k2); - - /** - * This is a tiny, growable hash class. - * Meant for quick and dirty dictionaries only! - */ - template - class THash - { - public: - struct THashNode - { - THashNode(const K & k, const V & v) : - key(k), val(v) - { - }; - THashNode & operator =(const THashNode &other) - { - key = other.key; - val = other.val; - } - K key; - V val; - }; - typedef List * NodePtr; - public: - class const_iterator; - THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f) - { - _Refactor(); - } - THash(const THash &other) : m_Buckets(new NodePtr[other.m_numBuckets]), - m_numBuckets(other.m_numBuckets), m_percentUsed(other.m_percentUsed) - { - for (size_t i=0; ikey)->val = iter->val; - } - void operator=(const THash &other) - { - clear(); - for (const_iterator iter = other.begin(); iter != other.end(); ++iter) - _FindOrInsert(iter->key)->val = iter->val; - } - - ~THash() - { - _Clear(); - } - void clear() - { - _Clear(); - _Refactor(); - } - size_t GetBuckets() - { - return m_numBuckets; - } - float PercentUsed() - { - return m_percentUsed; - } - V & operator [](const K & key) - { - THashNode *pNode = _FindOrInsert(key); - return pNode->val; - } - private: - void _Clear() - { - typename List::iterator iter, end; - for (size_t i=0; iend(); - iter = m_Buckets[i]->begin(); - while (iter != end) - { - delete (*iter); - iter++; - } - delete m_Buckets[i]; - m_Buckets[i] = NULL; - } - } - if (m_Buckets) - delete [] m_Buckets; - m_Buckets = NULL; - m_numBuckets = 0; - } - public: - template - V & AltFindOrInsert(const U & ukey) - { - size_t place = HashAlt(ukey) % m_numBuckets; - THashNode *pNode = NULL; - if (!m_Buckets[place]) - { - m_Buckets[place] = new List; - pNode = new THashNode(ukey, V()); - m_Buckets[place]->push_back(pNode); - m_percentUsed += (1.0f / (float)m_numBuckets); - } else { - typename List::iterator iter; - for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++) - { - if (CompareAlt(ukey, (*iter)->key) == 0) - { - return (*iter)->val; - } - } - //node does not exist - pNode = new THashNode(ukey, V()); - m_Buckets[place]->push_back(pNode); - } - if (PercentUsed() > 0.75f) - { - _Refactor(); - } - return pNode->val; - } - private: - THashNode *_FindOrInsert(const K & key) - { - size_t place = HashFunction(key) % m_numBuckets; - THashNode *pNode = NULL; - if (!m_Buckets[place]) - { - m_Buckets[place] = new List; - pNode = new THashNode(key, V()); - m_Buckets[place]->push_back(pNode); - m_percentUsed += (1.0f / (float)m_numBuckets); - } else { - typename List::iterator iter; - for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++) - { - if (Compare((*iter)->key, key) == 0) - return (*iter); - } - //node does not exist - pNode = new THashNode(key, V()); - m_Buckets[place]->push_back(pNode); - } - if (PercentUsed() > 0.75f) - { - _Refactor(); - } - return pNode; - } - void _Refactor() - { - m_percentUsed = 0.0f; - if (!m_numBuckets) - { - m_numBuckets = _T_INIT_HASH_SIZE; - m_Buckets = new NodePtr[m_numBuckets]; - for (size_t i=0; i::iterator iter; - size_t place; - THashNode *pHashNode; - NodePtr *temp = new NodePtr[m_numBuckets]; - for (size_t i=0; ibegin(); iter != m_Buckets[i]->end(); iter++) - { - pHashNode = (*iter); - //rehash it with the new bucket filter - place = HashFunction(pHashNode->key) % m_numBuckets; - //add it to the new hash table - if (!temp[place]) - { - temp[place] = new List; - m_percentUsed += (1.0f / (float)m_numBuckets); - } - temp[place]->push_back(pHashNode); - } - //delete that bucket! - delete m_Buckets[i]; - m_Buckets[i] = NULL; - } - } - //reassign bucket table - delete [] m_Buckets; - m_Buckets = temp; - } - } - public: - class iterator - { - friend class THash; - public: - iterator() : curbucket(-1), hash(NULL), end(true) - { - }; - iterator(THash *h) : curbucket(-1), hash(h), end(false) - { - if (!h->m_Buckets) - end = true; - else - _Inc(); - }; - //pre increment - iterator & operator++() - { - _Inc(); - return *this; - } - //post increment - iterator operator++(int) - { - iterator old(*this); - _Inc(); - return old; - } - const THashNode & operator * () const - { - return *(*iter); - } - THashNode & operator * () - { - return *(*iter); - } - const THashNode * operator ->() const - { - return (*iter); - } - THashNode * operator ->() - { - return (*iter); - } - bool operator ==(const iterator &where) const - { - if (where.hash == this->hash - && where.end == this->end - && - (this->end || - ((where.curbucket == this->curbucket) - && (where.iter == iter)) - )) - return true; - return false; - } - bool operator !=(const iterator &where) const - { - return !( (*this) == where ); - } - - void erase() - { - if (end || !hash || curbucket < 0 || curbucket >= static_cast(hash->m_numBuckets)) - return; - - // Remove this element and move to the next one - iterator tmp = *this; - ++tmp; - delete (*iter); - hash->m_Buckets[curbucket]->erase(iter); - *this = tmp; - - // :TODO: Maybe refactor to a lower size if required - } - private: - void _Inc() - { - if (end || !hash || curbucket >= static_cast(hash->m_numBuckets)) - return; - if (curbucket < 0) - { - for (int i=0; i<(int)hash->m_numBuckets; i++) - { - if (hash->m_Buckets[i]) - { - iter = hash->m_Buckets[i]->begin(); - if (iter == hash->m_Buckets[i]->end()) - continue; - curbucket = i; - break; - } - } - if (curbucket < 0) - end = true; - } else { - if (iter != hash->m_Buckets[curbucket]->end()) - iter++; - if (iter == hash->m_Buckets[curbucket]->end()) - { - int oldbucket = curbucket; - for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++) - { - if (hash->m_Buckets[i]) - { - iter = hash->m_Buckets[i]->begin(); - if (iter == hash->m_Buckets[i]->end()) - continue; - curbucket = i; - break; - } - } - if (curbucket == oldbucket) - end = true; - } - } - } - private: - int curbucket; - typename SourceHook::List::iterator iter; - THash *hash; - bool end; - }; - class const_iterator - { - friend class THash; - public: - const_iterator() : curbucket(-1), hash(NULL), end(true) - { - }; - const_iterator(const THash *h) : curbucket(-1), hash(h), end(false) - { - if (!h->m_Buckets) - end = true; - else - _Inc(); - }; - //pre increment - const_iterator & operator++() - { - _Inc(); - return *this; - } - //post increment - const_iterator operator++(int) - { - iterator old(*this); - _Inc(); - return old; - } - const THashNode & operator * () const - { - return *(*iter); - } - const THashNode * operator ->() const - { - return (*iter); - } - bool operator ==(const const_iterator &where) const - { - if (where.hash == this->hash - && where.end == this->end - && - (this->end || - ((where.curbucket == this->curbucket) - && (where.iter == iter)) - )) - return true; - return false; - } - bool operator !=(const const_iterator &where) const - { - return !( (*this) == where ); - } - private: - void _Inc() - { - if (end || !hash || curbucket >= static_cast(hash->m_numBuckets)) - return; - if (curbucket < 0) - { - for (int i=0; i<(int)hash->m_numBuckets; i++) - { - if (hash->m_Buckets[i]) - { - iter = hash->m_Buckets[i]->begin(); - if (iter == hash->m_Buckets[i]->end()) - continue; - curbucket = i; - break; - } - } - if (curbucket < 0) - end = true; - } else { - if (iter != hash->m_Buckets[curbucket]->end()) - iter++; - if (iter == hash->m_Buckets[curbucket]->end()) - { - int oldbucket = curbucket; - for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++) - { - if (hash->m_Buckets[i]) - { - iter = hash->m_Buckets[i]->begin(); - if (iter == hash->m_Buckets[i]->end()) - continue; - curbucket = i; - break; - } - } - if (curbucket == oldbucket) - end = true; - } - } - } - private: - int curbucket; - typename SourceHook::List::iterator iter; - const THash *hash; - bool end; - }; - public: - iterator begin() - { - return iterator(this); - } - iterator end() - { - iterator iter; - iter.hash = this; - return iter; - } - - const_iterator begin() const - { - return const_iterator(this); - } - const_iterator end() const - { - const_iterator iter; - iter.hash = this; - return iter; - } - - template - iterator find(const U & u) const - { - iterator b = begin(); - iterator e = end(); - for (iterator iter = b; iter != e; iter++) - { - if ( (*iter).key == u ) - return iter; - } - return end(); - } - template - iterator find(const U & u) - { - iterator b = begin(); - iterator e = end(); - for (iterator iter = b; iter != e; iter++) - { - if ( (*iter).key == u ) - return iter; - } - return end(); - } - template - iterator FindAlt(const U & u) - { - iterator b = begin(); - iterator e = end(); - for (iterator iter = b; iter != e; iter++) - { - if (CompareAlt(u, (*iter).key) == 0) - { - return iter; - } - } - return e; - } - iterator erase(iterator where) - { - where.erase(); - return where; - } - template - void erase(const U & u) - { - iterator iter = find(u); - if (iter == end()) - return; - iter.erase(); - } - friend class iterator; - friend class const_iterator; - private: - NodePtr *m_Buckets; - size_t m_numBuckets; - float m_percentUsed; - }; -}; - -#endif //_INCLUDE_SH_TINYHASH_H_ diff --git a/sourcehook/sh_vector.h b/sourcehook/sh_vector.h deleted file mode 100755 index 26b16b9..0000000 --- a/sourcehook/sh_vector.h +++ /dev/null @@ -1,519 +0,0 @@ -/* ======== SourceMM ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __CVECTOR_H__ -#define __CVECTOR_H__ - -#include - -//This file originally from AMX Mod X -namespace SourceHook -{ -// Vector -template class CVector -{ - bool Grow(size_t amount) - { - // automatic grow - size_t newSize = m_Size * 2; - - if (newSize == 0) - { - newSize = 8; - } - - while (m_CurrentUsedSize + amount > newSize) - { - newSize *= 2; - } - - T *newData = new T[newSize]; - - if (m_Data) - { - for (size_t i=0; i= m_Size) - { - return Grow(amount); - } - else - { - return true; - } - } - - bool ChangeSize(size_t size) - { - // change size - if (size == m_Size) - { - return true; - } - - if (!size) - { - if (m_Data) - { - delete [] m_Data; - m_Data = NULL; - m_Size = 0; - } - return true; - } - - T *newData = new T[size]; - - if (m_Data) - { - size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size; - for (size_t i=0; i m_Size) - { - m_CurrentUsedSize = m_Size; - } - - return true; - } - - void FreeMemIfPossible() - { - if (!m_Data) - { - return; - } - - if (!m_CurrentUsedSize) - { - ChangeSize(0); - return; - } - - size_t newSize = m_Size; - while (m_CurrentUsedSize <= newSize / 2) - { - newSize /= 2; - } - - if (newSize != m_Size) - { - ChangeSize(newSize); - } - } -protected: - T *m_Data; - size_t m_Size; - size_t m_CurrentUsedSize; -public: - class iterator - { - protected: - T *m_Ptr; - public: - // constructors / destructors - iterator() - { - m_Ptr = NULL; - } - - iterator(T * ptr) - { - m_Ptr = ptr; - } - - // member functions - T * base() - { - return m_Ptr; - } - - const T * base() const - { - return m_Ptr; - } - - // operators - T & operator*() - { - return *m_Ptr; - } - - T * operator->() - { - return m_Ptr; - } - - iterator & operator++() // preincrement - { - ++m_Ptr; - return (*this); - } - - iterator operator++(int) // postincrement - { - iterator tmp = *this; - ++m_Ptr; - return tmp; - } - - iterator & operator--() // predecrement - { - --m_Ptr; - return (*this); - } - - iterator operator--(int) // postdecrememnt - { - iterator tmp = *this; - --m_Ptr; - return tmp; - } - - bool operator==(T * right) const - { - return (m_Ptr == right); - } - - bool operator==(const iterator & right) const - { - return (m_Ptr == right.m_Ptr); - } - - bool operator!=(T * right) const - { - return (m_Ptr != right); - } - - bool operator!=(const iterator & right) const - { - return (m_Ptr != right.m_Ptr); - } - - iterator & operator+=(size_t offset) - { - m_Ptr += offset; - return (*this); - } - - iterator & operator-=(size_t offset) - { - m_Ptr -= offset; - return (*this); - } - - iterator operator+(size_t offset) const - { - iterator tmp(*this); - tmp.m_Ptr += offset; - return tmp; - } - - iterator operator-(size_t offset) const - { - iterator tmp(*this); - tmp.m_Ptr -= offset; - return tmp; - } - - T & operator[](size_t offset) - { - return (*(*this + offset)); - } - - const T & operator[](size_t offset) const - { - return (*(*this + offset)); - } - - bool operator<(const iterator & right) const - { - return m_Ptr < right.m_Ptr; - } - - bool operator>(const iterator & right) const - { - return m_Ptr > right.m_Ptr; - } - - bool operator<=(const iterator & right) const - { - return m_Ptr <= right.m_Ptr; - } - - bool operator>=(const iterator & right) const - { - return m_Ptr >= right.m_Ptr; - } - - size_t operator-(const iterator & right) const - { - return m_Ptr - right.m_Ptr; - } - }; - - // constructors / destructors - CVector() - { - m_Size = 0; - m_CurrentUsedSize = 0; - m_Data = NULL; - } - - CVector(const CVector & other) - { - // copy data - m_Data = new T [other.m_CurrentUsedSize]; - m_Size = other.m_CurrentUsedSize; - m_CurrentUsedSize = other.m_CurrentUsedSize; - for (size_t i=0; i() - { - clear(); - } - - CVector & operator =(const CVector & other) - { - clear(); - ChangeSize(other.size()); - m_CurrentUsedSize = other.size(); - for (size_t i=0; i m_CurrentUsedSize) - assert(0); - return iterator(m_Data + pos); - } - - bool reserve(size_t newSize) - { - if (newSize > m_Size) - return ChangeSize(newSize); - return true; - } - - bool push_back(const T & elem) - { - if (!GrowIfNeeded(1)) - { - return false; - } - - m_Data[m_CurrentUsedSize++] = elem; - - return true; - } - - void pop_back() - { - --m_CurrentUsedSize; - if (m_CurrentUsedSize < 0) - m_CurrentUsedSize = 0; - - FreeMemIfPossible(); - } - - bool resize(size_t newSize) - { - return resize(newSize, T()); - } - - bool resize(size_t newSize, T defval) - { - if (!ChangeSize(newSize)) - return false; - for (size_t i = m_CurrentUsedSize; i < newSize; ++i) - m_Data[i] = defval; - m_CurrentUsedSize = newSize; - return true; - } - - bool empty() const - { - return (m_CurrentUsedSize == 0); - } - - T & at(size_t pos) - { - if (pos > m_CurrentUsedSize) - { - assert(0); - } - return m_Data[pos]; - } - - const T & at(size_t pos) const - { - if (pos > m_CurrentUsedSize) - { - assert(0); - } - return m_Data[pos]; - } - - T & operator[](size_t pos) - { - return at(pos); - } - - const T & operator[](size_t pos) const - { - return at(pos); - } - - T & front() - { - if (m_CurrentUsedSize < 1) - { - assert(0); - } - return m_Data[0]; - } - - const T & front() const - { - if (m_CurrentUsedSize < 1) - { - assert(0); - } - return m_Data[0]; - } - - T & back() - { - if (m_CurrentUsedSize < 1) - { - assert(0); - } - return m_Data[m_CurrentUsedSize - 1]; - } - - const T & back() const - { - if (m_CurrentUsedSize < 1) - { - assert(0); - } - return m_Data[m_CurrentUsedSize - 1]; - } - - iterator insert(iterator where, const T & value) - { - // validate iter - if (where < m_Data || where > (m_Data + m_CurrentUsedSize)) - return iterator(0); - - size_t ofs = where - begin(); - - if (!GrowIfNeeded(1)) - { - return false; - } - - ++m_CurrentUsedSize; - - where = begin() + ofs; - - // Move subsequent entries - for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr) - *(ptr + 1) = *ptr; - - *where.base() = value; - - return where; - } - - iterator erase(iterator where) - { - // validate iter - if (where < m_Data || where >= (m_Data + m_CurrentUsedSize)) - return iterator(0); - - size_t ofs = where - begin(); - - if (m_CurrentUsedSize > 1) - { - // move - T *theend = m_Data + m_CurrentUsedSize; - for (T *ptr = where.base() + 1; ptr < theend; ++ptr) - *(ptr - 1) = *ptr; - } - - --m_CurrentUsedSize; - - FreeMemIfPossible(); - - return begin() + ofs; - } - - void clear() - { - m_Size = 0; - m_CurrentUsedSize = 0; - if (m_Data) - { - delete [] m_Data; - m_Data = NULL; - } - } -}; -}; //namespace SourceHook - -#endif // __CVECTOR_H__ diff --git a/sourcehook/sourcehook.cpp b/sourcehook/sourcehook.cpp deleted file mode 100644 index c817ac3..0000000 --- a/sourcehook/sourcehook.cpp +++ /dev/null @@ -1,1093 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* Contributors: Scott "Damaged Soul" Ehlert -* ============================ -*/ - -/** - * @file sourcehook.cpp - * @brief Contains the implementation of the SourceHook API -*/ - -#if defined __GNUC__ -#include -#endif - -#include "sourcehook_impl.h" - -namespace SourceHook -{ - template<> - int HashFunction(const int & k) - { - return k; - } - template<> - int Compare(const int & k1, const int & k2) - { - if (k1 == k2) - return 0; - if (k1 > k2) - return 1; - if (k1 < k2) - return -1; - return 0; - } - - namespace Impl - { - ////////////////////////////////////////////////////////////////////////// - // CProto - ////////////////////////////////////////////////////////////////////////// - void CProto::Fill(const ProtoInfo *pProto) - { - if (pProto == NULL) - m_Version = -1; - - m_ParamsPassInfo.clear(); - - if (pProto->paramsPassInfo[0].size == 0) - { - // Version 1 - m_Version = 0; - m_Convention = pProto->convention; - m_NumOfParams = pProto->numOfParams; - - m_RetPassInfo.size = pProto->retPassInfo.size; - m_RetPassInfo.type = pProto->retPassInfo.type; - m_RetPassInfo.flags = GetRealFlags(pProto->retPassInfo); - - m_RetPassInfo.pNormalCtor = NULL; - m_RetPassInfo.pCopyCtor = NULL; - m_RetPassInfo.pDtor = NULL; - m_RetPassInfo.pAssignOperator = NULL; - - - m_ParamsPassInfo.resize(pProto->numOfParams); - - for (int i = 1; i <= pProto->numOfParams; ++i) - { - m_ParamsPassInfo[i-1].size = pProto->paramsPassInfo[i].size; - m_ParamsPassInfo[i-1].type = pProto->paramsPassInfo[i].type; - m_ParamsPassInfo[i-1].flags = GetRealFlags(pProto->paramsPassInfo[i]); - - m_ParamsPassInfo[i-1].pNormalCtor = NULL; - m_ParamsPassInfo[i-1].pCopyCtor = NULL; - m_ParamsPassInfo[i-1].pDtor = NULL; - m_ParamsPassInfo[i-1].pAssignOperator = NULL; - } - } - else if (pProto->paramsPassInfo[0].size == 1) - { - // Version 2 - m_Version = 1; - m_Convention = pProto->convention; - m_NumOfParams = pProto->numOfParams; - - m_RetPassInfo.size = pProto->retPassInfo.size; - m_RetPassInfo.type = pProto->retPassInfo.type; - m_RetPassInfo.flags = pProto->retPassInfo.flags; - - m_RetPassInfo.pNormalCtor = pProto->retPassInfo2.pNormalCtor; - m_RetPassInfo.pCopyCtor = pProto->retPassInfo2.pCopyCtor; - m_RetPassInfo.pDtor = pProto->retPassInfo2.pDtor; - m_RetPassInfo.pAssignOperator = pProto->retPassInfo2.pAssignOperator; - - m_ParamsPassInfo.resize(pProto->numOfParams); - - for (int i = 1; i <= pProto->numOfParams; ++i) - { - m_ParamsPassInfo[i-1].size = pProto->paramsPassInfo[i].size; - m_ParamsPassInfo[i-1].type = pProto->paramsPassInfo[i].type; - m_ParamsPassInfo[i-1].flags = pProto->paramsPassInfo[i].flags; - - m_ParamsPassInfo[i-1].pNormalCtor = pProto->paramsPassInfo2[i].pNormalCtor; - m_ParamsPassInfo[i-1].pCopyCtor = pProto->paramsPassInfo2[i].pCopyCtor; - m_ParamsPassInfo[i-1].pDtor = pProto->paramsPassInfo2[i].pDtor; - m_ParamsPassInfo[i-1].pAssignOperator = pProto->paramsPassInfo2[i].pAssignOperator; - } - } - else - { - // Unknown - m_Version = -1; - } - } - - // Basic compat test - // Other than this, we assume that the plugins know what they're doing - bool CProto::operator == (const CProto &other) const - { - if (m_Version < 0 || other.GetVersion() < 0) - return false; - - if (m_NumOfParams != other.GetNumOfParams()) - return false; - - if (m_Convention != ProtoInfo::CallConv_Unknown && other.GetConvention() != ProtoInfo::CallConv_Unknown && - m_Convention != other.GetConvention()) - return false; - - if (GetRealSize(GetRet()) != GetRealSize(other.GetRet())) - return false; - - for (int i = 0; i < m_NumOfParams; ++i) - { - if (GetRealSize(GetParam(i)) != GetRealSize(other.GetParam(i))) - return false; - if (GetParam(i).type != PassInfo::PassType_Unknown && other.GetParam(i).type != PassInfo::PassType_Unknown) - { - if (GetParam(i).type != other.GetParam(i).type) - return false; - if (GetParam(i).flags != other.GetParam(i).flags) - return false; - } - } - - return true; - } - - bool CProto::ExactlyEqual(const CProto &other) const - { - if (m_Version != other.m_Version || - m_NumOfParams != other.m_NumOfParams || - m_Convention != other.m_Convention || - GetRet() != other.GetRet()) - { - return false; - } - - for (int i = 0; i < m_NumOfParams; ++i) - { - if(GetParam(i) != other.GetParam(i)) - return false; - } - - return true; - } - - ////////////////////////////////////////////////////////////////////////// - // CHookManager - ////////////////////////////////////////////////////////////////////////// - void CHookManager::SetInfo(int hookman_version, int vtbloffs, int vtblidx, - ProtoInfo *proto, void *hookfunc_vfnptr) - { - m_Version = hookman_version; - m_VtblOffs = vtbloffs; - m_VtblIdx = vtblidx; - m_Proto = proto; - m_HookfuncVfnptr = hookfunc_vfnptr; - } - - ////////////////////////////////////////////////////////////////////////// - // CVfnPtrList - ////////////////////////////////////////////////////////////////////////// - - CVfnPtr &CVfnPtrList::GetVfnPtr(void *vfnptr) - { - iterator iter = find(vfnptr); - if (iter == end()) - { - CVfnPtr newVfnPtr(vfnptr); - push_back(newVfnPtr); - - return back(); - } - else - { - return *iter; - } - } - ////////////////////////////////////////////////////////////////////////// - // CVfnPtr - ////////////////////////////////////////////////////////////////////////// - - void CVfnPtr::AddHookMan(CHookManager *pHookMan) - { - List::iterator iter; - - // Don't accept invalid hook managers - if (!*pHookMan) - return; - - // Check whether this hook manager already exists; if yes, ignore. - iter = m_HookMans.find(pHookMan); - if (iter != m_HookMans.end()) - return; - - // It doesn't -> add it. Add it to the end of its version group. - for (iter = m_HookMans.begin(); iter != m_HookMans.end(); ++iter) - { - if ((*iter)->GetVersion() < pHookMan->GetVersion()) - break; - } - - bool isBeginning = iter == m_HookMans.begin(); - - m_HookMans.insert(iter, pHookMan); - - if (isBeginning) - { - pHookMan->IncrRef(this); - if (m_HookMans.size() > 1) - { - // If another hookman was used until now but this one is better - // (which it is because it's the first -> it has a higher version) - // -> switch! - - List::iterator second = m_HookMans.begin(); - ++second; - - (*second)->DecrRef(this); - } - - // Make sure that this vfnptr points at it - Patch(pHookMan->GetHookFunc()); - } - } - - bool CVfnPtr::HookManRemoved(CHookManager *pHookMan) - { - // Don't accept invalid hook managers - if (!*pHookMan) - return true; - - List::iterator iter = m_HookMans.find(pHookMan); - if (iter == m_HookMans.end()) - return true; // Didn't exist here anyway - - if (iter == m_HookMans.begin()) - { - // It is the first one! - pHookMan->DecrRef(this); - m_HookMans.erase(iter); - - if (m_HookMans.empty()) - return false; // No more hookmans -> let SH delete us - - // Activate second -> now first hookman - m_HookMans.front()->IncrRef(this); - Patch(m_HookMans.front()->GetHookFunc()); - } - else - { - m_HookMans.erase(iter); - } - return true; - } - - bool CVfnPtr::Patch(void *newValue) - { - if (!SetMemAccess(m_Ptr, sizeof(void*), SH_MEM_READ | SH_MEM_WRITE)) - { - return false; - } - - *reinterpret_cast(m_Ptr) = newValue; - - return true; - } - - CIface &CVfnPtr::GetIface(void *iface) - { - List::iterator iter = m_IfaceList.find(iface); - if (iter == m_IfaceList.end()) - { - CIface newIface(iface); - if (iface == NULL) - { - m_IfaceList.push_front(newIface); - return m_IfaceList.front(); - } - else - { - m_IfaceList.push_back(newIface); - return m_IfaceList.back(); - } - } - else - { - return *iter; - } - } - - ////////////////////////////////////////////////////////////////////////// - // CHookIdManager - ////////////////////////////////////////////////////////////////////////// - CHookIDManager::CHookIDManager() - { - } - - int CHookIDManager::New(const CProto &proto, int vtbl_offs, int vtbl_idx, void *vfnptr, - void *adjustediface, Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post) - { - Entry tmp(proto, vtbl_offs, vtbl_idx, vfnptr, adjustediface, plug, thisptr_offs, handler, post); - - size_t cursize = m_Entries.size(); - for (size_t i = 0; i < cursize; ++i) - { - if (m_Entries[i].isfree) - { - m_Entries[i] = tmp; - return static_cast(i) + 1; - } - } - - m_Entries.push_back(tmp); - return static_cast(m_Entries.size()); // return size() because hookid = id+1 anyway - } - - bool CHookIDManager::Remove(int hookid) - { - int realid = hookid - 1; - if (realid < 0 || realid >= static_cast(m_Entries.size()) || m_Entries[realid].isfree) - return false; - - m_Entries[realid].isfree = true; - - // :TODO: remove free ids from back sometimes ?? - - return true; - } - - const CHookIDManager::Entry * CHookIDManager::QueryHook(int hookid) - { - int realid = hookid - 1; - if (realid < 0 || realid >= static_cast(m_Entries.size()) || m_Entries[realid].isfree) - return NULL; - - return &m_Entries[realid]; - } - - void CHookIDManager::FindAllHooks(CVector &output, const CProto &proto, int vtbl_offs, - int vtbl_idx, void *adjustediface, Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post) - { - // oh my god, a lot of parameters... - size_t cursize = m_Entries.size(); - for (size_t i = 0; i < cursize; ++i) - { - if (!m_Entries[i].isfree && m_Entries[i].proto == proto && m_Entries[i].vtbl_offs == vtbl_offs && - m_Entries[i].vtbl_idx == vtbl_idx && m_Entries[i].adjustediface == adjustediface && m_Entries[i].plug == plug && - m_Entries[i].thisptr_offs == thisptr_offs && m_Entries[i].handler->IsEqual(handler) && m_Entries[i].post == post) - { - output.push_back(static_cast(i) + 1); - } - } - } - - void CHookIDManager::FindAllHooks(CVector &output) - { - size_t cursize = m_Entries.size(); - for (size_t i = 0; i < cursize; ++i) - { - if (!m_Entries[i].isfree) - output.push_back(static_cast(i) + 1); - } - } - - void CHookIDManager::FindAllHooks(CVector &output, Plugin plug) - { - size_t cursize = m_Entries.size(); - for (size_t i = 0; i < cursize; ++i) - { - if (!m_Entries[i].isfree && m_Entries[i].plug == plug) - output.push_back(static_cast(i) + 1); - } - } - - - void CHookIDManager::RemoveAll(void *vfnptr) - { - size_t cursize = m_Entries.size(); - for (size_t i = 0; i < cursize; ++i) - { - if (!m_Entries[i].isfree && m_Entries[i].vfnptr == vfnptr) - m_Entries[i].isfree = true; - } - } - - ////////////////////////////////////////////////////////////////////////// - // CSourceHookImpl - ////////////////////////////////////////////////////////////////////////// - - - CSourceHookImpl::CSourceHookImpl() - { - } - CSourceHookImpl::~CSourceHookImpl() - { - CompleteShutdown(); - } - - int CSourceHookImpl::GetIfaceVersion() - { - return SH_IFACE_VERSION; - } - - int CSourceHookImpl::GetImplVersion() - { - return SH_IMPL_VERSION; - } - - int CSourceHookImpl::AddHook(Plugin plug, AddHookMode mode, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post) - { - if (mode != Hook_Normal && mode != Hook_VP && mode != Hook_DVP) - return 0; - - // Get info about hook manager - CHookManager hookManager(plug, myHookMan); - if (!hookManager) - return 0; - - void *adjustediface = NULL; - void **cur_vtptr = NULL; - void *cur_vfnptr = NULL; - - // find vfnptr - switch (mode) - { - case Hook_Normal: - adjustediface = reinterpret_cast(reinterpret_cast(iface) + thisptr_offs); - - cur_vtptr = *reinterpret_cast( - reinterpret_cast(adjustediface) + hookManager.GetVtblOffs()); - cur_vfnptr = reinterpret_cast(cur_vtptr + hookManager.GetVtblIdx()); - break; - - case Hook_VP: - - adjustediface = reinterpret_cast(reinterpret_cast(iface) + thisptr_offs); - - cur_vtptr = *reinterpret_cast( - reinterpret_cast(adjustediface) + hookManager.GetVtblOffs()); - cur_vfnptr = reinterpret_cast(cur_vtptr + hookManager.GetVtblIdx()); - - adjustediface = NULL; - break; - - case Hook_DVP: - adjustediface = NULL; - - cur_vtptr = reinterpret_cast(iface); - cur_vfnptr = cur_vtptr + hookManager.GetVtblIdx(); - - break; - } - - CVfnPtr &vfnPtr = m_VfnPtrs.GetVfnPtr(cur_vfnptr); - vfnPtr.AddHookMan(m_HookManList.GetHookMan(hookManager)); - CIface &ifaceinst = vfnPtr.GetIface(adjustediface); - - // Add the hook - CHook hook(plug, thisptr_offs, handler, - - m_HookIDMan.New(hookManager.GetProto(), hookManager.GetVtblOffs(), hookManager.GetVtblIdx(), - cur_vfnptr, adjustediface, plug, thisptr_offs, handler, post) - - ); - - if (post) - ifaceinst.GetPostHookList().push_back(hook); - else - ifaceinst.GetPreHookList().push_back(hook); - - return hook.GetID(); - } - - bool CSourceHookImpl::RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post) - { - // Get info about hook manager and compute adjustediface - CHookManager tmpHookMan(plug, myHookMan); - - void *adjustediface = reinterpret_cast(reinterpret_cast(iface)+thisptr_offs); - - // Loop through all hooks and remove those which match: - // hookman, vfnptr, iface, plug, adjusted iface, this ptr offs, handler, post - CVector removehooks; - m_HookIDMan.FindAllHooks(removehooks, tmpHookMan.GetProto(), tmpHookMan.GetVtblOffs(), tmpHookMan.GetVtblIdx(), - adjustediface, plug, thisptr_offs, handler, post); - - if (removehooks.empty()) - return false; - - bool status = false; - - for (CVector::iterator iter = removehooks.begin(); iter != removehooks.end(); ++iter) - { - if (RemoveHookByID(*iter)) - status = true; - } - return status; - } - - bool CSourceHookImpl::RemoveHookByID(int hookid) - { - const CHookIDManager::Entry *hentry; - - hentry = m_HookIDMan.QueryHook(hookid); - if (!hentry) - { - // hookid doesn't exist ! - return false; - } - - // find vfnptr - List::iterator vfnptr_iter = m_VfnPtrs.find(hentry->vfnptr); - if (vfnptr_iter == m_VfnPtrs.end()) - return false; - - // find iface - List::iterator iface_iter = vfnptr_iter->GetIfaceList().find(hentry->adjustediface); - if (iface_iter == vfnptr_iter->GetIfaceList().end()) - return false; - - // find hook - List &hooks = hentry->post ? iface_iter->GetPostHookList() : iface_iter->GetPreHookList(); - List::iterator hook_iter = hooks.find(hookid); - if (hook_iter == hooks.end()) - return false; - - hook_iter->GetHandler()->DeleteThis(); - - // Iterator movage! - List::iterator oldhookiter = hook_iter; - hook_iter = hooks.erase(hook_iter); - - for (CStack::iterator ctx_iter = m_ContextStack.begin(); - ctx_iter != m_ContextStack.end(); ++ctx_iter) - { - ctx_iter->HookRemoved(oldhookiter, hook_iter); - } - - if (iface_iter->GetPreHookList().empty() && iface_iter->GetPostHookList().empty()) - { - // -> Kill all contexts that use it! - for (CStack::iterator ctx_iter = m_ContextStack.begin(); - ctx_iter != m_ContextStack.end(); ++ctx_iter) - { - ctx_iter->IfaceRemoved(&(*iface_iter)); - } - - // There are no hooks on this iface anymore... - iface_iter = vfnptr_iter->GetIfaceList().erase(iface_iter); - - if (vfnptr_iter->GetIfaceList().empty()) - { - // No ifaces at all -> Deactivate the hook - - for (CStack::iterator ctx_iter = m_ContextStack.begin(); - ctx_iter != m_ContextStack.end(); ++ctx_iter) - { - ctx_iter->VfnPtrRemoved(&(*vfnptr_iter)); - } - - vfnptr_iter->Revert(); - - m_VfnPtrs.erase(vfnptr_iter); - } - } - - m_HookIDMan.Remove(hookid); - return true; - } - - void CSourceHookImpl::SetRes(META_RES res) - { - *m_ContextStack.front().pCurRes = res; - } - - META_RES CSourceHookImpl::GetPrevRes() - { - return *m_ContextStack.front().pPrevRes; - } - - META_RES CSourceHookImpl::GetStatus() - { - return *m_ContextStack.front().pStatus; - - } - - const void *CSourceHookImpl::GetOrigRet() - { - return m_ContextStack.front().pOrigRet; - } - - const void *CSourceHookImpl::GetOverrideRet() - { - return (*m_ContextStack.front().pStatus < MRES_OVERRIDE) ? - NULL : m_ContextStack.front().pOverrideRet; - } - - void *CSourceHookImpl::GetIfacePtr() - { - // If in recall: return last one - if (m_ContextStack.front().m_State >= CHookContext::State_Recall_Pre && - m_ContextStack.front().m_State <= CHookContext::State_Recall_PostVP) - { - return m_ContextStack.second().pIfacePtr; - } - else - { - return m_ContextStack.front().pIfacePtr; - } - } - - void *CSourceHookImpl::GetOverrideRetPtr() - { - return m_ContextStack.front().pOverrideRet; - } - - void CSourceHookImpl::UnloadPlugin(Plugin plug) - { - // 1) Remove all hooks by this plugin - - CVector removehooks; - m_HookIDMan.FindAllHooks(removehooks, plug); - - for (CVector::iterator iter = removehooks.begin(); iter != removehooks.end(); ++iter) - RemoveHookByID(*iter); - - // 2) Remove all hook managers - for (CHookManList::iterator iter = m_HookManList.begin(); iter != m_HookManList.end(); ) - { - if (iter->GetOwnerPlugin() == plug) - iter = RemoveHookManager(iter); - else - ++iter; - } - } - - CHookManList::iterator CSourceHookImpl::RemoveHookManager(CHookManList::iterator hookman_iter) - { - // 2) Remove it - for (CVfnPtrList::iterator vfnptr_iter = m_VfnPtrs.begin(); - vfnptr_iter != m_VfnPtrs.end();) - { - if (!vfnptr_iter->HookManRemoved(&(*hookman_iter))) - { - // This vfnptr has no more hook managers - // and asks to be removed. - - vfnptr_iter->Revert(); - - m_HookIDMan.RemoveAll(vfnptr_iter->GetPtr()); - vfnptr_iter = m_VfnPtrs.erase(vfnptr_iter); - } - else - { - ++vfnptr_iter; - } - } - - return m_HookManList.erase(hookman_iter); - } - - void CSourceHookImpl::RemoveHookManager(Plugin plug, HookManagerPubFunc pubFunc) - { - // Find the hook manager - CHookManList::iterator hookman_iter = m_HookManList.find(CHookManager::Descriptor(plug, pubFunc)); - - if (hookman_iter != m_HookManList.end()) - { - RemoveHookManager(hookman_iter); - } - } - - void CSourceHookImpl::SetIgnoreHooks(void *vfnptr) - { - CHookContext ctx; - ctx.m_State = CHookContext::State_Ignore; - m_ContextStack.push(ctx); - } - - void CSourceHookImpl::ResetIgnoreHooks(void *vfnptr) - { - if (!m_ContextStack.empty() && m_ContextStack.front().m_State == CHookContext::State_Ignore) - m_ContextStack.pop(); - } - - void *CSourceHookImpl::GetOrigVfnPtrEntry(void *vfnptr) - { - for (CVfnPtrList::iterator vfnptr_iter = m_VfnPtrs.begin(); vfnptr_iter != m_VfnPtrs.end(); ++vfnptr_iter) - { - if (vfnptr_iter->GetPtr() == vfnptr) - return vfnptr_iter->GetOrigEntry(); - } - return NULL; - } - - void CSourceHookImpl::DoRecall() - { - CHookContext newCtx; - CHookContext &curCtx = m_ContextStack.front(); - - - newCtx.m_State = curCtx.m_State + (CHookContext::State_Recall_Pre - CHookContext::State_Pre); - if (newCtx.m_State == CHookContext::State_Recall_Post || newCtx.m_State == CHookContext::State_Recall_PostVP) - { - // Also save orig ret - newCtx.pOrigRet = curCtx.pOrigRet; - } - - // The hookfunc usually does this, but it won't have a chance to see it, - // so for recalls, we update status here if it's required - if (*curCtx.pCurRes > *curCtx.pStatus) - *curCtx.pStatus = *curCtx.pCurRes; - - newCtx.pStatus = curCtx.pStatus; - newCtx.pOverrideRet = curCtx.pOverrideRet; - newCtx.pPrevRes = curCtx.pPrevRes; - newCtx.m_Iter = curCtx.m_Iter; - - // Take this with us! - newCtx.pCurRes = curCtx.pCurRes; - - m_ContextStack.push(newCtx); - curCtx.m_State = CHookContext::State_Dead; - } - - IHookContext *CSourceHookImpl::SetupHookLoop(IHookManagerInfo *hi, void *vfnptr, void *thisptr, void **origentry, META_RES *statusPtr, - META_RES *prevResPtr, META_RES *curResPtr, const void *origRetPtr, void *overrideRetPtr) - { - CHookContext *pCtx = NULL; - CHookContext *oldctx = m_ContextStack.empty() ? NULL : &m_ContextStack.front(); - if (oldctx) - { - // SH_CALL - if (oldctx->m_State == CHookContext::State_Ignore) - { - *statusPtr = MRES_IGNORED; - oldctx->m_CallOrig = true; - oldctx->m_State = CHookContext::State_Dead; - - List &vfnptr_list = static_cast(hi)->GetVfnPtrList(); - List::iterator vfnptr_iter; - for (vfnptr_iter = vfnptr_list.begin(); - vfnptr_iter != vfnptr_list.end(); ++vfnptr_iter) - { - if (**vfnptr_iter == vfnptr) - break; - } - if (vfnptr_iter == vfnptr_list.end()) - { - SH_ASSERT(false, ("How can a hook exist on a vfnptr which we don't have in our db?!")); - } - else - { - *origentry = (*vfnptr_iter)->GetOrigEntry(); - } - - oldctx->pOrigRet = origRetPtr; - return oldctx; - } - // Recall - else if (oldctx->m_State >= CHookContext::State_Recall_Pre && - oldctx->m_State <= CHookContext::State_Recall_PostVP) - { - pCtx = oldctx; - - *statusPtr = *(oldctx->pStatus); - *prevResPtr = *(oldctx->pPrevRes); - - pCtx->m_Iter = oldctx->m_Iter; - - // Only have possibility of calling the orig func in pre recall mode - pCtx->m_CallOrig = (oldctx->m_State == CHookContext::State_Recall_Pre || - oldctx->m_State == CHookContext::State_Recall_PreVP); - - overrideRetPtr = pCtx->pOverrideRet; - - // When the status is low so there's no override return value and we're in a post recall, - // give it the orig return value as override return value. - if (pCtx->m_State == CHookContext::State_Recall_Post || - pCtx->m_State == CHookContext::State_Recall_PostVP) - { - origRetPtr = oldctx->pOrigRet; - if (*statusPtr < MRES_OVERRIDE) - overrideRetPtr = const_cast(pCtx->pOrigRet); - } - } - } - if (!pCtx) - { - pCtx = m_ContextStack.make_next(); - pCtx->m_State = CHookContext::State_Born; - pCtx->m_CallOrig = true; - } - - pCtx->pIface = NULL; - - List &vfnptr_list = static_cast(hi)->GetVfnPtrList(); - List::iterator vfnptr_iter; - for (vfnptr_iter = vfnptr_list.begin(); - vfnptr_iter != vfnptr_list.end(); ++vfnptr_iter) - { - if (**vfnptr_iter == vfnptr) - break; - } - if (vfnptr_iter == vfnptr_list.end()) - { - pCtx->m_State = CHookContext::State_Dead; - } - else - { - pCtx->pVfnPtr = *vfnptr_iter; - *origentry = pCtx->pVfnPtr->GetOrigEntry(); - pCtx->pIface = pCtx->pVfnPtr->FindIface(thisptr); - } - - pCtx->pStatus = statusPtr; - pCtx->pPrevRes = prevResPtr; - pCtx->pCurRes = curResPtr; - pCtx->pThisPtr = thisptr; - pCtx->pOverrideRet = overrideRetPtr; - pCtx->pOrigRet = origRetPtr; - - return pCtx; - } - - void CSourceHookImpl::EndContext(IHookContext *pCtx) - { - m_ContextStack.pop(); - } - - void CSourceHookImpl::CompleteShutdown() - { - CVector removehooks; - m_HookIDMan.FindAllHooks(removehooks); - - for (CVector::iterator iter = removehooks.begin(); iter != removehooks.end(); ++iter) - RemoveHookByID(*iter); - } - - void CSourceHookImpl::PausePlugin(Plugin plug) - { - CVector pausehooks; - m_HookIDMan.FindAllHooks(pausehooks, plug); - - for (CVector::iterator iter = pausehooks.begin(); iter != pausehooks.end(); ++iter) - PauseHookByID(*iter); - } - - void CSourceHookImpl::UnpausePlugin(Plugin plug) - { - CVector unpausehooks; - m_HookIDMan.FindAllHooks(unpausehooks, plug); - - for (CVector::iterator iter = unpausehooks.begin(); iter != unpausehooks.end(); ++iter) - UnpauseHookByID(*iter); - } - - bool CSourceHookImpl::PauseHookByID(int hookid) - { - return SetHookPaused(hookid, true); - } - - bool CSourceHookImpl::UnpauseHookByID(int hookid) - { - return SetHookPaused(hookid, false); - } - - bool CSourceHookImpl::SetHookPaused(int hookid, bool paused) - { - const CHookIDManager::Entry *hentry; - - hentry = m_HookIDMan.QueryHook(hookid); - if (!hentry) - { - // hookid doesn't exist ! - return false; - } - - // find vfnptr - List::iterator vfnptr_iter = m_VfnPtrs.find(hentry->vfnptr); - if (vfnptr_iter == m_VfnPtrs.end()) - return false; - - // find iface - List::iterator iface_iter = vfnptr_iter->GetIfaceList().find(hentry->adjustediface); - if (iface_iter == vfnptr_iter->GetIfaceList().end()) - return false; - - // find hook - List &hooks = hentry->post ? iface_iter->GetPostHookList() : iface_iter->GetPreHookList(); - List::iterator hook_iter = hooks.find(hookid); - if (hook_iter == hooks.end()) - return false; - - hook_iter->SetPaused(paused); - return true; - } - - ////////////////////////////////////////////////////////////////////////// - // CHookContext - ////////////////////////////////////////////////////////////////////////// - ISHDelegate *CHookContext::GetNext() - { - CIface *pVPIface; - switch (m_State) - { - case State_Dead: - return NULL; - - case State_Born: - m_Iter = List::iterator(); - m_State = State_Pre; - - // fall-through - case State_Recall_Pre: - m_State = State_Pre; - case State_Pre: - if (pIface) - { - if (!m_Iter) - m_Iter = pIface->GetPreHookList().begin(); - else - ++m_Iter; - SkipPaused(m_Iter, pIface->GetPreHookList()); - - if (m_Iter != pIface->GetPreHookList().end()) - { - pIfacePtr = reinterpret_cast(reinterpret_cast(pThisPtr) - m_Iter->GetThisPointerOffset()); - return m_Iter->GetHandler(); - } - } - - // end of normal hooks -> VP - - m_State = State_PreVP; - m_Iter = List::iterator(); - - // fall-through - case State_Recall_PreVP: - m_State = State_PreVP; - case State_PreVP: - pVPIface = pVfnPtr->FindIface(NULL); - if (pVPIface) - { - if (!m_Iter) - m_Iter = pVPIface->GetPreHookList().begin(); - else - ++m_Iter; - SkipPaused(m_Iter, pVPIface->GetPreHookList()); - - if (m_Iter != pVPIface->GetPreHookList()) - { - pIfacePtr = reinterpret_cast(reinterpret_cast(pThisPtr) - m_Iter->GetThisPointerOffset()); - return m_Iter->GetHandler(); - } - } - - // end VP hooks -> orig call - - m_State = State_OrigCall; - return NULL; - - case State_OrigCall: - m_Iter = List::iterator(); - m_State = State_Post; - - // fall-through - case State_Post: - if (pIface) - { - if (!m_Iter) - m_Iter = pIface->GetPostHookList().begin(); - else - ++m_Iter; - SkipPaused(m_Iter, pIface->GetPostHookList()); - - if (m_Iter != pIface->GetPostHookList().end()) - { - pIfacePtr = reinterpret_cast(reinterpret_cast(pThisPtr) - m_Iter->GetThisPointerOffset()); - return m_Iter->GetHandler(); - } - } - // end of normal hooks -> VP - - m_State = State_PostVP; - m_Iter = List::iterator(); - - // fall-through - case State_PostVP: - pVPIface = pVfnPtr->FindIface(NULL); - if (pVPIface) - { - if (!m_Iter) - m_Iter = pVPIface->GetPostHookList().begin(); - else - ++m_Iter; - SkipPaused(m_Iter, pVPIface->GetPostHookList()); - - if (m_Iter != pVPIface->GetPostHookList()) - { - pIfacePtr = reinterpret_cast(reinterpret_cast(pThisPtr) - m_Iter->GetThisPointerOffset()); - return m_Iter->GetHandler(); - } - } - - // end VP hooks -> done - - m_State = State_Dead; - return NULL; - - case State_Recall_Post: - // Skip pre hooks _and_ orig call - m_State = State_Post; - return NULL; - - case State_Recall_PostVP: - // Skip pre hooks _and_ orig call - m_State = State_PostVP; - return NULL; - } - return NULL; - } - - void *CHookContext::GetOverrideRetPtr() - { - return pOverrideRet; - } - - const void *CHookContext::GetOrigRetPtr() - { - return pOrigRet; - } - - bool CHookContext::ShouldCallOrig() - { - return m_CallOrig; - } - - void CHookContext::HookRemoved(List::iterator oldhookiter, List::iterator nexthookiter) - { - if (m_Iter == oldhookiter) - { - m_Iter = nexthookiter; - --m_Iter; - } - } - - void CHookContext::IfaceRemoved(CIface *iface) - { - if (pIface == iface) - pIface = NULL; - } - - void CHookContext::VfnPtrRemoved(CVfnPtr *vfnptr) - { - if (pVfnPtr == vfnptr) - { - pVfnPtr = NULL; - m_State = State_Dead; - } - } - } -} diff --git a/sourcehook/sourcehook.h b/sourcehook/sourcehook.h deleted file mode 100644 index df5a477..0000000 --- a/sourcehook/sourcehook.h +++ /dev/null @@ -1,6043 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -/** -* @file sourcehook.h -* @brief Contains the public SourceHook API -*/ - -#ifndef __SOURCEHOOK_H__ -#define __SOURCEHOOK_H__ - -// Interface revisions: -// 1 - Initial revision -// 2 - Changed to virtual functions for iterators and all queries -// 3 - Added "hook loop status variable" -// 4 - Reentrant -// 5 - New "V2" interface -#define SH_IFACE_VERSION 5 - -// Impl versions: -// ??? -// 4 - addition of hook ids and vp hooks (with them, AddHookNew and RemoveHookNew) -// This is not a SH_IFACE_VERSION change so that old plugins continue working! -// 5 - implementation of the new "V2" interface -#define SH_IMPL_VERSION 5 - -// Hookman version: -// 1 - standard -#define SH_HOOKMAN_VERSION 1 - -// Hookmanautogen versions -// 1 - initial -#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1 -#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1 - -// The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook -// It's used in various macros -#ifndef SH_GLOB_SHPTR -#define SH_GLOB_SHPTR g_SHPtr -#endif - -// Used to identify the current plugin -#ifndef SH_GLOB_PLUGPTR -#define SH_GLOB_PLUGPTR g_PLID -#endif - -#ifdef SH_DEBUG -# include -# include - -# define SH_ASSERT(x, info) \ - do { \ - if (!(x)) \ - { \ - printf("SOURCEHOOK DEBUG ASSERTION FAILED: %s:%u(%s): %s: ", __FILE__, __LINE__, __FUNCTION__, #x); \ - printf info; \ - putchar('\n'); \ - abort(); \ - } \ - } while(0) - -#else -# define SH_ASSERT(x, info) -#endif - -// System -#define SH_SYS_WIN32 1 -#define SH_SYS_LINUX 2 - -#ifdef _WIN32 -# define SH_SYS SH_SYS_WIN32 -#elif defined __linux__ -# define SH_SYS SH_SYS_LINUX -#else -# error Unsupported system -#endif - -// Compiler -#define SH_COMP_GCC 1 -#define SH_COMP_MSVC 2 - -#ifdef _MSC_VER -# define SH_COMP SH_COMP_MSVC -#elif defined __GNUC__ -# define SH_COMP SH_COMP_GCC -#else -# error Unsupported compiler -#endif - -#if SH_COMP==SH_COMP_MSVC -# define vsnprintf _vsnprintf -#endif - -#if SH_SYS != SH_SYS_WIN32 -# include -#endif - -#define SH_PTRSIZE sizeof(void*) - -#include "sh_memfuncinfo.h" -#include "FastDelegate.h" - -// Good old metamod! - -// Flags returned by a plugin's api function. -// NOTE: order is crucial, as greater/less comparisons are made. -enum META_RES -{ - MRES_IGNORED=0, // plugin didn't take any action - MRES_HANDLED, // plugin did something, but real function should still be called - MRES_OVERRIDE, // call real function, but use my return value - MRES_SUPERCEDE // skip real function; use my return value -}; - - -namespace SourceHook -{ - /** - * @brief Specifies the size (in bytes) for the internal buffer of vafmt(printf-like) function handlers - */ - const int STRBUF_LEN=4096; - - /** - * @brief An empty class. No inheritance used. Used for original-function-call hacks - */ - class EmptyClass - { - }; - - /** - * @brief Implicit cast. - */ - template - inline Out implicit_cast(In input) - { - return input; - } - - /** - * @brief A plugin typedef - * - * SourceHook doesn't really care what this is. As long as the ==, != and = operators work on it and every - * plugin has a unique identifier, everything is ok. - * It should also be possible to set it to 0. - */ - typedef int Plugin; - - - template class CallClass : public T - { - }; - typedef void ManualCallClass; - - /** - * @brief Describes the way a parameter/retval is passed. - */ - struct PassInfo - { - enum PassType - { - PassType_Unknown=0, /**< Unknown -- no extra info available */ - PassType_Basic, /**< Plain old register data (pointers, integers) */ - PassType_Float, /**< Floating point data */ - PassType_Object, /**< Object or structure */ - }; - - enum PassFlags - { - PassFlag_ByVal = (1<<0), /**< Passing by value */ - PassFlag_ByRef = (1<<1), /**< Passing by reference */ - PassFlag_ODtor = (1<<2), /**< Object has a destructor */ - PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */ - PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */ - PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */ - - // The following two flags are only relevant for byval return types. - // SH tries to auto-detect these - // If you want to override SH's auto-detection, pass them in yourself - PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */ - PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */ - }; - - size_t size; //!< Size of the data being passed - - // Extra info: - // (might be used in future versions for automatic hookfunc generation) - int type; //!< PassType value - unsigned int flags; //!< Pass/return flags - - struct V2Info - { - void *pNormalCtor; - void *pCopyCtor; - void *pDtor; - void *pAssignOperator; - }; - }; - - struct ProtoInfo - { - enum CallConvention - { - CallConv_Unknown, /**< Unknown -- no extra info available (0)*/ - CallConv_ThisCall, /**< This call (object pointer required) (1)*/ - CallConv_Cdecl, /**< C call (2)*/ - CallConv_StdCall, /**< Windows "stdcall" (3)*/ - - CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */ - CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */ - }; - - int numOfParams; //!< number of parameters - PassInfo retPassInfo; //!< PassInfo for the return value. size=0 -> no retval - const PassInfo *paramsPassInfo; //!< PassInfos for the parameters - - // paramsPassInfo[0] is basically a dummy parameter. - // However, paramsPassInfo[0].size stores the version of the ProtoInfo structure. - - // Extra info: - int convention; - - // Version2: - PassInfo::V2Info retPassInfo2; - const PassInfo::V2Info *paramsPassInfo2; - }; - - struct IHookManagerInfo; - - /** - * @brief Pointer to hook manager interface function - * - * The hook manager should store hi for later use if store==true. It should then call hi->SetInfo(...) if hi - * is non-null. The hook manager can return 0 for success or a non-zero value if it doesn't want to be used. - * - * @param hi A pointer to IHookManagerInfo - */ - typedef int (*HookManagerPubFunc)(bool store, IHookManagerInfo *hi); - - class ISHDelegate - { - public: - virtual bool IsEqual(ISHDelegate *pOtherDeleg) = 0; // pOtherDeleg is from the same plugin and hookman - virtual void DeleteThis() = 0; - }; - - struct IHookManagerInfo - { - virtual void SetInfo(int hookman_version, int vtbloffs, int vtblidx, - ProtoInfo *proto, void *hookfunc_vfnptr) = 0; - }; - - // I'm adding support for functions which return references. - - // How it works: - // SH_SETUPCALLS doesn't use plain rettype to store the temporary return values (plugin ret, orig ret, - // override ret) anymore; instead, it uses SourceHook::ReferenceCarrier::type - // this is typedefed to the original rettype normally, but if the rettype is a reference, it's a special class - // which stores the reference as a pointer, and implements constructors, operator= and a conversion operator. - // special cases were needed for getoverrideret / getorigret; these are implemented through the - // SourceHook::MacroRefHelpers structs. - // Furthermore, SetOverrideRet had to be changed a bit; see SourceHook::OverrideFunctor somewhere down in this file. - template struct ReferenceCarrier - { - typedef T type; - }; - - template struct ReferenceCarrier - { - class type - { - T *m_StoredRef; - public: - type() : m_StoredRef(NULL) - { - } - type(T& ref) : m_StoredRef(&ref) - { - } - - T& operator= (T& ref) - { - m_StoredRef = &ref; - return ref; - } - - operator T& () const - { - return *m_StoredRef; - } - }; - }; - - struct IHookContext - { - virtual ISHDelegate *GetNext() = 0; - virtual void *GetOverrideRetPtr() = 0; - virtual const void *GetOrigRetPtr() = 0; - virtual bool ShouldCallOrig() = 0; - }; - - /** - * @brief The main SourceHook interface - */ - class ISourceHook - { - public: - /** - * @brief Return interface version - */ - virtual int GetIfaceVersion() = 0; - - /** - * @brief Return implementation version - */ - virtual int GetImplVersion() = 0; - - /** - * @brief Modes for the new AddHook - */ - enum AddHookMode - { - Hook_Normal, - Hook_VP, - Hook_DVP - }; - - /** - * @brief Add a (VP) hook. - * - * @return non-zero hook id on success, 0 otherwise - * - * @param plug The unique identifier of the plugin that calls this function - * @param mode Can be either Hook_Normal or Hook_VP (vtable-wide hook) - * @param iface The interface pointer - * @param ifacesize The size of the class iface points to - * @param myHookMan A hook manager function that should be capable of handling the function - * @param handler A pointer to the hook handler something - * @param post Set to true if you want a post handler - */ - virtual int AddHook(Plugin plug, AddHookMode mode, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post) = 0; - - // Source backwarts compat (only for normal hooks) - virtual bool RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post) = 0; - - /** - * @brief Remove a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool RemoveHookByID(int hookid) = 0; - - /** - * @brief Pause a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool PauseHookByID(int hookid) = 0; - - /** - * @brief Unpause a hook by ID. - * - * @return true on success, false otherwise - * - * @param hookid The hook id (returned by AddHook) - */ - virtual bool UnpauseHookByID(int hookid) = 0; - - /** - * @brief Checks whether a plugin has (a) hook manager(s) that is/are currently used by other plugins - * - * @param plug The unique identifier of the plugin in question - */ - - virtual void SetRes(META_RES res) = 0; //!< Sets the meta result - virtual META_RES GetPrevRes() = 0; //!< Gets the meta result of the - //!< previously calledhandler - virtual META_RES GetStatus() = 0; //!< Gets the highest meta result - virtual const void *GetOrigRet() = 0; //!< Gets the original result. - //!< If not in post function, undefined - virtual const void *GetOverrideRet() = 0; //!< Gets the override result. - //!< If none is specified, NULL - virtual void *GetIfacePtr() = 0; //!< Gets the interface pointer - - virtual void *GetOverrideRetPtr() = 0; //!< Used for setting the override return value - - /** - * @brief Remove a hook manager. Auto-removes all hooks attached to it from plugin plug. - * - * @param plug The owner of the hook manager - * @param pubFunc The hook manager's info function - */ - virtual void RemoveHookManager(Plugin plug, HookManagerPubFunc pubFunc) = 0; - - // For SH_CALL: - - /** - * @brief Makes sure that hooks are going to be ignored on the next call of vfnptr - * - * @param plug The unique identifier of the plugin that calls this function - * @param vfnptr The virtual function pointer of the function in question - */ - virtual void SetIgnoreHooks(void *vfnptr) = 0; - - /** - * @brief Reverses SetIgnoreHooks' effect - * - * @param plug The unique identifier of the plugin that calls this function - * @param vfnptr The virtual function pointer of the function in question - */ - virtual void ResetIgnoreHooks(void *vfnptr) = 0; - - /** - * @brief Finds the original entry of a virtual function pointer - * - * @param vfnptr The virtual function pointer - * @return The original entry if the virtual function pointer has been patched; NULL otherwise. - */ - virtual void *GetOrigVfnPtrEntry(void *vfnptr) = 0; - - ////////////////////////////////////////////////////////////////////////// - - // For hook managers - - // Returns the current iface ptr - virtual void DoRecall() = 0; //!< Initiates a recall sequence - - /* - HOW RECALLS WORK: - - The problem: - Users want the ability to change parameters of the called function - from inside their handler. - The solution: - 1) Mark as "recall" - 2) Recall the function - 3) => SH's hook func gets called: - 4) The first iterator points at the first hook the last hookfunc didn't execute yet - 5) does all iteration and returns normally - 6) The user's handler returns immediately - 7) The hook func returns immediately as well - - Also note that the recalled hookfunc starts with the status the recalling hookfunc - ended with. The last handler (doing the recall) is also able to specify its own - META_RES. - */ - - /** - * @brief Set up the hook loop. - * - * @param statusPtr pointer to status variable - * @param prevResPtr pointer to previous result variable - * @param curResPtr pointer to current result variable - * @param ifacePtrPtr pointer to interface this pointer variable - * @param origRetPr pointer to original return value variable. NULL for void funcs - * @param overrideRetPtr pointer to override return value variable. NULL for void funcs - * - * @return Override Return Pointer the hookfunc should use (may differ from overrideRetPtr - * when the hook func is being called as part of a recall - */ - virtual IHookContext *SetupHookLoop(IHookManagerInfo *hi, void *vfnptr, void *thisptr, void **origentry, - META_RES *statusPtr, META_RES *prevResPtr, META_RES *curResPtr, - const void *origRetPtr, void *overrideRetPtr) = 0; - - virtual void EndContext(IHookContext *pCtx) = 0; - }; - - - class IHookManagerAutoGen - { - public: - virtual int GetIfaceVersion() = 0; - virtual int GetImplVersion() = 0; - - virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0; - virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0; - }; - - // For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET: - // These have to be able to return references. If T is a reference, the pointers returned - // from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier::type. - template struct MacroRefHelpers - { - inline static const T* GetOrigRet(ISourceHook *shptr) - { - return reinterpret_cast(shptr->GetOrigRet()); - } - inline static const T* GetOverrideRet(ISourceHook *shptr) - { - return reinterpret_cast(shptr->GetOverrideRet()); - } - }; - - template struct MacroRefHelpers - { - inline static T* GetOrigRet(ISourceHook *shptr) - { - T &ref = *reinterpret_cast::type *>(shptr->GetOrigRet()); - return &ref; - } - inline static T* GetOverrideRet(ISourceHook *shptr) - { - T &ref = *reinterpret_cast::type *>(shptr->GetOverrideRet()); - return &ref; - } - }; - - template - void *GetOrigVfnPtrEntry(X *pInstance, MFP mfp, ISourceHook *pSH) - { - SourceHook::MemFuncInfo info = {true, -1, 0, 0}; - SourceHook::GetFuncInfo(pInstance, mfp, info); - - void *vfnptr = reinterpret_cast( - *reinterpret_cast(reinterpret_cast(pInstance) + info.thisptroffs + info.vtbloffs) + info.vtblindex); - - void *origentry = pSH->GetOrigVfnPtrEntry(vfnptr); - - return origentry ? origentry : *reinterpret_cast(vfnptr); - } - - template struct GetPassInfo - { - static const int type = 0; - static const unsigned int flags = PassInfo::PassFlag_ByVal; - }; - - template struct GetPassInfo - { - static const int type = 0; - static const unsigned int flags = PassInfo::PassFlag_ByRef; - }; -} - -/************************************************************************/ -/* High level interface */ -/************************************************************************/ -#define META_RESULT_STATUS SH_GLOB_SHPTR->GetStatus() -#define META_RESULT_PREVIOUS SH_GLOB_SHPTR->GetPrevRes() -#define META_RESULT_ORIG_RET(type) *SourceHook::MacroRefHelpers::GetOrigRet(SH_GLOB_SHPTR) -#define META_RESULT_OVERRIDE_RET(type) *SourceHook::MacroRefHelpers::GetOverrideRet(SH_GLOB_SHPTR) -#define META_IFACEPTR(type) reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()) - -#define SET_META_RESULT(result) SH_GLOB_SHPTR->SetRes(result) -#define RETURN_META(result) do { SET_META_RESULT(result); return; } while(0) -#define RETURN_META_VALUE(result, value) do { SET_META_RESULT(result); return (value); } while(0) - - -template -SourceHook::CallClass *SH_GET_CALLCLASS(T *p) -{ - return static_cast< SourceHook::CallClass *>(p); -} -#define SH_RELEASE_CALLCLASS(p) - -#define SH_GET_MCALLCLASS(p, size) reinterpret_cast(p) - -// only call these from the hook handlers directly! - -// If a hook on a function which returns a reference does not want to specify a return value, -// it can use this macro. -// ONLY USE THIS WITH MRES_IGNORED AND MRES_HANDLED !!! -#define RETURN_META_NOREF(result, rettype) do { SET_META_RESULT(result); return reinterpret_cast(*SH_GLOB_SHPTR); } while(0) - -// Why take a memfuncptr instead of iface and func when we have to deduce the iface anyway now? -// Well, without it, there'd be no way to specify which overloaded version we want in _VALUE - -// SourceHook::SetOverrideRet is defined later. -#define RETURN_META_NEWPARAMS(result, memfuncptr, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - (SourceHook::RecallGetIface(SH_GLOB_SHPTR, memfuncptr)->*(memfuncptr)) newparams; \ - RETURN_META(MRES_SUPERCEDE); \ - } while (0) - -#define RETURN_META_VALUE_NEWPARAMS(result, value, memfuncptr, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - if ((result) >= MRES_OVERRIDE) \ - { \ - /* meh, set the override result here because we don't get a chance to return */ \ - /* before continuing the hook loop through the recall */ \ - SourceHook::SetOverrideResult(memfuncptr)(SH_GLOB_SHPTR, value); \ - } \ - RETURN_META_VALUE(MRES_SUPERCEDE, \ - (SourceHook::RecallGetIface(SH_GLOB_SHPTR, memfuncptr)->*(memfuncptr)) newparams); \ - } while (0) - -// :TODO: thisptroffs in MNEWPARAMS ?? - -#if SH_COMP == SH_COMP_MSVC - -#define SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname) \ - union \ - { \ - SH_MFHCls(hookname)::ECMFP mfp; \ - void *addr; \ - } u; \ - SourceHook::EmptyClass *thisptr = reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()); \ - u.addr = (*reinterpret_cast(reinterpret_cast(thisptr) + SH_MFHCls(hookname)::ms_MFI.vtbloffs))[ \ - SH_MFHCls(hookname)::ms_MFI.vtblindex]; - -#elif SH_COMP == SH_COMP_GCC - -#define SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname) \ - union \ - { \ - SH_MFHCls(hookname)::ECMFP mfp; \ - struct \ - { \ - void *addr; \ - intptr_t adjustor; \ - } s; \ - } u; \ - SourceHook::EmptyClass *thisptr = reinterpret_cast(SH_GLOB_SHPTR->GetIfacePtr()); \ - u.s.addr = (*reinterpret_cast(reinterpret_cast(thisptr) + SH_MFHCls(hookname)::ms_MFI.vtbloffs))[ \ - SH_MFHCls(hookname)::ms_MFI.vtblindex]; \ - u.s.adjustor = 0; - -#endif - -#define RETURN_META_MNEWPARAMS(result, hookname, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname); \ - (thisptr->*(u.mfp)) newparams; \ - RETURN_META(MRES_SUPERCEDE); \ - } while (0) - -#define RETURN_META_VALUE_MNEWPARAMS(result, value, hookname, newparams) \ - do { \ - SET_META_RESULT(result); \ - SH_GLOB_SHPTR->DoRecall(); \ - if ((result) >= MRES_OVERRIDE) \ - { \ - /* see RETURN_META_VALUE_NEWPARAMS */ \ - SourceHook::SetOverrideResult(SH_GLOB_SHPTR, value); \ - } \ - SOUREHOOK__MNEWPARAMS_PREPAREMFP(hookname); \ - RETURN_META_VALUE(MRES_SUPERCEDE, (thisptr->*(u.mfp)) newparams); \ - } while (0) - - -#define SH_MANUALHOOK_RECONFIGURE(hookname, pvtblindex, pvtbloffs, pthisptroffs) \ - do { \ - SH_GLOB_SHPTR->RemoveHookManager(SH_GLOB_PLUGPTR, SH_MFHCls(hookname)::HookManPubFunc); \ - SH_MFHCls(hookname)::ms_MFI.thisptroffs = pthisptroffs; \ - SH_MFHCls(hookname)::ms_MFI.vtblindex = pvtblindex; \ - SH_MFHCls(hookname)::ms_MFI.vtbloffs = pvtbloffs; \ - } while (0) - -#define SH_GET_ORIG_VFNPTR_ENTRY(inst, mfp) (SourceHook::GetOrigVfnPtrEntry(inst, mfp, SH_GLOB_SHPTR)) - -// New ADD / REMOVE macros. -#define SH_STATIC(func) fastdelegate::MakeDelegate(func) -#define SH_MEMBER(inst, func) fastdelegate::MakeDelegate(inst, func) - -#define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_Normal, post, handler) - -#define SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHRemove##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - post, handler) - -#define SH_ADD_MANUALHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_Normal, post, handler) - -#define SH_REMOVE_MANUALHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMRemove##hookname(reinterpret_cast(ifaceptr), post, handler) - -#define SH_ADD_VPHOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_VP, post, handler) - -#define SH_ADD_DVPHOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ - __SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast(ifaceptr), \ - SourceHook::ISourceHook::Hook_DVP, post, handler) - -#define SH_ADD_MANUALVPHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), SourceHook::ISourceHook::Hook_VP, post, handler) - -#define SH_ADD_MANUALDVPHOOK(hookname, ifaceptr, handler, post) \ - __SourceHook_FHMAdd##hookname(reinterpret_cast(ifaceptr), SourceHook::ISourceHook::Hook_DVP, post, handler) - -#define SH_REMOVE_HOOK_ID(hookid) \ - (SH_GLOB_SHPTR->RemoveHookByID(hookid)) - -// Old macros -// !! These are now deprecated. Instead, use one of these: -// SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -// SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_ADD_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \ - SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -#define SH_ADD_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \ - SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -// SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_REMOVE_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \ - SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_STATIC(handler), post) -#define SH_REMOVE_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \ - SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -// SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_ADD_MANUALHOOK_STATICFUNC(hookname, ifaceptr, handler, post) \ - SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -#define SH_ADD_MANUALHOOK_MEMFUNC(hookname, ifaceptr, handler_inst, handler_func, post) \ - SH_ADD_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -// SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -// SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(inst, func), post) - -#define SH_REMOVE_MANUALHOOK_STATICFUNC(hookname, ifaceptr, handler, post) \ - SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_STATIC(handler), post) -#define SH_REMOVE_MANUALHOOK_MEMFUNC(hookname, ifaceptr, handler_inst, handler_func, post) \ - SH_REMOVE_MANUALHOOK(hookname, ifaceptr, SH_MEMBER(handler_inst, handler_func), post) - -#define SH_NOATTRIB - - - - -#if SH_COMP == SH_COMP_MSVC -# define SH_SETUP_MFP(mfp) \ - reinterpret_cast(&mfp)[0] = vfnptr_origentry; -#elif SH_COMP == SH_COMP_GCC -# define SH_SETUP_MFP(mfp) \ - reinterpret_cast(&mfp)[0] = vfnptr_origentry; \ - reinterpret_cast(&mfp)[1] = 0; -#else -# error Not supported yet. -#endif - -////////////////////////////////////////////////////////////////////////// -#define SH_FHCls(ift, iff, ov) __SourceHook_FHCls_##ift##iff##ov -#define SH_MFHCls(hookname) __SourceHook_MFHCls_##hookname - -#define SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) \ - static int HookManPubFunc(bool store, ::SourceHook::IHookManagerInfo *hi) \ - { \ - using namespace ::SourceHook; \ - GetFuncInfo(funcptr, ms_MFI); \ - /* Verify interface version */ \ - if (SH_GLOB_SHPTR->GetIfaceVersion() != SH_IFACE_VERSION) \ - return 1; \ - if (SH_GLOB_SHPTR->GetImplVersion() < SH_IMPL_VERSION) \ - return 1; \ - if (store) \ - ms_HI = hi; \ - if (hi) \ - { \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(&SH_FHCls(ifacetype,ifacefunc,overload)::Func, mfi); \ - hi->SetInfo(SH_HOOKMAN_VERSION, ms_MFI.vtbloffs, ms_MFI.vtblindex, &ms_Proto, \ - reinterpret_cast(reinterpret_cast(&ms_Inst) + mfi.vtbloffs)[mfi.vtblindex] ); \ - } \ - return 0; \ - } - -// It has to be possible to use the macros in namespaces -// -> So we need to access and extend the global SourceHook namespace -// We use a namespace alias for this -#define SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, funcptr) \ - struct SH_FHCls(ifacetype,ifacefunc,overload) \ - { \ - static SH_FHCls(ifacetype,ifacefunc,overload) ms_Inst; \ - static ::SourceHook::MemFuncInfo ms_MFI; \ - static ::SourceHook::IHookManagerInfo *ms_HI; \ - static ::SourceHook::ProtoInfo ms_Proto; \ - SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) - -#define SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, funcptr) \ - }; \ - SH_FHCls(ifacetype,ifacefunc,overload) SH_FHCls(ifacetype,ifacefunc,overload)::ms_Inst; \ - ::SourceHook::MemFuncInfo SH_FHCls(ifacetype,ifacefunc,overload)::ms_MFI; \ - ::SourceHook::IHookManagerInfo *SH_FHCls(ifacetype,ifacefunc,overload)::ms_HI; \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ - { \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(funcptr, mfi); \ - if (mfi.thisptroffs < 0 || !mfi.isVirtual) \ - return false; /* No non-virtual functions / virtual inheritance supported */ \ - \ - return SH_GLOB_SHPTR->AddHook(SH_GLOB_PLUGPTR, mode, \ - iface, mfi.thisptroffs, SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, \ - new SH_FHCls(ifacetype,ifacefunc,overload)::CMyDelegateImpl(handler), post); \ - } \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ - { \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(funcptr, mfi); \ - SH_FHCls(ifacetype,ifacefunc,overload)::CMyDelegateImpl tmp(handler); \ - return SH_GLOB_SHPTR->RemoveHook(SH_GLOB_PLUGPTR, iface, mfi.thisptroffs, \ - SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, &tmp, post); \ - } \ - -#define SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, pvtbloffs, pvtblidx, pthisptroffs) \ - struct SH_MFHCls(hookname) \ - { \ - static SH_MFHCls(hookname) ms_Inst; \ - static ::SourceHook::MemFuncInfo ms_MFI; \ - static ::SourceHook::IHookManagerInfo *ms_HI; \ - static ::SourceHook::ProtoInfo ms_Proto; \ - \ - SH_MFHCls(hookname)() \ - { \ - ms_MFI.isVirtual = true; \ - ms_MFI.thisptroffs = pthisptroffs; \ - ms_MFI.vtblindex = pvtblidx; \ - ms_MFI.vtbloffs = pvtbloffs; \ - } \ - static int HookManPubFunc(bool store, ::SourceHook::IHookManagerInfo *hi) \ - { \ - using namespace ::SourceHook; \ - /* Verify interface version */ \ - if (SH_GLOB_SHPTR->GetIfaceVersion() != SH_IFACE_VERSION) \ - return 1; \ - if (SH_GLOB_SHPTR->GetImplVersion() < SH_IMPL_VERSION) \ - return 1; \ - if (store) \ - ms_HI = hi; \ - if (hi) \ - { \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(&SH_MFHCls(hookname)::Func, mfi); \ - hi->SetInfo(SH_HOOKMAN_VERSION, ms_MFI.vtbloffs, ms_MFI.vtblindex, &ms_Proto, \ - reinterpret_cast(reinterpret_cast(&ms_Inst) + mfi.vtbloffs)[mfi.vtblindex] ); \ - } \ - return 0; \ - } - -#define SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, pvtbloffs, pvtblidx, pthisptroffs) \ - }; \ - SH_MFHCls(hookname) SH_MFHCls(hookname)::ms_Inst; \ - ::SourceHook::MemFuncInfo SH_MFHCls(hookname)::ms_MFI; \ - ::SourceHook::IHookManagerInfo *SH_MFHCls(hookname)::ms_HI; \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - SH_MFHCls(hookname)::FD handler) \ - { \ - return SH_GLOB_SHPTR->AddHook(SH_GLOB_PLUGPTR, mode, \ - iface, pthisptroffs, SH_MFHCls(hookname)::HookManPubFunc, \ - new SH_MFHCls(hookname)::CMyDelegateImpl(handler), post); \ - } \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - SH_MFHCls(hookname)::FD handler) \ - { \ - SH_MFHCls(hookname)::CMyDelegateImpl tmp(handler); \ - return SH_GLOB_SHPTR->RemoveHook(SH_GLOB_PLUGPTR, iface, pthisptroffs, \ - SH_MFHCls(hookname)::HookManPubFunc, &tmp, post); \ - } \ - -#define SH_SETUPCALLS(rettype, paramtypes, params) \ - /* 1) Set up */ \ - using namespace ::SourceHook; \ - void *ourvfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(this) + ms_MFI.vtbloffs) + ms_MFI.vtblindex); \ - void *vfnptr_origentry; \ - \ - META_RES status = MRES_IGNORED; \ - META_RES prev_res; \ - META_RES cur_res; \ - \ - typedef ReferenceCarrier< rettype >::type my_rettype; \ - my_rettype orig_ret; \ - my_rettype override_ret; \ - my_rettype plugin_ret; \ - IMyDelegate *iter; \ - IHookContext *pContext = SH_GLOB_SHPTR->SetupHookLoop(ms_HI, ourvfnptr, reinterpret_cast(this), \ - &vfnptr_origentry, &status, &prev_res, &cur_res, &orig_ret, &override_ret); - -#define SH_CALL_HOOKS(post, params) \ - prev_res = MRES_IGNORED; \ - while ( (iter = static_cast(pContext->GetNext())) ) \ - { \ - cur_res = MRES_IGNORED; \ - plugin_ret = iter->Call params; \ - prev_res = cur_res; \ - if (cur_res > status) \ - status = cur_res; \ - if (cur_res >= MRES_OVERRIDE) \ - *reinterpret_cast(pContext->GetOverrideRetPtr()) = plugin_ret; \ - } - -#define SH_CALL_ORIG(rettype, paramtypes, params) \ - if (status != MRES_SUPERCEDE && pContext->ShouldCallOrig()) \ - { \ - rettype (EmptyClass::*mfp)paramtypes; \ - SH_SETUP_MFP(mfp); \ - orig_ret = (reinterpret_cast(this)->*mfp)params; \ - } \ - else \ - orig_ret = override_ret; /* :TODO: ??? : use pContext->GetOverrideRetPtr() or not? */ - -#define SH_RETURN() \ - const my_rettype *retptr = reinterpret_cast( \ - (status >= MRES_OVERRIDE) ? pContext->GetOverrideRetPtr() : pContext->GetOrigRetPtr()); \ - SH_GLOB_SHPTR->EndContext(pContext); \ - return *retptr; - -#define SH_HANDLEFUNC(paramtypes, params, rettype) \ - SH_SETUPCALLS(rettype, paramtypes, params) \ - SH_CALL_HOOKS(pre, params) \ - SH_CALL_ORIG(rettype, paramtypes, params) \ - SH_CALL_HOOKS(post, params) \ - SH_RETURN() - -////////////////////////////////////////////////////////////////////////// -#define SH_SETUPCALLS_void(paramtypes, params) \ - /* 1) Set up */ \ - using namespace ::SourceHook; \ - void *ourvfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(this) + ms_MFI.vtbloffs) + ms_MFI.vtblindex); \ - void *vfnptr_origentry; \ - \ - META_RES status = MRES_IGNORED; \ - META_RES prev_res; \ - META_RES cur_res; \ - \ - IMyDelegate *iter; \ - IHookContext *pContext = SH_GLOB_SHPTR->SetupHookLoop(ms_HI, ourvfnptr, reinterpret_cast(this), \ - &vfnptr_origentry, &status, &prev_res, &cur_res, NULL, NULL); - -#define SH_CALL_HOOKS_void(post, params) \ - prev_res = MRES_IGNORED; \ - while ( (iter = static_cast(pContext->GetNext())) ) \ - { \ - cur_res = MRES_IGNORED; \ - iter->Call params; \ - prev_res = cur_res; \ - if (cur_res > status) \ - status = cur_res; \ - } - -#define SH_CALL_ORIG_void(paramtypes, params) \ - if (status != MRES_SUPERCEDE && pContext->ShouldCallOrig()) \ - { \ - void (EmptyClass::*mfp)paramtypes; \ - SH_SETUP_MFP(mfp); \ - (reinterpret_cast(this)->*mfp)params; \ - } - -#define SH_RETURN_void() \ - SH_GLOB_SHPTR->EndContext(pContext); - -#define SH_HANDLEFUNC_void(paramtypes, params) \ - SH_SETUPCALLS_void(paramtypes, params) \ - SH_CALL_HOOKS_void(pre, params) \ - SH_CALL_ORIG_void(paramtypes, params) \ - SH_CALL_HOOKS_void(post, params) \ - SH_RETURN_void() - - -// Special vafmt handlers -// :TODO: what -#define SH_HANDLEFUNC_vafmt(paramtypes, params_orig, params_plug, rettype) \ - SH_SETUPCALLS(rettype, paramtypes, params_orig) \ - SH_CALL_HOOKS(pre, params_plug) \ - SH_CALL_ORIG(rettype, paramtypes, params_orig) \ - SH_CALL_HOOKS(post, params_plug) \ - SH_RETURN() - -#define SH_HANDLEFUNC_void_vafmt(paramtypes, params_orig, params_plug) \ - SH_SETUPCALLS_void(paramtypes, params_orig) \ - SH_CALL_HOOKS_void(pre, params_plug) \ - SH_CALL_ORIG_void(paramtypes, params_orig) \ - SH_CALL_HOOKS_void(post, params_plug) \ - SH_RETURN_void() - -////////////////////////////////////////////////////////////////////////// - -#define MAKE_DELEG(ret_type, params_decl, params_pass) \ - struct IMyDelegate : ::SourceHook::ISHDelegate { virtual ret_type Call params_decl = 0; }; \ - struct CMyDelegateImpl : IMyDelegate \ - { \ - FD m_Deleg; \ - CMyDelegateImpl(FD deleg) : m_Deleg(deleg) {} \ - ret_type Call params_decl { return m_Deleg params_pass; } \ - void DeleteThis() { delete this; } \ - bool IsEqual(ISHDelegate *pOtherDeleg) { return m_Deleg == static_cast(pOtherDeleg)->m_Deleg; } \ - }; - -#define MAKE_DELEG_void(params_decl, params_pass) \ - struct IMyDelegate : ::SourceHook::ISHDelegate { virtual void Call params_decl = 0; }; \ - struct CMyDelegateImpl : IMyDelegate \ - { \ - FD m_Deleg; \ - CMyDelegateImpl(FD deleg) : m_Deleg(deleg) {} \ - void Call params_decl { m_Deleg params_pass; } \ - void DeleteThis() { delete this; } \ - bool IsEqual(ISHDelegate *pOtherDeleg) { return m_Deleg == static_cast(pOtherDeleg)->m_Deleg; } \ - }; - -// GetPassInfo -> easier access. __SH_GPI generates a SourceHook::PassInfo instance. -#define __SH_GPI(tt) { sizeof(tt), ::SourceHook::GetPassInfo< tt >::type, ::SourceHook::GetPassInfo< tt >::flags } -// Extra pass info V2 -#define __SH_EPI { 0, 0, 0, 0 } - - -// ********* Support for 0 arguments ********* -#define SH_DECL_HOOK0(ifacetype, ifacefunc, attr, overload, rettype) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate0 FD; \ - MAKE_DELEG(rettype, (), ()); \ - virtual rettype Func() \ - { SH_HANDLEFUNC((), (), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 0, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN0(ifacetype, ifacefunc, attr, overload, rettype) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate0 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate0 handler); - -#define SH_DECL_HOOK0_void(ifacetype, ifacefunc, attr, overload) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate0<> FD; \ - MAKE_DELEG_void((), ()); \ - virtual void Func() \ - { SH_HANDLEFUNC_void((), ()); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 0, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN0_void(ifacetype, ifacefunc, attr, overload) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate0<> handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate0<> handler); - -#define SH_DECL_HOOK0_vafmt(ifacetype, ifacefunc, attr, overload, rettype) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG(rettype, (const char *px), (px)); \ - virtual rettype Func( const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((...), ("%s", buf), (buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 0, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN0_vafmt(ifacetype, ifacefunc, attr, overload, rettype) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_HOOK0_void_vafmt(ifacetype, ifacefunc, attr, overload) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG_void((const char *px), (px)); \ - virtual void Func(const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((...), ("%s", buf), (buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 0, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN0_void_vafmt(ifacetype, ifacefunc, attr, overload) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_MANUALHOOK0(hookname, vtblidx, vtbloffs, thisptroffs, rettype) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate0 FD; \ - MAKE_DELEG(rettype, (), ()); \ - virtual rettype Func() \ - { SH_HANDLEFUNC((), (), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 0, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN0(hookname, rettype) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate0 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate0 handler); - -#define SH_DECL_MANUALHOOK0_void(hookname, vtblidx, vtbloffs, thisptroffs) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate0<> FD; \ - MAKE_DELEG_void((), ()); \ - virtual void Func() \ - { SH_HANDLEFUNC_void((), ()); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0} }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 0, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN0_void(hookname) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate0<> handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate0<> handler); - -// ********* Support for 1 arguments ********* -#define SH_DECL_HOOK1(ifacetype, ifacefunc, attr, overload, rettype, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG(rettype, (param1 p1), (p1)); \ - virtual rettype Func(param1 p1) \ - { SH_HANDLEFUNC((param1), (p1), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 1, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN1(ifacetype, ifacefunc, attr, overload, rettype, param1) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_HOOK1_void(ifacetype, ifacefunc, attr, overload, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG_void((param1 p1), (p1)); \ - virtual void Func(param1 p1) \ - { SH_HANDLEFUNC_void((param1), (p1)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 1, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN1_void(ifacetype, ifacefunc, attr, overload, param1) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_HOOK1_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG(rettype, (param1 p1, const char *px), (p1, px)); \ - virtual rettype Func(param1 p1 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, ...), (p1, "%s", buf), (p1, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 1, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN1_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_HOOK1_void_vafmt(ifacetype, ifacefunc, attr, overload, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG_void((param1 p1, const char *px), (p1, px)); \ - virtual void Func(param1 p1, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, ...), (p1, "%s", buf), (p1, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 1, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN1_void_vafmt(ifacetype, ifacefunc, attr, overload, param1) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_MANUALHOOK1(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG(rettype, (param1 p1), (p1)); \ - virtual rettype Func(param1 p1) \ - { SH_HANDLEFUNC((param1), (p1), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 1, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN1(hookname, rettype, param1) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -#define SH_DECL_MANUALHOOK1_void(hookname, vtblidx, vtbloffs, thisptroffs, param1) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate1 FD; \ - MAKE_DELEG_void((param1 p1), (p1)); \ - virtual void Func(param1 p1) \ - { SH_HANDLEFUNC_void((param1), (p1)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 1, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN1_void(hookname, param1) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate1 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate1 handler); - -// ********* Support for 2 arguments ********* -#define SH_DECL_HOOK2(ifacetype, ifacefunc, attr, overload, rettype, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2), (p1, p2)); \ - virtual rettype Func(param1 p1, param2 p2) \ - { SH_HANDLEFUNC((param1, param2), (p1, p2), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 2, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN2(ifacetype, ifacefunc, attr, overload, rettype, param1, param2) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_HOOK2_void(ifacetype, ifacefunc, attr, overload, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2), (p1, p2)); \ - virtual void Func(param1 p1, param2 p2) \ - { SH_HANDLEFUNC_void((param1, param2), (p1, p2)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 2, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN2_void(ifacetype, ifacefunc, attr, overload, param1, param2) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_HOOK2_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, const char *px), (p1, p2, px)); \ - virtual rettype Func(param1 p1, param2 p2 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, ...), (p1, p2, "%s", buf), (p1, p2, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 2, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN2_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_HOOK2_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, const char *px), (p1, p2, px)); \ - virtual void Func(param1 p1, param2 p2, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, ...), (p1, p2, "%s", buf), (p1, p2, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 2, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN2_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_MANUALHOOK2(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2), (p1, p2)); \ - virtual rettype Func(param1 p1, param2 p2) \ - { SH_HANDLEFUNC((param1, param2), (p1, p2), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 2, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN2(hookname, rettype, param1, param2) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -#define SH_DECL_MANUALHOOK2_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate2 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2), (p1, p2)); \ - virtual void Func(param1 p1, param2 p2) \ - { SH_HANDLEFUNC_void((param1, param2), (p1, p2)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 2, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN2_void(hookname, param1, param2) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate2 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate2 handler); - -// ********* Support for 3 arguments ********* -#define SH_DECL_HOOK3(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3), (p1, p2, p3)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3) \ - { SH_HANDLEFUNC((param1, param2, param3), (p1, p2, p3), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 3, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN3(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_HOOK3_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3), (p1, p2, p3)); \ - virtual void Func(param1 p1, param2 p2, param3 p3) \ - { SH_HANDLEFUNC_void((param1, param2, param3), (p1, p2, p3)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 3, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN3_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_HOOK3_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, const char *px), (p1, p2, p3, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, ...), (p1, p2, p3, "%s", buf), (p1, p2, p3, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 3, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN3_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_HOOK3_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, const char *px), (p1, p2, p3, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, ...), (p1, p2, p3, "%s", buf), (p1, p2, p3, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 3, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN3_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_MANUALHOOK3(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3), (p1, p2, p3)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3) \ - { SH_HANDLEFUNC((param1, param2, param3), (p1, p2, p3), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 3, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN3(hookname, rettype, param1, param2, param3) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -#define SH_DECL_MANUALHOOK3_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate3 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3), (p1, p2, p3)); \ - virtual void Func(param1 p1, param2 p2, param3 p3) \ - { SH_HANDLEFUNC_void((param1, param2, param3), (p1, p2, p3)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 3, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN3_void(hookname, param1, param2, param3) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate3 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate3 handler); - -// ********* Support for 4 arguments ********* -#define SH_DECL_HOOK4(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4), (p1, p2, p3, p4)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { SH_HANDLEFUNC((param1, param2, param3, param4), (p1, p2, p3, p4), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 4, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN4(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_HOOK4_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4), (p1, p2, p3, p4)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4), (p1, p2, p3, p4)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 4, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN4_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_HOOK4_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, const char *px), (p1, p2, p3, p4, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, ...), (p1, p2, p3, p4, "%s", buf), (p1, p2, p3, p4, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 4, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN4_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_HOOK4_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, const char *px), (p1, p2, p3, p4, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, ...), (p1, p2, p3, p4, "%s", buf), (p1, p2, p3, p4, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 4, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN4_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_MANUALHOOK4(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4), (p1, p2, p3, p4)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { SH_HANDLEFUNC((param1, param2, param3, param4), (p1, p2, p3, p4), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 4, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN4(hookname, rettype, param1, param2, param3, param4) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -#define SH_DECL_MANUALHOOK4_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate4 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4), (p1, p2, p3, p4)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4), (p1, p2, p3, p4)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 4, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN4_void(hookname, param1, param2, param3, param4) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate4 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate4 handler); - -// ********* Support for 5 arguments ********* -#define SH_DECL_HOOK5(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5), (p1, p2, p3, p4, p5)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5), (p1, p2, p3, p4, p5), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 5, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN5(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_HOOK5_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5), (p1, p2, p3, p4, p5)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5), (p1, p2, p3, p4, p5)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 5, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN5_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_HOOK5_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *px), (p1, p2, p3, p4, p5, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, ...), (p1, p2, p3, p4, p5, "%s", buf), (p1, p2, p3, p4, p5, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 5, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN5_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_HOOK5_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *px), (p1, p2, p3, p4, p5, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, ...), (p1, p2, p3, p4, p5, "%s", buf), (p1, p2, p3, p4, p5, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 5, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN5_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_MANUALHOOK5(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5), (p1, p2, p3, p4, p5)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5), (p1, p2, p3, p4, p5), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 5, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN5(hookname, rettype, param1, param2, param3, param4, param5) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -#define SH_DECL_MANUALHOOK5_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate5 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5), (p1, p2, p3, p4, p5)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5), (p1, p2, p3, p4, p5)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 5, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN5_void(hookname, param1, param2, param3, param4, param5) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate5 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate5 handler); - -// ********* Support for 6 arguments ********* -#define SH_DECL_HOOK6(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6), (p1, p2, p3, p4, p5, p6)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6), (p1, p2, p3, p4, p5, p6), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 6, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN6(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_HOOK6_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6), (p1, p2, p3, p4, p5, p6)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6), (p1, p2, p3, p4, p5, p6)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 6, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN6_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_HOOK6_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *px), (p1, p2, p3, p4, p5, p6, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, ...), (p1, p2, p3, p4, p5, p6, "%s", buf), (p1, p2, p3, p4, p5, p6, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 6, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN6_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_HOOK6_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *px), (p1, p2, p3, p4, p5, p6, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, ...), (p1, p2, p3, p4, p5, p6, "%s", buf), (p1, p2, p3, p4, p5, p6, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 6, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN6_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_MANUALHOOK6(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6), (p1, p2, p3, p4, p5, p6)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6), (p1, p2, p3, p4, p5, p6), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 6, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN6(hookname, rettype, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -#define SH_DECL_MANUALHOOK6_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate6 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6), (p1, p2, p3, p4, p5, p6)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6), (p1, p2, p3, p4, p5, p6)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 6, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN6_void(hookname, param1, param2, param3, param4, param5, param6) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate6 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate6 handler); - -// ********* Support for 7 arguments ********* -#define SH_DECL_HOOK7(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7), (p1, p2, p3, p4, p5, p6, p7)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7), (p1, p2, p3, p4, p5, p6, p7), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 7, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN7(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_HOOK7_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7), (p1, p2, p3, p4, p5, p6, p7)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7), (p1, p2, p3, p4, p5, p6, p7)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 7, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN7_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_HOOK7_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, const char *px), (p1, p2, p3, p4, p5, p6, p7, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, ...), (p1, p2, p3, p4, p5, p6, p7, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 7, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN7_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_HOOK7_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, const char *px), (p1, p2, p3, p4, p5, p6, p7, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, ...), (p1, p2, p3, p4, p5, p6, p7, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 7, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN7_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_MANUALHOOK7(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7), (p1, p2, p3, p4, p5, p6, p7)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7), (p1, p2, p3, p4, p5, p6, p7), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 7, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN7(hookname, rettype, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -#define SH_DECL_MANUALHOOK7_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate7 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7), (p1, p2, p3, p4, p5, p6, p7)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7), (p1, p2, p3, p4, p5, p6, p7)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 7, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN7_void(hookname, param1, param2, param3, param4, param5, param6, param7) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate7 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate7 handler); - -// ********* Support for 8 arguments ********* -#define SH_DECL_HOOK8(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8), (p1, p2, p3, p4, p5, p6, p7, p8)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8), (p1, p2, p3, p4, p5, p6, p7, p8), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 8, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN8(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_HOOK8_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8), (p1, p2, p3, p4, p5, p6, p7, p8)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8), (p1, p2, p3, p4, p5, p6, p7, p8)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 8, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN8_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_HOOK8_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, ...), (p1, p2, p3, p4, p5, p6, p7, p8, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 8, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN8_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_HOOK8_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, ...), (p1, p2, p3, p4, p5, p6, p7, p8, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 8, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN8_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_MANUALHOOK8(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8), (p1, p2, p3, p4, p5, p6, p7, p8)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8), (p1, p2, p3, p4, p5, p6, p7, p8), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 8, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN8(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -#define SH_DECL_MANUALHOOK8_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate8 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8), (p1, p2, p3, p4, p5, p6, p7, p8)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8), (p1, p2, p3, p4, p5, p6, p7, p8)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 8, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN8_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate8 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate8 handler); - -// ********* Support for 9 arguments ********* -#define SH_DECL_HOOK9(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9), (p1, p2, p3, p4, p5, p6, p7, p8, p9), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 9, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN9(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_HOOK9_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 9, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN9_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_HOOK9_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 9, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN9_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_HOOK9_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 9, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN9_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_MANUALHOOK9(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9), (p1, p2, p3, p4, p5, p6, p7, p8, p9), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 9, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN9(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -#define SH_DECL_MANUALHOOK9_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate9 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9), (p1, p2, p3, p4, p5, p6, p7, p8, p9)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 9, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN9_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate9 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate9 handler); - -// ********* Support for 10 arguments ********* -#define SH_DECL_HOOK10(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 10, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN10(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_HOOK10_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 10, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN10_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_HOOK10_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 10, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN10_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_HOOK10_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 10, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN10_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_MANUALHOOK10(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 10, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN10(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -#define SH_DECL_MANUALHOOK10_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate10 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 10, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN10_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate10 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate10 handler); - -// ********* Support for 11 arguments ********* -#define SH_DECL_HOOK11(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 11, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN11(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_HOOK11_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 11, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN11_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_HOOK11_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 11, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN11_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_HOOK11_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 11, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN11_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_MANUALHOOK11(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 11, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN11(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -#define SH_DECL_MANUALHOOK11_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate11 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 11, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN11_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate11 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate11 handler); - -// ********* Support for 12 arguments ********* -#define SH_DECL_HOOK12(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 12, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN12(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_HOOK12_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 12, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN12_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_HOOK12_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 12, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN12_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_HOOK12_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 12, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN12_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_MANUALHOOK12(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 12, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN12(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -#define SH_DECL_MANUALHOOK12_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate12 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 12, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN12_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate12 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate12 handler); - -// ********* Support for 13 arguments ********* -#define SH_DECL_HOOK13(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 13, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN13(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_HOOK13_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12),__SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 13, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN13_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_HOOK13_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 13, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN13_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_HOOK13_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 13, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN13_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_MANUALHOOK13(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 13, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN13(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -#define SH_DECL_MANUALHOOK13_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate13 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 13, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN13_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate13 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate13 handler); - -// ********* Support for 14 arguments ********* -#define SH_DECL_HOOK14(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 14, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN14(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_HOOK14_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12),__SH_GPI(param13),__SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 14, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN14_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_HOOK14_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 14, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN14_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_HOOK14_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 14, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN14_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_MANUALHOOK14(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 14, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN14(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -#define SH_DECL_MANUALHOOK14_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate14 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 14, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN14_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate14 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate14 handler); - -// ********* Support for 15 arguments ********* -#define SH_DECL_HOOK15(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 15, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN15(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_HOOK15_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12),__SH_GPI(param13),__SH_GPI(param14),__SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 15, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN15_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_HOOK15_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 15, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN15_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_HOOK15_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 15, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN15_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_MANUALHOOK15(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 15, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN15(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -#define SH_DECL_MANUALHOOK15_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate15 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 15, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN15_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate15 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate15 handler); - -// ********* Support for 16 arguments ********* -#define SH_DECL_HOOK16(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), rettype); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 16, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN16(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_HOOK16_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0},__SH_GPI(param1),__SH_GPI(param2),__SH_GPI(param3),__SH_GPI(param4),__SH_GPI(param5),__SH_GPI(param6),__SH_GPI(param7),__SH_GPI(param8),__SH_GPI(param9),__SH_GPI(param10),__SH_GPI(param11),__SH_GPI(param12),__SH_GPI(param13),__SH_GPI(param14),__SH_GPI(param15),__SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 16, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN16_void(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_HOOK16_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate17 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, px)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16 , const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, buf), rettype); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 16, __SH_GPI(rettype), \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN16_vafmt(ifacetype, ifacefunc, attr, overload, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate17 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate17 handler); - -#define SH_DECL_HOOK16_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN(ifacetype, ifacefunc, overload, (static_cast \ - (&ifacetype::ifacefunc))) \ - typedef fastdelegate::FastDelegate17 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16, const char *px), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, px)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16, const char *fmt, ...) \ - { \ - char buf[::SourceHook::STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, sizeof(buf), fmt, ap); \ - va_end(ap); \ - SH_HANDLEFUNC_void_vafmt((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, ...), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, "%s", buf), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, buf)); \ - } \ - SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, \ - (static_cast(&ifacetype::ifacefunc))) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_FHCls(ifacetype, ifacefunc, overload)::ms_Proto = { 16, { 0, 0, 0 }, \ - __SourceHook_ParamInfos_##ifacetype##ifacefunc##overload, 0, __SH_EPI, __SourceHook_ParamInfos2_##ifacetype##ifacefunc##overload }; - -#define SH_DECL_EXTERN16_void_vafmt(ifacetype, ifacefunc, attr, overload, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHAdd##ifacetype##ifacefunc(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate17 handler); \ - bool __SourceHook_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ - fastdelegate::FastDelegate17 handler); - -#define SH_DECL_MANUALHOOK16(hookname, vtblidx, vtbloffs, thisptroffs, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG(rettype, (param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); \ - virtual rettype Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16) \ - { SH_HANDLEFUNC((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), rettype); } \ - typedef rettype(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16); \ - typedef rettype RetType; \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 16, __SH_GPI(rettype), \ - __SourceHook_ParamInfosM_##hookname, 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN16(hookname, rettype, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - -#define SH_DECL_MANUALHOOK16_void(hookname, vtblidx, vtbloffs, thisptroffs, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - SHINT_MAKE_GENERICSTUFF_BEGIN_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - typedef fastdelegate::FastDelegate16 FD; \ - MAKE_DELEG_void((param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7, param8 p8, param9 p9, param10 p10, param11 p11, param12 p12, param13 p13, param14 p14, param15 p15, param16 p16) \ - { SH_HANDLEFUNC_void((param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)); } \ - typedef void(::SourceHook::EmptyClass::*ECMFP)(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16); \ - SHINT_MAKE_GENERICSTUFF_END_MANUAL(hookname, vtbloffs, vtblidx, thisptroffs) \ - \ - const ::SourceHook::PassInfo __SourceHook_ParamInfosM_##hookname[] = { {1, 0, 0}, __SH_GPI(param1), __SH_GPI(param2), __SH_GPI(param3), __SH_GPI(param4), __SH_GPI(param5), __SH_GPI(param6), __SH_GPI(param7), __SH_GPI(param8), __SH_GPI(param9), __SH_GPI(param10), __SH_GPI(param11), __SH_GPI(param12), __SH_GPI(param13), __SH_GPI(param14), __SH_GPI(param15), __SH_GPI(param16) }; \ - const ::SourceHook::PassInfo::V2Info __SourceHook_ParamInfos2M_##hookname[] = { __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI, __SH_EPI }; \ - ::SourceHook::ProtoInfo SH_MFHCls(hookname)::ms_Proto = { 16, { 0, 0, 0 }, \ - __SourceHook_ParamInfosM_##hookname , 0, __SH_EPI, __SourceHook_ParamInfos2M_##hookname }; - -#define SH_DECL_MANUALEXTERN16_void(hookname, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16) \ - int __SourceHook_FHMAdd##hookname(void *iface, ::SourceHook::ISourceHook::AddHookMode mode, bool post, \ - fastdelegate::FastDelegate16 handler); \ - bool __SourceHook_FHMRemove##hookname(void *iface, bool post, \ - fastdelegate::FastDelegate16 handler); - - - -////////////////////////////////////////////////////////////////////////// -// SH_CALL - -#define SH_MAKE_EXECUTABLECLASS_OB(call, prms) \ -{ \ - using namespace ::SourceHook; \ - \ - m_pSH->SetIgnoreHooks(m_VfnPtr); \ - RetType tmpret = (m_ThisPtr->*m_MFP)call; \ - m_pSH->ResetIgnoreHooks(m_VfnPtr); \ - return tmpret; \ -} - -#define SH_MAKE_EXECUTABLECLASS_OB_void(call, prms) \ -{ \ - using namespace ::SourceHook; \ - \ - m_pSH->SetIgnoreHooks(m_VfnPtr); \ - (m_ThisPtr->*m_MFP)call; \ - m_pSH->ResetIgnoreHooks(m_VfnPtr); \ -} - -namespace SourceHook -{ - - // Support for 0 arguments - template class ExecutableClass0 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass0(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()() const - SH_MAKE_EXECUTABLECLASS_OB((), ()) - - - template RetType operator()(Param1 p1) const - SH_MAKE_EXECUTABLECLASS_OB((p1), (Param1)) - - template RetType operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2), (Param1, Param2)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass0 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass0(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()() const - SH_MAKE_EXECUTABLECLASS_OB_void((), ()) - - - template void operator()(Param1 p1) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1), (Param1)) - - template void operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2), (Param1, Param2)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3), (Param1, Param2, Param3)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 1 arguments - template class ExecutableClass1 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass1(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1) const - SH_MAKE_EXECUTABLECLASS_OB((p1), (Param1)) - - - template RetType operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2), (Param1, Param2)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass1 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass1(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1), (Param1)) - - - template void operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2), (Param1, Param2)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3), (Param1, Param2, Param3)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 2 arguments - template class ExecutableClass2 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass2(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2), (Param1, Param2)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass2 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass2(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2), (Param1, Param2)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3), (Param1, Param2, Param3)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 3 arguments - template class ExecutableClass3 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass3(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3), (Param1, Param2, Param3)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass3 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass3(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3), (Param1, Param2, Param3)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 4 arguments - template class ExecutableClass4 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass4(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass4 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass4(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4), (Param1, Param2, Param3, Param4)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 5 arguments - template class ExecutableClass5 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass5(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass5 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass5(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5), (Param1, Param2, Param3, Param4, Param5)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 6 arguments - template class ExecutableClass6 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass6(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass6 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass6(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6), (Param1, Param2, Param3, Param4, Param5, Param6)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 7 arguments - template class ExecutableClass7 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass7(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass7 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass7(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7), (Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 8 arguments - template class ExecutableClass8 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass8(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass8 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass8(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 9 arguments - template class ExecutableClass9 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass9(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass9 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass9(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 10 arguments - template class ExecutableClass10 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass10(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass10 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass10(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 11 arguments - template class ExecutableClass11 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass11(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass11 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass11(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 12 arguments - template class ExecutableClass12 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass12(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass12 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass12(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 13 arguments - template class ExecutableClass13 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass13(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass13 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass13(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 14 arguments - template class ExecutableClass14 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass14(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass14 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass14(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 15 arguments - template class ExecutableClass15 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass15(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - - template RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - template class ExecutableClass15 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass15(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - - - template void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - }; - - // Support for 16 arguments - template class ExecutableClass16 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass16(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - RetType operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - - }; - - template class ExecutableClass16 - { - ObjType *m_ThisPtr; - void *m_VfnPtr; - MFPType m_MFP; - ISourceHook *m_pSH; - public: - ExecutableClass16(ObjType *tp, MFPType mfp, void *vp, ISourceHook *pSH) : m_ThisPtr(tp), - m_VfnPtr(vp), m_MFP(mfp), m_pSH(pSH) { } - - void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13, Param14 p14, Param15 p15, Param16 p16) const - SH_MAKE_EXECUTABLECLASS_OB_void((p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16), (Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - - - }; - - -} - -#define SH__CALL_GET_VFNPTR_NORMAL \ - using namespace ::SourceHook; \ - MemFuncInfo mfi = {true, -1, 0, 0}; \ - GetFuncInfo(ptr, mfp, mfi); \ - void *vfnptr = reinterpret_cast( \ - *reinterpret_cast(reinterpret_cast(ptr) + mfi.thisptroffs + mfi.vtbloffs) + mfi.vtblindex); - -#define SH__CALL_GET_VFNPTR_MANUAL \ - using namespace ::SourceHook; \ - void *vfnptr = reinterpret_cast( \ - *reinterpret_cast( (reinterpret_cast(ptr) + thisptroffs + vtbloffs) ) + vtblidx); \ - /* patch mfp */ \ - *reinterpret_cast(&mfp) = *reinterpret_cast(vfnptr); - -// SH_CALL needs to deduce the return type -> it uses templates and function overloading -// That's why SH_CALL takes two parameters: "mfp2" of type RetType(X::*mfp)(params), and "mfp" of type MFP -// The only purpose of the mfp2 parameter is to extract the return type - - -// Support for 0 arguments -template -SourceHook::ExecutableClass0 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass0(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass0 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)()const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass0(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass0 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass0( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 1 arguments -template -SourceHook::ExecutableClass1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass1 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass1( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 2 arguments -template -SourceHook::ExecutableClass2 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass2(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass2 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass2(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass2 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass2( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 3 arguments -template -SourceHook::ExecutableClass3 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass3(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass3 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass3(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass3 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass3( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 4 arguments -template -SourceHook::ExecutableClass4 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass4(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass4 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass4(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass4 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass4( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 5 arguments -template -SourceHook::ExecutableClass5 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass5(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass5 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass5(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass5 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass5( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 6 arguments -template -SourceHook::ExecutableClass6 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass6(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass6 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass6(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass6 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass6( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 7 arguments -template -SourceHook::ExecutableClass7 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass7(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass7 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass7(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass7 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass7( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 8 arguments -template -SourceHook::ExecutableClass8 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass8(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass8 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass8(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass8 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass8( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 9 arguments -template -SourceHook::ExecutableClass9 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass9(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass9 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass9(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass9 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass9( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 10 arguments -template -SourceHook::ExecutableClass10 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass10(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass10 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass10(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass10 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass10( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 11 arguments -template -SourceHook::ExecutableClass11 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass11(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass11 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass11(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass11 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass11( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 12 arguments -template -SourceHook::ExecutableClass12 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass12(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass12 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass12(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass12 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass12( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 13 arguments -template -SourceHook::ExecutableClass13 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass13(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass13 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass13(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass13 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass13( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 14 arguments -template -SourceHook::ExecutableClass14 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass14(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass14 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass14(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass14 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass14( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 15 arguments -template -SourceHook::ExecutableClass15 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass15(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass15 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass15(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass15 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass15( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - -// Support for 16 arguments -template -SourceHook::ExecutableClass16 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass16(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass16 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass16(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass16 -SH_MCALL3(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), int vtblidx, int vtbloffs, int thisptroffs, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_MANUAL - return SourceHook::ExecutableClass16( - reinterpret_cast(ptr), mfp, vfnptr, shptr); -} - - -#if SH_COMP != SH_COMP_MSVC || _MSC_VER > 1300 -// GCC & MSVC 7.1 need this, MSVC 7.0 doesn't like it - - -// Support for 0 arguments -template -SourceHook::ExecutableClass0 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass0(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass0 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass0(ptr, mfp, vfnptr, shptr); -} - - -// Support for 1 arguments -template -SourceHook::ExecutableClass1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass1(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass1 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass1(ptr, mfp, vfnptr, shptr); -} - - -// Support for 2 arguments -template -SourceHook::ExecutableClass2 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass2(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass2 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass2(ptr, mfp, vfnptr, shptr); -} - - -// Support for 3 arguments -template -SourceHook::ExecutableClass3 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass3(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass3 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass3(ptr, mfp, vfnptr, shptr); -} - - -// Support for 4 arguments -template -SourceHook::ExecutableClass4 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass4(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass4 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass4(ptr, mfp, vfnptr, shptr); -} - - -// Support for 5 arguments -template -SourceHook::ExecutableClass5 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass5(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass5 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass5(ptr, mfp, vfnptr, shptr); -} - - -// Support for 6 arguments -template -SourceHook::ExecutableClass6 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass6(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass6 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass6(ptr, mfp, vfnptr, shptr); -} - - -// Support for 7 arguments -template -SourceHook::ExecutableClass7 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass7(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass7 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass7(ptr, mfp, vfnptr, shptr); -} - - -// Support for 8 arguments -template -SourceHook::ExecutableClass8 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass8(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass8 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass8(ptr, mfp, vfnptr, shptr); -} - - -// Support for 9 arguments -template -SourceHook::ExecutableClass9 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass9(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass9 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass9(ptr, mfp, vfnptr, shptr); -} - - -// Support for 10 arguments -template -SourceHook::ExecutableClass10 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass10(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass10 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass10(ptr, mfp, vfnptr, shptr); -} - - -// Support for 11 arguments -template -SourceHook::ExecutableClass11 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass11(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass11 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass11(ptr, mfp, vfnptr, shptr); -} - - -// Support for 12 arguments -template -SourceHook::ExecutableClass12 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass12(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass12 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass12(ptr, mfp, vfnptr, shptr); -} - - -// Support for 13 arguments -template -SourceHook::ExecutableClass13 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass13(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass13 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass13(ptr, mfp, vfnptr, shptr); -} - - -// Support for 14 arguments -template -SourceHook::ExecutableClass14 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass14(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass14 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass14(ptr, mfp, vfnptr, shptr); -} - - -// Support for 15 arguments -template -SourceHook::ExecutableClass15 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass15(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass15 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass15(ptr, mfp, vfnptr, shptr); -} - - -// Support for 16 arguments -template -SourceHook::ExecutableClass16 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...), SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass16(ptr, mfp, vfnptr, shptr); -} - -template -SourceHook::ExecutableClass16 -SH_CALL2(Y *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)const, SourceHook::ISourceHook *shptr) -{ - SH__CALL_GET_VFNPTR_NORMAL - return SourceHook::ExecutableClass16(ptr, mfp, vfnptr, shptr); -} - - - -#endif - -#define SH_CALL(ptr, mfp) SH_CALL2((ptr), (mfp), (mfp), SH_GLOB_SHPTR) -#define SH_MCALL2(ptr, mfp, vtblidx, vtbloffs, thisptroffs) SH_MCALL3((ptr), (mfp), (mfp), (vtblidx), (vtbloffs), (thisptroffs), SH_GLOB_SHPTR) -#define SH_MCALL(ptr, mhookname) SH_MCALL2((ptr), SH_MFHCls(mhookname)::ECMFP(), SH_MFHCls(mhookname)::ms_MFI.vtblindex, \ - SH_MFHCls(mhookname)::ms_MFI.vtbloffs, SH_MFHCls(mhookname)::ms_MFI.thisptroffs) - -#undef SH_MAKE_EXECUTABLECLASS_OB -#undef SH_MAKE_EXECUTABLECLASS_OB_void - -////////////////////////////////////////////////////////////////////////// -// SetOverrideRet and RecallGetIface for recalls -// These take a ISourceHook pointer instead of using SH_GLOB_SHPTR directly -// The reason is that the user may want to redefine SH_GLOB_SHPTR - then the macros -// (META_RETURN_VALUE_NEWPARAMS) should obey the new pointer. - -namespace SourceHook -{ - template - void SetOverrideResult(ISourceHook *shptr, const RetType res) - { - *reinterpret_cast(shptr->GetOverrideRetPtr()) = res; - } - - // SetOverrideResult used to be implemented like this: - // SetOverrideResult(shptr, memfuncptr, return); - // normally the compiler can deduce the return type from memfuncptr, but (at least msvc8) failed when it was a reference - // (it thought it was ambigous - the ref and non-ref type) - // so now SetOverrideResult(memfuncptr) deduces the ret type, and returns a functor which does the work - // new syntax: SetOverrideResult(memfuncptr)(shptr, return) - // This also allows us to create a special version for references which respects ReferenceCarrier. - - template struct OverrideFunctor - { - void operator()(ISourceHook *shptr, T res) - { - *reinterpret_cast(shptr->GetOverrideRetPtr()) = res; - } - }; - template struct OverrideFunctor - { - void operator()(ISourceHook *shptr, T &res) - { - // overrideretptr points to ReferenceCarrier - *reinterpret_cast::type *>(shptr->GetOverrideRetPtr()) = res; - } - }; - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)()) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)()) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - { - return OverrideFunctor(); - } - - template - OverrideFunctor SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)) - { - return OverrideFunctor(); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - - template - Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)) - { - return reinterpret_cast(shptr->GetIfacePtr()); - } - -} - -#endif - // The pope is dead. -> :( diff --git a/sourcehook/sourcehook_hookmangen.cpp b/sourcehook/sourcehook_hookmangen.cpp deleted file mode 100644 index 69c10c1..0000000 --- a/sourcehook/sourcehook_hookmangen.cpp +++ /dev/null @@ -1,2030 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* Contributor(s): Borja "faluco" Ferav (many thanks for assitance!) -* David "BAILOPAN" Anderson -* ============================ -*/ - -// recommended literature: -// http://www.cs.umbc.edu/~chang/cs313.s02/stack.shtml -// http://www.angelcode.com/dev/callconv/callconv.html -// http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-1.html - -#include "sourcehook_impl.h" -#include "sourcehook_hookmangen.h" -#include "sourcehook_hookmangen_x86.h" -#include "sh_memory.h" -#include // we might need the address of vsnprintf -#include - -#if SH_COMP == SH_COMP_MSVC -# define GCC_ONLY(x) -# define MSVC_ONLY(x) x -#elif SH_COMP == SH_COMP_GCC -# define GCC_ONLY(x) x -# define MSVC_ONLY(x) -#endif - -// :TODO: test BIG vtable indices - -namespace SourceHook -{ - namespace Impl - { - CPageAlloc GenBuffer::ms_Allocator(16); - - template - jit_int32_t DownCastPtr(T ptr) - { - return reinterpret_cast(ptr); - } - - jit_uint32_t DownCastSize(size_t size) - { - return static_cast(size); - } - - GenContext::GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr) - : m_GeneratedPubFunc(NULL), m_OrigProto(proto), m_Proto(proto), m_VtblOffs(vtbl_offs), - m_VtblIdx(vtbl_idx), m_SHPtr(pSHPtr), m_pHI(NULL), m_HookfuncVfnptr(NULL), m_RegCounter(0) - { - m_pHI = new void*; - m_HookfuncVfnptr = new void*; - m_BuiltPI = new ProtoInfo; - m_BuiltPI_Params = NULL; - m_BuiltPI_Params2 = NULL; - } - - GenContext::~GenContext() - { - Clear(); - delete m_pHI; - delete m_HookfuncVfnptr; - delete m_BuiltPI; - } - - void GenContext::Clear() - { - m_HookFunc.clear(); - m_PubFunc.clear(); - if (m_BuiltPI_Params) - { - delete m_BuiltPI_Params; - m_BuiltPI_Params = NULL; - } - if (m_BuiltPI_Params2) - { - delete m_BuiltPI_Params2; - m_BuiltPI_Params2 = NULL; - } - } - - void GenContext::BuildProtoInfo() - { - m_BuiltPI->convention = m_Proto.GetConvention(); - m_BuiltPI->numOfParams = m_Proto.GetNumOfParams(); - - m_BuiltPI->retPassInfo.size = m_Proto.GetRet().size; - m_BuiltPI->retPassInfo.type = m_Proto.GetRet().type; - m_BuiltPI->retPassInfo.flags = m_Proto.GetRet().flags; - m_BuiltPI->retPassInfo2.pNormalCtor = m_Proto.GetRet().pNormalCtor; - m_BuiltPI->retPassInfo2.pCopyCtor = m_Proto.GetRet().pCopyCtor; - m_BuiltPI->retPassInfo2.pDtor = m_Proto.GetRet().pDtor; - m_BuiltPI->retPassInfo2.pAssignOperator = m_Proto.GetRet().pAssignOperator; - - if (m_BuiltPI_Params) - delete m_BuiltPI_Params; - m_BuiltPI_Params = new PassInfo[m_BuiltPI->numOfParams + 1]; - if (m_BuiltPI_Params2) - delete m_BuiltPI_Params2; - m_BuiltPI_Params2 = new PassInfo::V2Info[m_BuiltPI->numOfParams + 1]; - - m_BuiltPI_Params[0].size = 1; // Version 1 - m_BuiltPI_Params[0].type = 0; - m_BuiltPI_Params[0].flags = 0; - - for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) - { - m_BuiltPI_Params[i+1].size = m_Proto.GetParam(i).size; - m_BuiltPI_Params[i+1].type = m_Proto.GetParam(i).type; - m_BuiltPI_Params[i+1].flags = m_Proto.GetParam(i).flags; - - m_BuiltPI_Params2[i+1].pNormalCtor = m_Proto.GetParam(i).pNormalCtor; - m_BuiltPI_Params2[i+1].pCopyCtor = m_Proto.GetParam(i).pCopyCtor; - m_BuiltPI_Params2[i+1].pDtor = m_Proto.GetParam(i).pDtor; - m_BuiltPI_Params2[i+1].pAssignOperator = m_Proto.GetParam(i).pAssignOperator; - } - - m_BuiltPI->paramsPassInfo = m_BuiltPI_Params; - m_BuiltPI->paramsPassInfo2 = m_BuiltPI_Params2; - } - - jit_int32_t GenContext::GetRealSize(const IntPassInfo &info) - { - if (info.flags & (PassInfo::PassFlag_ByRef | PassFlag_ForcedByRef)) - { - return SIZE_PTR; - } - return static_cast(info.size); - } - - jit_int32_t GenContext::AlignSize(jit_int32_t x, jit_int32_t boundary) - { - if (x % boundary != 0) - x = (x & ~(boundary-1)) + boundary; - return x; - } - - // Computes size on the stack - jit_int32_t GenContext::GetParamStackSize(const IntPassInfo &info) - { - // Align up to 4 byte boundaries - return AlignSize(GetRealSize(info), 4); - } - - jit_int8_t GenContext::NextRegEBX_ECX_EDX() - { - switch ((m_RegCounter++) % 3) - { - case 0: - return REG_EBX; - case 1: - return REG_ECX; - case 2: - default: - m_RegCounter = 0; - return REG_EDX; - } - } - - void GenContext::BitwiseCopy_Setup() - { - //cld - //push edi - //push esi - - IA32_Cld(&m_HookFunc); - IA32_Push_Reg(&m_HookFunc, REG_EDI); - IA32_Push_Reg(&m_HookFunc, REG_ESI); - } - - void GenContext::BitwiseCopy_Do(size_t size) - { - jit_uint32_t dwords = DownCastSize(size) / 4; - jit_uint32_t bytes = DownCastSize(size) % 4; - - //if dwords - // mov ecx, - // rep movsd - //if bytes - // mov ecx, - // rep movsb - //pop esi - //pop edi - - if (dwords) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords); - IA32_Rep(&m_HookFunc); - IA32_Movsd(&m_HookFunc); - } - if (bytes) - { - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes); - IA32_Rep(&m_HookFunc); - IA32_Movsb(&m_HookFunc); - } - IA32_Pop_Reg(&m_HookFunc, REG_ESI); - IA32_Pop_Reg(&m_HookFunc, REG_EDI); - } - - jit_int32_t GenContext::AlignStackBeforeCall(int paramsize, int flags) - { - paramsize += - GCC_ONLY( ((flags & AlignStack_GCC_ThisOnStack)!=0 ? SIZE_PTR : 0) + ) - MSVC_ONLY( ((flags & AlignStack_MSVC_ThisOnStack)!=0 ? SIZE_PTR : 0) + ) - ((flags & AlignStack_MemRet)!=0 ? SIZE_PTR : 0); - - // At the beginning of the hookfunc, the stack is aligned to a 16 bytes boundary. - // Then, m_BytesPushedAfterInitialAlignment were pushed (can also be 0). - - // After this function is called, paramsize bytes will be pushed onto the stack - // After that, the alignment has to be a 16 bytes boundary again. - - - // How many bytes we would subtract if the alignment was alright now: - int subtractFromEsp = 16 - (paramsize % 16); - if (subtractFromEsp == 16) - subtractFromEsp = 0; - - // But: there might be bytes pushed alreay! - subtractFromEsp -= m_BytesPushedAfterInitialAlignment; - - // For example: paramsize was 0 and m_BytesPushedAfterInitialAlignment was 4. - // we then have to push another 12 bytes to reach 16 bytes alignment again. - - if (subtractFromEsp < 0) - subtractFromEsp = 16 - ((-subtractFromEsp) % 16); - - if (subtractFromEsp != 0) - IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, subtractFromEsp, MOD_REG); - - return subtractFromEsp; - } - - void GenContext::AlignStackAfterCall(jit_int32_t numofbytes) - { - if (numofbytes != 0) - IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, numofbytes, MOD_REG); - } - - void GenContext::CheckAlignmentBeforeCall() - { -#if 0 - IA32_Test_Rm_Imm32(&m_HookFunc, REG_ESP, 15, MOD_REG); - IA32_Jump_Cond_Imm8(&m_HookFunc, CC_Z, 1); - IA32_Int3(&m_HookFunc); -#endif - } - - short GenContext::GetParamsTotalStackSize() - { - short acc = 0; - for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) - { - acc += GetParamStackSize(m_Proto.GetParam(i)); - } - - return acc; - } - - short GenContext::GetForcedByRefParamOffset(int p) - { - short off = 0; - for (int i = 0; i < p; ++i) - { - if (m_Proto.GetParam(i).flags & PassFlag_ForcedByRef) - off += AlignSize(static_cast(m_Proto.GetParam(i).size), 4); - } - return off; - } - - short GenContext::GetForcedByRefParamsSize() - { - return GetForcedByRefParamOffset(m_Proto.GetNumOfParams()); - } - - jit_int32_t GenContext::PushRef(jit_int32_t param_offset, const IntPassInfo &pi) - { - // push [ebp+] - IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_offset); - - return SIZE_PTR; - } - - jit_int32_t GenContext::PushBasic(jit_int32_t param_offset, const IntPassInfo &pi) - { - int reg; - int reg2; - - switch (pi.size) - { - default: - SH_ASSERT(0, ("Unsupported!")); - return 0; - case 1: - reg = NextRegEBX_ECX_EDX(); - //movzx reg, BYTE PTR [ebp+] - //push reg - IA32_Movzx_Reg32_Rm8_DispAuto(&m_HookFunc, reg, REG_EBP, param_offset); - IA32_Push_Reg(&m_HookFunc, reg); - - return 4; - case 2: - reg = NextRegEBX_ECX_EDX(); - //movzx reg, WORD PTR [ebp+] - //push reg - m_HookFunc.write_ubyte(IA32_16BIT_PREFIX); - IA32_Movzx_Reg32_Rm16_DispAuto(&m_HookFunc, reg, REG_EBP, param_offset); - IA32_Push_Reg(&m_HookFunc, reg); - - return 4; - case 4: - reg = NextRegEBX_ECX_EDX(); - //mov reg, DWORD PTR [ebp+] - //push reg - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, reg, REG_EBP, param_offset); - IA32_Push_Reg(&m_HookFunc, reg); - - return 4; - case 8: - reg = NextRegEBX_ECX_EDX(); - reg2 = NextRegEBX_ECX_EDX(); - //mov reg, DWORD PTR [ebp++4] - //mov reg2, DWORD PTR [ebp+] - //push reg - //push reg2 - - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, reg, REG_EBP, param_offset+4); - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, reg2, REG_EBP, param_offset); - IA32_Push_Reg(&m_HookFunc, reg); - IA32_Push_Reg(&m_HookFunc, reg2); - - return 8; - } - } - - jit_int32_t GenContext::PushFloat(jit_int32_t param_offset, const IntPassInfo &pi) - { - switch (pi.size) - { - default: - SH_ASSERT(0, ("Unsupported!")); - return 0; - case 4: - //fld DWORD PTR [ebp+] - //push reg - //fstp DWORD PTR [esp] - IA32_Fld_Mem32_DispAuto(&m_HookFunc, REG_EBP, param_offset); - IA32_Push_Reg(&m_HookFunc, NextRegEBX_ECX_EDX()); - IA32_Fstp_Mem32_ESP(&m_HookFunc); - return 4; - case 8: - //fld QWORD PTR [ebp+] - //sub esp, 8 - //fstp QWORD PTR [esp] - IA32_Fld_Mem64_DispAuto(&m_HookFunc, REG_EBP, param_offset); - IA32_Sub_Rm_Imm8(&m_HookFunc, REG_ESP, 8, MOD_REG); - IA32_Fstp_Mem64_ESP(&m_HookFunc); - return 8; - } - } - - jit_int32_t GenContext::PushObject(jit_int32_t param_offset, const IntPassInfo &pi, jit_int32_t place_fbrr) - { - if ((pi.flags & PassFlag_ForcedByRef) == 0) - { - // make room on the stack - // sub esp, - IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, GetParamStackSize(pi), MOD_REG); - } - - // if there is a copy constructor.. - if (pi.pCopyCtor) - { - // :TODO: alignment here? - // can't use normal alignment methods - // because an unknown number of bytes has been pushed already (the other params) - - // save eax - IA32_Push_Reg(&m_HookFunc, REG_EAX); - - // compute dest addr to ECX - // = forcedbyref ? ebp+place_fbrr : esp+12 - if (pi.flags & PassFlag_ForcedByRef) - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, place_fbrr); - else - IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_ECX, REG_NOIDX, REG_ESP, NOSCALE, 4); - - // compute src addr to EAX - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_offset); - - // push params (gcc: also this) - IA32_Push_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - - // call - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EDX, DownCastPtr(pi.pCopyCtor)); - IA32_Call_Reg(&m_HookFunc, REG_EDX); - - // gcc: clean up stack - GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); - - // restore eax - IA32_Pop_Reg(&m_HookFunc, REG_EAX); - } - else - { - // bitwise copy - - BitwiseCopy_Setup(); - - //if forcedbyref: - // lea edi, [ebp_place_fbrr] - //else - // lea edi, [esp+8] - bc_setup pushed two regs onto the stack! - //lea esi, [ebp+] - if (pi.flags & PassFlag_ForcedByRef) - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, place_fbrr); - else - IA32_Lea_Reg_DispRegMultImm8(&m_HookFunc, REG_EDI, REG_NOIDX, REG_ESP, NOSCALE, 8); - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, param_offset); - - BitwiseCopy_Do(pi.size); - } - - // forcedref: push reference to ebp+place_fbrr - if (pi.flags & PassFlag_ForcedByRef) - { - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, place_fbrr); - IA32_Push_Reg(&m_HookFunc, REG_ECX); - return SIZE_PTR; - } - - return GetParamStackSize(pi); - } - - void GenContext::DestroyParams(jit_int32_t fbrr_base) - { - for (int i = m_Proto.GetNumOfParams() - 1; i >= 0; --i) - { - const IntPassInfo &pi = m_Proto.GetParam(i); - if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ODtor) && - (pi.flags & PassInfo::PassFlag_ByVal) && (pi.flags & PassFlag_ForcedByRef)) - { - // Actually, this is only for GCC (see line above: ForcedByRef) - jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, fbrr_base + GetForcedByRefParamOffset(i)); - IA32_Push_Reg(&m_HookFunc, REG_ECX); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - IA32_Pop_Reg(&m_HookFunc, REG_ECX); - - AlignStackAfterCall(tmpAlign); - } - } - } - - // May not touch eax! - jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to, int v_place_for_memret, - jit_int32_t v_place_fbrr_base) - { - jit_int32_t added_to_stack = 0; - jit_int32_t ret = 0; - - // compute the offset _after_ the last parameter - jit_int32_t cur_offset = param_base_offset; - for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) - { - cur_offset += GetParamStackSize(m_Proto.GetParam(i)); - } - - // push parameters in reverse order - for (int i = m_Proto.GetNumOfParams() - 1; i >= 0; --i) - { - const IntPassInfo &pi = m_Proto.GetParam(i); - cur_offset -= GetParamStackSize(pi); - if (pi.flags & PassInfo::PassFlag_ByVal) - { - switch (pi.type) - { - case PassInfo::PassType_Basic: - ret = PushBasic(cur_offset, pi); - break; - case PassInfo::PassType_Float: - ret = PushFloat(cur_offset, pi); - break; - case PassInfo::PassType_Object: - ret = PushObject(cur_offset, pi, v_place_fbrr_base + GetForcedByRefParamOffset(i)); - break; - } - } - else if (pi.flags & PassInfo::PassFlag_ByRef) - { - ret = PushRef(cur_offset, pi); - } - else - { - SH_ASSERT(0, ("Unsupported!")); - } - added_to_stack += ret; - } - - return added_to_stack; - } - - // It is IMPORTANT that PushMemRetPtr doesn't touch ecx and eax - jit_int32_t GenContext::PushMemRetPtr(jit_int32_t save_ret_to, jit_int32_t v_place_for_memret) - { - // Memory return support - if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - { - // push address where to save it! - int reg = REG_EDX; - IA32_Lea_DispRegImmAuto(&m_HookFunc, reg, REG_EBP, - MemRetWithTempObj() ? v_place_for_memret : save_ret_to); - IA32_Push_Reg(&m_HookFunc, reg); - - return (SH_COMP==SH_COMP_MSVC) ? 4 : 0; // varargs funcs on msvc might need this. - // gcc doesn't: callee cleans the memret ptr, caller the other params :s - } - return 0; - } - - void GenContext::SaveRetVal(int v_where, int v_place_for_memret) - { - size_t size = GetRealSize(m_Proto.GetRet()); - if (size == 0) - { - // No return value -> nothing - return; - } - - if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef) - { - // mov [ebp + v_plugin_ret], eax - IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where); - return; - } - // else: ByVal - - - // Memory return: - if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - { - if (MemRetWithTempObj()) - { - // *v_where = *v_place_for_memret - - // if we have an assign operator, use that - if (m_Proto.GetRet().pAssignOperator) - { - // lea edx, [ebp + v_place_for_memret] <-- src addr - // lea ecx, [ebp + v_where] <-- dest addr - // push edx - // gcc: push ecx - // call it - // gcc: clean up - - jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR, AlignStack_GCC_ThisOnStack); - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_place_for_memret); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_where); - IA32_Push_Reg(&m_HookFunc, REG_EDX); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); - - AlignStackAfterCall(tmpAlign); - } - else - { - // bitwise copy - BitwiseCopy_Setup(); - - //lea edi, [evp+v_where] <-- destination - //lea esi, [ebp+v_place_for_memret] <-- src - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, v_where); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_place_for_memret); - - BitwiseCopy_Do(m_Proto.GetRet().size); - } - - // Then: destruct *v_place_for_memret if required - if (m_Proto.GetRet().pDtor) - { - //lea ecx, [ebp+v_place_for_memret] - //gcc: push ecx - //call it - //gcc: clean up - - jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_place_for_memret); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - AlignStackAfterCall(tmpAlign); - } - } - else - { - // Already copied to correct address -> we're done - return; - } - } - - if (m_Proto.GetRet().type == PassInfo::PassType_Float) - { - if (size == 4) - IA32_Fstp_Mem32_DispAuto(&m_HookFunc, REG_EBP, v_where); - else if (size == 8) - IA32_Fstp_Mem64_DispAuto(&m_HookFunc, REG_EBP, v_where); - } - else if (m_Proto.GetRet().type == PassInfo::PassType_Basic) - { - if (size <= 4) - { - // size <= 4: return in EAX - // We align <4 sizes up to 4 - - - // mov [ebp + v_plugin_ret], eax - IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where); - } - else if (size <= 8) - { - // size <= 4: return in EAX:EDX - // We align 4 8 !")); - } - } - } - } - - bool GenContext::MemRetWithTempObj() - { - // Memory return AND (has destructor OR has assign operator) - return ((m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - && (m_Proto.GetRet().flags & (PassInfo::PassFlag_ODtor | PassInfo::PassFlag_AssignOp))); - } - - void GenContext::ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret) - { - // only for non-void functions! - if (m_Proto.GetRet().size == 0) - return; - - // if (cur_res >= MRES_OVERRIDE) - // *reinterpret_cast(pContext->GetOverrideRetPtr()) = plugin_ret; - - // eax = cur_res - // cmp eax,MRES_OVERRIDE - // jnge thelabel - // pContext->GetOverrideRetPtr() --> overrideretptr in eax - // *eax = plugin_ret - // thelabel: - // - - jitoffs_t tmppos, counter; - - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_cur_res); - - IA32_Cmp_Rm_Imm32(&m_HookFunc, MOD_REG, REG_EAX, MRES_OVERRIDE); - tmppos = IA32_Jump_Cond_Imm8(&m_HookFunc, CC_NGE, 0); - m_HookFunc.start_count(counter); - - // eax = pContext->GetOverrideRetPtr() no alignment needs - // ECX = pContext - // gcc: push ecx - // eax = [ecx] - // eax = [eax + 4] - // call eax - // gcc: clean up - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - - // vtbloffs=0, vtblidx=1 - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 4); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - - // *eax = plugin_ret - if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef) - { - // mov ecx, [ebp+v_plugin_ret] - // mov [eax], ecx - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); - IA32_Mov_Rm_Reg(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); - } - else - { - if (m_Proto.GetRet().pAssignOperator) - { - // lea edx, [ebp + v_plugin_ret] - // push edx <-- src addr - // msvc: ecx = eax <-- dest addr - // gcc: push eax <-- dest addr - // call it - // gcc: clean up - - jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR, AlignStack_GCC_ThisOnStack); - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_plugin_ret); - IA32_Push_Reg(&m_HookFunc, REG_EDX); -#if SH_COMP == SH_COMP_MSVC - IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); -#elif SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_HookFunc, REG_EAX); -#endif - - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); - - AlignStackAfterCall(tmpAlign); - } - else - { - // bitwise copy - BitwiseCopy_Setup(); - - //mov edi, eax <-- destination - //lea esi, [ebp+v_plugin_ret] <-- src - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDI, REG_EAX, MOD_REG); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_plugin_ret); - - BitwiseCopy_Do(m_Proto.GetRet().size); - } - } - - m_HookFunc.end_count(counter); - m_HookFunc.rewrite(tmppos, static_cast(counter)); - } - - void GenContext::PrepareReturn(int v_status, int v_pContext, int v_retptr) - { - // only for non-void functions! - if (m_Proto.GetRet().size == 0) - return; - - // retptr = status >= MRES_OVERRIDE ? pContext->GetOverrideRetPtr() : pContext->GetOrigRetPtr() - - // OverrideRetPtr: vtblidx = 1 - // OrigRetPtr: vtbldix = 2 - // vtblidx = (status >= MRES_OVERRIDE) ? 1 : 2 - - // - // eax = pContext->GetOverrideRetPtr() - // ECX = pContext - // gcc: push ecx - - // eax = (status < MRES_OVERRIDE) ? 1 : 0 - // xor eax, eax - // cmp [ebp + v_status], MRES_OVERRIDE - // setl al <-- setcc optimization for ternary operators, - - - // lea eax, [4*eax + 0x4] - - // edx = [ecx] - // add edx, eax - // mov edx, [edx] - - // call edx - // gcc: clean up - - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - IA32_Xor_Reg_Rm(&m_HookFunc, REG_EAX, REG_EAX, MOD_REG); - IA32_Cmp_Rm_Disp8_Imm8(&m_HookFunc, REG_EBP, v_status, MRES_OVERRIDE); - IA32_SetCC_Rm8(&m_HookFunc, REG_EAX, CC_L); - - IA32_Lea_Reg_RegMultImm32(&m_HookFunc, REG_EAX, REG_EAX, SCALE4, 4); - - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_ECX, MOD_MEM_REG); - IA32_Add_Reg_Rm(&m_HookFunc, REG_EDX, REG_EAX, MOD_REG); - - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_EDX, MOD_MEM_REG); - IA32_Call_Reg(&m_HookFunc, REG_EDX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_retptr); - } - - void GenContext::DoReturn(int v_retptr, int v_memret_outaddr) - { - size_t size = m_Proto.GetRet().size; - if (!size) - return; - - // Get real ret pointer into ecx - // mov ecx, [ebp + v_ret_ptr] - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_retptr); - - if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef) - { - // mov eax, [ecx] - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); - return; - } - // else: byval - - if (m_Proto.GetRet().type == PassInfo::PassType_Float) - { - if (size == 4) - IA32_Fld_Mem32(&m_HookFunc, REG_ECX); - else if (size == 8) - IA32_Fld_Mem64(&m_HookFunc, REG_ECX); - } - else if (m_Proto.GetRet().type == PassInfo::PassType_Basic || - ((m_Proto.GetRet().type == PassInfo::PassType_Object) && (m_Proto.GetRet().flags & PassInfo::PassFlag_RetReg)) ) - { - if (size <= 4) - { - // size <= 4: return in EAX - // We align <4 sizes up to 4 - - // mov eax, [ecx] - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); - } - else if (size <= 8) - { - // size <= 4: return in EAX:EDX - // We align 48: return in memory - // handled later - } - } - - if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - { - // *memret_outaddr = plugin_ret - if (m_Proto.GetRet().pCopyCtor) - { - // mov edx, ecx <-- src ( we set ecx to [ebp+v_retptr] before ) - // push edx <-- src addr - // msvc: ecx = [ebp + v_memret_outaddr] <-- dest addr - // gcc: push [ebp + v_memret_outaddr] <-- dest addr - // call it - // gcc: clean up - - jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR, AlignStack_GCC_ThisOnStack); - - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_ECX, MOD_REG); - IA32_Push_Reg(&m_HookFunc, REG_EDX); - -#if SH_COMP == SH_COMP_MSVC - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_memret_outaddr); -#elif SH_COMP == SH_COMP_GCC - IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, v_memret_outaddr); -#endif - - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pCopyCtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2 * SIZE_PTR, MOD_REG)); - - AlignStackAfterCall(tmpAlign); - } - else - { - // bitwise copy - BitwiseCopy_Setup(); - - //mov edi, [ebp+v_memret_outaddr] <-- destination - //mov esi, ecx <-- src ( we set ecx to [ebp+v_retptr] before ) - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EDI, REG_EBP, v_memret_outaddr); - IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESI, REG_ECX, MOD_REG); - - BitwiseCopy_Do(m_Proto.GetRet().size); - } - - // In both cases: return the pointer in EAX - // mov eax, [ebp + v_memret_outaddr] - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_memret_outaddr); - } - } - - void GenContext::GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, - int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf) - { - jitoffs_t counter, tmppos; - jitoffs_t counter2, tmppos2; - - jitoffs_t loop_begin_counter; - - // prev_res = MRES_IGNORED - IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_prev_res); - - m_HookFunc.start_count(loop_begin_counter); - - // eax = pContext->GetNext() - // ECX = pContext - // gcc: push ecx - // eax = [ecx] - // eax = [eax] - // call eax - // gcc: clean up - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - - // vtbloffs=0, vtblidx=0 - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_EAX, MOD_MEM_REG); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - // quit on zero - // test eax, eax - // jz exit - IA32_Test_Rm_Reg(&m_HookFunc, REG_EAX, REG_EAX, MOD_REG); - tmppos = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_Z, 0); - m_HookFunc.start_count(counter); - - // prev_res = MRES_IGNORED - IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_cur_res); - - // iter->call() - // push params - // ecx = eax - // gcc: push ecx - // eax = [ecx] - // eax = [eax+2*SIZE_PTR] - // call eax - // gcc: clean up - - jit_int32_t caller_clean_bytes = 0; // gcc always, msvc never (hooks never have varargs!) - - jit_int32_t alignBytes = AlignStackBeforeCall( - GetParamsTotalStackSize() + ((m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt)!=0 ? SIZE_PTR : 0), - AlignStack_GCC_ThisOnStack | ((m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) == 0 ? 0 : AlignStack_MemRet) - ); - - // vafmt: push va_buf - if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) - { - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); - IA32_Push_Reg(&m_HookFunc, REG_ECX); - caller_clean_bytes += SIZE_PTR; - } - - caller_clean_bytes += PushParams(base_param_offset, v_plugin_ret, v_place_for_memret, v_place_fbrr_base); - - IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG); - if (SH_COMP == SH_COMP_GCC) - IA32_Push_Reg(&m_HookFunc, REG_ECX); - caller_clean_bytes += PushMemRetPtr(v_plugin_ret, v_place_for_memret); - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EAX, 2*SIZE_PTR); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - - AlignStackAfterCall(alignBytes); - - // cleanup (gcc only) - // params + thisptr - if (SH_COMP == SH_COMP_GCC) - IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, caller_clean_bytes + SIZE_PTR, MOD_REG); - - DestroyParams(v_place_fbrr_base); - - SaveRetVal(v_plugin_ret, v_place_for_memret); - - // process meta return: - // prev_res = cur_res - // if (cur_res > status) status = cur_res; - // - // eax = cur_res - // edx = status - // prev_res = eax - // cmp eax,edx - // jng thelabel - // status = eax - // thelabel: - // - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_cur_res); - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EDX, REG_EBP, v_status); - IA32_Mov_Rm_Reg_Disp8(&m_HookFunc, REG_EBP, REG_EAX, v_prev_res); - - IA32_Cmp_Reg_Rm(&m_HookFunc, REG_EAX, REG_EDX, MOD_REG); - tmppos2 = IA32_Jump_Cond_Imm8(&m_HookFunc, CC_NG, 0); - m_HookFunc.start_count(counter2); - - IA32_Mov_Rm_Reg_Disp8(&m_HookFunc, REG_EBP, REG_EAX, v_status); - - m_HookFunc.end_count(counter2); - m_HookFunc.rewrite(tmppos2, static_cast(counter2)); - - // process retval for non-void functions - ProcessPluginRetVal(v_cur_res, v_pContext, v_plugin_ret); - - // jump back to loop begin - tmppos2 = IA32_Jump_Imm32(&m_HookFunc, 0); - m_HookFunc.end_count(loop_begin_counter); - m_HookFunc.rewrite(tmppos2, static_cast(-loop_begin_counter)); - - m_HookFunc.end_count(counter); - m_HookFunc.rewrite(tmppos, static_cast(counter)); - } - - void GenContext::GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this, - int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf) - { - jitoffs_t counter, tmppos; - jitoffs_t counter2, tmppos2; - jitoffs_t counter3, tmppos3; - - // if (status != MRES_SUPERCEDE && pConteext->ShouldCallOrig()) - // *v_orig_ret = orig_call() - // else - // *v_orig_ret = *v_override_ret - - // mov eax, status - // cmp eax, MRES_SUPERCEDE - // je dont_call - // call pContext->ShouldCallOrig() - // test al, al !! important: al, not eax! bool is only stored in the LSbyte - // jz dont_call - // - // orig_call() - // SaveRet(v_orig_ret) - // jmp skip_dont_call: - // - // dont_call: - // *v_orig_ret = *v_override_ret - // skip_dont_call: - - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_status); - IA32_Cmp_Rm_Imm32(&m_HookFunc, MOD_REG, REG_EAX, MRES_SUPERCEDE); - - tmppos = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_E, 0); - m_HookFunc.start_count(counter); - - // eax = pContext->ShouldCallOrig() - // ECX = pContext - // gcc: push ecx - // eax = [ecx] - // eax = [eax + 3*SIZE_PTR] - // call eax - // gcc: clean up - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - - // vtbloffs=0, vtblidx=3 - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG); - IA32_Mov_Reg_Rm_Disp8(&m_HookFunc, REG_EAX, REG_EAX, 3*SIZE_PTR); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - IA32_Test_Rm_Reg8(&m_HookFunc, REG_EAX, REG_EAX, MOD_REG); - tmppos2 = IA32_Jump_Cond_Imm32(&m_HookFunc, CC_Z, 0); - m_HookFunc.start_count(counter2); - - jit_int32_t caller_clean_bytes = 0; // gcc always, msvc when cdecl-like (varargs) - - jit_int32_t alignBytes = AlignStackBeforeCall( - GetParamsTotalStackSize() + ((m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt)!=0 ? 2*SIZE_PTR : 0), - AlignStack_GCC_ThisOnStack | - ((m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) == 0 ? 0 : AlignStack_MemRet) | - ((m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) == 0 ? 0 : AlignStack_MSVC_ThisOnStack) - ); - - // vafmt: push va_buf, then "%s" - if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) - { - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); - IA32_Push_Reg(&m_HookFunc, REG_ECX); - IA32_Push_Imm32(&m_HookFunc, DownCastPtr("%s")); - caller_clean_bytes += 2*SIZE_PTR; - } - - // push params - caller_clean_bytes += PushParams(param_base_offs, v_orig_ret, v_place_for_memret, v_place_fbrr_base); - - // thisptr - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); - if (SH_COMP == SH_COMP_GCC) - { - // on gcc/mingw, this is the first parameter - IA32_Push_Reg(&m_HookFunc, REG_ECX); - // on msvc without varargs, simply leave it in ecx - - // actually, if we're returning in memory, this pointer is the second param - // and the memret pointer is the real first parameter - caller_clean_bytes += PushMemRetPtr(v_orig_ret, v_place_for_memret); - } - else - { - // On msvc, if we're returning in memory, the memret pointer is the first parameter - caller_clean_bytes += PushMemRetPtr(v_orig_ret, v_place_for_memret); - - // actually, with varargs, the this pointer is the first param and the memret ptr - // is the second one - if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) - { - IA32_Push_Reg(&m_HookFunc, REG_ECX); - } - } - - // call - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_vfnptr_origentry); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - - AlignStackAfterCall(alignBytes); - - // cleanup - if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) - IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, caller_clean_bytes + SIZE_PTR, MOD_REG); - - DestroyParams(v_place_fbrr_base); - - // save retval - SaveRetVal(v_orig_ret, v_place_for_memret); - - // Skip don't call variant - tmppos3 = IA32_Jump_Imm32(&m_HookFunc, 0); - m_HookFunc.start_count(counter3); - - - // don't call: - m_HookFunc.end_count(counter); - m_HookFunc.rewrite(tmppos, static_cast(counter)); - - m_HookFunc.end_count(counter2); - m_HookFunc.rewrite(tmppos2, static_cast(counter2)); - - // *v_orig_ret = *v_override_ret - if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef) - { - // mov ecx, [ebp + v_override_ret] - // mov [ebp + v_orig_ret], ecx - - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); - IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_ECX, v_orig_ret); - } - else - { - if (m_Proto.GetRet().pAssignOperator) - { - // lea edx, [ebp + v_override_ret] <-- src addr - // lea ecx, [ebp + v_orig_ret] <-- dest addr - // push edx <-- src addr - // gcc: push ecx - // call it - // gcc: clean up - - jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR, AlignStack_GCC_ThisOnStack); - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_override_ret); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); - IA32_Push_Reg(&m_HookFunc, REG_EDX); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG)); - - AlignStackAfterCall(tmpAlign); - } - else - { - // bitwise copy - BitwiseCopy_Setup(); - - //lea edi, [ebp+v_orig_ret] <-- destination - //lea esi, [ebp+v_override_ret] <-- src - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDI, REG_EBP, v_orig_ret); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_override_ret); - - BitwiseCopy_Do(m_Proto.GetRet().size); - } - } - - // skip don't call label target: - m_HookFunc.end_count(counter3); - m_HookFunc.rewrite(tmppos3, static_cast(counter3)); - } - - // Sets *v_pContext to return value - void GenContext::CallSetupHookLoop(int v_orig_ret, int v_override_ret, - int v_cur_res, int v_prev_res, int v_status, int v_vfnptr_origentry, - int v_this, int v_pContext) - { - // call shptr->SetupHookLoop(ms_HI, ourvfnptr, reinterpret_cast(this), - // &vfnptr_origentry, &status, &prev_res, &cur_res, &orig_ret, &override_ret); - // The last two params are null for void funcs. - - if (m_Proto.GetRet().size == 0) - { - // void - IA32_Push_Imm8(&m_HookFunc, 0); // orig_ret - IA32_Push_Imm8(&m_HookFunc, 0); // override_ret - } - else - { - // orig_ret and override_ret - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, v_override_ret); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_orig_ret); - IA32_Push_Reg(&m_HookFunc, REG_EAX); - IA32_Push_Reg(&m_HookFunc, REG_EDX); - } - - // cur_res and prev_res - IA32_Lea_DispRegImm8(&m_HookFunc, REG_EAX, REG_EBP, v_cur_res); - IA32_Lea_DispRegImm8(&m_HookFunc, REG_EDX, REG_EBP, v_prev_res); - IA32_Push_Reg(&m_HookFunc, REG_EAX); - IA32_Push_Reg(&m_HookFunc, REG_EDX); - - // status and vfnptr_origentry - IA32_Lea_DispRegImm8(&m_HookFunc, REG_EAX, REG_EBP, v_status); - IA32_Lea_DispRegImm8(&m_HookFunc, REG_EDX, REG_EBP, v_vfnptr_origentry); - IA32_Push_Reg(&m_HookFunc, REG_EAX); - IA32_Push_Reg(&m_HookFunc, REG_EDX); - - // this - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_this); - IA32_Push_Reg(&m_HookFunc, REG_EAX); - - // our vfn ptr - // *(this + vtbloffs) + SIZE_PTR*vtblidx - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this); // get this into ecx (gcc!) - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_ECX, m_VtblOffs); - IA32_Add_Rm_ImmAuto(&m_HookFunc, REG_EAX, m_VtblIdx * SIZE_PTR, MOD_REG); - IA32_Push_Reg(&m_HookFunc, REG_EAX); - - // *m_pHI - IA32_Mov_Rm_Imm32(&m_HookFunc, REG_EDX, DownCastPtr(m_pHI), MOD_REG); - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_EDX, MOD_MEM_REG); - IA32_Push_Reg(&m_HookFunc, REG_EAX); - - // set up thisptr -#if SH_COMP == SH_COMP_GCC - // on gcc/mingw, this is the first parameter - GCC_ONLY(IA32_Push_Imm32(&m_HookFunc, DownCastPtr(m_SHPtr))); -#elif SH_COMP == SH_COMP_MSVC - // on msvc, it's ecx - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, DownCastPtr(m_SHPtr)); -#endif - - // call the function. vtbloffs = 0, vtblidx = 19 - // get vtptr into edx -- we know shptr on jit time -> dereference it here! - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, - (*reinterpret_cast(m_SHPtr))[19]); - - IA32_Call_Reg(&m_HookFunc, REG_EAX); - - // on gcc/mingw, we have to clean up after the call - // 9 params + hidden thisptr param - GCC_ONLY(IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 10*SIZE_PTR, MOD_REG)); - - // store return value - IA32_Mov_Rm_Reg_Disp8(&m_HookFunc, REG_EBP, REG_EAX, v_pContext); - } - - void GenContext::CallEndContext(int v_pContext) - { - // call endcontext: - // shptr->EndContext(pContex) - IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_pContext); - IA32_Push_Reg(&m_HookFunc, REG_EAX); - - // thisptr -#if SH_COMP == SH_COMP_GCC - // on gcc/mingw, this is the first parameter - IA32_Push_Imm32(&m_HookFunc, DownCastPtr(m_SHPtr)); -#elif SH_COMP == SH_COMP_MSVC - // on msvc, it's ecx - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, DownCastPtr(m_SHPtr)); -#endif - - // get vtptr into edx -- we know shptr on jit time -> dereference it here! - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, - (*reinterpret_cast(m_SHPtr))[20]); - - IA32_Call_Reg(&m_HookFunc, REG_EAX); - - // on gcc/mingw, we have to clean up after the call - // 1 param + hidden thisptr param - GCC_ONLY(IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG)); - } - - void GenContext::ResetFrame(jit_int32_t startOffset) - { - m_HookFunc_FrameOffset = startOffset; - m_HookFunc_FrameVarsSize = 0; - } - - jit_int32_t GenContext::AddVarToFrame(jit_int32_t size) - { - m_HookFunc_FrameOffset -= size; - m_HookFunc_FrameVarsSize += size; - return m_HookFunc_FrameOffset; - } - - jit_int32_t GenContext::ComputeVarsSize() - { - return m_HookFunc_FrameVarsSize; - } - - void * GenContext::GenerateHookFunc() - { - // prologue - IA32_Push_Reg(&m_HookFunc, REG_EBP); - IA32_Push_Reg(&m_HookFunc, REG_EBX); - IA32_Mov_Reg_Rm(&m_HookFunc, REG_EBP, REG_ESP, MOD_REG); - - jit_int32_t v_this = 0; - jit_int32_t param_base_offs = 0; - if (SH_COMP == SH_COMP_GCC || (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) - { - // gcc or msvc with varargs: - v_this = 12; // first param - param_base_offs = 16; - ResetFrame(0); - } - else - { - // on msvc without varargs, save thisptr - v_this = -4; - param_base_offs = 12; - IA32_Push_Reg(&m_HookFunc, REG_ECX); - ResetFrame(-4); // start placing local vars on offset -4 - // because there already is the thisptr variable - } - - // ********************** stack frame ********************** - // MSVC without varargs - // second param (gcc: first real param) ebp + 16 - // first param (gcc: thisptr) ebp + 12 - // ret address: ebp + 8 - // caller's ebp ebp + 4 - // saved ebx ebp - // MSVC ONLY: current this ebp - 4 - // void *vfnptr_origentry ebp - 4 -4 - // META_RES status = MRES_IGNORED ebp - 8 -4 - // META_RES prev_res ebp - 12 -4 - // META_RES cur_res ebp - 16 -4 - // IMyDelegate *iter ebp - 20 -4 - // IHookContext *pContext ebp - 24 -4 - // == 3 ptrs + 3 enums = 24 bytes - // - // non-void: add: - // my_rettype *ret_ptr ebp - 28 -4 - // my_rettype orig_ret ebp - 28 - sizeof(my_rettype) -4 - // my_rettype override_ret ebp - 28 - sizeof(my_rettype)*2 -4 - // my_rettype plugin_ret ebp - 28 - sizeof(my_rettype)*3 -4 - // == + 3 * sizeof(my_rettype) bytes - - // if required: - // my_rettype place_for_memret ebp - 28 - sizeof(my_rettype)*4 -4 - - // gcc only: if required: - // place forced byref params ebp - 28 - sizeof(my_rettype)*{4 or 5} - // - // varargs: - // va_list argptr - // char va_buf[something]; - - - const jit_int8_t v_vfnptr_origentry = AddVarToFrame(SIZE_PTR); - const jit_int8_t v_status = AddVarToFrame(sizeof(META_RES)); - const jit_int8_t v_prev_res = AddVarToFrame(sizeof(META_RES)); - const jit_int8_t v_cur_res = AddVarToFrame(sizeof(META_RES)); - const jit_int8_t v_iter = AddVarToFrame(SIZE_PTR); - const jit_int8_t v_pContext = AddVarToFrame(SIZE_PTR); - - // Memory return: first param is the address - jit_int32_t v_memret_addr = 0; - if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - { - if (SH_COMP == SH_COMP_GCC) - { - // gcc: now: first param = mem ret addr - // second param = this pointer - // third param = actual first param - v_memret_addr = 12; - v_this += 4; - param_base_offs += SIZE_PTR; - } - else // MSVC - { - if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) - { - // varargs -> cdecl - // msvc: now: - // first param = this pointer - // second param = mem ret addr - // third param = actual first param - - // params_base_offs is already updated to point to after the this pointer - v_memret_addr = param_base_offs; - param_base_offs += SIZE_PTR; - } - else - { - v_memret_addr = param_base_offs; - param_base_offs += SIZE_PTR; - } - } - } - - jit_int32_t v_ret_ptr = 0; - jit_int32_t v_orig_ret = 0; - jit_int32_t v_override_ret = 0; - jit_int32_t v_plugin_ret = 0; - - if (m_Proto.GetRet().size != 0) - { - v_ret_ptr = AddVarToFrame(SIZE_PTR); - v_orig_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet())); - v_override_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet())); - v_plugin_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet())); - } - - jit_int32_t v_place_for_memret = 0; - if (MemRetWithTempObj()) - { - v_place_for_memret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet())); - } - - jit_int32_t v_place_fbrr_base = 0; - if (SH_COMP == SH_COMP_GCC && GetForcedByRefParamsSize()) - { - v_place_fbrr_base = AddVarToFrame(GetForcedByRefParamsSize()); - } - - // Only exists for varargs functions - jit_int32_t v_va_argptr = 0; - if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) - { - v_va_argptr = AddVarToFrame(SIZE_PTR); - } - - jit_int32_t v_va_buf = 0; - if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) - { - v_va_buf = AddVarToFrame(SourceHook::STRBUF_LEN); - } - - IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, ComputeVarsSize(), MOD_REG); - - // Initial stack alignment - IA32_And_Rm_Imm32(&m_HookFunc, REG_ESP, MOD_REG, -16); - m_BytesPushedAfterInitialAlignment = 0; - - // init status localvar - IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_status); - - // VarArgs: init argptr & format - if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) - { - // argptr = first vararg param - // lea eax, [ebp + param_base_offs + paramssize] - // mov argptr, eax - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_base_offs + GetParamsTotalStackSize() + SIZE_PTR); // +SIZE_PTR: last const char * is not in protoinfo - IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_va_argptr); - } - if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt) - { - // vsnprintf - - jit_int32_t tmpAlign = AlignStackBeforeCall(SIZE_PTR*3 + sizeof(size_t), 0); - - // push valist, fmt param, maxsize, buffer - IA32_Push_Reg(&m_HookFunc, REG_EAX); - IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_base_offs + GetParamsTotalStackSize()); // last given param (+4-4, see above) - IA32_Push_Imm32(&m_HookFunc, SourceHook::STRBUF_LEN - 1); - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf); - IA32_Push_Reg(&m_HookFunc, REG_ECX); - - // call - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(&vsnprintf)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - - // Clean up (cdecl) - IA32_Add_Rm_Imm32(&m_HookFunc, REG_ESP, 0x10, MOD_REG); - - AlignStackAfterCall(tmpAlign); - - // Set trailing zero - IA32_Xor_Reg_Rm(&m_HookFunc, REG_EDX, REG_EDX, MOD_REG); - IA32_Mov_Rm8_Reg8_DispAuto(&m_HookFunc, REG_EBP, REG_EDX, v_va_buf + SourceHook::STRBUF_LEN - 1); - } - - // Call constructors for ret vars if required - if((m_Proto.GetRet().flags & PassInfo::PassFlag_ByVal) && - m_Proto.GetRet().pNormalCtor) - { - jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); - - // orig_reg - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - // override_reg - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - // plugin_ret - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pNormalCtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - AlignStackAfterCall(tmpAlign); - - // _don't_ call a constructor for v_place_for_memret ! - } - - // ********************** SetupHookLoop ********************** - CallSetupHookLoop(v_orig_ret, v_override_ret, v_cur_res, v_prev_res, v_status, v_vfnptr_origentry, - v_this, v_pContext); - - // ********************** call pre hooks ********************** - GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, - v_plugin_ret, v_place_for_memret, v_place_fbrr_base, v_va_buf); - - // ********************** call orig func ********************** - GenerateCallOrig(v_status, v_pContext, param_base_offs, v_this, v_vfnptr_origentry, v_orig_ret, - v_override_ret, v_place_for_memret, v_place_fbrr_base, v_va_buf); - - // ********************** call post hooks ********************** - GenerateCallHooks(v_status, v_prev_res, v_cur_res, v_iter, v_pContext, param_base_offs, - v_plugin_ret, v_place_for_memret, v_place_fbrr_base, v_va_buf); - - // ********************** end context and return ********************** - - PrepareReturn(v_status, v_pContext, v_ret_ptr); - - CallEndContext(v_pContext); - - // Call destructors of byval object params which have a destructor - - jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); - - jit_int32_t cur_param_pos = param_base_offs; - for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) - { - const IntPassInfo &pi = m_Proto.GetParam(i); - // GCC: NOT of forced byref params. the caller destructs those. - if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ODtor) && - (pi.flags & PassInfo::PassFlag_ByVal) && !(pi.flags & PassFlag_ForcedByRef)) - { - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, cur_param_pos); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor)); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - } - cur_param_pos += GetParamStackSize(pi); - } - - AlignStackAfterCall(tmpAlign); - - DoReturn(v_ret_ptr, v_memret_addr); - - // Call destructors of orig_ret/ ... - if((m_Proto.GetRet().flags & PassInfo::PassFlag_ByVal) && - m_Proto.GetRet().pDtor) - { - // Preserve return value in EAX(:EDX) - IA32_Push_Reg(&m_HookFunc, REG_EAX); - IA32_Push_Reg(&m_HookFunc, REG_EDX); - - m_BytesPushedAfterInitialAlignment += 8; - - jit_int32_t tmpAlign = AlignStackBeforeCall(0, AlignStack_GCC_ThisOnStack); - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_override_ret); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret); - GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX)); - IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pDtor)); - CheckAlignmentBeforeCall(); - IA32_Call_Reg(&m_HookFunc, REG_EAX); - GCC_ONLY(IA32_Pop_Reg(&m_HookFunc, REG_ECX)); - - AlignStackAfterCall(tmpAlign); - - IA32_Pop_Reg(&m_HookFunc, REG_EDX); - IA32_Pop_Reg(&m_HookFunc, REG_EAX); - - m_BytesPushedAfterInitialAlignment -= 8; - } - - // epilogue - IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESP, REG_EBP, MOD_REG); - IA32_Pop_Reg(&m_HookFunc, REG_EBX); - IA32_Pop_Reg(&m_HookFunc, REG_EBP); - - if (SH_COMP == SH_COMP_MSVC && !(m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)) - { - // msvc without varargs: - // callee cleans the stack - - short cleansize = GetParamsTotalStackSize(); - // Memory return: address is first param - if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem) - cleansize += SIZE_PTR; - - IA32_Return_Popstack(&m_HookFunc, cleansize); - } - else - { - // gcc or msvc with varargs: caller cleans the stack - // exception: gcc removes the memret addr on memret: - if (SH_COMP == SH_COMP_GCC && (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)) - IA32_Return_Popstack(&m_HookFunc, SIZE_PTR); - else - IA32_Return(&m_HookFunc); - } - - - // Store pointer for later use - // m_HookfuncVfnPtr is a pointer to a void* because SH expects a pointer - // into the hookman's vtable - *m_HookfuncVfnptr = reinterpret_cast(m_HookFunc.GetData()); - - m_HookFunc.SetRE(); - - return m_HookFunc.GetData(); - } - - // Pre-condition: GenerateHookFunc() has been called! - void * GenContext::GeneratePubFunc() - { - jitoffs_t counter, tmppos; - - // The pubfunc is a static cdecl function. - // C Code: - // int HookManPubFunc( - // bool store, ebp + 8 - // IHookManagerInfo *hi ebp + 12 - // ) - // { - // if (store) - // *m_pHI = hi; - // if (hi) - // hi->SetInfo(HOOKMAN_VERSION, m_VtblOffs, m_VtblIdx, m_Proto.GetProto(), m_HookfuncVfnptr) - // } - - // prologue - IA32_Push_Reg(&m_PubFunc, REG_EBP); - IA32_Mov_Reg_Rm(&m_PubFunc, REG_EBP, REG_ESP, MOD_REG); - - - // save store in eax, hi in ecx - IA32_Movzx_Reg32_Rm8_Disp8(&m_PubFunc, REG_EAX, REG_EBP, 8); - IA32_Mov_Reg_Rm_DispAuto(&m_PubFunc, REG_ECX, REG_EBP, 12); - - // Check for store == 0 - IA32_Test_Rm_Reg8(&m_PubFunc, REG_EAX, REG_EAX, MOD_REG); - tmppos = IA32_Jump_Cond_Imm8(&m_PubFunc, CC_Z, 0); - m_PubFunc.start_count(counter); - - // nonzero -> store hi - IA32_Mov_Rm_Imm32(&m_PubFunc, REG_EDX, DownCastPtr(m_pHI), MOD_REG); - IA32_Mov_Rm_Reg(&m_PubFunc, REG_EDX, REG_ECX, MOD_MEM_REG); - - // zero - m_PubFunc.end_count(counter); - m_PubFunc.rewrite(tmppos, static_cast(counter)); - - // check for hi == 0 - IA32_Test_Rm_Reg(&m_PubFunc, REG_ECX, REG_ECX, MOD_REG); - tmppos = IA32_Jump_Cond_Imm8(&m_PubFunc, CC_Z, 0); - m_PubFunc.start_count(counter); - - // nonzero -> call vfunc - // push params in reverse order - IA32_Push_Imm32(&m_PubFunc, DownCastPtr(m_HookfuncVfnptr)); - IA32_Push_Imm32(&m_PubFunc, DownCastPtr(m_BuiltPI)); - IA32_Push_Imm32(&m_PubFunc, m_VtblIdx); - IA32_Push_Imm32(&m_PubFunc, m_VtblOffs); - IA32_Push_Imm32(&m_PubFunc, SH_HOOKMAN_VERSION); - - // hi == this is in ecx - // on gcc/mingw, ecx is the first parameter -#if SH_COMP == SH_COMP_GCC - IA32_Push_Reg(&m_PubFunc, REG_ECX); -#endif - - // call the function. vtbloffs = 0, vtblidx = 0 - // get vtptr into edx - IA32_Mov_Reg_Rm(&m_PubFunc, REG_EDX, REG_ECX, MOD_MEM_REG); - // get funcptr into eax - IA32_Mov_Reg_Rm(&m_PubFunc, REG_EAX, REG_EDX, MOD_MEM_REG); - - IA32_Call_Reg(&m_PubFunc, REG_EAX); - - // on gcc/mingw, we have to clean up after the call -#if SH_COMP == SH_COMP_GCC - // 5 params + hidden thisptr param - IA32_Add_Rm_Imm8(&m_PubFunc, REG_ESP, 6*SIZE_MWORD, MOD_REG); -#endif - - // zero - m_PubFunc.end_count(counter); - m_PubFunc.rewrite(tmppos, static_cast(counter)); - - // return value - IA32_Xor_Reg_Rm(&m_PubFunc, REG_EAX, REG_EAX, MOD_REG); - - // epilogue - IA32_Mov_Reg_Rm(&m_PubFunc, REG_ESP, REG_EBP, MOD_REG); - IA32_Pop_Reg(&m_PubFunc, REG_EBP); - IA32_Return(&m_PubFunc); - - m_PubFunc.SetRE(); - - return m_PubFunc; - } - - bool GenContext::PassInfoSupported(const IntPassInfo &pi, bool is_ret) - { - // :TODO: Error returns - if (pi.type != PassInfo::PassType_Basic && - pi.type != PassInfo::PassType_Float && - pi.type != PassInfo::PassType_Object) - { - return false; - } - - if (pi.type == PassInfo::PassType_Object && - (pi.flags & PassInfo::PassFlag_ByVal)) - { - if ((pi.flags & PassInfo::PassFlag_CCtor) && !pi.pCopyCtor) - { - return false; - } - - if ((pi.flags & PassInfo::PassFlag_ODtor) && !pi.pDtor) - { - return false; - } - - if ((pi.flags & PassInfo::PassFlag_AssignOp) && !pi.pAssignOperator) - { - return false; - } - - if ((pi.flags & PassInfo::PassFlag_OCtor) && !pi.pNormalCtor) - { - return false; - } - } - - if ((pi.flags & (PassInfo::PassFlag_ByVal | PassInfo::PassFlag_ByRef)) == 0) - { - return false; // Neither byval nor byref! - } - return true; - } - - void GenContext::AutoDetectRetType() - { - IntPassInfo &pi = m_Proto.GetRet(); - - // Only relevant for byval types - if (pi.flags & PassInfo::PassFlag_ByVal) - { - // Basic + float: - if (pi.type == PassInfo::PassType_Basic || - pi.type == PassInfo::PassType_Float) - { - // <= 8 bytes: - // _always_ in registers, no matter what the user says - if (pi.size <= 8) - { - pi.flags &= ~PassInfo::PassFlag_RetMem; - pi.flags |= PassInfo::PassFlag_RetReg; - } - else - { - // Does this even exist? No idea, if it does: in memory! - pi.flags &= ~PassInfo::PassFlag_RetReg; - pi.flags |= PassInfo::PassFlag_RetMem; - } - } - // Object: - else if (pi.type == PassInfo::PassType_Object) - { - // If the user says nothing, auto-detect - if ((pi.flags & (PassInfo::PassFlag_RetMem | PassInfo::PassFlag_RetReg)) == 0) - { -#if SH_COMP == SH_COMP_MSVC - // MSVC seems to return _all_ structs, classes, unions in memory - pi.flags |= PassInfo::PassFlag_RetMem; -#elif SH_COMP == SH_COMP_GCC - // Same goes for GCC :) - pi.flags |= PassInfo::PassFlag_RetMem; -#endif - } - } - } - else - { - // byref: make sure that the flag is _not_ set - pi.flags &= ~PassInfo::PassFlag_RetMem; - pi.flags |= PassInfo::PassFlag_RetReg; - } - } - - void GenContext::AutoDetectParamFlags() - { -#if SH_COMP == SH_COMP_GCC - // On GCC, all objects are passed by reference if they have a destructor - for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) - { - IntPassInfo &pi = m_Proto.GetParam(i); - if (pi.type == PassInfo::PassType_Object && (pi.flags & PassInfo::PassFlag_ByVal) && - (pi.flags & PassInfo::PassFlag_ODtor)) - { - pi.flags |= PassFlag_ForcedByRef; - } - } -#endif - } - - HookManagerPubFunc GenContext::Generate() - { - Clear(); - - // Check conditions: - // -1) good proto version - // 0) we don't support unknown passtypes, convention, ... - // 1) we don't support functions which return objects by value or take parameters by value - // that have a constructor, a destructor or an overloaded assignment op - // (we wouldn't know how to call it!) - - if (m_Proto.GetVersion() < 1) - { - return NULL; - } - - AutoDetectRetType(); - AutoDetectParamFlags(); - - // Basically, we only support ThisCall/thiscall with varargs - if ((m_Proto.GetConvention() & (~ProtoInfo::CallConv_HasVafmt)) != ProtoInfo::CallConv_ThisCall) - { - return NULL; - } - - - if (m_Proto.GetRet().size != 0 && !PassInfoSupported(m_Proto.GetRet(), true)) - { - return NULL; - } - - for (int i = 0; i < m_Proto.GetNumOfParams(); ++i) - { - if (!PassInfoSupported(m_Proto.GetParam(i), false)) - return NULL; - } - - BuildProtoInfo(); - GenerateHookFunc(); - return fastdelegate::detail::horrible_cast(GeneratePubFunc()); - } - - HookManagerPubFunc GenContext::GetPubFunc() - { - if (m_GeneratedPubFunc == 0) - m_GeneratedPubFunc = Generate(); - - return m_GeneratedPubFunc; - } - - bool GenContext::Equal(const CProto &proto, int vtbl_offs, int vtbl_idx) - { - return (m_OrigProto.ExactlyEqual(proto) && m_VtblOffs == vtbl_offs && m_VtblIdx == vtbl_idx); - } - - bool GenContext::Equal(HookManagerPubFunc other) - { - return m_GeneratedPubFunc == other; - } - - // *********************************** class GenContextContainer - CHookManagerAutoGen::CHookManagerAutoGen(ISourceHook *pSHPtr) : m_pSHPtr(pSHPtr) - { - } - - CHookManagerAutoGen::~CHookManagerAutoGen() - { - for (List::iterator iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter) - { - delete iter->m_GenContext; - } - } - - int CHookManagerAutoGen::GetIfaceVersion() - { - return SH_HOOKMANAUTOGEN_IFACE_VERSION; - } - - int CHookManagerAutoGen::GetImplVersion() - { - return SH_HOOKMANAUTOGEN_IMPL_VERSION; - } - - HookManagerPubFunc CHookManagerAutoGen::MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) - { - CProto mproto(proto); - for (List::iterator iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter) - { - if (iter->m_GenContext->Equal(mproto, vtbl_offs, vtbl_idx)) - { - iter->m_RefCnt++; - return iter->m_GenContext->GetPubFunc(); - } - } - - // Not found yet -> new one - StoredContext sctx; - sctx.m_RefCnt = 1; - sctx.m_GenContext = new GenContext(proto, vtbl_offs, vtbl_idx, m_pSHPtr); - - if (sctx.m_GenContext->GetPubFunc() == NULL) - { - return NULL; - } - else - { - m_Contexts.push_back(sctx); - return sctx.m_GenContext->GetPubFunc(); - } - } - - void CHookManagerAutoGen::ReleaseHookMan(HookManagerPubFunc pubFunc) - { - for (List::iterator iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter) - { - if (iter->m_GenContext->Equal(pubFunc)) - { - iter->m_RefCnt--; - if (iter->m_RefCnt == 0) - { - delete iter->m_GenContext; - m_Contexts.erase(iter); - } - break; - } - } - } - } -} diff --git a/sourcehook/sourcehook_hookmangen.h b/sourcehook/sourcehook_hookmangen.h deleted file mode 100644 index 148c9ab..0000000 --- a/sourcehook/sourcehook_hookmangen.h +++ /dev/null @@ -1,299 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_HOOKMANGEN_H__ -#define __SOURCEHOOK_HOOKMANGEN_H__ - -#include "sh_pagealloc.h" - -namespace SourceHook -{ - namespace Impl - { - - // Code gen stuff -#if SH_COMP == SH_COMP_GCC -#include - typedef int8_t jit_int8_t; - typedef uint8_t jit_uint8_t; - typedef int32_t jit_int32_t; - typedef uint32_t jit_uint32_t; - typedef int64_t jit_int64_t; - typedef uint64_t jit_uint64_t; -#elif SH_COMP == SH_COMP_MSVC - typedef __int8 jit_int8_t; - typedef unsigned __int8 jit_uint8_t; - typedef __int32 jit_int32_t; - typedef unsigned __int32 jit_uint32_t; - typedef __int64 jit_int64_t; - typedef unsigned __int64 jit_uint64_t; -#endif - typedef unsigned int jitoffs_t; - typedef signed int jitrel_t; - - - class GenBuffer - { - static CPageAlloc ms_Allocator; - - unsigned char *m_pData; - jitoffs_t m_Size; - jitoffs_t m_AllocatedSize; - - public: - GenBuffer() : m_pData(NULL), m_Size(0), m_AllocatedSize(0) - { - } - ~GenBuffer() - { - clear(); - } - jitoffs_t GetSize() - { - return m_Size; - } - unsigned char *GetData() - { - return m_pData; - } - - template void push(PT what) - { - push((const unsigned char *)&what, sizeof(PT)); - } - - void push(const unsigned char *data, jitoffs_t size) - { - jitoffs_t newSize = m_Size + size; - if (newSize > m_AllocatedSize) - { - m_AllocatedSize = newSize > m_AllocatedSize*2 ? newSize : m_AllocatedSize*2; - if (m_AllocatedSize < 64) - m_AllocatedSize = 64; - - unsigned char *newBuf; - newBuf = reinterpret_cast(ms_Allocator.Alloc(m_AllocatedSize)); - ms_Allocator.SetRW(newBuf); - if (!newBuf) - { - SH_ASSERT(0, ("bad_alloc: couldn't allocate 0x%08X bytes of memory\n", m_AllocatedSize)); - return; - } - memset((void*)newBuf, 0xCC, m_AllocatedSize); // :TODO: remove this ! - memcpy((void*)newBuf, (const void*)m_pData, m_Size); - if (m_pData) - { - ms_Allocator.SetRE(reinterpret_cast(m_pData)); - ms_Allocator.SetRW(newBuf); - ms_Allocator.Free(reinterpret_cast(m_pData)); - } - m_pData = newBuf; - } - memcpy((void*)(m_pData + m_Size), (const void*)data, size); - m_Size = newSize; - } - - template void rewrite(jitoffs_t offset, PT what) - { - rewrite(offset, (const unsigned char *)&what, sizeof(PT)); - } - - void rewrite(jitoffs_t offset, const unsigned char *data, jitoffs_t size) - { - SH_ASSERT(offset + size <= m_AllocatedSize, ("rewrite too far")); - - memcpy((void*)(m_pData + offset), (const void*)data, size); - } - - void clear() - { - if (m_pData) - ms_Allocator.Free(reinterpret_cast(m_pData)); - m_pData = NULL; - m_Size = 0; - m_AllocatedSize = 0; - } - - void SetRE() - { - ms_Allocator.SetRE(reinterpret_cast(m_pData)); - } - - operator void *() - { - return reinterpret_cast(GetData()); - } - - void write_ubyte(jit_uint8_t x) { push(x); } - void write_byte(jit_uint8_t x) { push(x); } - - void write_ushort(unsigned short x) { push(x); } - void write_short(signed short x) { push(x); } - - void write_uint32(jit_uint32_t x) { push(x); } - void write_int32(jit_uint32_t x) { push(x); } - - jitoffs_t get_outputpos() - { - return m_Size; - } - - void start_count(jitoffs_t &offs) - { - offs = get_outputpos(); - } - void end_count(jitoffs_t &offs) - { - offs = get_outputpos() - offs; - } - }; - - class GenContext - { - const static int SIZE_MWORD = 4; - const static int SIZE_PTR = sizeof(void*); - const static int PassFlag_ForcedByRef = (1<<30); // ByVal in source, but actually passed by reference (GCC) -> private pass, destruct - - HookManagerPubFunc m_GeneratedPubFunc; - - CProto m_OrigProto; // original passed-in prototype - CProto m_Proto; - int m_VtblOffs; - int m_VtblIdx; - ISourceHook *m_SHPtr; - - GenBuffer m_HookFunc; - GenBuffer m_PubFunc; - - ProtoInfo *m_BuiltPI; - PassInfo *m_BuiltPI_Params; - PassInfo::V2Info *m_BuiltPI_Params2; - - // For hookfunc - void **m_pHI; - void **m_HookfuncVfnptr; - - // Level 3 - Helpers - int m_RegCounter; - jit_int8_t NextRegEBX_ECX_EDX(); - - int m_BytesPushedAfterInitialAlignment; - enum AlignStackFlags - { - AlignStack_GCC_ThisOnStack = 1, - AlignStack_MSVC_ThisOnStack = 2, - AlignStack_MemRet = 4 - }; - jit_int32_t AlignStackBeforeCall(int paramsize, int flags); - void AlignStackAfterCall(jit_int32_t numofbytes); - void CheckAlignmentBeforeCall(); - - // size info - jit_int32_t GetRealSize(const IntPassInfo &info); // checks for reference - jit_int32_t AlignSize(jit_int32_t x, jit_int32_t boundary); // align a size - jit_int32_t GetParamStackSize(const IntPassInfo &info); // get the size of a param in the param stack - short GetParamsTotalStackSize(); // sum(GetParamStackSize(param[i]), 0 <= i < numOfParams) - - // Helpers - void BitwiseCopy_Setup(); - void BitwiseCopy_Do(size_t size); - - - // HookFunc frame - jit_int32_t m_HookFunc_FrameOffset; - jit_int32_t m_HookFunc_FrameVarsSize; - - void ResetFrame(jit_int32_t startOffset); - jit_int32_t AddVarToFrame(jit_int32_t size); - jit_int32_t ComputeVarsSize(); - - // Param push - short GetForcedByRefParamsSize(); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < numOfParams) - short GetForcedByRefParamOffset(int p); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < p) - jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to, - jit_int32_t v_place_for_memret, jit_int32_t v_place_fbrr_base); // save_ret_to and v_place_for_memret only used for memory returns - jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi); - jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi); - jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi); - jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi, jit_int32_t v_place_fbrr); - jit_int32_t PushMemRetPtr(jit_int32_t save_ret_to, jit_int32_t v_place_for_memret); - void DestroyParams(jit_int32_t fbrr_base); - - // Ret val processing - void SaveRetVal(jit_int32_t v_where, jit_int32_t v_place_for_memret); - void ProcessPluginRetVal(jit_int32_t v_cur_res, jit_int32_t v_pContext, jit_int32_t v_plugin_ret); - - void PrepareReturn(jit_int32_t v_status, jit_int32_t v_pContext, jit_int32_t v_retptr); - void DoReturn(jit_int32_t v_retptr, jit_int32_t v_memret_outaddr); - - bool MemRetWithTempObj(); // do we do a memory return AND need a temporary place for it? - - // Call hooks - void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, - int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf); - - // Call orig - void GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this, - int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf); - - // Hook loop - void CallSetupHookLoop(int v_orig_ret, int v_override_ret, - int v_cur_res, int v_prev_res, int v_status, int v_vnfptr_origentry, - int v_this, int v_pContext); - - void CallEndContext(int v_pContext); - - // Level 2 -> called from Generate() - void AutoDetectRetType(); - void AutoDetectParamFlags(); - bool PassInfoSupported(const IntPassInfo &pi, bool is_ret); - void Clear(); - void BuildProtoInfo(); - void *GenerateHookFunc(); - void *GeneratePubFunc(); - - HookManagerPubFunc Generate(); - public: - // Level 1 -> Public interface - GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr); - ~GenContext(); - - bool Equal(const CProto &proto, int vtbl_offs, int vtbl_idx); - bool Equal(HookManagerPubFunc other); - - HookManagerPubFunc GetPubFunc(); - }; - - class CHookManagerAutoGen : public IHookManagerAutoGen - { - struct StoredContext - { - int m_RefCnt; - GenContext *m_GenContext; - }; - List m_Contexts; - ISourceHook *m_pSHPtr; - - public: - CHookManagerAutoGen(ISourceHook *pSHPtr); - ~CHookManagerAutoGen(); - - int GetIfaceVersion(); - int GetImplVersion(); - - HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx); - void ReleaseHookMan(HookManagerPubFunc pubFunc); - }; - - } -} - - -#endif diff --git a/sourcehook/sourcehook_hookmangen_x86.h b/sourcehook/sourcehook_hookmangen_x86.h deleted file mode 100644 index 6d268ed..0000000 --- a/sourcehook/sourcehook_hookmangen_x86.h +++ /dev/null @@ -1,1611 +0,0 @@ -/* ======== SourceHook ======== -* vim: set ts=4 : -* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. -* No warranties of any kind -* -* License: zlib/libpng -* -* from the SourcePawn JIT SDK -* ============================ -*/ - -#ifndef __SOURCEHOOK_HOOKMANGEN_X86_H__ -#define __SOURCEHOOK_HOOKMANGEN_X86_H__ - -#include - -#undef REG_EAX -#undef REG_ECX -#undef REG_EDX -#undef REG_EBX -#undef REG_ESP -#undef REG_SIB -#undef REG_EBP -#undef REG_ESI -#undef REG_EDI - -//MOD R/M -#define MOD_MEM_REG 0 -#define MOD_DISP8 1 -#define MOD_DISP32 2 -#define MOD_REG 3 - -//SIB -#define NOSCALE 0 -#define SCALE2 1 -#define SCALE4 2 -#define SCALE8 3 - -//Register codes -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 -#define REG_ESP 4 -#define REG_SIB 4 -#define REG_NOIDX 4 -#define REG_IMM_BASE 5 -#define REG_EBP 5 -#define REG_ESI 6 -#define REG_EDI 7 - -#define IA32_16BIT_PREFIX 0x66 - -//condition codes (for example, Jcc opcodes) -#define CC_B 0x2 -#define CC_NAE CC_B -#define CC_NB 0x3 -#define CC_AE CC_NB -#define CC_E 0x4 -#define CC_Z CC_E -#define CC_NE 0x5 -#define CC_NZ CC_NE -#define CC_NA 0x6 -#define CC_BE CC_NA -#define CC_A 0x7 -#define CC_NBE CC_A -#define CC_L 0xC -#define CC_NGE CC_L -#define CC_NL 0xD -#define CC_GE CC_NL -#define CC_NG 0xE -#define CC_LE CC_NG -#define CC_G 0xF -#define CC_NLE CC_G - -//Opcodes with encoding information -#define IA32_XOR_RM_REG 0x31 // encoding is /r -#define IA32_XOR_REG_RM 0x33 // encoding is /r -#define IA32_XOR_EAX_IMM32 0x35 // encoding is /r -#define IA32_XOR_RM_IMM32 0x81 // encoding is /6 -#define IA32_XOR_RM_IMM8 0x83 // encoding is /6 -#define IA32_ADD_RM_REG 0x01 // encoding is /r -#define IA32_ADD_REG_RM 0x03 // encoding is /r -#define IA32_ADD_RM_IMM32 0x81 // encoding is /0 -#define IA32_ADD_RM_IMM8 0x83 // encoding is /0 -#define IA32_ADD_EAX_IMM32 0x05 // no extra encoding -#define IA32_SUB_RM_REG 0x29 // encoding is /r -#define IA32_SUB_REG_RM 0x2B // encoding is /r -#define IA32_SUB_RM_IMM8 0x83 // encoding is /5 -#define IA32_SUB_RM_IMM32 0x81 // encoding is /5 -#define IA32_SBB_REG_RM 0x1B // encoding is /r -#define IA32_SBB_RM_IMM8 0x83 // encoding is -#define IA32_JMP_IMM32 0xE9 // encoding is imm32 -#define IA32_JMP_IMM8 0xEB // encoding is imm8 -#define IA32_JMP_RM 0xFF // encoding is /4 -#define IA32_CALL_IMM32 0xE8 // relative call, -#define IA32_CALL_RM 0xFF // encoding is /2 -#define IA32_MOV_REG_IMM 0xB8 // encoding is +r -#define IA32_MOV_RM8_REG 0x88 // encoding is /r -#define IA32_MOV_RM_REG 0x89 // encoding is /r -#define IA32_MOV_REG_RM 0x8B // encoding is /r -#define IA32_MOV_REG8_RM8 0x8A // encoding is /r -#define IA32_MOV_RM8_REG8 0x88 // encoding is /r -#define IA32_MOV_RM_IMM32 0xC7 // encoding is /0 -#define IA32_CMP_RM_IMM32 0x81 // encoding is /7 -#define IA32_CMP_RM_IMM8 0x83 // encoding is /7 -#define IA32_CMP_AL_IMM32 0x3C // no extra encoding -#define IA32_CMP_EAX_IMM32 0x3D // no extra encoding -#define IA32_CMP_RM_REG 0x39 // encoding is /r -#define IA32_CMP_REG_RM 0x3B // encoding is /r -#define IA32_CMPSB 0xA6 // no extra encoding -#define IA32_TEST_RM_REG8 0x84 // encoding is /r -#define IA32_TEST_RM_REG 0x85 // encoding is /r -#define IA32_TEST_RM_IMM32 0xF7 // encoding is /0 -#define IA32_JCC_IMM 0x70 // encoding is +cc -#define IA32_JCC_IMM32_1 0x0F // opcode part 1 -#define IA32_JCC_IMM32_2 0x80 // encoding is +cc -#define IA32_RET 0xC3 // no extra encoding -#define IA32_RETN 0xC2 // encoding is -#define IA32_NEG_RM 0xF7 // encoding is /3 -#define IA32_INC_REG 0x40 // encoding is +r -#define IA32_INC_RM 0xFF // encoding is /0 -#define IA32_DEC_REG 0x48 // encoding is +r -#define IA32_DEC_RM 0xFF // encoding is /1 -#define IA32_OR_REG_RM 0x0B // encoding is /r -#define IA32_AND_REG_RM 0x23 // encoding is /r -#define IA32_AND_EAX_IMM32 0x25 // encoding is -#define IA32_AND_RM_IMM32 0x81 // encoding is /4 -#define IA32_AND_RM_IMM8 0x83 // encoding is /4 -#define IA32_NOT_RM 0xF7 // encoding is /2 -#define IA32_DIV_RM 0xF7 // encoding is /6 -#define IA32_MUL_RM 0xF7 // encoding is /4 -#define IA32_IDIV_RM 0xF7 // encoding is /7 -#define IA32_IMUL_RM 0xF7 // encoding is /5 -#define IA32_IMUL_REG_IMM32 0x69 // encoding is /r -#define IA32_IMUL_REG_IMM8 0x6B // encoding is /r -#define IA32_IMUL_REG_RM_1 0x0F // encoding is _2 -#define IA32_IMUL_REG_RM_2 0xAF // encoding is /r -#define IA32_SHR_RM_IMM8 0xC1 // encoding is /5 -#define IA32_SHR_RM_1 0xD1 // encoding is /5 -#define IA32_SHL_RM_IMM8 0xC1 // encoding is /4 -#define IA32_SHL_RM_1 0xD1 // encoding is /4 -#define IA32_SAR_RM_CL 0xD3 // encoding is /7 -#define IA32_SAR_RM_1 0xD1 // encoding is /7 -#define IA32_SHR_RM_CL 0xD3 // encoding is /5 -#define IA32_SHL_RM_CL 0xD3 // encoding is /4 -#define IA32_SAR_RM_IMM8 0xC1 // encoding is /7 -#define IA32_SETCC_RM8_1 0x0F // opcode part 1 -#define IA32_SETCC_RM8_2 0x90 // encoding is +cc /0 (8bits) -#define IA32_CMOVCC_RM_1 0x0F // opcode part 1 -#define IA32_CMOVCC_RM_2 0x40 // encoding is +cc /r -#define IA32_XCHG_EAX_REG 0x90 // encoding is +r -#define IA32_LEA_REG_MEM 0x8D // encoding is /r -#define IA32_POP_REG 0x58 // encoding is +r -#define IA32_PUSH_REG 0x50 // encoding is +r -#define IA32_PUSH_RM 0xFF // encoding is /6 -#define IA32_PUSH_IMM32 0x68 // encoding is -#define IA32_PUSH_IMM8 0x6A // encoding is -#define IA32_REP 0xF3 // no extra encoding -#define IA32_MOVSD 0xA5 // no extra encoding -#define IA32_MOVSB 0xA4 // no extra encoding -#define IA32_STOSD 0xAB // no extra encoding -#define IA32_CLD 0xFC // no extra encoding -#define IA32_PUSHAD 0x60 // no extra encoding -#define IA32_POPAD 0x61 // no extra encoding -#define IA32_NOP 0x90 // no extra encoding -#define IA32_INT3 0xCC // no extra encoding -#define IA32_FSTP_MEM32 0xD9 // encoding is /3 -#define IA32_FSTP_MEM64 0xDD // encoding is /3 -#define IA32_FLD_MEM32 0xD9 // encoding is /0 -#define IA32_FLD_MEM64 0xDD // encoding is /0 -#define IA32_FILD_MEM32 0xDB // encoding is /0 -#define IA32_FADD_MEM32 0xD8 // encoding is /0 -#define IA32_FADD_FPREG_ST0_1 0xDC // opcode part 1 -#define IA32_FADD_FPREG_ST0_2 0xC0 // encoding is +r -#define IA32_FSUB_MEM32 0xD8 // encoding is /4 -#define IA32_FMUL_MEM32 0xD8 // encoding is /1 -#define IA32_FDIV_MEM32 0xD8 // encoding is /6 -#define IA32_FSTCW_MEM16_1 0x9B // opcode part 1 -#define IA32_FSTCW_MEM16_2 0xD9 // encoding is /7 -#define IA32_FLDCW_MEM16 0xD9 // encoding is /5 -#define IA32_FISTP_MEM32 0xDB // encoding is /3 -#define IA32_FUCOMIP_1 0xDF // opcode part 1 -#define IA32_FUCOMIP_2 0xE8 // encoding is +r -#define IA32_FSTP_FPREG_1 0xDD // opcode part 1 -#define IA32_FSTP_FPREG_2 0xD8 // encoding is +r -#define IA32_MOVZX_R32_RM8_1 0x0F // opcode part 1 -#define IA32_MOVZX_R32_RM8_2 0xB6 // encoding is /r -#define IA32_MOVZX_R32_RM16_1 0x0F // opcode part 1 -#define IA32_MOVZX_R32_RM16_2 0xB7 // encoding is /r - - -namespace SourceHook -{ - namespace Impl - { - typedef GenBuffer JitWriter; - - inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm) - { - jit_uint8_t modrm = (mode << 6); - - modrm |= (reg << 3); - modrm |= (rm); - - return modrm; - } - - //mode is the scaling method - NOSCALE ... SCALE8 - //index is the register that is scaled - //base is the base register - inline jit_uint8_t ia32_sib(jit_uint8_t mode, jit_uint8_t index, jit_uint8_t base) - { - jit_uint8_t sib = (mode << 6); - - sib |= (index << 3); - sib |= (base); - - return sib; - } - - inline void IA32_Int3(JitWriter *jit) - { - jit->write_ubyte(IA32_INT3); - } - - /*********************** - * INCREMENT/DECREMENT * - ***********************/ - - inline void IA32_Inc_Reg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_INC_REG+reg); - } - - inline void IA32_Inc_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp) - { - jit->write_ubyte(IA32_INC_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, reg)); - jit->write_byte(disp); - } - - inline void IA32_Inc_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp) - { - jit->write_ubyte(IA32_INC_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, reg)); - jit->write_int32(disp); - } - - inline void IA32_Inc_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale) - { - jit->write_ubyte(IA32_INC_RM); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, REG_SIB)); - jit->write_ubyte(ia32_sib(scale, reg, base)); - } - - inline void IA32_Dec_Reg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_DEC_REG+reg); - } - - inline void IA32_Dec_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp) - { - jit->write_ubyte(IA32_DEC_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 1, reg)); - jit->write_byte(disp); - } - - inline void IA32_Dec_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp) - { - jit->write_ubyte(IA32_DEC_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP32, 1, reg)); - jit->write_int32(disp); - } - - inline void IA32_Dec_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale) - { - jit->write_ubyte(IA32_DEC_RM); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 1, REG_SIB)); - jit->write_ubyte(ia32_sib(scale, reg, base)); - } - - /**************** - * BINARY LOGIC * - ****************/ - - inline void IA32_Xor_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode) - { - jit->write_ubyte(IA32_XOR_RM_REG); - jit->write_ubyte(ia32_modrm(dest_mode, src, dest)); - } - - inline void IA32_Xor_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode) - { - jit->write_ubyte(IA32_XOR_REG_RM); - jit->write_ubyte(ia32_modrm(dest_mode, dest, src)); - } - - inline void IA32_Xor_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value) - { - jit->write_ubyte(IA32_XOR_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 6, reg)); - jit->write_byte(value); - } - - inline void IA32_Xor_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value) - { - jit->write_ubyte(IA32_XOR_RM_IMM32); - jit->write_ubyte(ia32_modrm(mode, 6, reg)); - jit->write_int32(value); - } - - inline void IA32_Xor_Eax_Imm32(JitWriter *jit, jit_int32_t value) - { - jit->write_ubyte(IA32_XOR_EAX_IMM32); - jit->write_int32(value); - } - - inline void IA32_Neg_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_NEG_RM); - jit->write_ubyte(ia32_modrm(mode, 3, reg)); - } - - inline void IA32_Or_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_OR_REG_RM); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_And_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_AND_REG_RM); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_And_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value) - { - jit->write_ubyte(IA32_AND_RM_IMM32); - jit->write_ubyte(ia32_modrm(mode, 4, reg)); - jit->write_int32(value); - } - - inline void IA32_And_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value) - { - jit->write_ubyte(IA32_AND_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 4, reg)); - jit->write_byte(value); - } - - inline void IA32_And_Eax_Imm32(JitWriter *jit, jit_int32_t value) - { - jit->write_ubyte(IA32_AND_EAX_IMM32); - jit->write_int32(value); - } - - inline void IA32_Not_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_NOT_RM); - jit->write_ubyte(ia32_modrm(mode, 2, reg)); - } - - inline void IA32_Shr_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SHR_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 5, dest)); - jit->write_ubyte(value); - } - - inline void IA32_Shr_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SHR_RM_1); - jit->write_ubyte(ia32_modrm(mode, 5, dest)); - } - - inline void IA32_Shl_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SHL_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 4, dest)); - jit->write_ubyte(value); - } - - inline void IA32_Shl_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SHL_RM_1); - jit->write_ubyte(ia32_modrm(mode, 4, dest)); - } - - inline void IA32_Sar_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SAR_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 7, dest)); - jit->write_ubyte(value); - } - - inline void IA32_Sar_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SAR_RM_CL); - jit->write_ubyte(ia32_modrm(mode, 7, reg)); - } - - inline void IA32_Sar_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SAR_RM_1); - jit->write_ubyte(ia32_modrm(mode, 7, dest)); - } - - inline void IA32_Shr_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SHR_RM_CL); - jit->write_ubyte(ia32_modrm(mode, 5, reg)); - } - - inline void IA32_Shl_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SHL_RM_CL); - jit->write_ubyte(ia32_modrm(mode, 4, reg)); - } - - inline void IA32_Xchg_Eax_Reg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_XCHG_EAX_REG+reg); - } - - /********************** - * ARITHMETIC (BASIC) * - **********************/ - - inline void IA32_Add_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_ADD_RM_REG); - jit->write_ubyte(ia32_modrm(mode, src, dest)); - } - - inline void IA32_Add_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_ADD_REG_RM); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Add_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t value, jit_uint8_t mode) - { - jit->write_ubyte(IA32_ADD_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 0, reg)); - jit->write_byte(value); - } - - inline void IA32_Add_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode) - { - jit->write_ubyte(IA32_ADD_RM_IMM32); - jit->write_ubyte(ia32_modrm(mode, 0, reg)); - jit->write_int32(value); - } - - inline void IA32_Add_Rm_ImmAuto(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode) - { - if (value >= SCHAR_MIN && value <= SCHAR_MAX) - IA32_Add_Rm_Imm8(jit, reg, static_cast(value), mode); - else - IA32_Add_Rm_Imm32(jit, reg, value, mode); - } - - inline void IA32_Add_Eax_Imm32(JitWriter *jit, jit_int32_t value) - { - jit->write_ubyte(IA32_ADD_EAX_IMM32); - jit->write_int32(value); - } - - inline void IA32_Sub_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SUB_RM_REG); - jit->write_ubyte(ia32_modrm(mode, src, dest)); - } - - inline void IA32_Sub_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SUB_REG_RM); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Sub_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8) - { - jit->write_ubyte(IA32_SUB_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); - jit->write_byte(disp8); - } - - inline void IA32_Sub_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8) - { - jit->write_ubyte(IA32_SUB_RM_REG); - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest)); - jit->write_byte(disp8); - } - - inline void IA32_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SUB_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 5, reg)); - jit->write_byte(val); - } - - inline void IA32_Sub_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SUB_RM_IMM32); - jit->write_ubyte(ia32_modrm(mode, 5, reg)); - jit->write_int32(val); - } - - inline void IA32_Sub_Rm_ImmAuto(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode) - { - if (val >= SCHAR_MIN && val <= SCHAR_MAX) - IA32_Sub_Rm_Imm8(jit, reg, static_cast(val), mode); - else - IA32_Sub_Rm_Imm32(jit, reg, val, mode); - } - - inline void IA32_Sbb_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SBB_REG_RM); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Sbb_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_int8_t value, jit_uint8_t mode) - { - jit->write_ubyte(IA32_SBB_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 3, dest)); - jit->write_byte(value); - } - - inline void IA32_Div_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_DIV_RM); - jit->write_ubyte(ia32_modrm(mode, 6, reg)); - } - - inline void IA32_IDiv_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_IDIV_RM); - jit->write_ubyte(ia32_modrm(mode, 7, reg)); - } - - inline void IA32_Mul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_MUL_RM); - jit->write_ubyte(ia32_modrm(mode, 4, reg)); - } - - inline void IA32_IMul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_IMUL_RM); - jit->write_ubyte(ia32_modrm(mode, 5, reg)); - } - - inline void IA32_IMul_Reg_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value) - { - jit->write_ubyte(IA32_IMUL_REG_IMM8); - jit->write_ubyte(ia32_modrm(mode, 0, reg)); - jit->write_byte(value); - } - - inline void IA32_IMul_Reg_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value) - { - jit->write_ubyte(IA32_IMUL_REG_IMM32); - jit->write_ubyte(ia32_modrm(mode, 0, reg)); - jit->write_int32(value); - } - - inline void IA32_IMul_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_IMUL_REG_RM_1); - jit->write_ubyte(IA32_IMUL_REG_RM_2); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Add_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) - { - jit->write_ubyte(IA32_ADD_RM_REG); - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest)); - jit->write_byte(disp); - } - - inline void IA32_Add_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) - { - jit->write_ubyte(IA32_ADD_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); - jit->write_byte(disp); - } - - inline void IA32_Add_Rm_Imm8_Disp8(JitWriter *jit, - jit_uint8_t dest, - jit_int8_t val, - jit_int8_t disp8) - { - jit->write_ubyte(IA32_ADD_RM_IMM8); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest)); - jit->write_byte(disp8); - jit->write_byte(val); - } - - inline void IA32_Add_Rm_Imm32_Disp8(JitWriter *jit, - jit_uint8_t dest, - jit_int32_t val, - jit_int8_t disp8) - { - jit->write_ubyte(IA32_ADD_RM_IMM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest)); - jit->write_byte(disp8); - jit->write_int32(val); - } - - inline jitoffs_t IA32_Add_Rm_Imm32_Later(JitWriter *jit, - jit_uint8_t dest, - jit_uint8_t mode) - { - jit->write_ubyte(IA32_ADD_RM_IMM32); - jit->write_ubyte(ia32_modrm(mode, 0, dest)); - jitoffs_t ptr = jit->get_outputpos(); - jit->write_int32(0); - return ptr; - } - - inline void IA32_Add_Rm_Imm8_Disp32(JitWriter *jit, - jit_uint8_t dest, - jit_int8_t val, - jit_int32_t disp32) - { - jit->write_ubyte(IA32_ADD_RM_IMM8); - jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest)); - jit->write_int32(disp32); - jit->write_byte(val); - } - - inline void IA32_Add_RmEBP_Imm8_Disp_Reg(JitWriter *jit, - jit_uint8_t dest_base, - jit_uint8_t dest_index, - jit_uint8_t dest_scale, - jit_int8_t val) - { - jit->write_ubyte(IA32_ADD_RM_IMM8); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB)); - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); - jit->write_byte(0); - jit->write_byte(val); - } - - inline void IA32_Sub_Rm_Imm8_Disp8(JitWriter *jit, - jit_uint8_t dest, - jit_int8_t val, - jit_int8_t disp8) - { - jit->write_ubyte(IA32_SUB_RM_IMM8); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, dest)); - jit->write_byte(disp8); - jit->write_byte(val); - } - - inline void IA32_Sub_Rm_Imm8_Disp32(JitWriter *jit, - jit_uint8_t dest, - jit_int8_t val, - jit_int32_t disp32) - { - jit->write_ubyte(IA32_SUB_RM_IMM8); - jit->write_ubyte(ia32_modrm(MOD_DISP32, 5, dest)); - jit->write_int32(disp32); - jit->write_byte(val); - } - - inline void IA32_Sub_RmEBP_Imm8_Disp_Reg(JitWriter *jit, - jit_uint8_t dest_base, - jit_uint8_t dest_index, - jit_uint8_t dest_scale, - jit_int8_t val) - { - jit->write_ubyte(IA32_SUB_RM_IMM8); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, REG_SIB)); - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); - jit->write_byte(0); - jit->write_byte(val); - } - - /** - * Memory Instructions - */ - - inline void IA32_Lea_Reg_DispRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale) - { - jit->write_ubyte(IA32_LEA_REG_MEM); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(scale, src_index, src_base)); - } - - inline void IA32_Lea_Reg_DispEBPRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale) - { - jit->write_ubyte(IA32_LEA_REG_MEM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(scale, src_index, src_base)); - jit->write_byte(0); - } - - inline void IA32_Lea_Reg_DispRegMultImm8(JitWriter *jit, - jit_uint8_t dest, - jit_uint8_t src_base, - jit_uint8_t src_index, - jit_uint8_t scale, - jit_int8_t val) - { - jit->write_ubyte(IA32_LEA_REG_MEM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(scale, src_index, src_base)); - jit->write_byte(val); - } - - inline void IA32_Lea_Reg_DispRegMultImm32(JitWriter *jit, - jit_uint8_t dest, - jit_uint8_t src_base, - jit_uint8_t src_index, - jit_uint8_t scale, - jit_int32_t val) - { - jit->write_ubyte(IA32_LEA_REG_MEM); - jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(scale, src_index, src_base)); - jit->write_int32(val); - } - - inline void IA32_Lea_Reg_RegMultImm32(JitWriter *jit, - jit_uint8_t dest, - jit_uint8_t src_index, - jit_uint8_t scale, - jit_int32_t val) - { - jit->write_ubyte(IA32_LEA_REG_MEM); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(scale, src_index, REG_IMM_BASE)); - jit->write_int32(val); - } - - inline void IA32_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val) - { - jit->write_ubyte(IA32_LEA_REG_MEM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src_base)); - jit->write_byte(val); - } - - inline void IA32_Lea_DispRegImm32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val) - { - jit->write_ubyte(IA32_LEA_REG_MEM); - jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src_base)); - jit->write_int32(val); - } - - inline void IA32_Lea_DispRegImmAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val) - { - if (val >= SCHAR_MIN && val <= SCHAR_MAX) - IA32_Lea_DispRegImm8(jit, dest, src_base, static_cast(val)); - else - IA32_Lea_DispRegImm32(jit, dest, src_base, val); - } - - /** - * Stack Instructions - */ - - inline void IA32_Pop_Reg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_POP_REG+reg); - } - - inline void IA32_Push_Reg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_PUSH_REG+reg); - } - - inline void IA32_Push_Imm8(JitWriter *jit, jit_int8_t val) - { - jit->write_ubyte(IA32_PUSH_IMM8); - jit->write_byte(val); - } - - inline void IA32_Push_Imm32(JitWriter *jit, jit_int32_t val) - { - jit->write_ubyte(IA32_PUSH_IMM32); - jit->write_int32(val); - } - - inline void IA32_Pushad(JitWriter *jit) - { - jit->write_ubyte(IA32_PUSHAD); - } - - inline void IA32_Popad(JitWriter *jit) - { - jit->write_ubyte(IA32_POPAD); - } - - inline void IA32_Push_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8) - { - jit->write_ubyte(IA32_PUSH_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, reg)); - jit->write_byte(disp8); - } - - inline void IA32_Push_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp32) - { - jit->write_ubyte(IA32_PUSH_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP32, 6, reg)); - jit->write_int32(disp32); - } - - inline void IA32_Push_Rm_DispAuto(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp) - { - if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) - IA32_Push_Rm_Disp8(jit, reg, static_cast(disp)); - else - IA32_Push_Rm_Disp32(jit, reg, disp); - } - - inline void IA32_Push_Rm_Disp8_ESP(JitWriter *jit, jit_int8_t disp8) - { - jit->write_ubyte(IA32_PUSH_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - jit->write_byte(disp8); - } - - /** - * Moving from REGISTER/MEMORY to REGISTER - */ - - inline void IA32_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_MOV_REG_RM); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Mov_Reg8_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_MOV_REG8_RM8); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Mov_Reg_RmESP(JitWriter *jit, jit_uint8_t dest) - { - jit->write_ubyte(IA32_MOV_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_ESP)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) - { - jit->write_ubyte(IA32_MOV_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); - jit->write_byte(disp); - } - - inline void IA32_Mov_Reg8_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) - { - jit->write_ubyte(IA32_MOV_REG8_RM8); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); - jit->write_byte(disp); - } - - inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t disp) - { - jit->write_ubyte(IA32_MOV_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - jit->write_byte(disp); - } - - inline void IA32_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - jit->write_ubyte(IA32_MOV_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); - jit->write_int32(disp); - } - - inline void IA32_Mov_Reg8_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - jit->write_ubyte(IA32_MOV_REG8_RM8); - jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); - jit->write_int32(disp); - } - - inline void IA32_Mov_Reg_Rm_Disp_Reg(JitWriter *jit, - jit_uint8_t dest, - jit_uint8_t src_base, - jit_uint8_t src_index, - jit_uint8_t src_scale) - { - jit->write_ubyte(IA32_MOV_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); - } - - inline void IA32_Mov_Reg_Rm_Disp_Reg_Disp8(JitWriter *jit, - jit_uint8_t dest, - jit_uint8_t src_base, - jit_uint8_t src_index, - jit_uint8_t src_scale, - jit_int8_t disp8) - { - jit->write_ubyte(IA32_MOV_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); - jit->write_byte(disp8); - } - - inline void IA32_Mov_Reg_RmEBP_Disp_Reg(JitWriter *jit, - jit_uint8_t dest, - jit_uint8_t src_base, - jit_uint8_t src_index, - jit_uint8_t src_scale) - { - jit->write_ubyte(IA32_MOV_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB)); - jit->write_ubyte(ia32_sib(src_scale, src_index, src_base)); - jit->write_byte(0); - } - - inline void IA32_Mov_Reg_Rm_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - if (disp == 0) - IA32_Mov_Reg_Rm(jit, dest, src, MOD_MEM_REG); - else if (disp <= SCHAR_MAX) - IA32_Mov_Reg_Rm_Disp8(jit, dest, src, static_cast(disp)); - else - IA32_Mov_Reg_Rm_Disp32(jit, dest, src, disp); - } - - /** - * Moving from REGISTER to REGISTER/MEMORY - */ - - inline void IA32_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_MOV_RM_REG); - jit->write_ubyte(ia32_modrm(mode, src, dest)); - } - - inline void IA32_Mov_Rm8_Reg8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_MOV_RM8_REG8); - jit->write_ubyte(ia32_modrm(mode, src, dest)); - } - - inline void IA32_Mov_Rm8_Reg8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) - { - jit->write_ubyte(IA32_MOV_RM8_REG8); - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest)); - jit->write_byte(disp); - } - - inline void IA32_Mov_Rm8_Reg8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - jit->write_ubyte(IA32_MOV_RM8_REG8); - jit->write_ubyte(ia32_modrm(MOD_DISP32, src, dest)); - jit->write_int32(disp); - } - - inline void IA32_Mov_Rm8_Reg8_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) - IA32_Mov_Rm8_Reg8_Disp8(jit, dest, src, static_cast(disp)); - else - IA32_Mov_Rm8_Reg8_Disp32(jit, dest, src, disp); - } - - inline void IA32_Mov_RmESP_Reg(JitWriter *jit, jit_uint8_t src) - { - jit->write_ubyte(IA32_MOV_RM_REG); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src, REG_ESP)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) - { - jit->write_ubyte(IA32_MOV_RM_REG); - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest)); - jit->write_byte(disp); - } - - inline void IA32_Mov_Rm_Reg_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - jit->write_ubyte(IA32_MOV_RM_REG); - jit->write_ubyte(ia32_modrm(MOD_DISP32, src, dest)); - jit->write_int32(disp); - } - - inline void IA32_Mov_Rm_Reg_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) - IA32_Mov_Rm_Reg_Disp8(jit, dest, src, static_cast(disp)); - else - IA32_Mov_Rm_Reg_Disp32(jit, dest, src, disp); - } - - inline void IA32_Mov_RmEBP_Reg_Disp_Reg(JitWriter *jit, - jit_uint8_t dest_base, - jit_uint8_t dest_index, - jit_uint8_t dest_scale, - jit_uint8_t src) - { - jit->write_ubyte(IA32_MOV_RM_REG); - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB)); - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); - jit->write_byte(0); - } - - inline void IA32_Mov_Rm8EBP_Reg_Disp_Reg(JitWriter *jit, - jit_uint8_t dest_base, - jit_uint8_t dest_index, - jit_uint8_t dest_scale, - jit_uint8_t src) - { - jit->write_ubyte(IA32_MOV_RM8_REG); - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB)); - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); - jit->write_byte(0); - } - - inline void IA32_Mov_Rm16EBP_Reg_Disp_Reg(JitWriter *jit, - jit_uint8_t dest_base, - jit_uint8_t dest_index, - jit_uint8_t dest_scale, - jit_uint8_t src) - { - jit->write_ubyte(IA32_16BIT_PREFIX); - jit->write_ubyte(IA32_MOV_RM_REG); - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB)); - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); - jit->write_byte(0); - } - - /** - * Moving from IMMEDIATE to REGISTER - */ - - inline jitoffs_t IA32_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t num) - { - jitoffs_t offs; - jit->write_ubyte(IA32_MOV_REG_IMM+dest); - offs = jit->get_outputpos(); - jit->write_int32(num); - return offs; - } - - inline void IA32_Mov_Rm_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val, jit_uint8_t mode) - { - jit->write_ubyte(IA32_MOV_RM_IMM32); - jit->write_ubyte(ia32_modrm(mode, 0, dest)); - jit->write_int32(val); - } - - inline void IA32_Mov_Rm_Imm32_Disp8(JitWriter *jit, - jit_uint8_t dest, - jit_int32_t val, - jit_int8_t disp8) - { - jit->write_ubyte(IA32_MOV_RM_IMM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest)); - jit->write_byte(disp8); - jit->write_int32(val); - } - - inline void IA32_Mov_Rm_Imm32_Disp32(JitWriter *jit, - jit_uint8_t dest, - jit_int32_t val, - jit_int32_t disp32) - { - jit->write_ubyte(IA32_MOV_RM_IMM32); - jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest)); - jit->write_int32(disp32); - jit->write_int32(val); - } - - inline void IA32_Mov_RmEBP_Imm32_Disp_Reg(JitWriter *jit, - jit_uint8_t dest_base, - jit_uint8_t dest_index, - jit_uint8_t dest_scale, - jit_int32_t val) - { - jit->write_ubyte(IA32_MOV_RM_IMM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB)); - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base)); - jit->write_byte(0); - jit->write_int32(val); - } - - inline void IA32_Mov_ESP_Disp8_Imm32(JitWriter *jit, jit_int8_t disp8, jit_int32_t val) - { - jit->write_ubyte(IA32_MOV_RM_IMM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - jit->write_byte(disp8); - jit->write_int32(val); - } - - /** - * Floating Point Instructions - */ - - inline void IA32_Fstcw_Mem16_ESP(JitWriter *jit) - { - jit->write_ubyte(IA32_FSTCW_MEM16_1); - jit->write_ubyte(IA32_FSTCW_MEM16_2); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 7, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Fldcw_Mem16_ESP(JitWriter *jit) - { - jit->write_ubyte(IA32_FLDCW_MEM16); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 5, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Fldcw_Mem16_Disp8_ESP(JitWriter *jit, jit_int8_t disp8) - { - jit->write_ubyte(IA32_FLDCW_MEM16); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - jit->write_byte(disp8); - } - - inline void IA32_Fistp_Mem32_ESP(JitWriter *jit) - { - jit->write_ubyte(IA32_FISTP_MEM32); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Fistp_Mem32_Disp8_Esp(JitWriter *jit, jit_int8_t disp8) - { - jit->write_ubyte(IA32_FISTP_MEM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 3, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - jit->write_byte(disp8); - } - - inline void IA32_Fucomip_ST0_FPUreg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_FUCOMIP_1); - jit->write_ubyte(IA32_FUCOMIP_2+reg); - } - - inline void IA32_Fadd_FPUreg_ST0(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_FADD_FPREG_ST0_1); - jit->write_ubyte(IA32_FADD_FPREG_ST0_2+reg); - } - - inline void IA32_Fadd_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) - { - jit->write_ubyte(IA32_FADD_MEM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src)); - jit->write_byte(val); - } - - inline void IA32_Fadd_Mem32_ESP(JitWriter *jit) - { - jit->write_ubyte(IA32_FADD_MEM32); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Fsub_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) - { - jit->write_ubyte(IA32_FSUB_MEM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 4, src)); - jit->write_byte(val); - } - - inline void IA32_Fmul_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) - { - jit->write_ubyte(IA32_FMUL_MEM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 1, src)); - jit->write_byte(val); - } - - inline void IA32_Fdiv_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) - { - jit->write_ubyte(IA32_FDIV_MEM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, src)); - jit->write_byte(val); - } - - inline void IA32_Fild_Mem32(JitWriter *jit, jit_uint8_t src) - { - jit->write_ubyte(IA32_FILD_MEM32); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src)); - } - - inline void IA32_Fstp_Mem32(JitWriter *jit, jit_uint8_t dest) - { - jit->write_ubyte(IA32_FSTP_MEM32); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, dest)); - } - - inline void IA32_Fstp_Mem32_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_int32_t disp) - { - jit->write_ubyte(IA32_FSTP_MEM32); - - if (disp > SCHAR_MIN && disp < SCHAR_MAX) - { - jit->write_ubyte(ia32_modrm(MOD_DISP8, 3, dest)); - jit->write_byte(static_cast(disp)); - } - else - { - jit->write_ubyte(ia32_modrm(MOD_DISP32, 3, dest)); - jit->write_byte(disp); - } - } - - inline void IA32_Fstp_Mem64(JitWriter *jit, jit_uint8_t dest) - { - jit->write_ubyte(IA32_FSTP_MEM64); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, dest)); - } - - inline void IA32_Fstp_Mem64_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_int32_t disp) - { - jit->write_ubyte(IA32_FSTP_MEM64); - - if (disp > SCHAR_MIN && disp < SCHAR_MAX) - { - jit->write_ubyte(ia32_modrm(MOD_DISP8, 3, dest)); - jit->write_byte(static_cast(disp)); - } - else - { - jit->write_ubyte(ia32_modrm(MOD_DISP32, 3, dest)); - jit->write_byte(disp); - } - } - - inline void IA32_Fstp_Mem32_ESP(JitWriter *jit) - { - jit->write_ubyte(IA32_FSTP_MEM32); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Fstp_Mem64_ESP(JitWriter *jit) - { - jit->write_ubyte(IA32_FSTP_MEM64); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Fstp_FPUreg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_FSTP_FPREG_1); - jit->write_ubyte(IA32_FSTP_FPREG_2+reg); - } - - inline void IA32_Fld_Mem32(JitWriter *jit, jit_uint8_t src) - { - jit->write_ubyte(IA32_FLD_MEM32); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src)); - } - - inline void IA32_Fld_Mem64(JitWriter *jit, jit_uint8_t src) - { - jit->write_ubyte(IA32_FLD_MEM64); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src)); - } - - inline void IA32_Fld_Mem32_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) - { - jit->write_ubyte(IA32_FLD_MEM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src)); - jit->write_byte(val); - } - - inline void IA32_Fld_Mem64_Disp8(JitWriter *jit, jit_uint8_t src, jit_int8_t val) - { - jit->write_ubyte(IA32_FLD_MEM64); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src)); - jit->write_byte(val); - } - - inline void IA32_Fld_Mem32_Disp32(JitWriter *jit, jit_uint8_t src, jit_int32_t val) - { - jit->write_ubyte(IA32_FLD_MEM32); - jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, src)); - jit->write_int32(val); - } - - inline void IA32_Fld_Mem64_Disp32(JitWriter *jit, jit_uint8_t src, jit_int32_t val) - { - jit->write_ubyte(IA32_FLD_MEM64); - jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, src)); - jit->write_int32(val); - } - - inline void IA32_Fld_Mem32_DispAuto(JitWriter *jit, jit_uint8_t src, jit_int32_t disp) - { - if (disp == 0) - IA32_Fld_Mem32(jit, src); - else if (disp <= SCHAR_MAX) - IA32_Fld_Mem32_Disp8(jit, src, static_cast(disp)); - else - IA32_Fld_Mem32_Disp32(jit, src, disp); - } - - inline void IA32_Fld_Mem64_DispAuto(JitWriter *jit, jit_uint8_t src, jit_int32_t disp) - { - if (disp == 0) - IA32_Fld_Mem64(jit, src); - else if (disp <= SCHAR_MAX) - IA32_Fld_Mem64_Disp8(jit, src, static_cast(disp)); - else - IA32_Fld_Mem64_Disp32(jit, src, disp); - } - - /** - * Move data with zero extend - */ - - inline void IA32_Movzx_Reg32_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_MOVZX_R32_RM8_1); - jit->write_ubyte(IA32_MOVZX_R32_RM8_2); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Movzx_Reg32_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) - { - jit->write_ubyte(IA32_MOVZX_R32_RM8_1); - jit->write_ubyte(IA32_MOVZX_R32_RM8_2); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); - jit->write_byte(disp); - } - - inline void IA32_Movzx_Reg32_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - jit->write_ubyte(IA32_MOVZX_R32_RM8_1); - jit->write_ubyte(IA32_MOVZX_R32_RM8_2); - jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); - jit->write_int32(disp); - } - - inline void IA32_Movzx_Reg32_Rm8_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) - IA32_Movzx_Reg32_Rm8_Disp8(jit, dest, src, static_cast(disp)); - else - IA32_Movzx_Reg32_Rm8_Disp32(jit, dest, src, disp); - } - - inline void IA32_Movzx_Reg32_Rm16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_MOVZX_R32_RM16_1); - jit->write_ubyte(IA32_MOVZX_R32_RM16_2); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Movzx_Reg32_Rm16_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp) - { - jit->write_ubyte(IA32_MOVZX_R32_RM16_1); - jit->write_ubyte(IA32_MOVZX_R32_RM16_2); - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src)); - jit->write_byte(disp); - } - - inline void IA32_Movzx_Reg32_Rm16_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - jit->write_ubyte(IA32_MOVZX_R32_RM16_1); - jit->write_ubyte(IA32_MOVZX_R32_RM16_2); - jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src)); - jit->write_int32(disp); - } - - inline void IA32_Movzx_Reg32_Rm16_DispAuto(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp) - { - if (disp >= SCHAR_MIN && disp <= SCHAR_MAX) - IA32_Movzx_Reg32_Rm16_Disp8(jit, dest, src, static_cast(disp)); - else - IA32_Movzx_Reg32_Rm16_Disp32(jit, dest, src, disp); - } - - /** - * Branching/Jumping - */ - - inline jitoffs_t IA32_Jump_Cond_Imm8(JitWriter *jit, jit_uint8_t cond, jit_int8_t disp) - { - jitoffs_t ptr; - jit->write_ubyte(IA32_JCC_IMM+cond); - ptr = jit->get_outputpos(); - jit->write_byte(disp); - return ptr; - } - - inline jitoffs_t IA32_Jump_Imm32(JitWriter *jit, jit_int32_t disp) - { - jitoffs_t ptr; - jit->write_ubyte(IA32_JMP_IMM32); - ptr = jit->get_outputpos(); - jit->write_int32(disp); - return ptr; - } - - inline jitoffs_t IA32_Jump_Imm8(JitWriter *jit, jit_int8_t disp) - { - jitoffs_t ptr; - jit->write_ubyte(IA32_JMP_IMM8); - ptr = jit->get_outputpos(); - jit->write_byte(disp); - return ptr; - } - - inline jitoffs_t IA32_Jump_Cond_Imm32(JitWriter *jit, jit_uint8_t cond, jit_int32_t disp) - { - jitoffs_t ptr; - jit->write_ubyte(IA32_JCC_IMM32_1); - jit->write_ubyte(IA32_JCC_IMM32_2+cond); - ptr = jit->get_outputpos(); - jit->write_int32(disp); - return ptr; - } - - inline void IA32_Jump_Reg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_JMP_RM); - jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg)); - } - - inline void IA32_Jump_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_JMP_RM); - jit->write_ubyte(ia32_modrm(mode, 4, reg)); - } - - inline jitoffs_t IA32_Call_Imm32(JitWriter *jit, jit_int32_t disp) - { - jitoffs_t ptr; - jit->write_ubyte(IA32_CALL_IMM32); - ptr = jit->get_outputpos(); - jit->write_int32(disp); - return ptr; - } - - inline void IA32_Call_Reg(JitWriter *jit, jit_uint8_t reg) - { - jit->write_ubyte(IA32_CALL_RM); - jit->write_ubyte(ia32_modrm(MOD_REG, 2, reg)); - } - - inline void IA32_Call_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode) - { - jit->write_ubyte(IA32_CALL_RM); - jit->write_ubyte(ia32_modrm(mode, 4, reg)); - } - - inline void IA32_Return(JitWriter *jit) - { - jit->write_ubyte(IA32_RET); - } - - inline void IA32_Return_Popstack(JitWriter *jit, unsigned short bytes) - { - jit->write_ubyte(IA32_RETN); - jit->write_ushort(bytes); - } - - inline void IA32_Test_Rm_Reg(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_uint8_t mode) - { - jit->write_ubyte(IA32_TEST_RM_REG); - jit->write_ubyte(ia32_modrm(mode, reg2, reg1)); - } - - inline void IA32_Test_Rm_Reg8(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_uint8_t mode) - { - jit->write_ubyte(IA32_TEST_RM_REG8); - jit->write_ubyte(ia32_modrm(mode, reg2, reg1)); - } - - inline void IA32_Test_Rm_Imm32(JitWriter *jit, jit_uint8_t operand1, jit_int32_t imm_operand, jit_uint8_t mode) - { - jit->write_ubyte(IA32_TEST_RM_IMM32); - jit->write_ubyte(ia32_modrm(mode, 0, operand1)); - jit->write_int32(imm_operand); - } - - inline void IA32_Cmp_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_CMP_RM_REG); - jit->write_ubyte(ia32_modrm(mode, src, dest)); - } - - inline void IA32_Cmp_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode) - { - jit->write_ubyte(IA32_CMP_REG_RM); - jit->write_ubyte(ia32_modrm(mode, dest, src)); - } - - inline void IA32_Cmp_Reg_Rm_ESP(JitWriter *jit, jit_uint8_t cmpreg) - { - jit->write_ubyte(IA32_CMP_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, cmpreg, REG_SIB)); - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP)); - } - - inline void IA32_Cmp_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_int8_t disp8) - { - jit->write_ubyte(IA32_CMP_REG_RM); - jit->write_ubyte(ia32_modrm(MOD_DISP8, reg1, reg2)); - jit->write_byte(disp8); - } - - inline void IA32_Cmp_Rm_Imm8(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int8_t imm8) - { - jit->write_ubyte(IA32_CMP_RM_IMM8); - jit->write_ubyte(ia32_modrm(mode, 7, rm)); - jit->write_byte(imm8); - } - - inline void IA32_Cmp_Rm_Imm32(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int32_t imm32) - { - jit->write_ubyte(IA32_CMP_RM_IMM32); - jit->write_ubyte(ia32_modrm(mode, 7, rm)); - jit->write_int32(imm32); - } - - inline void IA32_Cmp_Rm_Imm32_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8, jit_int32_t imm32) - { - jit->write_ubyte(IA32_CMP_RM_IMM32); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg)); - jit->write_byte(disp8); - jit->write_int32(imm32); - } - - inline void IA32_Cmp_Rm_Disp8_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp, jit_int8_t imm8) - { - jit->write_ubyte(IA32_CMP_RM_IMM8); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg)); - jit->write_byte(disp); - jit->write_byte(imm8); - } - - inline void IA32_Cmp_Al_Imm8(JitWriter *jit, jit_int8_t value) - { - jit->write_ubyte(IA32_CMP_AL_IMM32); - jit->write_byte(value); - } - - inline void IA32_Cmp_Eax_Imm32(JitWriter *jit, jit_int32_t value) - { - jit->write_ubyte(IA32_CMP_EAX_IMM32); - jit->write_int32(value); - } - - inline void IA32_SetCC_Rm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t cond) - { - jit->write_ubyte(IA32_SETCC_RM8_1); - jit->write_ubyte(IA32_SETCC_RM8_2+cond); - jit->write_ubyte(ia32_modrm(MOD_REG, 0, reg)); - } - - inline void IA32_CmovCC_Rm(JitWriter *jit, jit_uint8_t src, jit_uint8_t cond) - { - jit->write_ubyte(IA32_CMOVCC_RM_1); - jit->write_ubyte(IA32_CMOVCC_RM_2+cond); - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, src)); - } - - inline void IA32_CmovCC_Rm_Disp8(JitWriter *jit, jit_uint8_t src, jit_uint8_t cond, jit_int8_t disp) - { - jit->write_ubyte(IA32_CMOVCC_RM_1); - jit->write_ubyte(IA32_CMOVCC_RM_2+cond); - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, src)); - jit->write_byte(disp); - } - - inline void IA32_Cmpsb(JitWriter *jit) - { - jit->write_ubyte(IA32_CMPSB); - } - - inline void IA32_Rep(JitWriter *jit) - { - jit->write_ubyte(IA32_REP); - } - - inline void IA32_Movsd(JitWriter *jit) - { - jit->write_ubyte(IA32_MOVSD); - } - - inline void IA32_Movsb(JitWriter *jit) - { - jit->write_ubyte(IA32_MOVSB); - } - - inline void IA32_Stosd(JitWriter *jit) - { - jit->write_ubyte(IA32_STOSD); - } - - inline void IA32_Cld(JitWriter *jit) - { - jit->write_ubyte(IA32_CLD); - } - - } -} - -#endif //_INCLUDE_JIT_X86_MACROS_H diff --git a/sourcehook/sourcehook_impl.h b/sourcehook/sourcehook_impl.h deleted file mode 100644 index 2ee0fa5..0000000 --- a/sourcehook/sourcehook_impl.h +++ /dev/null @@ -1,340 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_IMPL_H__ -#define __SOURCEHOOK_IMPL_H__ - -#include "sourcehook.h" -#include "sh_memory.h" -#include "sh_list.h" -#include "sh_vector.h" -#include "sh_tinyhash.h" -#include "sh_stack.h" - -/* - -IMPLEMENTATION INFO - ---------------------------------------- - :TODO: update ??? - -Protos ("Prototypes") - The purpose of protos is to provide the amount of type information about a function - which is required to be able to execute a function call without corrupting the stack. - Our protos do not fully do this, but they provide the size of the return value, the number of - parameters, and the size of each parameter, which is enough for most situations. - - There are two version of protos: - OLD: - C-Style strings. - - 0_void: - "attrib" - 1_void: - "attrib|param1_type" - 2_void: - "attrib|param1_type|param2_type - 0: - "attrib|ret_type" - 1: - "attrib|ret_type|param1_type" - 2: - "attrib|ret_type|param2_type" - - Old protos are deprecated. - - NEW: - New protos are in fact pointers to the ProtoInfo structure (see sourcehook.h) - - Old protos begin with a non-zero byte, new protos begin with a zero byte. - - Protos are usually stored in a CProto instance. - ---------------------------------------- -Hook managers and hook manager containers - Each hookman container is tied to _one_ proto/vtable index/vtable offset info. - Hookman containers then contain a list of hook managers provided by plugins, sorted by version. - (higher versions come first) - - Duplicate hook managers are ignored (ie. hook managers where proto, vtable index, vtable offset, - plugin, version are the same as in an already exisiting hook manager) - - A new hook manager is always added to the end of the version group in the corresponding - hook container. - - If the new hook manager was added to the beginning of the container (which only happens if - it is the first one or if it has a higher version than the previously first hook manager), - the now second hook manager is shut down and the new hook manager takes its job. - - A "hook manager container id" (HMCI) consits of three values: proto, vtbl index, vtbl offset. ---------------------------------------- -Hooks - When adding a hook, first the proposed hook manager is added to the corresponding - hook manager container as described above. - - Then the first hook manager in the the manhook container is chosen to handle the function. - - Removing a hook does not neccessarily unreigster the plugin's hook manager. In order to do this, - use RemoveHookManager or UnloadPlugin/ - - Hooks can be paused - they remain in memory but they are not called. In SH, the hook iterator - classes handle pausing transparently. - - The hook loop is supposed to call ShouldContinue before each iteration. This makes hook handlers - able to remove themselves. - ---------------------------------------- -Call classes - - !! deprecated !! - see below (new SH_CALL) - - Call classes are identified by a this pointer and an instance size - - We use the instance size because a derived class instance and a base class instance could - have the same this pointers, and we want to avoid that the derived class - (which could be bigger) gets the same callclass as the base class (mainly if the - base class' callclass was requested first). - - Call classes are reference counted. - - The original function pointers are stored in a vector (in order to allow fast random access). - These vectors are stored as the value type of a hash. The key type is int and represents the - vtable offset. - - If the hash key doesn't exist or the vtblidx is out of range or the corresponding element in the - vector is NULL, there is no hook on that function. - ---------------------------------------- -Recalls - Recalls are used for the META_RETURN_(VALUE_)NEWPARAMS macros, ie. to change the parameters - in the hook loop on the fly. - - First, the macro calls DoRecall(), then it calls the function the hook is attached to -> it - calls the hookfunc. SourceHook makes sure that the newly invoked hook loop starts where the last - one left off and that status variables like status, previous result, override return are kept. - When this recurisvely called hookfunc returns, the macro returns what it returned - (using MRES_SUPERCEDE). CSourceHookImpl returns false from ShouldContinue so the original hook loop - is abandonned. - -Post Recalls - People wanted to be able to use META_RETURN_(VALUE_)NEWPARAMS from post hooks as well. Crazy people! - Anyway, for this, we have to know where a hook handler is. Is it executing pre or post hooks at the moment? - The only way we can know this is watching when it calls CHookList::GetIter(). So CHookList gets a new variable: - m_RequestedFlag. It also gets two new functions: RQFlagReset() and RQFlagGet(). - HookLoopBegin() calls RQFlagReset on both hooklists of the iface; then DoRecall() checks whether the postlist's - RQ flag is set. if yes, the hook loop is in post mode. - - So, what a about a recall in post mode? The first ShouldContinue returns false and sets Status to supercede. - This way the pre hooks and the function call will be skipped. Then, then next ShouldContinue returns true, so we get - into the post hooks. HA! - -Return Values in Post Recalls - The easy case is when we already have an override return value. In this case, the status register gets transferred, - and so does the override return pointer. So, basically, everything is ok. - - However, what happens if we don't? ie. the status register is on MRES_IGNORED? In this case we'd have to transfer the - orig ret value. But we can't: There's no way to tell the hookfunc: "Use this as orig ret pointer". It uses its own. - So, we emulate it. GetOrigRet will return the orig ret pointer from the old hook loop. If still no one overrides it, - we'd have to return it. BUT! HOW TO DO THIS? Check out SH_RETURN(). First calls HookLoopEnd(), then decides whether - to return the override retval or the orig retval. But it doesn't ask for a new override return. So we give the function - the last orig return value as its new override return value; but leave status where it is so everything works, and in - HookLoopEnd we make sure that status is high enough so that the override return will be returned. crazy. - - All this stuff could be much less complicated if I didn't try to preserve binary compatibility :) - -VP Hooks - VP hooks are hooks which are called on a vfnptr, regardless of the this pointer with which it was called. They are - implemented as a special CIface instance with m_Ptr = NULL. All Hook Lists have a new "ListCatIterator" which - virtually concatenates the NULL-interface-hook-list with their normal hook list. - - - I'm afraid that with the addition of Recalls and VP Hooks, SourceHook is now a pretty complex and hacked-together - binary compatible beast which is pretty hard to maintain unless you've written it :) - -New SH_CALL - The addition of VP hooks messed up the Call Classes concept (see above) - call classes are bound to an - instance pointer; they only work on one of the hooked instances. But VP hooks are called on all instances. - - That's why now, SH_CALL takes an instance pointer instead of a callclass pointer. It basically does this: - 1) call SH_GLOB_PTR->SetIgnoreHooks(vfnptr) - 2) call this->*mfp - 3) call SH_GLOB_PTR->ResetIgnoreHooks(vfnptr) - - SourceHook stroes the "ignored vfnptr" and makes CVfnPtr::FindIface return NULL if the CVfnPtr instance - corresponds to the ignored vfnptr. This way the hook manager thinks that the instance isn't hooked, and calls - the original function. Everything works fine. This works even for VP hooks. -*/ - -#include "sourcehook_impl_cproto.h" -#include "sourcehook_impl_chookmaninfo.h" -#include "sourcehook_impl_chook.h" -#include "sourcehook_impl_ciface.h" -#include "sourcehook_impl_cvfnptr.h" -#include "sourcehook_impl_chookidman.h" - -namespace SourceHook -{ - /** - * @brief The SourceHook implementation - */ - - namespace Impl - { - struct CHookContext : IHookContext - { - enum State - { - State_Born, - State_Pre, - State_PreVP, - State_Post, - State_PostVP, - State_OrigCall, - State_Dead, - - // Special - State_Ignore, - State_Recall_Pre, - State_Recall_PreVP, - State_Recall_Post, - State_Recall_PostVP - }; - - int m_State; - List::iterator m_Iter; - - CVfnPtr *pVfnPtr; - CIface *pIface; - - META_RES *pStatus; - META_RES *pPrevRes; - META_RES *pCurRes; - - void *pThisPtr; - const void *pOrigRet; - void *pOverrideRet; - void *pIfacePtr; - - bool m_CallOrig; - - void SkipPaused(List::iterator &iter, List &list) - { - while (iter != list.end() && iter->IsPaused()) - ++iter; - } - public: - void HookRemoved(List::iterator oldhookiter, List::iterator nexthookiter); - void IfaceRemoved(CIface *iface); - void VfnPtrRemoved(CVfnPtr *vfnptr); - - ISHDelegate *GetNext(); - void *GetOverrideRetPtr(); - const void *GetOrigRetPtr(); - bool ShouldCallOrig(); - }; - - class CVfnPtrList : public List - { - public: - CVfnPtr &GetVfnPtr(void *p); - }; - - typedef CStack HookContextStack; - - - class CSourceHookImpl : public ISourceHook - { - private: - CHookManList m_HookManList; - CVfnPtrList m_VfnPtrs; - CHookIDManager m_HookIDMan; - HookContextStack m_ContextStack; - - bool SetHookPaused(int hookid, bool paused); - CHookManList::iterator RemoveHookManager(CHookManList::iterator iter); - public: - CSourceHookImpl(); - virtual ~CSourceHookImpl(); - - /** - * @brief Returns the interface version - */ - int GetIfaceVersion(); - - /** - * @brief Returns the implemnetation version - */ - int GetImplVersion(); - - int AddHook(Plugin plug, AddHookMode mode, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post); - - bool RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, - ISHDelegate *handler, bool post); - - bool RemoveHookByID(int hookid); - - bool PauseHookByID(int hookid); - bool UnpauseHookByID(int hookid); - - void SetRes(META_RES res); //!< Sets the meta result - META_RES GetPrevRes(); //!< Gets the meta result of the - //!< previously calledhandler - META_RES GetStatus(); //!< Gets the highest meta result - const void *GetOrigRet(); //!< Gets the original result. - //!< If not in post function, undefined - const void *GetOverrideRet(); //!< Gets the override result. - //!< If none is specified, NULL - void *GetIfacePtr(); //!< Gets the interface pointer - - void *GetOverrideRetPtr(); //!< Used for setting the override return value - - /** - * @brief Make sure that a plugin is not used by any other plugins anymore, and unregister all its hook managers - */ - void UnloadPlugin(Plugin plug); - - void RemoveHookManager(Plugin plug, HookManagerPubFunc pubFunc); - - void SetIgnoreHooks(void *vfnptr); - void ResetIgnoreHooks(void *vfnptr); - - void DoRecall(); - - IHookContext *SetupHookLoop(IHookManagerInfo *hi, void *vfnptr, void *thisptr, void **origentry, META_RES *statusPtr, - META_RES *prevResPtr, META_RES *curResPtr, const void *origRetPtr, void *overrideRetPtr); - - void EndContext(IHookContext *pCtx); - - void *GetOrigVfnPtrEntry(void *vfnptr); - - /** - * @brief Shut down the whole system, unregister all hook managers - */ - void CompleteShutdown(); - - /** - * @brief Pauses all hooks of a plugin - * - * @param plug The unique identifier of the plugin - */ - void PausePlugin(Plugin plug); - - /** - * @brief Unpauses all hooks of a plugin - * - * @param plug The unique identifier of the plugin - */ - void UnpausePlugin(Plugin plug); - }; - } -} - -#endif diff --git a/sourcehook/sourcehook_impl_chook.h b/sourcehook/sourcehook_impl_chook.h deleted file mode 100644 index db00e5b..0000000 --- a/sourcehook/sourcehook_impl_chook.h +++ /dev/null @@ -1,106 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_IMPL_CHOOK_H__ -#define __SOURCEHOOK_IMPL_CHOOK_H__ - -namespace SourceHook -{ - namespace Impl - { - class CHook - { - // *** Data *** - Plugin m_OwnerPlugin; - int m_ThisPointerOffset; - ISHDelegate *m_pHandler; - int m_HookID; - bool m_Paused; - public: - - // *** Descriptor *** - struct Descriptor - { - Plugin m_OwnerPlugin; - int m_ThisPointerOffset; - ISHDelegate *m_pHandler; - - Descriptor(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler) - : m_OwnerPlugin(ownerPlugin), m_ThisPointerOffset(thisPtrOffset), - m_pHandler(pHandler) - { - } - }; - - // *** Interface *** - inline CHook(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler, int hookid, bool paused=false); - inline bool operator==(const Descriptor &other) const; - inline bool operator==(int hookid) const; - inline Plugin GetOwnerPlugin() const; - inline int GetThisPointerOffset() const; - inline ISHDelegate *GetHandler() const; - inline void SetPaused(bool value); - inline bool IsPaused() const; - inline int GetID() const; - }; - - // *** Implementation *** - inline CHook::CHook(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler, int hookid, bool paused) - : m_OwnerPlugin(ownerPlugin), m_ThisPointerOffset(thisPtrOffset), - m_pHandler(pHandler), m_HookID(hookid), m_Paused(paused) - { - } - - inline bool CHook::operator==(const Descriptor &other) const - { - return m_OwnerPlugin == other.m_OwnerPlugin - && m_ThisPointerOffset == other.m_ThisPointerOffset - && m_pHandler == other.m_pHandler; - } - - inline bool CHook::operator==(int hookid) const - { - return m_HookID == hookid; - } - - inline Plugin CHook::GetOwnerPlugin() const - { - return m_OwnerPlugin; - } - - inline int CHook::GetThisPointerOffset() const - { - return m_ThisPointerOffset; - } - - inline ISHDelegate *CHook::GetHandler() const - { - return m_pHandler; - } - - inline void CHook::SetPaused(bool value) - { - m_Paused = value; - } - - inline bool CHook::IsPaused() const - { - return m_Paused; - } - - inline int CHook::GetID() const - { - return m_HookID; - } - } -} - -#endif - diff --git a/sourcehook/sourcehook_impl_chookidman.h b/sourcehook/sourcehook_impl_chookidman.h deleted file mode 100644 index 9fad57b..0000000 --- a/sourcehook/sourcehook_impl_chookidman.h +++ /dev/null @@ -1,81 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_IMPL_CHOOKIDMAN_H__ -#define __SOURCEHOOK_IMPL_CHOOKIDMAN_H__ - -#include "sh_vector.h" - -namespace SourceHook -{ - namespace Impl - { - // Associates hook ids with info about the hooks - // Also used to keep track of used hook ids - class CHookIDManager - { - public: - struct Entry - { - bool isfree; - - // hookman info - CProto proto; - int vtbl_offs; - int vtbl_idx; - - // vfnptr - void *vfnptr; - - // iface - void* adjustediface; - - // hook - Plugin plug; - int thisptr_offs; - ISHDelegate *handler; - bool post; - - Entry(const CProto &pprt, int pvo, int pvi, void *pvp, void *pai, Plugin pplug, int pto, - ISHDelegate *ph, bool ppost) - : isfree(false), proto(pprt), vtbl_offs(pvo), vtbl_idx(pvi), vfnptr(pvp), - adjustediface(pai), plug(pplug), thisptr_offs(pto), handler(ph), post(ppost) - { - } - Entry() - { - } - }; - private: - // Internally, hookid 1 is stored as m_Entries[0] - - CVector m_Entries; - public: - CHookIDManager(); - int New(const CProto &proto, int vtbl_offs, int vtbl_idx, void *vfnptr, void *adjustediface, - Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post); - bool Remove(int hookid); - const Entry * QueryHook(int hookid); - - // Finds all hooks with the given info, and fills the hookids into output. - void FindAllHooks(CVector &output, const CProto &proto, int vtbl_offs, int vtbl_idx, - void *adjustediface, Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post); - - // Removes all hooks with a specified vfnptr - void RemoveAll(void *vfnptr); - - void FindAllHooks(CVector &output); - void FindAllHooks(CVector &output, Plugin plug); - }; - } -} - -#endif - diff --git a/sourcehook/sourcehook_impl_chookmaninfo.h b/sourcehook/sourcehook_impl_chookmaninfo.h deleted file mode 100644 index 176f164..0000000 --- a/sourcehook/sourcehook_impl_chookmaninfo.h +++ /dev/null @@ -1,199 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_IMPL_CHOOKMANINFO_H__ -#define __SOURCEHOOK_IMPL_CHOOKMANINFO_H__ - -#include "sh_list.h" -#include "sourcehook_impl_cproto.h" -#include "sourcehook_hookmangen.h" - -namespace SourceHook -{ - namespace Impl - { - class CVfnPtr; - - class CHookManager : public IHookManagerInfo - { - // *** Data *** - Plugin m_OwnerPlugin; - HookManagerPubFunc m_PubFunc; - int m_VtblOffs; - int m_VtblIdx; - CProto m_Proto; - int m_Version; - - void *m_HookfuncVfnptr; - - List m_VfnPtrs; - public: - // *** Descriptor *** - struct Descriptor - { - Plugin m_OwnerPlugin; - HookManagerPubFunc m_PubFunc; - Descriptor(Plugin ownerPlugin, HookManagerPubFunc pubFunc) - : m_OwnerPlugin(ownerPlugin), m_PubFunc(pubFunc) - { - } - }; - - // *** Interface *** - inline CHookManager(Plugin ownerPlugin, HookManagerPubFunc pubFunc); - - inline bool operator==(const Descriptor &other) const; - inline bool operator==(const CHookManager &other) const; - - inline operator bool() const; - inline Plugin GetOwnerPlugin() const; - inline int GetVtblOffs() const; - inline int GetVtblIdx() const; - inline const CProto &GetProto() const; - inline int GetVersion() const; - inline void *GetHookFunc() const; - inline HookManagerPubFunc GetPubFunc() const; - - inline void Register(); - inline void Unregister(); - - inline void IncrRef(CVfnPtr *pVfnPtr); - inline void DecrRef(CVfnPtr *pVfnPtr); - - List &GetVfnPtrList() - { - return m_VfnPtrs; - } - - // *** IHookManagerInfo interface *** - void SetInfo(int hookman_version, int vtbloffs, int vtblidx, - ProtoInfo *proto, void *hookfunc_vfnptr); - }; - - class CHookManList : public List - { - public: - inline CHookManager *GetHookMan(Plugin plug, HookManagerPubFunc pubFunc); - inline CHookManager *GetHookMan(CHookManager &hm); - }; - - // *** Implementation *** - inline CHookManager::CHookManager(Plugin ownerPlugin, HookManagerPubFunc pubFunc) - : m_OwnerPlugin(ownerPlugin), m_PubFunc(pubFunc), m_Version(-1) - { - // Query pubfunc - // -> Should call SetInfo and set all the other variables! - if (m_PubFunc(false, this) != 0) - { - // Error! - m_Version = -1; - } - } - - inline CHookManager::operator bool() const - { - return m_Version != -1; - } - - inline bool CHookManager::operator==(const Descriptor &other) const - { - return m_OwnerPlugin == other.m_OwnerPlugin - && m_PubFunc == other.m_PubFunc; - } - - inline bool CHookManager::operator==(const CHookManager &other) const - { - return m_OwnerPlugin == other.m_OwnerPlugin - && m_PubFunc == other.m_PubFunc; - } - - inline Plugin CHookManager::GetOwnerPlugin() const - { - return m_OwnerPlugin; - } - - inline int CHookManager::GetVtblOffs() const - { - return m_VtblOffs; - } - - inline int CHookManager::GetVtblIdx() const - { - return m_VtblIdx; - } - - inline const CProto &CHookManager::GetProto() const - { - return m_Proto; - } - - inline int CHookManager::GetVersion() const - { - return m_Version; - } - - inline void *CHookManager::GetHookFunc() const - { - return *reinterpret_cast(m_HookfuncVfnptr); - } - - inline HookManagerPubFunc CHookManager::GetPubFunc() const - { - return m_PubFunc; - } - - inline void CHookManager::Register() - { - m_PubFunc(true, this); - } - - inline void CHookManager::Unregister() - { - m_PubFunc(true, NULL); - } - - inline void CHookManager::IncrRef(CVfnPtr *pVfnPtr) - { - m_VfnPtrs.push_back(pVfnPtr); - if (m_VfnPtrs.size() == 1) - Register(); - } - - inline void CHookManager::DecrRef(CVfnPtr *pVfnPtr) - { - m_VfnPtrs.remove(pVfnPtr); - if (m_VfnPtrs.empty()) - Unregister(); - } - - inline CHookManager *CHookManList::GetHookMan(Plugin plug, HookManagerPubFunc pubFunc) - { - CHookManager hm(plug, pubFunc); - return GetHookMan(hm); - } - - inline CHookManager *CHookManList::GetHookMan(CHookManager &hm) - { - iterator iter = find(hm); - if (iter == end()) - { - push_back(hm); - return &(back()); - } - else - { - return &(*iter); - } - } - } -} - -#endif - diff --git a/sourcehook/sourcehook_impl_ciface.h b/sourcehook/sourcehook_impl_ciface.h deleted file mode 100644 index 482dd7c..0000000 --- a/sourcehook/sourcehook_impl_ciface.h +++ /dev/null @@ -1,81 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_IMPL_CIFACE_H__ -#define __SOURCEHOOK_IMPL_CIFACE_H__ - -#include "sh_list.h" - -namespace SourceHook -{ - namespace Impl - { - class CIface - { - // *** Data *** - void *m_Ptr; - - List m_PreHooks; - List m_PostHooks; - public: - - // *** Descriptor *** - typedef void* Descriptor; - - // *** Interface *** - inline CIface(void *ptr); - inline bool operator==(const Descriptor &other); - inline void *GetPtr() const; - inline List &GetPreHookList(); - inline List &GetPostHookList(); - inline const List &GetPreHookList() const; - inline const List &GetPostHookList() const; - }; - - // *** Implementation *** - inline CIface::CIface(void *ptr) - : m_Ptr(ptr) - { - } - - inline bool CIface::operator==(const Descriptor &other) - { - return m_Ptr == other; - } - - inline void *CIface::GetPtr() const - { - return m_Ptr; - } - - inline List &CIface::GetPreHookList() - { - return m_PreHooks; - } - - inline List &CIface::GetPostHookList() - { - return m_PostHooks; - } - - inline const List &CIface::GetPreHookList() const - { - return m_PreHooks; - } - - inline const List &CIface::GetPostHookList() const - { - return m_PostHooks; - } - } -} - -#endif - diff --git a/sourcehook/sourcehook_impl_cproto.h b/sourcehook/sourcehook_impl_cproto.h deleted file mode 100644 index 9521cd2..0000000 --- a/sourcehook/sourcehook_impl_cproto.h +++ /dev/null @@ -1,141 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_IMPL_CPROTO_H__ -#define __SOURCEHOOK_IMPL_CPROTO_H__ - -namespace SourceHook -{ - namespace Impl - { - // Internal representation - struct IntPassInfo - { - size_t size; - int type; - unsigned int flags; - - void *pNormalCtor; - void *pCopyCtor; - void *pDtor; - void *pAssignOperator; - - bool operator == (const IntPassInfo &other) const - { - return size == other.size - && type == other.type - && flags == other.flags - && pNormalCtor == other.pNormalCtor - && pDtor == other.pDtor - && pAssignOperator == other.pAssignOperator; - } - - bool operator != (const IntPassInfo &other) const - { - return !(*this == other); - } - }; - - class CProto - { - int m_Version; // -1 = invalid - int m_NumOfParams; - IntPassInfo m_RetPassInfo; - CVector m_ParamsPassInfo; - int m_Convention; - - void Fill(const ProtoInfo *pProto); - - // For old sourcehook.h: flags 0 -> assume ByVal - static unsigned int GetRealFlags(const PassInfo &info) - { - return (info.flags == 0) ? PassInfo::PassFlag_ByVal : info.flags; - } - - public: - CProto() : m_Version(-1) - { - } - - CProto(const ProtoInfo *pProto) - { - Fill(pProto); - } - - CProto(const CProto &other) : m_Version(other.m_Version), m_NumOfParams(other.m_NumOfParams), - m_RetPassInfo(other.m_RetPassInfo), m_ParamsPassInfo(other.m_ParamsPassInfo), - m_Convention(other.m_Convention) - { - - } - - ~CProto() - { - } - - void operator = (const ProtoInfo *pProto) - { - Fill (pProto); - } - - bool operator == (const CProto &other) const; - - bool ExactlyEqual(const CProto &other) const; - - int GetVersion() const - { - return m_Version; - } - - int GetNumOfParams() const - { - return m_NumOfParams; - } - - const IntPassInfo & GetParam(int i) const - { - return m_ParamsPassInfo[i]; - } - - IntPassInfo & GetParam(int i) - { - return m_ParamsPassInfo[i]; - } - - const IntPassInfo & GetRet() const - { - return m_RetPassInfo; - } - - IntPassInfo & GetRet() - { - return m_RetPassInfo; - } - - int GetConvention() const - { - return m_Convention; - } - - static size_t GetRealSize(const IntPassInfo &info) - { - if (info.flags & PassInfo::PassFlag_ByRef) - { - return sizeof(void*); - } - - return info.size; - } - }; - } -} - -#endif - diff --git a/sourcehook/sourcehook_impl_cvfnptr.h b/sourcehook/sourcehook_impl_cvfnptr.h deleted file mode 100644 index 8c59652..0000000 --- a/sourcehook/sourcehook_impl_cvfnptr.h +++ /dev/null @@ -1,117 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_IMPL_CVFNPTR_H__ -#define __SOURCEHOOK_IMPL_CVFNPTR_H__ - -#include "sh_list.h" -#include "sh_memory.h" - -namespace SourceHook -{ - namespace Impl - { - class CVfnPtr - { - // *** Data *** - void *m_Ptr; - void *m_OrigEntry; - - List m_HookMans; - List m_IfaceList; - public: - // *** Descriptor *** - typedef void* Descriptor; - - // *** Interface *** - inline CVfnPtr(void *ptr); - inline ~CVfnPtr(); - inline bool operator==(const Descriptor &other); - inline void *GetPtr() const; - inline void *GetOrigEntry() const; - inline List &GetIfaceList(); - inline const List &GetIfaceList() const; - inline CIface *FindIface(void *iface); - CIface &GetIface(void *iface); - bool Patch(void *newValue); - inline bool Revert(); - - void AddHookMan(CHookManager *pHookMan); - // If this returns false, it means that there is no hook manager left - // to use and that this vfnptr should be removed. - bool HookManRemoved(CHookManager *pHookMan); - }; - - // *** Implementation *** - inline CVfnPtr::CVfnPtr(void *ptr) - : m_Ptr(ptr), m_OrigEntry(*reinterpret_cast(m_Ptr)) - { - } - - inline CVfnPtr::~CVfnPtr() - { - if (!m_HookMans.empty()) - m_HookMans.front()->DecrRef(this); - } - - inline bool CVfnPtr::operator==(const Descriptor &other) - { - return m_Ptr == other; - } - - inline void *CVfnPtr::GetPtr() const - { - return m_Ptr; - } - - inline void *CVfnPtr::GetOrigEntry() const - { - return m_OrigEntry; - } - - inline List &CVfnPtr::GetIfaceList() - { - return m_IfaceList; - } - - inline const List &CVfnPtr::GetIfaceList() const - { - return m_IfaceList; - } - - inline bool CVfnPtr::Revert() - { - // Only patch the vfnptr back if the module is still in memory - // If it's not, do not remove stuff like we did before - // First off we did it wrong (shutdown the whole hookman, uh..) and secondly applications may be - // confused by RemoveHook returning false then (yeah, I know, I made this one up, no one checks for RemoveHook error) - if (ModuleInMemory(reinterpret_cast(m_Ptr), SH_PTRSIZE)) - { - return Patch(m_OrigEntry); - } - else - { - return true; - } - } - - inline CIface *CVfnPtr::FindIface(void *iface) - { - List::iterator iter = m_IfaceList.find(iface); - if (iter == m_IfaceList.end()) - return NULL; - else - return &(*iter); - } - } -} - -#endif - diff --git a/sourcehook/sourcehook_pibuilder.h b/sourcehook/sourcehook_pibuilder.h deleted file mode 100644 index 6c2f592..0000000 --- a/sourcehook/sourcehook_pibuilder.h +++ /dev/null @@ -1,109 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __SOURCEHOOK_PIBUILDER_H__ -#define __SOURCEHOOK_PIBUILDER_H__ - -#include "sourcehook.h" -#include "sh_vector.h" - -namespace SourceHook -{ - // Helper class: protocol information builder - class CProtoInfoBuilder - { - ProtoInfo m_PI; - CVector m_Params; - CVector m_Params2; - public: - CProtoInfoBuilder(int cc) - { - memset(reinterpret_cast(&m_PI), 0, sizeof(ProtoInfo)); - m_PI.convention = cc; - - // dummy 0 params - PassInfo dummy; - PassInfo::V2Info dummy2; - memset(reinterpret_cast(&dummy), 0, sizeof(PassInfo)); - memset(reinterpret_cast(&dummy2), 0, sizeof(PassInfo::V2Info)); - - dummy.size = 1; // Version1 - - m_Params.push_back(dummy); - m_Params2.push_back(dummy2); - } - - void SetReturnType(size_t size, PassInfo::PassType type, int flags, - void *pNormalCtor, void *pCopyCtor, void *pDtor, void *pAssignOperator) - { - if (pNormalCtor) - flags |= PassInfo::PassFlag_OCtor; - - if (pCopyCtor) - flags |= PassInfo::PassFlag_CCtor; - - if (pDtor) - flags |= PassInfo::PassFlag_ODtor; - - if (pAssignOperator) - flags |= PassInfo::PassFlag_AssignOp; - - m_PI.retPassInfo.size = size; - m_PI.retPassInfo.type = type; - m_PI.retPassInfo.flags = flags; - m_PI.retPassInfo2.pNormalCtor = pNormalCtor; - m_PI.retPassInfo2.pCopyCtor = pCopyCtor; - m_PI.retPassInfo2.pDtor = pDtor; - m_PI.retPassInfo2.pAssignOperator = pAssignOperator; - } - - void AddParam(size_t size, PassInfo::PassType type, int flags, - void *pNormalCtor, void *pCopyCtor, void *pDtor, void *pAssignOperator) - { - PassInfo pi; - PassInfo::V2Info pi2; - - if (pNormalCtor) - flags |= PassInfo::PassFlag_OCtor; - - if (pCopyCtor) - flags |= PassInfo::PassFlag_CCtor; - - if (pDtor) - flags |= PassInfo::PassFlag_ODtor; - - if (pAssignOperator) - flags |= PassInfo::PassFlag_AssignOp; - - - pi.size = size; - pi.type = type; - pi.flags = flags; - pi2.pNormalCtor = pNormalCtor; - pi2.pCopyCtor = pCopyCtor; - pi2.pDtor = pDtor; - pi2.pAssignOperator = pAssignOperator; - - m_Params.push_back(pi); - m_Params2.push_back(pi2); - ++m_PI.numOfParams; - } - - operator ProtoInfo*() - { - m_PI.paramsPassInfo = &(m_Params[0]); - m_PI.paramsPassInfo2 = &(m_Params2[0]); - return &m_PI; - } - }; -} - -#endif - diff --git a/sourcehook/test/Makefile b/sourcehook/test/Makefile deleted file mode 100644 index 18b7275..0000000 --- a/sourcehook/test/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -#(C)2004-2007 SourceMM Development Team -# Makefile written by David "BAILOPAN" Anderson and Pavol Marko - -OPT_FLAGS = -O3 -funroll-loops -s -pipe -DEBUG_FLAGS = -g -ggdb3 -CPP = gcc -LINK = -lstdc++ -INCLUDE = -I. -I.. -MAX_PARAMS=20 - -BINARY = sourcehook_test -OBJECTS = main.cpp sourcehook.cpp ../sourcehook_hookmangen.cpp $(shell ls -t test*.cpp) -HEADERS = ../sh_list.h ../sh_tinyhash.h ../sh_memory.h ../sh_string.h ../sh_vector.h ../sourcehook_impl.h ../FastDelegate.h ../sourcehook.h ../sh_memfuncinfo.h - -ifeq "$(DEBUG)" "true" - BIN_DIR = Debug - CFLAGS = $(DEBUG_FLAGS) -else - BIN_DIR = Release - CFLAGS = $(OPT_FLAGS) -endif - -CFLAGS += -Wall -Wno-non-virtual-dtor -# Also, enable SH_ASSERT -CFLAGS += -DSH_DEBUG - -OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) - - -default: all - -$(BIN_DIR)/%.o: %.cpp $(HEADERS) - $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< - -../sourcehook.h: ../generate/sourcehook.hxx - (cd ../generate; ./shworker.bin iter sourcehook.hxx sourcehook.h $(MAX_PARAMS); cp sourcehook.h ..) - -../sourcehook.hxx: ../generate/sh_memfuncinfo.hxx - (cd ../generate; ./shworker.bin iter sh_memfuncinfo.hxx sh_memfuncinfo.h $(MAX_PARAMS); cp sh_memfuncino.h ..) - -../FastDelegate.hxx: ../generate/FastDelegate.hxx - (cd ../generate; ./shworker.bin iter FastDelegate.hxx FastDelegate.h $(MAX_PARAMS); cp FastDelegate.h ..) - -debug: - $(MAKE) all DEBUG=true - -all: - mkdir -p $(BIN_DIR) - ln -sf ../sourcehook.cpp sourcehook.cpp - $(MAKE) $(BINARY) - rm -f $(BINARY) - rm -f sourcehook.cpp - ln -sf $(BIN_DIR)/$(BINARY) $(BINARY) - - -$(BINARY): $(OBJ_LINUX) - $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -o$(BIN_DIR)/$(BINARY) - -clean: - rm -rf Release/*.o - rm -rf Release/$(BINARY) - rm -rf Debug/*.o - rm -rf Debug/$(BINARY) diff --git a/sourcehook/test/generate.bat b/sourcehook/test/generate.bat deleted file mode 100644 index f6d3d65..0000000 --- a/sourcehook/test/generate.bat +++ /dev/null @@ -1,6 +0,0 @@ -:: Generates everything -:: Usage: -:: generate.bat - - -..\generate\shworker iter testhookmangen.hxx testhookmangen.h %1 \ No newline at end of file diff --git a/sourcehook/test/main.cpp b/sourcehook/test/main.cpp deleted file mode 100644 index 9b2ba82..0000000 --- a/sourcehook/test/main.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// Hello BAIL! -// hello pm how are you -// I'm fine, what about you? -// not bad, just looking for mem leaks -// mem leaks in my code!? never! I have to preserve binary compatibility :( -// This is a test file - -#include -#include -#include -#include -#include - -#include "sourcehook_impl.h" -#include "sourcehook.h" -#include "sourcehook_hookmangen.h" - -using namespace std; -bool g_Verbose; - -#define DECL_TEST(x) bool Test##x(std::string &error); - -#define DO_TEST(x) \ - error.clear(); \ - if (Test##x(error)) \ - { \ - ++passed; \ - cout << "Test" << #x << " passed" << endl; \ - } \ - else \ - { \ - ++failed; \ - cout << "Test" << #x << " FAILED: " << error << endl; \ - } \ - - -DECL_TEST(List); -DECL_TEST(Basic); -DECL_TEST(VafmtAndOverload); -DECL_TEST(ThisPtrOffs); -DECL_TEST(PlugSys); -DECL_TEST(Bail); -DECL_TEST(Reentr); -DECL_TEST(Manual); -DECL_TEST(Recall); -DECL_TEST(Multi); -DECL_TEST(Ref); -DECL_TEST(RefRet); -DECL_TEST(VPHooks); -DECL_TEST(CPageAlloc); // in testhookmangen.cpp -DECL_TEST(HookManGen); - -int main(int argc, char *argv[]) -{ - std::string error; - - g_Verbose = argc > 1 && strcmp(argv[1], "-v") == 0; - - int passed = 0, failed = 0; - - DO_TEST(List); - DO_TEST(Basic); - DO_TEST(VafmtAndOverload); - DO_TEST(ThisPtrOffs); - DO_TEST(PlugSys); - DO_TEST(Bail); - DO_TEST(Reentr); - DO_TEST(Manual); - DO_TEST(Recall); - DO_TEST(Multi); - DO_TEST(Ref); - DO_TEST(RefRet); - DO_TEST(VPHooks); - DO_TEST(CPageAlloc); - DO_TEST(HookManGen); - - cout << endl << "----" << endl << "Passed: " << passed << endl << "Failed: " << failed << endl; - cout << "Total: " << passed + failed << endl; - - cout << "Press enter to continue" << endl; - - char x; - cin.read(&x, 1); -} - -SourceHook::ISourceHook *Test_Factory() -{ - return new SourceHook::Impl::CSourceHookImpl(); -} - -void Test_Delete(SourceHook::ISourceHook *shptr) -{ - delete static_cast(shptr); -} - -void Test_CompleteShutdown(SourceHook::ISourceHook *shptr) -{ - static_cast(shptr)->CompleteShutdown(); -} - -void Test_UnloadPlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug) -{ - static_cast(shptr)->UnloadPlugin(plug); -} - -void Test_PausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug) -{ - static_cast(shptr)->PausePlugin(plug); -} - -void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug) -{ - static_cast(shptr)->UnpausePlugin(plug); -} - -SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *shptr) -{ - return new SourceHook::Impl::CHookManagerAutoGen(shptr); -} - -void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr) -{ - delete static_cast(ptr); -} - diff --git a/sourcehook/test/msvc7/test.vcproj b/sourcehook/test/msvc7/test.vcproj deleted file mode 100644 index 6d9b638..0000000 --- a/sourcehook/test/msvc7/test.vcproj +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sourcehook/test/msvc8/test.vcproj b/sourcehook/test/msvc8/test.vcproj deleted file mode 100644 index a0f1533..0000000 --- a/sourcehook/test/msvc8/test.vcproj +++ /dev/null @@ -1,574 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sourcehook/test/sourcehook_test.h b/sourcehook/test/sourcehook_test.h deleted file mode 100644 index 065b543..0000000 --- a/sourcehook/test/sourcehook_test.h +++ /dev/null @@ -1,49 +0,0 @@ -// This file is used for backwards compatibility testing -// It allows us to test binary backwards compatibility by using an older include file HERE: -#include "sourcehook.h" // <-- here -// There. main.cpp which implements all of the following function is always usign sourcehook.h -// and the up-to-date sourcehook_impl.h/sourcehook.cpp. The tests use this file however. -// If the test needs an up-to-date version (like the recall test), it can simply -// #include "sourcehook.h" before including this, thus overriding our decision. - - -SourceHook::ISourceHook *Test_Factory(); -void Test_Delete(SourceHook::ISourceHook *shptr); - -template -struct CAutoPtrDestruction -{ - T *m_Ptr; - CAutoPtrDestruction(T *p) : m_Ptr(p) { } - ~CAutoPtrDestruction() { if (m_Ptr) delete m_Ptr; } - void clear() { m_Ptr = NULL; } - void set(T *ptr) { m_Ptr = ptr; } -}; - -struct CSHPtrAutoDestruction -{ - SourceHook::ISourceHook *m_SHPtr; - CSHPtrAutoDestruction(SourceHook::ISourceHook *shptr) : m_SHPtr(shptr) {} - ~CSHPtrAutoDestruction() { Test_Delete(m_SHPtr); } -}; - -#define GET_SHPTR(var) var = Test_Factory(); CSHPtrAutoDestruction ___autodestruction(var); - -// Access to CSourceHookImpl functions -void Test_CompleteShutdown(SourceHook::ISourceHook *shptr); -void Test_UnloadPlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); -void Test_PausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); -void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); - -SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *pSHPtr); -void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr); - -struct CHMAGAutoDestruction -{ - SourceHook::IHookManagerAutoGen *m_Ptr; - CHMAGAutoDestruction(SourceHook::IHookManagerAutoGen *ptr) : m_Ptr(ptr) {} - ~CHMAGAutoDestruction() { Test_HMAG_Delete(m_Ptr); } -}; - - -#define GET_HMAG(var, shptr) var = Test_HMAG_Factory(shptr); CHMAGAutoDestruction __hmagautodestruction(var); diff --git a/sourcehook/test/test1.cpp b/sourcehook/test/test1.cpp deleted file mode 100644 index 08bdbd7..0000000 --- a/sourcehook/test/test1.cpp +++ /dev/null @@ -1,750 +0,0 @@ -#include -#include "sourcehook_test.h" -#include "testevents.h" - -#include "sh_memory.h" - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - // TEST1 - // Basic tests - // Hooking and callclass - - MAKE_STATE_1(State_ModuleInMemory, bool); - MAKE_STATE(State_F1_Called); - MAKE_STATE_1(State_F1_PreHandler_Called, void*); - MAKE_STATE_1(State_F1_PostHandler_Called, void*); - MAKE_STATE_1(State_F1_HookAdded, bool); - MAKE_STATE(State_F1_HookRemoved); - MAKE_STATE(State_F1_CallClassGenerated); - MAKE_STATE(State_F1_CallClassReleased); - MAKE_STATE_1(State_F299_Called, std::string); - MAKE_STATE_1(State_F299_PreHandlerCalled, std::string); - MAKE_STATE_1(State_F299_PostHandlerCalled, std::string); - MAKE_STATE_1(State_F299Ret, bool); - - class Test - { - public: - virtual void F1() - { - ADD_STATE(State_F1_Called); - } - virtual void F2(){} - virtual void F3(){} - virtual void F4(){} - virtual void F5(){} - virtual void F6(){} - virtual void F7(){} - virtual void F8(){} - virtual void F9(){} - virtual void F10(){} - virtual void F11(){} - virtual void F12(){} - virtual void F13(){} - virtual void F14(){} - virtual void F15(){} - virtual void F16(){} - virtual void F17(){} - virtual void F18(){} - virtual void F19(){} - virtual float F20() const { return 1.0f; } // Look! F20 is const-ed and returns a float - virtual void F21(){} - virtual void F22(){} - virtual void F23(){} - virtual void F24(){} - virtual void F25(){} - virtual void F26(){} - virtual void F27(){} - virtual void F28(){} - virtual void F29(){} - virtual void F30(){} - virtual void F31(){} - virtual void F32(){} - virtual void F33(){} - virtual void F34(){} - virtual void F35(){} - virtual void F36(){} - virtual void F37(){} - virtual void F38(){} - virtual void F39(){} - virtual void F40(){} - virtual void F41(){} - virtual void F42(){} - virtual void F43(){} - virtual void F44(){} - virtual void F45(){} - virtual void F46(){} - virtual void F47(){} - virtual void F48(){} - virtual void F49(){} - virtual void F50(){} - virtual void F51(){} - virtual void F52(){} - virtual void F53(){} - virtual void F54(){} - virtual void F55(){} - virtual void F56(){} - virtual void F57(){} - virtual void F58(){} - virtual void F59(){} - virtual void F60(int &hello){} - virtual void F61(){} - virtual void F62(){} - virtual void F63(){} - virtual void F64(){} - virtual void F65(){} - virtual void F66(){} - virtual void F67(){} - virtual void F68(){} - virtual void F69(){} - virtual void F70(){} - virtual void F71(){} - virtual void F72(){} - virtual void F73(){} - virtual void F74(){} - virtual void F75(){} - virtual void F76(){} - virtual void F77(){} - virtual void F78(){} - virtual void F79(){} - virtual void F80(){} - virtual void F81(){} - virtual void F82(){} - virtual void F83(){} - virtual void F84(){} - virtual void F85(){} - virtual void F86(){} - virtual void F87(){} - virtual void F88(){} - virtual void F89(){} - virtual void F90(){} - virtual void F91(){} - virtual void F92(){} - virtual void F93(){} - virtual void F94(){} - virtual void F95(){} - virtual void F96(){} - virtual void F97(){} - virtual void F98(){} - virtual void F99(){} - virtual void F100(){} - virtual void F101(){} - virtual void F102(){} - virtual void F103(){} - virtual void F104(){} - virtual void F105(){} - virtual void F106(){} - virtual void F107(){} - virtual void F108(){} - virtual void F109(){} - virtual void F110(){} - virtual void F111(){} - virtual void F112(){} - virtual void F113(){} - virtual void F114(){} - virtual void F115(){} - virtual void F116(){} - virtual void F117(){} - virtual void F118(){} - virtual void F119(){} - virtual void F120(){} - virtual void F121(){} - virtual void F122(){} - virtual void F123(){} - virtual void F124(){} - virtual void F125(){} - virtual void F126(){} - virtual void F127(){} - virtual void F128(){} - virtual void F129(){} - virtual void F130(){} - virtual void F131(){} - virtual void F132(){} - virtual void F133(){} - virtual void F134(){} - virtual void F135(){} - virtual void F136(){} - virtual void F137(){} - virtual void F138(){} - virtual void F139(){} - virtual void F140(){} - virtual void F141(){} - virtual void F142(){} - virtual void F143(){} - virtual void F144(){} - virtual void F145(){} - virtual void F146(){} - virtual void F147(){} - virtual void F148(){} - virtual void F149(){} - virtual void F150(){} - virtual void F151(){} - virtual void F152(){} - virtual void F153(){} - virtual void F154(){} - virtual void F155(){} - virtual void F156(){} - virtual void F157(){} - virtual void F158(){} - virtual void F159(){} - virtual void F160(){} - virtual void F161(){} - virtual void F162(){} - virtual void F163(){} - virtual void F164(){} - virtual void F165(){} - virtual void F166(){} - virtual void F167(){} - virtual void F168(){} - virtual void F169(){} - virtual void F170(){} - virtual void F171(){} - virtual void F172(){} - virtual void F173(){} - virtual void F174(){} - virtual void F175(){} - virtual void F176(){} - virtual void F177(){} - virtual void F178(){} - virtual void F179(){} - virtual void F180(){} - virtual void F181(){} - virtual void F182(){} - virtual void F183(){} - virtual void F184(){} - virtual void F185(){} - virtual void F186(){} - virtual void F187(){} - virtual void F188(){} - virtual void F189(){} - virtual void F190(){} - virtual void F191(){} - virtual void F192(){} - virtual void F193(){} - virtual void F194(){} - virtual void F195(){} - virtual void F196(){} - virtual void F197(){} - virtual void F198(){} - virtual void F199(){} - virtual void F200(){} - virtual void F201(){} - virtual void F202(){} - virtual void F203(){} - virtual void F204(){} - virtual void F205(){} - virtual void F206(){} - virtual void F207(){} - virtual void F208(){} - virtual void F209(){} - virtual void F210(){} - virtual void F211(){} - virtual void F212(){} - virtual void F213(){} - virtual void F214(){} - virtual void F215(){} - virtual void F216(){} - virtual void F217(){} - virtual void F218(){} - virtual void F219(){} - virtual void F220(){} - virtual void F221(){} - virtual void F222(){} - virtual void F223(){} - virtual void F224(){} - virtual void F225(){} - virtual void F226(){} - virtual void F227(){} - virtual void F228(){} - virtual void F229(){} - virtual void F230(){} - virtual void F231(){} - virtual void F232(){} - virtual void F233(){} - virtual void F234(){} - virtual void F235(){} - virtual void F236(){} - virtual void F237(){} - virtual void F238(){} - virtual void F239(){} - virtual void F240(){} - virtual void F241(){} - virtual void F242(){} - virtual void F243(){} - virtual void F244(){} - virtual void F245(){} - virtual void F246(){} - virtual void F247(){} - virtual void F248(){} - virtual void F249(){} - virtual void F250(){} - virtual void F251(){} - virtual void F252(){} - virtual void F253(){} - virtual void F254(){} - virtual void F255(){} - virtual void F256(){} - virtual void F257(){} - virtual void F258(){} - virtual void F259(){} - virtual void F260(){} - virtual void F261(){} - virtual void F262(){} - virtual void F263(){} - virtual void F264(){} - virtual void F265(){} - virtual void F266(){} - virtual void F267(){} - virtual void F268(){} - virtual void F269(){} - virtual void F270(){} - virtual void F271(){} - virtual void F272(){} - virtual void F273(){} - virtual void F274(){} - virtual void F275(){} - virtual void F276(){} - virtual void F277(){} - virtual void F278(){} - virtual void F279(){} - virtual void F280(){} - virtual void F281(){} - virtual void F282(){} - virtual void F283(){} - virtual void F284(){} - virtual void F285(){} - virtual void F286(){} - virtual void F287(){} - virtual void F288(){} - virtual void F289(){} - virtual void F290(){} - virtual void F291(){} - virtual void F292(){} - virtual void F293(){} - virtual void F294(){} - virtual void F295(){} - virtual void F296(){} - virtual void F297(){} - virtual void F298(){} - virtual bool F299(const char *mwah) - { - ADD_STATE(State_F299_Called(mwah)); - return true; - } - }; - - SH_DECL_HOOK1(Test, F299, SH_NOATTRIB, 0, bool, const char *); - SH_DECL_HOOK0_void(Test, F1, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F2, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F3, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F4, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F5, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F6, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F7, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F8, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F9, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Test, F10, SH_NOATTRIB, 0); - - SH_DECL_HOOK0(Test, F20, const, 0, float); - SH_DECL_HOOK1_void(Test, F60, SH_NOATTRIB, 0, int&); - - SH_DECL_EXTERN1(Test, F299, SH_NOATTRIB, 0, bool, const char *); - SH_DECL_EXTERN0_void(Test, F1, SH_NOATTRIB, 0); - - META_RES g_F1Pre_WhatToDo; - META_RES g_F1Post_WhatToDo; - - struct HandlersF1 - { - void Pre() - { - ADD_STATE(State_F1_PreHandler_Called(reinterpret_cast(this))); - RETURN_META(g_F1Pre_WhatToDo); - } - - void Post() - { - ADD_STATE(State_F1_PostHandler_Called(reinterpret_cast(this))); - RETURN_META(g_F1Post_WhatToDo); - } - }; - - META_RES g_F299Pre_WhatToDo; - bool g_F299Pre_WhatToRet; - - bool F299_Pre(const char *mwah) - { - ADD_STATE(State_F299_PreHandlerCalled(mwah)); - RETURN_META_VALUE(g_F299Pre_WhatToDo, g_F299Pre_WhatToRet); - } - - bool F299_Post(const char *mwah) - { - ADD_STATE(State_F299_PostHandlerCalled(mwah)); - RETURN_META_VALUE(MRES_OVERRIDE, META_RESULT_STATUS >= MRES_OVERRIDE ? !META_RESULT_OVERRIDE_RET(bool) : - !META_RESULT_ORIG_RET(bool)); - } - - void F60_Pre(int &hello) - { - hello = 10; - } - - Test *MyTestFactory() - { - return new Test; - } -} - -template T func(T a) -{ - return a; -} - -bool TestBasic(std::string &error) -{ - // Simple test for ModuleInMemory - // 1) &error should on the stack - // 2) 0 should not be mapped - ADD_STATE(State_ModuleInMemory(SourceHook::ModuleInMemory(reinterpret_cast(&error), sizeof(error)))); - ADD_STATE(State_ModuleInMemory(SourceHook::ModuleInMemory(0, 1))); - - CHECK_STATES((&g_States, - new State_ModuleInMemory(true), - new State_ModuleInMemory(false), - NULL), "ModuleInMemory"); - - GET_SHPTR(g_SHPtr); - g_PLID = 1337; - - HandlersF1 f1_handlers; - Test *pTest = MyTestFactory(); - CAutoPtrDestruction apd(pTest); - - void *pOrigVfnPtrF1 = (*reinterpret_cast(pTest))[0]; - - // 1) Get a call class and call the member through it and normally - SourceHook::CallClass *cc = SH_GET_CALLCLASS(pTest); - - ADD_STATE(State_F1_CallClassGenerated); - - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_CallClassGenerated, - new State_F1_Called, - new State_F1_Called, - NULL), "Part 1"); - - CHECK_COND(SH_GET_ORIG_VFNPTR_ENTRY(pTest, &Test::F1) == pOrigVfnPtrF1, "Part S1"); - - // 2) Request a call class again - SourceHook::CallClass *cc2 = SH_GET_CALLCLASS(pTest); - ADD_STATE(State_F1_CallClassGenerated); - - SH_CALL(cc, &Test::F1)(); - SH_CALL(cc2, &Test::F1)(); - pTest->F1(); - - SH_RELEASE_CALLCLASS(cc2); - ADD_STATE(State_F1_CallClassReleased); - - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_CallClassGenerated, - new State_F1_Called, - new State_F1_Called, - new State_F1_Called, - new State_F1_CallClassReleased, - new State_F1_Called, - new State_F1_Called, - NULL), "Part 2"); - - // 3) Add a pre hook - // (one add memfunc in old format) - g_F1Pre_WhatToDo = MRES_SUPERCEDE; - ADD_STATE(State_F1_HookAdded(SH_ADD_HOOK_MEMFUNC(Test, F1, pTest, &f1_handlers, &HandlersF1::Pre, false) ? true : false)); - - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_HookAdded(true), - new State_F1_Called, - new State_F1_PreHandler_Called(&f1_handlers), - NULL), "Part 3"); - - CHECK_COND(SH_GET_ORIG_VFNPTR_ENTRY(pTest, &Test::F1) == pOrigVfnPtrF1, "Part S3"); - - // 4) Rerequest the callclass - SH_RELEASE_CALLCLASS(cc); - - ADD_STATE(State_F1_CallClassReleased); - cc2 = SH_GET_CALLCLASS(pTest); - ADD_STATE(State_F1_CallClassGenerated); - - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_CallClassReleased, - new State_F1_CallClassGenerated, - new State_F1_Called, - new State_F1_PreHandler_Called(&f1_handlers), - NULL), "Part 4"); - - // 5) Check ignore / supercede - g_F1Pre_WhatToDo = MRES_SUPERCEDE; - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - g_F1Pre_WhatToDo = MRES_IGNORED; - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_Called, - new State_F1_PreHandler_Called(&f1_handlers), - new State_F1_Called, - new State_F1_PreHandler_Called(&f1_handlers), - new State_F1_Called, - NULL), "Part 5"); - - // 6) remove the hook again - // (one remove memfunc in old format) - SH_REMOVE_HOOK_MEMFUNC(Test, F1, pTest, &f1_handlers, &HandlersF1::Pre, false); - ADD_STATE(State_F1_HookRemoved); - - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_HookRemoved, - new State_F1_Called, - new State_F1_Called, - NULL), "Part 6"); - - // 7) add a post hook now - g_F1Post_WhatToDo = MRES_IGNORED; - ADD_STATE(State_F1_HookAdded(SH_ADD_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Post), true) ? true : false)); - - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_HookAdded(true), - new State_F1_Called, - new State_F1_Called, - new State_F1_PostHandler_Called(&f1_handlers), - NULL), "Part 7"); - - // 8) And a pre hook again - g_F1Pre_WhatToDo = MRES_IGNORED; - ADD_STATE(State_F1_HookAdded(SH_ADD_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false) ? true : false)); - - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - g_F1Pre_WhatToDo = MRES_SUPERCEDE; - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_HookAdded(true), - new State_F1_Called, - new State_F1_PreHandler_Called(&f1_handlers), - new State_F1_Called, - new State_F1_PostHandler_Called(&f1_handlers), - new State_F1_Called, - new State_F1_PreHandler_Called(&f1_handlers), - new State_F1_PostHandler_Called(&f1_handlers), - NULL), "Part 8"); - - // 9) Remove all hooks - SH_REMOVE_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - ADD_STATE(State_F1_HookRemoved); - SH_REMOVE_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Post), true); - ADD_STATE(State_F1_HookRemoved); - - SH_CALL(cc, &Test::F1)(); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_HookRemoved, - new State_F1_HookRemoved, - new State_F1_Called, - new State_F1_Called, - NULL), "Part 9"); - - // 10) Some checks on F299 - g_F299Pre_WhatToDo = MRES_IGNORED; - g_F299Pre_WhatToRet = false; - - ADD_STATE(State_F299Ret(pTest->F299("hi"))); - ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi"))); - - CHECK_STATES((&g_States, - new State_F299_Called("hi"), - new State_F299Ret(true), - new State_F299_Called("hi"), - new State_F299Ret(true), - NULL), "Part 10.1"); - - // (one add staticfunc in old format) - SH_ADD_HOOK_STATICFUNC(Test, F299, pTest, F299_Pre, false); - ADD_STATE(State_F299Ret(pTest->F299("hi"))); - ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi"))); - - CHECK_STATES((&g_States, - new State_F299_PreHandlerCalled("hi"), - new State_F299_Called("hi"), - new State_F299Ret(true), - new State_F299_Called("hi"), - new State_F299Ret(true), - NULL), "Part 10.2"); - - SH_ADD_HOOK(Test, F299, pTest, SH_STATIC(F299_Post), true); - ADD_STATE(State_F299Ret(pTest->F299("hi"))); - ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi"))); - - CHECK_STATES((&g_States, - new State_F299_PreHandlerCalled("hi"), - new State_F299_Called("hi"), - new State_F299_PostHandlerCalled("hi"), - new State_F299Ret(false), - new State_F299_Called("hi"), - new State_F299Ret(true), - NULL), "Part 10.3"); - - g_F299Pre_WhatToDo = MRES_OVERRIDE; - ADD_STATE(State_F299Ret(pTest->F299("hi"))); - ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi"))); - - CHECK_STATES((&g_States, - new State_F299_PreHandlerCalled("hi"), - new State_F299_Called("hi"), - new State_F299_PostHandlerCalled("hi"), - new State_F299Ret(true), - new State_F299_Called("hi"), - new State_F299Ret(true), - NULL), "Part 10.4"); - - g_F299Pre_WhatToDo = MRES_SUPERCEDE; - ADD_STATE(State_F299Ret(pTest->F299("hi"))); - ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi"))); - - CHECK_STATES((&g_States, - new State_F299_PreHandlerCalled("hi"), - new State_F299_PostHandlerCalled("hi"), - new State_F299Ret(true), - new State_F299_Called("hi"), - new State_F299Ret(true), - NULL), "Part 10.5"); - - // (one remove staticfunc in old format) - SH_REMOVE_HOOK_STATICFUNC(Test, F299, pTest, F299_Pre, false); - ADD_STATE(State_F299Ret(pTest->F299("hi"))); - ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi"))); - - CHECK_STATES((&g_States, - new State_F299_Called("hi"), - new State_F299_PostHandlerCalled("hi"), - new State_F299Ret(false), - new State_F299_Called("hi"), - new State_F299Ret(true), - NULL), "Part 10.6"); - - SH_REMOVE_HOOK(Test, F299, pTest, SH_STATIC(F299_Post), true); - ADD_STATE(State_F299Ret(pTest->F299("hi"))); - ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi"))); - - CHECK_STATES((&g_States, - new State_F299_Called("hi"), - new State_F299Ret(true), - new State_F299_Called("hi"), - new State_F299Ret(true), - NULL), "Part 10.7"); - - // 11) Release callclass - SH_RELEASE_CALLCLASS(cc); - ADD_STATE(State_F1_CallClassReleased); - - - CHECK_STATES((&g_States, - new State_F1_CallClassReleased, - NULL), "Part 11"); - - // 11 1/2) Test removing hook by id - - g_F1Pre_WhatToDo = MRES_IGNORED; - - pTest->F1(); - int hookPre = SH_ADD_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - int hookPost = SH_ADD_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Post), true); - - pTest->F1(); - SH_REMOVE_HOOK_ID(hookPost); - pTest->F1(); - SH_REMOVE_HOOK_ID(hookPre); - pTest->F1(); - - CHECK_STATES((&g_States, - new State_F1_Called, - - new State_F1_PreHandler_Called(&f1_handlers), - new State_F1_Called, - new State_F1_PostHandler_Called(&f1_handlers), - - new State_F1_PreHandler_Called(&f1_handlers), - new State_F1_Called, - - new State_F1_Called, - - NULL), "Part 11 1/2"); - - // 12) Try out one ref param - SH_ADD_HOOK(Test, F60, pTest, SH_STATIC(F60_Pre), false); - int a = 0; - pTest->F60(a); - CHECK_COND(a == 10, "Part12"); - SH_REMOVE_HOOK(Test, F60, pTest, SH_STATIC(F60_Pre), false); - - // 13) Remove hooks after the instance has been removed - SH_ADD_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), true); - SH_ADD_HOOK(Test, F2, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), true); - SH_ADD_HOOK(Test, F3, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_ADD_HOOK(Test, F4, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), true); - SH_ADD_HOOK(Test, F5, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_ADD_HOOK(Test, F6, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), true); - SH_ADD_HOOK(Test, F7, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_ADD_HOOK(Test, F8, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_ADD_HOOK(Test, F9, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_ADD_HOOK(Test, F10, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - - delete pTest; - apd.clear(); - - SH_REMOVE_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), true); - SH_REMOVE_HOOK(Test, F2, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), true); - SH_REMOVE_HOOK(Test, F3, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_REMOVE_HOOK(Test, F4, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), true); - SH_REMOVE_HOOK(Test, F5, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_REMOVE_HOOK(Test, F6, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), true); - SH_REMOVE_HOOK(Test, F7, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_REMOVE_HOOK(Test, F8, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_REMOVE_HOOK(Test, F9, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - SH_REMOVE_HOOK(Test, F10, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false); - CHECK_COND(SH_REMOVE_HOOK(Test, F10, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false) == false, "Part 12.1"); - - Test_CompleteShutdown(g_SHPtr); - - return true; -} diff --git a/sourcehook/test/test2.cpp b/sourcehook/test/test2.cpp deleted file mode 100644 index cb84b84..0000000 --- a/sourcehook/test/test2.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include "sourcehook_test.h" -#include "testevents.h" -#include - -// TEST2 -// Vafmt and Overloaded functions -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - MAKE_STATE_1(State_EatYams_Called, int); - MAKE_STATE_1(State_EatYams_Handler_Called, int); - MAKE_STATE_2(State_Vafmt_Called, int, std::string); - MAKE_STATE_2(State_Vafmt_PreHandler_Called, int, std::string); - MAKE_STATE_2(State_Vafmt_PostHandler_Called, int, std::string); - - class IGaben - { - public: - virtual void EatYams() - { - ADD_STATE(State_EatYams_Called(0)); - } - virtual bool EatYams(const char *location) const - { - ADD_STATE(State_EatYams_Called(1)); - return true; - } - virtual void Vafmt1(bool param1, int x, const char *fmt, ...) - { - va_list ap; - va_start(ap, fmt); - char buffer[512]; - vsprintf(buffer, fmt, ap); - va_end(ap); - ADD_STATE(State_Vafmt_Called(1, std::string(buffer))); - } - virtual float Vafmt2(const char *fmt, ...) - { - va_list ap; - va_start(ap, fmt); - char buffer[512]; - vsprintf(buffer, fmt, ap); - va_end(ap); - ADD_STATE(State_Vafmt_Called(2, std::string(buffer))); - return 0.0f; - } - }; - - SH_DECL_HOOK0_void(IGaben, EatYams, SH_NOATTRIB, 0); - SH_DECL_HOOK1(IGaben, EatYams, const, 1, bool, const char *); - SH_DECL_HOOK2_void_vafmt(IGaben, Vafmt1, SH_NOATTRIB, 0, bool, int); - SH_DECL_HOOK0_vafmt(IGaben, Vafmt2, SH_NOATTRIB, 0, float); - - SH_DECL_EXTERN2_void_vafmt(IGaben, Vafmt1, SH_NOATTRIB, 0, bool, int); - SH_DECL_EXTERN0_vafmt(IGaben, Vafmt2, SH_NOATTRIB, 0, float); - - void EatYams0_Handler() - { - ADD_STATE(State_EatYams_Handler_Called(0)); - } - - bool EatYams1_Handler(const char *loc) - { - ADD_STATE(State_EatYams_Handler_Called(1)); - return true; - } - - void Vafmt1_PreHandler(bool param1, int x, const char *in) - { - ADD_STATE(State_Vafmt_PreHandler_Called(1, std::string(in))); - } - void Vafmt1_PostHandler(bool param1, int x, const char *in) - { - ADD_STATE(State_Vafmt_PostHandler_Called(1, std::string(in))); - } - float Vafmt2_PreHandler(const char *in) - { - ADD_STATE(State_Vafmt_PreHandler_Called(2, std::string(in))); - return 0.0f; - } - float Vafmt2_PostHandler(const char *in) - { - ADD_STATE(State_Vafmt_PostHandler_Called(2, std::string(in))); - return 0.0f; - } - - IGaben *MyInstanceFactory() - { - return new IGaben; - } -} - - -bool TestVafmtAndOverload(std::string &error) -{ - int h1, h2, h3, h4; - GET_SHPTR(g_SHPtr); - g_PLID = 1337; - - IGaben *pGab = MyInstanceFactory(); - CAutoPtrDestruction apd(pGab); - - // Part 1 - SH_CALL(pGab, static_cast(&IGaben::EatYams))(); - SH_CALL(pGab, static_cast(&IGaben::EatYams))("Here!"); - - h1 = SH_ADD_HOOK(IGaben, EatYams, pGab, EatYams0_Handler, false); - h2 = SH_ADD_HOOK(IGaben, EatYams, pGab, EatYams1_Handler, false); - - pGab->EatYams(); - pGab->EatYams("Here!"); - - SH_REMOVE_HOOK_ID(h1); - SH_REMOVE_HOOK_ID(h2); - - CHECK_STATES((&g_States, - new State_EatYams_Called(0), - new State_EatYams_Called(1), - new State_EatYams_Handler_Called(0), - new State_EatYams_Called(0), - new State_EatYams_Handler_Called(1), - new State_EatYams_Called(1), - NULL),"Part 1"); - - // Part 2 - pGab->Vafmt1(true, 55, "Hello %s%d%s", "BA", 1, "L"); - SH_CALL(pGab, &IGaben::Vafmt1)(true, 55, "Hello %s%d%s", "BA", 1, "L"); - pGab->Vafmt2("Hello %s%d%s", "BA", 1, "LOPAN"); - SH_CALL(pGab, &IGaben::Vafmt2)("Hello %s%d%s", "BA", 1, "LOPAN"); - - CHECK_STATES((&g_States, - new State_Vafmt_Called(1, "Hello BA1L"), - new State_Vafmt_Called(1, "Hello BA1L"), - new State_Vafmt_Called(2, "Hello BA1LOPAN"), - new State_Vafmt_Called(2, "Hello BA1LOPAN"), - NULL), "Part 2"); - - // Part 3 - h1 = SH_ADD_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PreHandler, false); - h2 = SH_ADD_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PostHandler, true); - h3 = SH_ADD_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PreHandler, false); - h4 = SH_ADD_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PostHandler, true); - - pGab->Vafmt1(true, 55, "Hello %s%d%s", "BA", 1, "L"); - pGab->Vafmt2("Hello %s%d%s", "BA", 1, "LOPAN"); - - CHECK_STATES((&g_States, - new State_Vafmt_PreHandler_Called(1, std::string("Hello BA1L")), - new State_Vafmt_Called(1, std::string("Hello BA1L")), - new State_Vafmt_PostHandler_Called(1, std::string("Hello BA1L")), - - new State_Vafmt_PreHandler_Called(2, std::string("Hello BA1LOPAN")), - new State_Vafmt_Called(2, std::string("Hello BA1LOPAN")), - new State_Vafmt_PostHandler_Called(2, std::string("Hello BA1LOPAN")), - NULL), "Part 3"); - - // Part 4 - SH_REMOVE_HOOK_ID(h1); - SH_REMOVE_HOOK_ID(h2); - SH_REMOVE_HOOK_ID(h3); - SH_REMOVE_HOOK_ID(h4); - - pGab->Vafmt1(true, 55, "Hello %s%d%s", "BA", 1, "L"); - pGab->Vafmt2("Hello %s%d%s", "BA", 1, "LOPAN"); - - CHECK_STATES((&g_States, - new State_Vafmt_Called(1, "Hello BA1L"), - new State_Vafmt_Called(2, "Hello BA1LOPAN"), - NULL), "Part 4"); - - return true; -} diff --git a/sourcehook/test/test3.cpp b/sourcehook/test/test3.cpp deleted file mode 100644 index c4e88da..0000000 --- a/sourcehook/test/test3.cpp +++ /dev/null @@ -1,245 +0,0 @@ -#include -#include "sourcehook_test.h" -#include "testevents.h" - -// TEST3 -// Tests with inheritance / thisptroffsets - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - MAKE_STATE_1(State_Func1_Called, void*); // param1: This pointer - MAKE_STATE_1(State_Func2_Called, void*); // param1: This pointer - MAKE_STATE_1(State_Func3_Called, void*); // param1: This pointer - - MAKE_STATE_1(State_Func1H_Called, void*); - MAKE_STATE_1(State_Func2H_Called, void*); - MAKE_STATE_1(State_Func3H_Called, void*); - - class Base1 - { - int a; - public: - virtual void Func1() - { - ADD_STATE(State_Func1_Called(reinterpret_cast(this))); - } - }; - class Base2 - { - int b; - public: - virtual void Func2() - { - ADD_STATE(State_Func2_Called(reinterpret_cast(this))); - } - }; - class Derived : public Base1, public Base2 - { - int c; - public: - virtual void Func3() - { - ADD_STATE(State_Func3_Called(reinterpret_cast(this))); - } - }; - - SH_DECL_HOOK0_void(Derived, Func1, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Derived, Func2, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Derived, Func3, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Base1, Func1, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(Base2, Func2, SH_NOATTRIB, 0); - - void Handler_Func1() - { - ADD_STATE(State_Func1H_Called(META_IFACEPTR(void))); - } - void Handler_Func2() - { - ADD_STATE(State_Func2H_Called(META_IFACEPTR(void))); - } - void Handler_Func3() - { - ADD_STATE(State_Func3H_Called(META_IFACEPTR(void))); - } - - Derived *MyInstanceFactory() - { - return new Derived; - } -} - -bool TestThisPtrOffs(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1337; - - Derived *pD = MyInstanceFactory(); - Base1 *pB1 = pD; - Base2 *pB2 = pD; - - CAutoPtrDestruction apd(pD); - - - // It should be: - // pB1 = pD - // pB2 > pB1 - - // 1) - // Get a callclass for pD - // Verify whether the this pointers are correct - // Also call them normally to make sure that we aren't messing it up ;) - SourceHook::CallClass *pD_CC = SH_GET_CALLCLASS(pD); - - SH_CALL(pD_CC, &Derived::Func1)(); - SH_CALL(pD_CC, &Derived::Func2)(); - SH_CALL(pD_CC, &Derived::Func3)(); - pD->Func1(); - pD->Func2(); - pD->Func3(); - - CHECK_STATES((&g_States, - new State_Func1_Called(pB1), - new State_Func2_Called(pB2), - new State_Func3_Called(pD), - new State_Func1_Called(pB1), - new State_Func2_Called(pB2), - new State_Func3_Called(pD), - NULL), "Part 1"); - - SH_CALL(pD_CC, &Base1::Func1)(); - SH_CALL(pD_CC, &Base2::Func2)(); - - CHECK_STATES((&g_States, - new State_Func1_Called(pB1), - new State_Func2_Called(pB2), - NULL), "Part 1.1"); - - // 2) - // Get callclasses for the other ones and verify it as well - - SourceHook::CallClass *pB1_CC = SH_GET_CALLCLASS(pB1); - SourceHook::CallClass *pB2_CC = SH_GET_CALLCLASS(pB2); - - SH_CALL(pB1_CC, &Base1::Func1)(); - SH_CALL(pB2_CC, &Base2::Func2)(); - - CHECK_STATES((&g_States, - new State_Func1_Called(pB1), - new State_Func2_Called(pB2), - NULL), "Part 2"); - - - // 3) Add hooks on them (referring to them through pD1 / Derived) - // Check whether the hooks are called with the correct this pointer - - SH_ADD_HOOK(Derived, Func1, pD, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false); - SH_ADD_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); - - pD->Func1(); - pD->Func2(); - pD->Func3(); - pB1->Func1(); - pB2->Func2(); - - // The handlers should always be called with the pointer to Derived - CHECK_STATES((&g_States, - new State_Func1H_Called(pD), - new State_Func1_Called(pB1), - new State_Func2H_Called(pD), - new State_Func2_Called(pB2), - new State_Func3H_Called(pD), - new State_Func3_Called(pD), - new State_Func1H_Called(pD), - new State_Func1_Called(pB1), - new State_Func2H_Called(pD), - new State_Func2_Called(pB2), - NULL), "Part 3"); - - SH_REMOVE_HOOK(Derived, Func1, pD, SH_STATIC(Handler_Func1), false); - SH_REMOVE_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false); - SH_REMOVE_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); - - // 4) - // Now add the hooks on Base1 and Base2 and check again - - // Note that the new implicit_cast should convert the pD to Base1*/Base2* :) - SH_ADD_HOOK(Base1, Func1, pD, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(Base2, Func2, pD, SH_STATIC(Handler_Func2), false); - SH_ADD_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); - - pD->Func1(); - pD->Func2(); - pD->Func3(); - pB1->Func1(); - pB2->Func2(); - - // This time, the handlers for Func1 should be called with pB1 and the handlers - // for Func2 should be called with pB2 - CHECK_STATES((&g_States, - new State_Func1H_Called(pB1), - new State_Func1_Called(pB1), - new State_Func2H_Called(pB2), - new State_Func2_Called(pB2), - new State_Func3H_Called(pD), - new State_Func3_Called(pD), - new State_Func1H_Called(pB1), - new State_Func1_Called(pB1), - new State_Func2H_Called(pB2), - new State_Func2_Called(pB2), - NULL), "Part 4"); - - SH_REMOVE_HOOK(Base1, Func1, pD, SH_STATIC(Handler_Func1), false); - SH_REMOVE_HOOK(Base2, Func2, pD, SH_STATIC(Handler_Func2), false); - SH_REMOVE_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); - - - // 5) - // Add some hooks, and use callclasses - - // 5.1) First off, add all of them on pD - SH_ADD_HOOK(Derived, Func1, pD, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false); - SH_ADD_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); - - pD->Func1(); - pD->Func2(); - pD->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called(pD), - new State_Func1_Called(pB1), - new State_Func2H_Called(pD), - new State_Func2_Called(pB2), - new State_Func3H_Called(pD), - new State_Func3_Called(pD), - NULL), "Part 5.1"); - - SH_CALL(pD_CC, &Derived::Func1)(); - SH_CALL(pD_CC, &Derived::Func2)(); - SH_CALL(pD_CC, &Derived::Func3)(); - SH_CALL(pB1_CC, &Base1::Func1)(); - SH_CALL(pB2_CC, &Base2::Func2)(); - - CHECK_STATES((&g_States, - new State_Func1_Called(pB1), - new State_Func2_Called(pB2), - new State_Func3_Called(pD), - new State_Func1_Called(pB1), - new State_Func2_Called(pB2), - NULL), "Part 5.2"); - - SH_REMOVE_HOOK(Derived, Func1, pD, SH_STATIC(Handler_Func1), false); - SH_REMOVE_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false); - SH_REMOVE_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false); - - SH_RELEASE_CALLCLASS(pB1_CC); - SH_RELEASE_CALLCLASS(pB2_CC); - SH_RELEASE_CALLCLASS(pD_CC); - - return true; -} diff --git a/sourcehook/test/test4.cpp b/sourcehook/test/test4.cpp deleted file mode 100644 index 8776204..0000000 --- a/sourcehook/test/test4.cpp +++ /dev/null @@ -1,315 +0,0 @@ -#include -#include "sourcehook_test.h" -#include "testevents.h" - -// TEST4 -// Tests of plugin management system - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - MAKE_STATE(State_Func1_Called); - MAKE_STATE(State_Func2_Called); - MAKE_STATE(State_Func3_Called); - - MAKE_STATE(State_Func1H_Called); - MAKE_STATE(State_Func2H_Called); - MAKE_STATE(State_Func3H_Called); - - class Test - { - public: - virtual void Func1() - { - ADD_STATE(State_Func1_Called); - } - - virtual void Func2() - { - ADD_STATE(State_Func2_Called); - } - - virtual void Func3() - { - ADD_STATE(State_Func3_Called); - } - }; - - SH_DECL_HOOK0_void(Test, Func1, SH_NOATTRIB, 1); - SH_DECL_HOOK0_void(Test, Func2, SH_NOATTRIB, 1); - SH_DECL_HOOK0_void(Test, Func3, SH_NOATTRIB, 1); - - void Handler_Func1() - { - ADD_STATE(State_Func1H_Called); - } - void Handler_Func2() - { - ADD_STATE(State_Func2H_Called); - } - void Handler_Func3() - { - ADD_STATE(State_Func3H_Called); - } - - Test *MyTestFactory() - { - return new Test; - } -} - -bool TestPlugSys(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1; - - Test *pInst = MyTestFactory(); - CAutoPtrDestruction apd(pInst); - - // 1) - // Add hooks, then issue a complete shutdown - SH_ADD_HOOK(Test, Func1, pInst, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(Test, Func2, pInst, SH_STATIC(Handler_Func2), true); - SH_ADD_HOOK(Test, Func3, pInst, SH_STATIC(Handler_Func3), false); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called, - new State_Func1_Called, - new State_Func2_Called, - new State_Func2H_Called, - new State_Func3H_Called, - new State_Func3_Called, - NULL), "Part 1.1"); - - Test_CompleteShutdown(g_SHPtr); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1_Called, - new State_Func2_Called, - new State_Func3_Called, - NULL), "Part 1.2"); - - // 2) - // Add hooks from "different plugins", then shutdown the plugins - - g_PLID = 1; - SH_ADD_HOOK(Test, Func1, pInst, SH_STATIC(Handler_Func1), false); - g_PLID = 2; - SH_ADD_HOOK(Test, Func2, pInst, SH_STATIC(Handler_Func2), true); - g_PLID = 3; - SH_ADD_HOOK(Test, Func3, pInst, SH_STATIC(Handler_Func3), false); - - g_PLID = 1; - SH_ADD_HOOK(Test, Func2, pInst, SH_STATIC(Handler_Func2), true); - SH_ADD_HOOK(Test, Func3, pInst, SH_STATIC(Handler_Func3), false); - - g_PLID = 2; - SH_ADD_HOOK(Test, Func1, pInst, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(Test, Func3, pInst, SH_STATIC(Handler_Func3), false); - - g_PLID = 3; - SH_ADD_HOOK(Test, Func1, pInst, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(Test, Func2, pInst, SH_STATIC(Handler_Func2), true); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called, - new State_Func1H_Called, - new State_Func1H_Called, - new State_Func1_Called, - new State_Func2_Called, - new State_Func2H_Called, - new State_Func2H_Called, - new State_Func2H_Called, - new State_Func3H_Called, - new State_Func3H_Called, - new State_Func3H_Called, - new State_Func3_Called, - NULL), "Part 2.1"); - - // Unload plugins one by one - Test_UnloadPlugin(g_SHPtr, 3); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called, - new State_Func1H_Called, - new State_Func1_Called, - new State_Func2_Called, - new State_Func2H_Called, - new State_Func2H_Called, - new State_Func3H_Called, - new State_Func3H_Called, - new State_Func3_Called, - NULL), "Part 2.3.1"); - - Test_UnloadPlugin(g_SHPtr, 2); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called, - new State_Func1_Called, - new State_Func2_Called, - new State_Func2H_Called, - new State_Func3H_Called, - new State_Func3_Called, - NULL), "Part 2.4.1"); - - Test_UnloadPlugin(g_SHPtr, 1); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1_Called, - new State_Func2_Called, - new State_Func3_Called, - NULL), "Part 2.5.1"); - - - // 3) - // Add hooks from "different plugins", then pause the plugins - - g_PLID = 1; - SH_ADD_HOOK(Test, Func1, pInst, SH_STATIC(Handler_Func1), false); - g_PLID = 2; - SH_ADD_HOOK(Test, Func2, pInst, SH_STATIC(Handler_Func2), true); - g_PLID = 3; - SH_ADD_HOOK(Test, Func3, pInst, SH_STATIC(Handler_Func3), false); - - g_PLID = 1; - SH_ADD_HOOK(Test, Func2, pInst, SH_STATIC(Handler_Func2), true); - SH_ADD_HOOK(Test, Func3, pInst, SH_STATIC(Handler_Func3), false); - - g_PLID = 2; - SH_ADD_HOOK(Test, Func1, pInst, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(Test, Func3, pInst, SH_STATIC(Handler_Func3), false); - - g_PLID = 3; - SH_ADD_HOOK(Test, Func1, pInst, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(Test, Func2, pInst, SH_STATIC(Handler_Func2), true); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called, - new State_Func1H_Called, - new State_Func1H_Called, - new State_Func1_Called, - new State_Func2_Called, - new State_Func2H_Called, - new State_Func2H_Called, - new State_Func2H_Called, - new State_Func3H_Called, - new State_Func3H_Called, - new State_Func3H_Called, - new State_Func3_Called, - NULL), "Part 3.1"); - - // Unload plugins one by one - Test_PausePlugin(g_SHPtr, 3); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called, - new State_Func1H_Called, - new State_Func1_Called, - new State_Func2_Called, - new State_Func2H_Called, - new State_Func2H_Called, - new State_Func3H_Called, - new State_Func3H_Called, - new State_Func3_Called, - NULL), "Part 3.3.1"); - - Test_PausePlugin(g_SHPtr, 2); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called, - new State_Func1_Called, - new State_Func2_Called, - new State_Func2H_Called, - new State_Func3H_Called, - new State_Func3_Called, - NULL), "Part 3.4.1"); - - Test_PausePlugin(g_SHPtr, 1); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1_Called, - new State_Func2_Called, - new State_Func3_Called, - NULL), "Part 3.5.1"); - - Test_UnpausePlugin(g_SHPtr, 1); - Test_UnpausePlugin(g_SHPtr, 2); - Test_UnpausePlugin(g_SHPtr, 3); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1H_Called, - new State_Func1H_Called, - new State_Func1H_Called, - new State_Func1_Called, - new State_Func2_Called, - new State_Func2H_Called, - new State_Func2H_Called, - new State_Func2H_Called, - new State_Func3H_Called, - new State_Func3H_Called, - new State_Func3H_Called, - new State_Func3_Called, - NULL), "Part 3.7"); - - // 4) Shutdown :) - Test_CompleteShutdown(g_SHPtr); - - pInst->Func1(); - pInst->Func2(); - pInst->Func3(); - - CHECK_STATES((&g_States, - new State_Func1_Called, - new State_Func2_Called, - new State_Func3_Called, - NULL), "Part 4"); - - return true; -} diff --git a/sourcehook/test/testbail.cpp b/sourcehook/test/testbail.cpp deleted file mode 100644 index 46f7b9d..0000000 --- a/sourcehook/test/testbail.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// TESTBAIL -// This test used to be a test for a bug BAIL found. -// That bug is now fixed so I've granted BAIL the pleasure of being a test for -// the correct priority ordering of hook managers based on their version. - -/* - THE PROBLEM: - Old hook funcs don't work right when you combine override returns and recalls. - THE SOLUTION: - Always use a new hook func when possible. For this, hook funcs have to be able to say - " HELLO I'M NEW! " - - This file tests that functionality. - - How it works: - testbail.cpp compiles with old version of sourcehook.h. - It sets everything up, adds a hook on a function - Then testbail2.cpp which has the new version adds a hook on the same function and - does a recall and overrides the value in it. -*/ -#include "sourcehook_test.h" -#include "testbail.h" - -namespace N_TestBail -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - IGaben *g_Gabgab; -} - -namespace -{ - int EatYams_Handler1(int a) - { - ADD_STATE(State_EatYams_Handler1_Called(a)); - RETURN_META_VALUE(MRES_IGNORED, 0); - } -} - -bool TestBail(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1; - - g_Gabgab = new IGaben; - - SH_ADD_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler1), false); - - ADD_STATE(State_EatYams_Return(g_Gabgab->EatYams(0xDEAD))); - - CHECK_STATES((&g_States, - new State_EatYams_Handler1_Called(0xDEAD), - new State_EatYams_Called(0xDEAD), - new State_EatYams_Return(5), - NULL), "Part 1"); - - if (!TestBail2(error)) - return false; - - CHECK_STATES((&g_States, - new State_EatYams_Handler1_Called(0xDEAD), - new State_EatYams_Handler2_Called(0xDEAD), - new State_EatYams_Handler3_Called(0xBEEF), - new State_EatYams_Called(0xBEEF), - NULL), "Part 2.1"); - - // WHAT IF NOW SOMEONE UNLOADS PLUGIN 2 !?!?!?!? - Test_UnloadPlugin(g_SHPtr, 2); - - ADD_STATE(State_EatYams_Return(g_Gabgab->EatYams(0xDEAD))); - - CHECK_STATES((&g_States, - new State_EatYams_Handler1_Called(0xDEAD), - new State_EatYams_Called(0xDEAD), - new State_EatYams_Return(5), - NULL), "Part 3"); - - SH_REMOVE_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler1), false); - - ADD_STATE(State_EatYams_Return(g_Gabgab->EatYams(0xDEAD))); - - CHECK_STATES((&g_States, - new State_EatYams_Called(0xDEAD), - new State_EatYams_Return(5), - NULL), "Part 4"); - - // Now, heh, try it the other way round. - - Test_CompleteShutdown(g_SHPtr); - - if (!TestBail2(error)) - return false; - - CHECK_STATES((&g_States, - new State_EatYams_Handler2_Called(0xDEAD), - new State_EatYams_Handler3_Called(0xBEEF), - new State_EatYams_Called(0xBEEF), - NULL), "Part 5"); - - SH_ADD_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler1), false); - - ADD_STATE(State_EatYams_Return(g_Gabgab->EatYams(0xDEAD))); - - CHECK_STATES((&g_States, - new State_EatYams_Handler2_Called(0xDEAD), - new State_EatYams_Handler3_Called(0xBEEF), - new State_EatYams_Handler1_Called(0xBEEF), - new State_EatYams_Called(0xBEEF), - new State_EatYams_Return(6), - NULL), "Part 6"); - - delete g_Gabgab; - - return true; -} diff --git a/sourcehook/test/testbail.h b/sourcehook/test/testbail.h deleted file mode 100644 index 258a49c..0000000 --- a/sourcehook/test/testbail.h +++ /dev/null @@ -1,39 +0,0 @@ -////////////////////////////////////////////////////////////////////////// -// Shared data for testbail - -#include -#include "testevents.h" - -namespace N_TestBail -{ - extern StateList g_States; - extern SourceHook::ISourceHook *g_SHPtr; - - MAKE_STATE_1(State_EatYams_Called, int); - MAKE_STATE_1(State_EatYams_Handler1_Called, int); - MAKE_STATE_1(State_EatYams_Handler2_Called, int); - MAKE_STATE_1(State_EatYams_Handler3_Called, int); - MAKE_STATE_1(State_EatYams_Return, int); - - class IGaben - { - public: - virtual int EatYams(int a) - { - ADD_STATE(State_EatYams_Called(a)); - return 5; - } - }; - - extern IGaben *g_Gabgab; - - bool TestBail2(std::string &error); -} - -using namespace N_TestBail; - -namespace -{ - SourceHook::Plugin g_PLID; - SH_DECL_HOOK1(IGaben, EatYams, SH_NOATTRIB, 0, int, int); -} diff --git a/sourcehook/test/testbail2.cpp b/sourcehook/test/testbail2.cpp deleted file mode 100644 index d3f7f28..0000000 --- a/sourcehook/test/testbail2.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// TESTBAIL -// Different compilation unit - -#include "sourcehook.h" -#include "sourcehook_test.h" -#include "testbail.h" - - -int EatYams_Handler2(int a) -{ - ADD_STATE(State_EatYams_Handler2_Called(a)); - RETURN_META_VALUE_NEWPARAMS(MRES_OVERRIDE, 6, &IGaben::EatYams, (0xBEEF)); -} - -int EatYams_Handler3(int a) -{ - ADD_STATE(State_EatYams_Handler3_Called(a)); - RETURN_META_VALUE(MRES_IGNORED, 0); -} - -namespace N_TestBail -{ - bool TestBail2(std::string &error) - { - g_PLID = 2; - - SH_ADD_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler2), false); - SH_ADD_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler3), false); - - int ret = g_Gabgab->EatYams(0xDEAD); - - CHECK_COND(ret == 6, "Part 2.1"); - - return true; - } -} diff --git a/sourcehook/test/testevents.h b/sourcehook/test/testevents.h deleted file mode 100644 index 7a0175c..0000000 --- a/sourcehook/test/testevents.h +++ /dev/null @@ -1,214 +0,0 @@ -/* ======== SourceHook ======== -* Copyright (C) 2004-2007 Metamod:Source Development Team -* No warranties of any kind -* -* License: zlib/libpng -* -* Author(s): Pavol "PM OnoTo" Marko -* ============================ -*/ - -#ifndef __TESTEVENTS_H__ -#define __TESTEVENTS_H__ - -#include -#include -#include -#include -#include - -extern bool g_Verbose; - -static unsigned int MakeHash(const char *name) -{ - int a = 0; - unsigned int res = 0xFFFFFFFF; - - while (*name) - { - res ^= ((unsigned int)*name << ((a++ % 4)*8)); - ++name; - } - return res; -} - -struct State -{ - virtual ~State() - { - - } - - virtual bool IsEqual(State *other) - { - return (MakeHash(GetName()) == MakeHash(other->GetName())) ? true : false; - } - - virtual bool Ignore() - { - return false; - } - - virtual void Dump() = 0; - virtual const char *GetName() = 0; -}; - -struct IgnoreState : public State -{ - virtual bool Ignore() - { - return true; - } - virtual void Dump() - { - } -}; - -typedef std::list StateList; -namespace -{ - void DumpStates(StateList *sl) - { - for (StateList::iterator iter = sl->begin(); iter != sl->end(); ++iter) - (*iter)->Dump(); - } - - bool StatesOk(StateList *sl, ...) - { - StateList requiredstates; - va_list argptr; - va_start(argptr, sl); - while (true) - { - State *cs = va_arg(argptr, State*); - if (!cs) - break; - if (cs->Ignore()) - continue; - requiredstates.push_back(cs); - } - va_end(argptr); - - if (requiredstates.size() != sl->size()) - { - if (g_Verbose) - { - std::cout << std::endl << "FAIL: Should be:" << std::endl; - DumpStates(&requiredstates); - std::cout << std::endl << "FAIL: Is:" << std::endl; - DumpStates(sl); - } - - for (StateList::iterator iter = requiredstates.begin(); iter != requiredstates.end(); ++iter) - delete *iter; - for (StateList::iterator iter = sl->begin(); iter != sl->end(); ++iter) - delete *iter; - sl->clear(); - return false; - } - - bool ok = true; - StateList::iterator req_iter = requiredstates.begin(); - for (StateList::iterator o_iter = sl->begin(); o_iter != sl->end(); ++o_iter, ++req_iter) - { - if (!(*o_iter)->IsEqual(*req_iter)) - { - ok = false; - break; - } - } - - if (!ok && g_Verbose) - { - std::cout << std::endl << "FAIL: Should be:" << std::endl; - DumpStates(&requiredstates); - std::cout << std::endl << "FAIL: Is:" << std::endl; - DumpStates(sl); - } - - for (StateList::iterator iter = requiredstates.begin(); iter != requiredstates.end(); ++iter) - delete *iter; - for (StateList::iterator iter = sl->begin(); iter != sl->end(); ++iter) - delete *iter; - sl->clear(); - - return ok; - } -} - -#define ADD_STATE(name) g_States.push_back(new name) -#define ADD_STATE_PTR(statesptr, name) statesptr->push_back(new name) - -#define CHECK_STATES(mwah, myerr) if (!StatesOk mwah) { error=myerr; return false; } else if (g_Verbose) { std::cout << "No error: " << myerr << std::endl; } - -#define MAKE_STATE(name) struct name : State { \ - virtual void Dump() { \ - std::cout << " " << #name << std::endl; } \ - const char *GetName() { return #name; } \ - }; - -#define MAKE_STATE_1(name, p1_type) struct name : State { \ - p1_type m_Param1; \ - name(p1_type param1) : m_Param1(param1) {} \ - virtual bool IsEqual(State *other) { \ - if (MakeHash(GetName()) != MakeHash(other->GetName())) \ - return false; \ - name *other2 = static_cast(other); \ - return other2->m_Param1 == m_Param1;\ - } \ - virtual void Dump() { \ - std::cout << " " << #name << "; Param1=" << m_Param1 << std::endl; } \ - const char *GetName() { return #name; } \ - } - -#define MAKE_STATE_2(name, p1_type, p2_type) struct name : State { \ - p1_type m_Param1; \ - p2_type m_Param2; \ - name(p1_type param1, p2_type param2) : m_Param1(param1), m_Param2(param2) {} \ - virtual bool IsEqual(State *other) { \ - if (MakeHash(GetName()) != MakeHash(other->GetName())) \ - return false; \ - name *other2 = static_cast(other); \ - return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2;\ - } \ - virtual void Dump() { \ - std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << std::endl; } \ - const char *GetName() { return #name; } \ - } - -#define MAKE_STATE_3(name, p1_type, p2_type, p3_type) struct name : State { \ - p1_type m_Param1; \ - p2_type m_Param2; \ - p3_type m_Param3; \ - name(p1_type param1, p2_type param2, p3_type param3) : m_Param1(param1), m_Param2(param2), m_Param3(param3) {} \ - virtual bool IsEqual(State *other) { \ - if (MakeHash(GetName()) != MakeHash(other->GetName())) \ - return false; \ - name *other2 = static_cast(other); \ - return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2 && other2->m_Param3 == m_Param3;\ - } \ - virtual void Dump() { \ - std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << "; Param3=" << m_Param3 << std::endl; } \ - const char *GetName() { return #name; } \ - } - -#define MAKE_STATE_4(name, p1_type, p2_type, p3_type, p4_type) struct name : State { \ - p1_type m_Param1; \ - p2_type m_Param2; \ - p3_type m_Param3; \ - p4_type m_Param4; \ - name(p1_type param1, p2_type param2, p3_type param3, p4_type param4) : m_Param1(param1), m_Param2(param2), m_Param3(param3), m_Param4(param4) {} \ - virtual bool IsEqual(State *other) { \ - if (MakeHash(GetName()) != MakeHash(other->GetName())) \ - return false; \ - name *other2 = static_cast(other); \ - return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2 && other2->m_Param3 == m_Param3 && other2->m_Param4 == m_Param4;\ - } \ - virtual void Dump() { \ - std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << "; Param3=" << m_Param3 << "; Param4=" << m_Param4 << std::endl; } \ - const char *GetName() { return #name; } \ - } - -#define CHECK_COND(c, err) if (!(c)) { error = err; return false; } - -#endif diff --git a/sourcehook/test/testhookmangen.cpp b/sourcehook/test/testhookmangen.cpp deleted file mode 100644 index 06cd501..0000000 --- a/sourcehook/test/testhookmangen.cpp +++ /dev/null @@ -1,1229 +0,0 @@ -#include -#include "sourcehook.h" -#include "sourcehook_test.h" -#include "testevents.h" -#include "sh_memory.h" -#include "sh_pagealloc.h" -#include "sourcehook_pibuilder.h" - -// TESTHOOKMANGEN -// Test automatic hookman generation -// Tests void and non-void functions -// 0 to 6 params: -// integer-type, float-type, plain-old-data struct and objects with ctors/dtors -// both byval and byref -// also tests ignore/supercede -// also tests recalls - -// :TODO: test override as well - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - SourceHook::IHookManagerAutoGen *g_HMAGPtr; - - // PtrBuf(ptr) gives ptrs unique numbers - // in the order they appear - SourceHook::List g_PtrHash; - - bool g_Inside_LeafFunc = false; // inside a hook or a func - bool g_Silent_CtorDtor = false; // inside a hook or a func - - - // POD / Object types - template - struct POD - { - char x[MYSIZE]; - - bool operator==(const POD &other) - { - return memcmp(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE) == 0; - } - - bool operator==(char other) - { - for (int i = 0; i < MYSIZE; ++i) - { - if (x[i] != other) - return false; - } - return true; - } - }; - - template - std::ostream& operator <<(std::ostream &os, const POD &obj) - { - os << "Some POD!"; - return os; - } - - MAKE_STATE_1(State_ObjOCtor_Called, int /*MYSIZE*/); - MAKE_STATE_1(State_ObjCCtor_Called, int /*MYSIZE*/); - MAKE_STATE_1(State_ObjODtor_Called, int /*MYSIZE*/); - MAKE_STATE_1(State_ObjAssignOp_Called, int /*MYSIZE*/); - - template - struct Object - { - char x[MYSIZE]; - - Object(char initch) - { - memset(reinterpret_cast(x), initch, MYSIZE); - if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) - ADD_STATE(State_ObjOCtor_Called(MYSIZE)); - } - - Object() - { - if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) - ADD_STATE(State_ObjOCtor_Called(MYSIZE)); - } - - Object(const Object & other) - { - memcpy(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE); - if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) - ADD_STATE(State_ObjCCtor_Called(MYSIZE)); - } - - ~Object() - { - if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) - ADD_STATE(State_ObjODtor_Called(MYSIZE)); - } - - Object & operator = (const Object &other) - { - if (!g_Inside_LeafFunc && !g_Silent_CtorDtor) - ADD_STATE(State_ObjAssignOp_Called(MYSIZE)); - - memcpy(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE); - - return *this; - } - - bool operator==(const Object &other) - { - return memcmp(reinterpret_cast(x), reinterpret_cast(other.x), MYSIZE) == 0; - } - }; - - template - std::ostream& operator <<(std::ostream &os, const Object &obj) - { - os << "Some Obj" << static_cast(obj.x[0]); - return os; - } - - // Because of some weird bug in MSVC < 1400 -#define MAKE_PODRET(size) \ - struct PodRet##size \ - { \ - POD actPod; \ - bool operator==(const PodRet##size &other) { return actPod == other.actPod; } \ - bool operator==(char other) { return actPod == other; } \ - }; \ - std::ostream& operator <<(std::ostream &os, const PodRet##size &obj) \ - { \ - os << obj.actPod; \ - return os; \ - } \ - template <> struct MakeRet< PodRet##size > \ - { \ - static PodRet##size Do(int a) \ - { \ - PodRet##size x; \ - memset(reinterpret_cast(x.actPod.x), a, size); \ - return x; \ - } \ - }; - -#define MAKE_OBJRET(size) \ - struct ObjRet##size \ - { \ - Object actObj; \ - bool operator==(const ObjRet##size &other) { return actObj == other.actObj; } \ - bool operator==(char other) { return actObj == other; } \ - }; \ - std::ostream& operator <<(std::ostream &os, const ObjRet##size &obj) \ - { \ - os << obj.actObj; \ - return os; \ - } \ - template <> struct MakeRet< ObjRet##size > \ - { \ - static ObjRet##size Do(int a) NO_OPTIMIZE \ - { \ - ObjRet##size *x = new ObjRet##size; /* ptr: otherwise gcc optimizes away the temp obj */ \ - CAutoPtrDestruction< ObjRet##size > apd(x); \ - memset(reinterpret_cast(x->actObj.x), a, size); \ - return *x; \ - } \ - }; - - - - // "Increment" something: (reproducible change for recall tests) - // integer: ++ - // float: += 1.3 - // pod/object: x[i]++, 0 <= i < MYSIZE - template - struct Increment - { - static void Incr(T &what) - { - ++what; - } - }; - - template<> - struct Increment - { - static void Incr(float &what) - { - what += 1.3f; - } - }; - - template<> - struct Increment - { - static void Incr(double &what) - { - what += 1.3; - } - }; - - template - struct Increment< POD > - { - static void Incr(POD &what) - { - for (int i = 0; i < MYSIZE; ++i) - ++ what.x[i]; - } - }; - - template - struct Increment< Object > - { - static void Incr(Object &what) - { - for (int i = 0; i < MYSIZE; ++i) - ++ what.x[i]; - } - }; - - template<> - struct Increment - { - static void Incr(std::string &what) - { - what += "!"; - } - }; - - #include "testhookmangen.h" - - template - int PtrBuf(T ptr) - { - int a = 0; - - const void *vptr = reinterpret_cast(ptr); - for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter) - { - if (*iter == vptr) - return a; - else - ++a; - } - g_PtrHash.push_back(vptr); - return static_cast(g_PtrHash.size()) - 1; - } - - template - T PtrBufPtr(T ptr) - { - PtrBuf(ptr); - return ptr; - } - - void PtrBuf_Clear(int leave_in = 0) - { - for (SourceHook::List::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();) - { - if (--leave_in < 0) - iter = g_PtrHash.erase(iter); - else - ++iter; - } - } - - // MyDelegate base class for other delegates - class MyDelegate : public SourceHook::ISHDelegate - { - // Unneeded - // because we don't use old SH_REMOVE_HOOK syntax - virtual bool IsEqual(SourceHook::ISHDelegate *pOtherDeleg) - { - return false; - } - - virtual void DeleteThis() - { - delete this; - } - }; - - THGM_MAKE_TEST0_void(0); - THGM_SETUP_PI0(0); - - THGM_MAKE_TEST1_void(1, char); - THGM_SETUP_PI1(1, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_void(2, short); - THGM_SETUP_PI1(2, short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_void(3, int); - THGM_SETUP_PI1(3, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_void(4, float); - THGM_SETUP_PI1(4, float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_void(5, double); - THGM_SETUP_PI1(5, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST5_void(6, char, short, int, float, double); - THGM_SETUP_PI5(6, - char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, - short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, - float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal, - double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal - ); - - THGM_MAKE_TEST2_void(7, char&, double&); - THGM_SETUP_PI2(7, - char&, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByRef, - double&, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByRef - ); - - THGM_MAKE_TEST1_void(8, POD<7>); - THGM_SETUP_PI1(8, POD<7>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_void(9, POD<600>); - THGM_SETUP_PI1(9, POD<600>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_void(10, POD<600> &); - THGM_SETUP_PI1(10, POD<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef); - - THGM_MAKE_TEST2_void(11, Object<3>, Object<600>&); - THGM_SETUP_PI2(11, - Object<3>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor, - Object<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor - ); - - THGM_MAKE_TEST0(101, char); - THGM_SETUP_PI0(101); - THGM_SETUP_RI(101, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST0(102, short); - THGM_SETUP_PI0(102); - THGM_SETUP_RI(102, short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST0(103, int); - THGM_SETUP_PI0(103); - THGM_SETUP_RI(103, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST0(104, float); - THGM_SETUP_PI0(104); - THGM_SETUP_RI(104, float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST0(105, double); - THGM_SETUP_PI0(105); - THGM_SETUP_RI(105, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); - - // pod 1-13 - MAKE_PODRET(1); - THGM_MAKE_TEST1(106, PodRet1, int); - THGM_SETUP_PI1(106, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal - ); - THGM_SETUP_RI(106, PodRet1, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - - MAKE_PODRET(4); - THGM_MAKE_TEST1(107, PodRet4, int); - THGM_SETUP_PI1(107, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal - ); - THGM_SETUP_RI(107, PodRet4, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - - MAKE_PODRET(8); - THGM_MAKE_TEST1(108, PodRet8, int); - THGM_SETUP_PI1(108, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal - ); - THGM_SETUP_RI(108, PodRet8, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - - MAKE_PODRET(13); - THGM_MAKE_TEST1(109, PodRet13, int); - THGM_SETUP_PI1(109, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal - ); - THGM_SETUP_RI(109, PodRet13, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - - MAKE_OBJRET(13); - THGM_MAKE_TEST1(110, ObjRet13, int); - THGM_SETUP_PI1(110, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal - ); - THGM_SETUP_RI(110, ObjRet13, SourceHook::PassInfo::PassType_Object, - SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | - SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); - - MAKE_OBJRET(111); - ObjRet111 g_O111_0; - ObjRet111 g_O111_1; - ObjRet111 g_O111_2; - ObjRet111 g_O111_3; - ObjRet111 g_O111_4; - - template <> - struct MakeRet< ObjRet111& > - { - static ObjRet111 &Do(int a) - { - switch (a) - { - case 0: - return g_O111_0; - case 1: - return g_O111_1; - case 2: - return g_O111_2; - case 3: - return g_O111_3; - default: - return g_O111_4; - } - } - }; - - THGM_MAKE_TEST0(111, ObjRet111& ); - THGM_SETUP_PI0(111); - THGM_SETUP_RI(111, ObjRet111& , SourceHook::PassInfo::PassType_Object, - SourceHook::PassInfo::PassFlag_ByRef | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | - SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); - - - THGM_MAKE_TEST3_void(150, int, double, int); - THGM_SETUP_PI3(150, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, - double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - // vafmt tests - THGM_MAKE_TEST0_vafmt_void(200); - THGM_SETUP_PI0(200); - - THGM_MAKE_TEST1_vafmt_void(201, char); - THGM_SETUP_PI1(201, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_vafmt_void(203, int); - THGM_SETUP_PI1(203, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST5_vafmt_void(206, char, short, int, float, double); - THGM_SETUP_PI5(206, - char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, - short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal, - float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal, - double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal - ); - - THGM_MAKE_TEST2_vafmt_void(207, char&, double&); - THGM_SETUP_PI2(207, - char&, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByRef, - double&, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByRef - ); - - THGM_MAKE_TEST1_vafmt_void(208, POD<7>); - THGM_SETUP_PI1(208, POD<7>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_vafmt_void(210, POD<600> &); - THGM_SETUP_PI1(210, POD<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef) - - THGM_MAKE_TEST1_vafmt(211, int, int); - THGM_SETUP_PI1(211, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal - ); - THGM_SETUP_RI(211, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_vafmt(212, double, int); - THGM_SETUP_PI1(212, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal - ); - THGM_SETUP_RI(212, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_vafmt(213, PodRet8, int); - THGM_SETUP_PI1(213, - int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal - ); - THGM_SETUP_RI(213, PodRet8, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal); - - THGM_MAKE_TEST1_vafmt_void(214, Object<133>); - THGM_SETUP_PI1(214, Object<133>, SourceHook::PassInfo::PassType_Object, - SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | - SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp); - - - MAKE_STATE(State_Hello_Func4_Called); - MAKE_STATE(State_Hello_Func79_Called); - - MAKE_STATE(State_Hello_Func4_PreHook); - MAKE_STATE(State_Hello_Func79_PreHook); - - // Test for larger vtable indices - class Hello - { - public: - virtual void Func0() {} - virtual void Func1() {} - virtual void Func2() {} - virtual void Func3() {} - virtual void Func4() - { - ADD_STATE(State_Hello_Func4_Called); - } - virtual void Func5() {} - virtual void Func6() {} - virtual void Func7() {} - virtual void Func8() {} - virtual void Func9() {} - virtual void Func10() {} - virtual void Func11() {} - virtual void Func12() {} - virtual void Func13() {} - virtual void Func14() {} - virtual void Func15() {} - virtual void Func16() {} - virtual void Func17() {} - virtual void Func18() {} - virtual void Func19() {} - virtual void Func20() {} - virtual void Func21() {} - virtual void Func22() {} - virtual void Func23() {} - virtual void Func24() {} - virtual void Func25() {} - virtual void Func26() {} - virtual void Func27() {} - virtual void Func28() {} - virtual void Func29() {} - virtual void Func30() {} - virtual void Func31() {} - virtual void Func32() {} - virtual void Func33() {} - virtual void Func34() {} - virtual void Func35() {} - virtual void Func36() {} - virtual void Func37() {} - virtual void Func38() {} - virtual void Func39() {} - virtual void Func40() {} - virtual void Func41() {} - virtual void Func42() {} - virtual void Func43() {} - virtual void Func44() {} - virtual void Func45() {} - virtual void Func46() {} - virtual void Func47() {} - virtual void Func48() {} - virtual void Func49() {} - virtual void Func50() {} - virtual void Func51() {} - virtual void Func52() {} - virtual void Func53() {} - virtual void Func54() {} - virtual void Func55() {} - virtual void Func56() {} - virtual void Func57() {} - virtual void Func58() {} - virtual void Func59() {} - virtual void Func60() {} - virtual void Func61() {} - virtual void Func62() {} - virtual void Func63() {} - virtual void Func64() {} - virtual void Func65() {} - virtual void Func66() {} - virtual void Func67() {} - virtual void Func68() {} - virtual void Func69() {} - virtual void Func70() {} - virtual void Func71() {} - virtual void Func72() {} - virtual void Func73() {} - virtual void Func74() {} - virtual void Func75() {} - virtual void Func76() {} - virtual void Func77() {} - virtual void Func78() {} - virtual void Func79() - { - ADD_STATE(State_Hello_Func79_Called); - } - }; - class Hello_Func4_Deleg : public MyDelegate - { - virtual void Func() - { - ADD_STATE(State_Hello_Func4_PreHook); - } - }; - class Hello_Func79_Deleg : public MyDelegate - { - int a; - virtual void Func() - { - ADD_STATE(State_Hello_Func79_PreHook); - } - }; - - bool Tests1(std::string &error) - { - THGM_DO_TEST_void(0, ()); - - THGM_DO_TEST_void(1, (100)); - - THGM_DO_TEST_void(2, (0x1F00)); - - THGM_DO_TEST_void(3, (0x1F000000)); - - THGM_DO_TEST_void(4, (0.5f)); - - THGM_DO_TEST_void(5, (5.5)); - - THGM_DO_TEST_void(6, (100, 0x1f00, 0x1f000000, 0.5f, 5.5)); - - return true; - } - - bool Tests2(std::string &error) - { - char a = 5; - double b = 233.33; - THGM_DO_TEST_void(7, (a, b)); - - POD<7> pod7 = MakeRet< POD<7> >::Do(78); - THGM_DO_TEST_void(8, (pod7)); - - POD<600> pod600 = MakeRet< POD<600> >::Do(34); - THGM_DO_TEST_void(9, (pod600)); - - THGM_DO_TEST_void(10, (pod600)); - - // Test11: Special: constructors/destructors - PtrBuf_Clear(); - Object<3> *obj3_real = new Object<3>(33); - Object<600> *obj600_real = new Object<600>(21); - - Object<3> & obj3 = *obj3_real; - Object<600> & obj600 = *obj600_real; - - CHECK_STATES((&g_States, - new State_ObjOCtor_Called(3), - new State_ObjOCtor_Called(600), - NULL), "Test11 Part0"); - - setuppi_11(); - SourceHook::HookManagerPubFunc myhookman11 = g_HMAGPtr->MakeHookMan(protoinfo_11, 0, 0); \ - CAutoReleaseHookMan arhm_11(myhookman11); \ - int hook1_11, hook2_11, hook3_11, hook4_11; - - TestClass11 *pTest11 = new TestClass11; - CAutoPtrDestruction apd11(pTest11); - - /* no hooks - no hooks */ - PtrBuf_Clear(); - pTest11->Func(obj3, obj600); - - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_ObjCCtor_Called(3), - new State_Func11(pTest11, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - NULL), "Test" "11" " Part1"); - g_Inside_LeafFunc = false; - - /* hook1 - no hooks */ - THGM_ADD_HOOK(11, 1); - - PtrBuf_Clear(); - pTest11->Func(obj3, obj600); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_ObjCCtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg_11(1, pTest11, 0, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Func11(pTest11, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjODtor_Called(3), - NULL), "Test" "11" " Part2"); - g_Inside_LeafFunc = false; - - THGM_REMOVE_HOOK(11, 1); - - /* hook1, hook2 - hook3, hook4 */ - THGM_ADD_HOOK(11, 1); - THGM_ADD_HOOK(11, 2); - THGM_ADD_HOOK(11, 3); - THGM_ADD_HOOK(11, 4); - PtrBuf_Clear(); - pTest11->Func(obj3, obj600); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_ObjCCtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg_11(1, pTest11, 0, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg_11(2, pTest11, 1, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg_11(3, pTest11, 2, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg_11(4, pTest11, 3, ParamState_m11 (obj3, obj600)), - new State_ObjODtor_Called(3), - - new State_ObjODtor_Called(3), - NULL), "Test" "11" " Part3"); - g_Inside_LeafFunc = false; - - /* hook1 - hook3, hook4 WITH RECALLS */ - THGM_REMOVE_HOOK(11, 2); - PtrBuf_Clear(); - TestClass11::ms_DoRecall = true; - pTest11->Func(obj3, obj600); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_ObjCCtor_Called(3), - - new State_ObjCCtor_Called(3), - new State_Deleg_11(1, pTest11, 0 /* first deleg ptr */, ParamState_m11 (obj3, obj600)), - - // recall ! - // second hookfunc -> new copy - new State_ObjCCtor_Called(3), - - // in second hookfunc now - // -> calls orig func - - new State_ObjCCtor_Called(3), - new State_Func11(pTest11, ParamState_m11 (obj3, obj600)(1)), - new State_ObjODtor_Called(3), - - // calls first posthook - new State_ObjCCtor_Called(3), - new State_Deleg_11(3, pTest11, 1 /* second deleg ptr */, ParamState_m11 (obj3, obj600)(1)), - - // recall! - // third hookfunc -> new copy - new State_ObjCCtor_Called(3), - - // calls second posthook - - new State_ObjCCtor_Called(3), - new State_Deleg_11(4, pTest11, 2 /* third deleg ptr */, ParamState_m11 (obj3, obj600)(2)), - - // recall! - // fourth hookfunc -> new copy - new State_ObjCCtor_Called(3), - - // has nothing to do though! - - // fourth hookfunc done -> ret - new State_ObjODtor_Called(3), - - // third hookfunc done -> ret - new State_ObjODtor_Called(3), - // ret from hookhandler which did the recall - new State_ObjODtor_Called(3), - - // second hookfunc done -> ret - new State_ObjODtor_Called(3), - // ret from hookhandler which did the recall - new State_ObjODtor_Called(3), - - // deleg1's instance - new State_ObjODtor_Called(3), - // first hookfunc done -> ret - new State_ObjODtor_Called(3), - NULL), "Test" "11" " Part4"); - g_Inside_LeafFunc = false; - - THGM_REMOVE_HOOK(11, 1); - THGM_REMOVE_HOOK(11, 3); - THGM_REMOVE_HOOK(11, 4); - - delete obj3_real; - delete obj600_real; - - CHECK_STATES((&g_States, - new State_ObjODtor_Called(3), - new State_ObjODtor_Called(600), - NULL), "Test11 Part100"); - - return true; - } - - bool Tests3(std::string &error) - { - THGM_DO_TEST(101, ()); - - THGM_DO_TEST(102, ()); - - THGM_DO_TEST(103, ()); - - THGM_DO_TEST(104, ()); - - THGM_DO_TEST(105, ()); - - // pod returns - THGM_DO_TEST(106, (5)); - THGM_DO_TEST(107, (5)); - THGM_DO_TEST(108, (5)); - THGM_DO_TEST(109, (5)); - - return true; - } - - bool Tests4(std::string &error) - { - // Test110: Special: constructors/destructors on return - PtrBuf_Clear(); - ObjRet13 *obj13_real = new ObjRet13; - ObjRet13 &obj13 = *obj13_real; - - CHECK_STATES((&g_States, - new State_ObjOCtor_Called(13), - NULL), "Test110 Part0"); - - setuppi_110(); - setupri_110(); - - SourceHook::HookManagerPubFunc myhookman110 = g_HMAGPtr->MakeHookMan(protoinfo_110, 0, 0); \ - CAutoReleaseHookMan arhm_110(myhookman110); \ - int hook1_110, hook2_110, hook3_110, hook4_110; - - TestClass110 *pTest110 = new TestClass110; - CAutoPtrDestruction apd110(pTest110); - - /* no hooks - no hooks */ - PtrBuf_Clear(); - obj13 = pTest110->Func(5); - - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - new State_Func110(pTest110, ParamState_m110 (5)), - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in our stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack - new State_ObjODtor_Called(13), // Func110: destruction of temporary object - NULL), "Test" "110" " Part1"); - g_Inside_LeafFunc = false; - - /* hook1 - no hooks */ - THGM_ADD_HOOK(110, 1); - - PtrBuf_Clear(); - obj13 = pTest110->Func(5); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - // HookFunc: construct orig_ret/override_ret/plugin_ret objects - new State_ObjOCtor_Called(13), - new State_ObjOCtor_Called(13), - new State_ObjOCtor_Called(13), - - // Calling delegate - new State_Deleg_110(1, pTest110, 0, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // Calling orig function Func110 - new State_Func110(pTest110, ParamState_m110 (5)), - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: orig_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // hookfunc is returning: - new State_ObjCCtor_Called(13), // copy to temp object in our stack - - // hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret - new State_ObjODtor_Called(13), - new State_ObjODtor_Called(13), - new State_ObjODtor_Called(13), - - // we are in our function: assign - new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack - new State_ObjODtor_Called(13), // Func110: destruction of temporary object - - NULL), "Test" "11" " Part2"); - - CHECK_COND(obj13 == 0, "Test" "11" " Part 2.1"); - g_Inside_LeafFunc = false; - - THGM_REMOVE_HOOK(110, 1); - - /* hook1, hook2 - hook3, hook4 */ - THGM_ADD_HOOK(110, 1); - THGM_ADD_HOOK(110, 2); - THGM_ADD_HOOK(110, 3); - THGM_ADD_HOOK(110, 4); - - PtrBuf_Clear(); - obj13 = pTest110->Func(5); - g_Inside_LeafFunc = true; - CHECK_STATES((&g_States, - // HookFunc: construct orig_ret/override_ret/plugin_ret objects - new State_ObjOCtor_Called(13), - new State_ObjOCtor_Called(13), - new State_ObjOCtor_Called(13), - - // Calling delegate1 - new State_Deleg_110(1, pTest110, 0, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - - // Calling delegate2 - new State_Deleg_110(2, pTest110, 1, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret - new State_ObjAssignOp_Called(13), - - // SUPERCEDE -> orig function is not called - // instead: orig_ret = override_ret - new State_ObjAssignOp_Called(13), - - // Calling delegate3 - new State_Deleg_110(3, pTest110, 2, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // Calling delegate4 - new State_Deleg_110(4, pTest110, 3, ParamState_m110 (5)), - - new State_ObjOCtor_Called(13), // MakeRet: Construction of x - new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // MakeRet: Destruction of x - - // back in hookfunc - new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack - new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack - - // hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret (yes really, we overwrite the old value!) - new State_ObjAssignOp_Called(13), - - // hookfunc is returning: - new State_ObjCCtor_Called(13), // copy to temp object in our stack - - // hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret - new State_ObjODtor_Called(13), - new State_ObjODtor_Called(13), - new State_ObjODtor_Called(13), - - // we are in our function: assign - new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack - new State_ObjODtor_Called(13), // Func110: destruction of temporary object - - NULL), "Test" "11" " Part3"); - - CHECK_COND(obj13 == 4, "Test" "11" " Part 3.1"); - g_Inside_LeafFunc = false; - - THGM_REMOVE_HOOK(110, 1); - THGM_REMOVE_HOOK(110, 2); - THGM_REMOVE_HOOK(110, 3); - THGM_REMOVE_HOOK(110, 4); - - delete obj13_real; - - CHECK_STATES((&g_States, - new State_ObjODtor_Called(13), - NULL), "Test110 Part100"); - - - THGM_DO_TEST_void(150, (5, 5.5, 6)); - - return true; - } - - bool Tests5(std::string &error) - { - // RefRet - THGM_DO_TEST(111, ()); - - // Vafmt - - THGM_DO_TEST_void(200, ("Hello %s%d%s", "BA", 1, "L!")); - - THGM_DO_TEST_void(201, (100, "Hello %s%d%s", "BA", 1, "L!")); - - THGM_DO_TEST_void(203, (0x1F000000, "Hello %s%d%s", "BA", 1, "L!")); - - THGM_DO_TEST_void(206, (100, 0x1f00, 0x1f000000, 0.5f, 5.5, "Hello %s%d%s", "BA", 1, "L!")); - - char a = 5; - double b = 233.33; - THGM_DO_TEST_void(207, (a, b, "Hello %s%d%s", "BA", 1, "L!")); - - POD<7> pod7 = MakeRet< POD<7> >::Do(78); - THGM_DO_TEST_void(208, (pod7, "Hello %s%d%s", "BA", 1, "L!")); - - POD<600> pod600 = MakeRet< POD<600> >::Do(34); - THGM_DO_TEST_void(210, (pod600, "Hello %s%d%s", "BA", 1, "L!")); - - - THGM_DO_TEST(211, (5, "Hello %s%d%s", "BA", 1, "L!")); - THGM_DO_TEST(212, (5, "Hello %s%d%s", "BA", 1, "L!")); - THGM_DO_TEST(213, (5, "Hello %s%d%s", "BA", 1, "L!")); - - // Silence Object's ctors/dtors: we only want a forced byref param - g_Silent_CtorDtor = true; - Object<133> *myobj133 = new Object<133>; - THGM_DO_TEST_void(214, (*myobj133, "Hello %s%d%s", "BA", 1, "L!")); - delete myobj133; - g_Silent_CtorDtor = false; - - // Test for high vtable indices - Hello *pHello = new Hello; - SourceHook::CProtoInfoBuilder helloPi(SourceHook::ProtoInfo::CallConv_ThisCall); - SourceHook::HookManagerPubFunc helloHM_4 = g_HMAGPtr->MakeHookMan(helloPi, 0, 4); - SourceHook::HookManagerPubFunc helloHM_79 = g_HMAGPtr->MakeHookMan(helloPi, 0, 79); - - pHello->Func4(); - pHello->Func79(); - SH_CALL(pHello, &Hello::Func4)(); - SH_CALL(pHello, &Hello::Func79)(); - CHECK_STATES((&g_States, - new State_Hello_Func4_Called, - new State_Hello_Func79_Called, - new State_Hello_Func4_Called, - new State_Hello_Func79_Called, - NULL), "Test" "Hello" " Part1"); - - int helloHook4 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pHello), - 0, helloHM_4, new Hello_Func4_Deleg, false); - - int helloHook79 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pHello), - 0, helloHM_79, new Hello_Func79_Deleg, false); - - pHello->Func4(); - pHello->Func79(); - SH_CALL(pHello, &Hello::Func4)(); - SH_CALL(pHello, &Hello::Func79)(); - - CHECK_STATES((&g_States, - new State_Hello_Func4_PreHook, - new State_Hello_Func4_Called, - new State_Hello_Func79_PreHook, - new State_Hello_Func79_Called, - new State_Hello_Func4_Called, - new State_Hello_Func79_Called, - NULL), "Test" "Hello" " Part2"); - - g_SHPtr->RemoveHookByID(helloHook4); - g_SHPtr->RemoveHookByID(helloHook79); - - g_HMAGPtr->ReleaseHookMan(helloHM_4); - g_HMAGPtr->ReleaseHookMan(helloHM_79); - - return true; - } -} - - -bool TestHookManGen(std::string &error) -{ - GET_SHPTR(g_SHPtr); - GET_HMAG(g_HMAGPtr, g_SHPtr); - g_PLID = 1337; - - // 5 Global constructors (g_O111_*) - CHECK_STATES((&g_States, - new State_ObjOCtor_Called(111), - new State_ObjOCtor_Called(111), - new State_ObjOCtor_Called(111), - new State_ObjOCtor_Called(111), - new State_ObjOCtor_Called(111), - NULL), "GlobCtors"); - - if (!Tests1(error)) - return false; - if (!Tests2(error)) - return false; - if (!Tests3(error)) - return false; - if (!Tests4(error)) - return false; - if (!Tests5(error)) - return false; - - // Shutdown now! - // If we don't SH will auto-shutdown _after_ genc's destructor is called - // -> crash - - Test_CompleteShutdown(g_SHPtr); - - CHECK_COND(sizeof(PodRet1) == 1, "WTF!"); - CHECK_COND(sizeof(PodRet4) == 4, "WTF!"); - CHECK_COND(sizeof(PodRet8) == 8, "WTF!"); - CHECK_COND(sizeof(PodRet13) == 13, "WTF!"); - - return true; -} - -bool TestCPageAlloc(std::string &error) -{ - using namespace SourceHook; - - CPageAlloc alloc; - int i; - size_t ps = alloc.GetPageSize(); - - char *test1[8]; - - for (i = 0; i < 8; ++i) - test1[i] = (char*) alloc.Alloc(ps / 4); - - CHECK_COND(test1[1] == test1[0] + ps/4, "Part 1.1"); - CHECK_COND(test1[2] == test1[1] + ps/4, "Part 1.2"); - CHECK_COND(test1[3] == test1[2] + ps/4, "Part 1.3"); - - CHECK_COND(test1[5] == test1[4] + ps/4, "Part 1.4"); - CHECK_COND(test1[6] == test1[5] + ps/4, "Part 1.5"); - CHECK_COND(test1[7] == test1[6] + ps/4, "Part 1.6"); - - void *test2 = alloc.Alloc(ps * 3); - - alloc.SetRW(test2); - memset(test2, 0, ps * 3); // should not crash :) - alloc.SetRE(test2); - - alloc.Free(test2); - - // Dealloc a ps/4 block and place two ps/8 blocks into it - alloc.Free(test1[2]); - - char *test3[2]; - test3[0] = (char*) alloc.Alloc(ps / 8); - test3[1] = (char*) alloc.Alloc(ps / 8); - - CHECK_COND(test3[0] == test1[2], "Part 2.1"); - CHECK_COND(test3[1] == test1[2] + ps/8, "Part 2.2"); - - // Isolated - char *test4[8]; - for (i = 0; i < 8; ++i) - test4[i] = (char*) alloc.AllocIsolated(ps / 4); - - // -> The difference is at least one page - CHECK_COND(static_cast(abs(test4[1] - test4[0])) >= ps, "Part 3.1"); - CHECK_COND(static_cast(abs(test4[2] - test4[1])) >= ps, "Part 3.2"); - CHECK_COND(static_cast(abs(test4[3] - test4[2])) >= ps, "Part 3.3"); - - CHECK_COND(static_cast(abs(test4[5] - test4[4])) >= ps, "Part 3.4"); - CHECK_COND(static_cast(abs(test4[6] - test4[5])) >= ps, "Part 3.5"); - CHECK_COND(static_cast(abs(test4[7] - test4[6])) >= ps, "Part 3.6"); - - // Thus i can set everything except for test4[2] to RE and still write to test4[2] - - alloc.SetRW(test4[2]); - - alloc.SetRE(test4[0]); - alloc.SetRE(test4[1]); - alloc.SetRE(test4[3]); - alloc.SetRE(test4[4]); - alloc.SetRE(test4[5]); - alloc.SetRE(test4[6]); - alloc.SetRE(test4[7]); - - memset((void*)test4[2], 0, ps / 4); - - // alignement tests - CPageAlloc alloc1(1); - CPageAlloc alloc4(4); - CPageAlloc alloc16(16); - - void *last1 = alloc1.Alloc(1); - void *last4 = alloc4.Alloc(4); - void *last16 = alloc16.Alloc(16); - void *cur; - for (int i = 0; i < 20; ++i) - { - cur = alloc1.Alloc(1); - CHECK_COND(reinterpret_cast(cur) == reinterpret_cast(last1) + 1, "Part 4.1"); - last1 = cur; - - cur = alloc4.Alloc(1); - CHECK_COND(reinterpret_cast(cur) == reinterpret_cast(last4) + 4, "Part 4.2"); - last4 = cur; - - cur = alloc16.Alloc(1); - CHECK_COND(reinterpret_cast(cur) == reinterpret_cast(last16) + 16, "Part 4.3"); - last16 = cur; - } - - alloc16.Free(alloc16.Alloc(1)); - return true; -} diff --git a/sourcehook/test/testhookmangen.h b/sourcehook/test/testhookmangen.h deleted file mode 100644 index 736894b..0000000 --- a/sourcehook/test/testhookmangen.h +++ /dev/null @@ -1,2192 +0,0 @@ -struct CAutoReleaseHookMan -{ - SourceHook::HookManagerPubFunc m_Ptr; - CAutoReleaseHookMan(SourceHook::HookManagerPubFunc ptr) : m_Ptr(ptr) - { - } - ~CAutoReleaseHookMan() - { - g_HMAGPtr->ReleaseHookMan(m_Ptr); - } -}; - -// Strip & -template struct StripRef -{ - typedef T type; -}; - -template struct StripRef -{ - typedef T type; -}; - -// Address of constructor/destructor -// (using wrappers) -template -class Ctor_Thunk -{ -public: - void NormalConstructor() - { - new(this) T; - } - - void CopyConstructor(const T &other) - { - new(this) T(other); - } - - void Destructor() - { - reinterpret_cast(this)->~T(); - } - - const T& AssignOp(const T &other) - { - return (*reinterpret_cast(this) = other); - } -}; - - -template -void *FindFuncAddr(T mfp) -{ - union - { - T a; - void *b; - } u; - u.a = mfp; - return u.b; -} - -// Reference carrier -template struct MyRefCarrier -{ - typedef T type; -}; - -template struct MyRefCarrier -{ - class type - { - T *m_StoredRef; - public: - type() : m_StoredRef(NULL) - { - } - type(T& ref) : m_StoredRef(&ref) - { - } - - T& operator= (T& ref) - { - m_StoredRef = &ref; - return ref; - } - - operator T& () const - { - return *m_StoredRef; - } - - bool operator== (const typename MyRefCarrier::type &other) - { - return m_StoredRef == other.m_StoredRef; - } - - friend std::ostream& operator <<(std::ostream &os,const typename MyRefCarrier::type &obj) - { - os << *obj.m_StoredRef; - return os; - } - }; -}; - -#if SH_COMP==SH_COMP_GCC -#define NO_OPTIMIZE __attribute__((noinline)) -#else -#define NO_OPTIMIZE -#endif - -// Return value maker -template -struct MakeRet -{ - static T Do(int a) - { - return a; - } -}; - -template -struct MakeRet< POD > -{ - static POD Do(int a) - { - POD x; - memset(reinterpret_cast(x.x), a, SIZE); - return x; - } -}; - -// Stores parameter status -template -bool EqualToMyFmtString(T sth) -{ - return false; -} - -bool EqualToMyFmtString(std::string &sth) -{ - if (sth == "Hello %s%d%s") - sth = "Hello BA1L!"; - return true; -} - - - - -template -struct ParamState0 -{ - - - bool operator==(const ParamState0 &other) - { - return true - - ; - } - ParamState0(...) - { - - } - - ParamState0 & operator() (int incrsteps) - { - - - - return *this; - } -}; - - -std::ostream& operator <<(std::ostream &os,const ParamState0<0> &obj) -{ - ; - return os; -} - - - -template -struct ParamState1 -{ - typename MyRefCarrier::type m_1; - - bool operator==(const ParamState1 &other) - { - return true - && m_1 == other.m_1 - ; - } - ParamState1(p1 a1, ...) : m_1(a1) - { - - EqualToMyFmtString(m_1); - - } - - ParamState1 & operator() (int incrsteps) - { - int i; - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_1); - - - return *this; - } -}; - -template -std::ostream& operator <<(std::ostream &os,const ParamState1<0, p1> &obj) -{ - os << obj.m_1; - return os; -} - - - -template -struct ParamState2 -{ - typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; - - bool operator==(const ParamState2 &other) - { - return true - && m_2 == other.m_2 && m_2 == other.m_2 - ; - } - ParamState2(p1 a1, p2 a2, ...) : m_1(a1), m_2(a2) - { - - EqualToMyFmtString(m_1); - - EqualToMyFmtString(m_2); - - } - - ParamState2 & operator() (int incrsteps) - { - int i; - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_1); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_2); - - - return *this; - } -}; - -template -std::ostream& operator <<(std::ostream &os,const ParamState2<0, p1, p2> &obj) -{ - os << obj.m_1<< obj.m_2; - return os; -} - - - -template -struct ParamState3 -{ - typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; typename MyRefCarrier::type m_3; - - bool operator==(const ParamState3 &other) - { - return true - && m_3 == other.m_3 && m_3 == other.m_3 && m_3 == other.m_3 - ; - } - ParamState3(p1 a1, p2 a2, p3 a3, ...) : m_1(a1), m_2(a2), m_3(a3) - { - - EqualToMyFmtString(m_1); - - EqualToMyFmtString(m_2); - - EqualToMyFmtString(m_3); - - } - - ParamState3 & operator() (int incrsteps) - { - int i; - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_1); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_2); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_3); - - - return *this; - } -}; - -template -std::ostream& operator <<(std::ostream &os,const ParamState3<0, p1, p2, p3> &obj) -{ - os << obj.m_1<< obj.m_2<< obj.m_3; - return os; -} - - - -template -struct ParamState4 -{ - typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; typename MyRefCarrier::type m_3; typename MyRefCarrier::type m_4; - - bool operator==(const ParamState4 &other) - { - return true - && m_4 == other.m_4 && m_4 == other.m_4 && m_4 == other.m_4 && m_4 == other.m_4 - ; - } - ParamState4(p1 a1, p2 a2, p3 a3, p4 a4, ...) : m_1(a1), m_2(a2), m_3(a3), m_4(a4) - { - - EqualToMyFmtString(m_1); - - EqualToMyFmtString(m_2); - - EqualToMyFmtString(m_3); - - EqualToMyFmtString(m_4); - - } - - ParamState4 & operator() (int incrsteps) - { - int i; - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_1); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_2); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_3); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_4); - - - return *this; - } -}; - -template -std::ostream& operator <<(std::ostream &os,const ParamState4<0, p1, p2, p3, p4> &obj) -{ - os << obj.m_1<< obj.m_2<< obj.m_3<< obj.m_4; - return os; -} - - - -template -struct ParamState5 -{ - typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; typename MyRefCarrier::type m_3; typename MyRefCarrier::type m_4; typename MyRefCarrier::type m_5; - - bool operator==(const ParamState5 &other) - { - return true - && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 && m_5 == other.m_5 - ; - } - ParamState5(p1 a1, p2 a2, p3 a3, p4 a4, p5 a5, ...) : m_1(a1), m_2(a2), m_3(a3), m_4(a4), m_5(a5) - { - - EqualToMyFmtString(m_1); - - EqualToMyFmtString(m_2); - - EqualToMyFmtString(m_3); - - EqualToMyFmtString(m_4); - - EqualToMyFmtString(m_5); - - } - - ParamState5 & operator() (int incrsteps) - { - int i; - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_1); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_2); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_3); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_4); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_5); - - - return *this; - } -}; - -template -std::ostream& operator <<(std::ostream &os,const ParamState5<0, p1, p2, p3, p4, p5> &obj) -{ - os << obj.m_1<< obj.m_2<< obj.m_3<< obj.m_4<< obj.m_5; - return os; -} - - - -template -struct ParamState6 -{ - typename MyRefCarrier::type m_1; typename MyRefCarrier::type m_2; typename MyRefCarrier::type m_3; typename MyRefCarrier::type m_4; typename MyRefCarrier::type m_5; typename MyRefCarrier::type m_6; - - bool operator==(const ParamState6 &other) - { - return true - && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 && m_6 == other.m_6 - ; - } - ParamState6(p1 a1, p2 a2, p3 a3, p4 a4, p5 a5, p6 a6, ...) : m_1(a1), m_2(a2), m_3(a3), m_4(a4), m_5(a5), m_6(a6) - { - - EqualToMyFmtString(m_1); - - EqualToMyFmtString(m_2); - - EqualToMyFmtString(m_3); - - EqualToMyFmtString(m_4); - - EqualToMyFmtString(m_5); - - EqualToMyFmtString(m_6); - - } - - ParamState6 & operator() (int incrsteps) - { - int i; - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_1); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_2); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_3); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_4); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_5); - - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_6); - - - return *this; - } -}; - -template -std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4, p5, p6> &obj) -{ - os << obj.m_1<< obj.m_2<< obj.m_3<< obj.m_4<< obj.m_5<< obj.m_6; - return os; -} - - - -#define CAT2(a, b) a##b -#define CAT3(a, b, c) a##b##c -#define CAT4(a, b, c, d) a##b##c##d - -// hook1: pre ignore -// hook2: pre supercede -// hook3: post ignore -// hook4: post supercede - - - - -#define THGM_MAKE_TEST0_void(id) \ - struct TestClass##id; \ - typedef ParamState0<0 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - - -#define THGM_MAKE_TEST0(id, ret_type) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState0<0 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call() \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id())); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, ()); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - -#define THGM_MAKE_TEST0_vafmt_void(id) \ - struct TestClass##id; \ - typedef ParamState1<0, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(std::string(buf)))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, ("%s!", buf)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST0_vafmt(id, ret_type) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState1<0, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(std::string(buf)))); \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, ("%s!", buf)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_SETUP_PI0(id) \ - void setuppi_##id() \ - { \ - \ - } - - - -#define THGM_MAKE_TEST1_void(id, param1) \ - struct TestClass##id; \ - typedef ParamState1<0, param1 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - - -#define THGM_MAKE_TEST1(id, ret_type, param1) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState1<0, param1 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - -#define THGM_MAKE_TEST1_vafmt_void(id, param1) \ - struct TestClass##id; \ - typedef ParamState2<0, param1, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, std::string(buf)))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, "%s!", buf)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST1_vafmt(id, ret_type, param1) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState2<0, param1, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, std::string(buf)))); \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, "%s!", buf)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_SETUP_PI1(id, p1_type, p1_passtype, p1_flags) \ - void setuppi_##id() \ - { \ - \ - protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ - (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - } - - - -#define THGM_MAKE_TEST2_void(id, param1, param2) \ - struct TestClass##id; \ - typedef ParamState2<0, param1, param2 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - - -#define THGM_MAKE_TEST2(id, ret_type, param1, param2) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState2<0, param1, param2 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - -#define THGM_MAKE_TEST2_vafmt_void(id, param1, param2) \ - struct TestClass##id; \ - typedef ParamState3<0, param1, param2, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, std::string(buf)))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, "%s!", buf)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST2_vafmt(id, ret_type, param1, param2) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState3<0, param1, param2, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, std::string(buf)))); \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, "%s!", buf)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_SETUP_PI2(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags) \ - void setuppi_##id() \ - { \ - \ - protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ - (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ - (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - } - - - -#define THGM_MAKE_TEST3_void(id, param1, param2, param3) \ - struct TestClass##id; \ - typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - - -#define THGM_MAKE_TEST3(id, ret_type, param1, param2, param3) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState3<0, param1, param2, param3 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - -#define THGM_MAKE_TEST3_vafmt_void(id, param1, param2, param3) \ - struct TestClass##id; \ - typedef ParamState4<0, param1, param2, param3, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, param3 p3, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, std::string(buf)))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, param3 p3, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST3_vafmt(id, ret_type, param1, param2, param3) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState4<0, param1, param2, param3, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, std::string(buf)))); \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, "%s!", buf)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_SETUP_PI3(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags) \ - void setuppi_##id() \ - { \ - \ - protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ - (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ - (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p3_type), p3_passtype, p3_flags, \ - (p3_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - } - - - -#define THGM_MAKE_TEST4_void(id, param1, param2, param3, param4) \ - struct TestClass##id; \ - typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - - -#define THGM_MAKE_TEST4(id, ret_type, param1, param2, param3, param4) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState4<0, param1, param2, param3, param4 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - -#define THGM_MAKE_TEST4_vafmt_void(id, param1, param2, param3, param4) \ - struct TestClass##id; \ - typedef ParamState5<0, param1, param2, param3, param4, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, std::string(buf)))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST4_vafmt(id, ret_type, param1, param2, param3, param4) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState5<0, param1, param2, param3, param4, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, std::string(buf)))); \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, "%s!", buf)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_SETUP_PI4(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags) \ - void setuppi_##id() \ - { \ - \ - protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ - (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ - (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p3_type), p3_passtype, p3_flags, \ - (p3_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p4_type), p4_passtype, p4_flags, \ - (p4_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - } - - - -#define THGM_MAKE_TEST5_void(id, param1, param2, param3, param4, param5) \ - struct TestClass##id; \ - typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - - -#define THGM_MAKE_TEST5(id, ret_type, param1, param2, param3, param4, param5) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState5<0, param1, param2, param3, param4, param5 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - -#define THGM_MAKE_TEST5_vafmt_void(id, param1, param2, param3, param4, param5) \ - struct TestClass##id; \ - typedef ParamState6<0, param1, param2, param3, param4, param5, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, std::string(buf)))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST5_vafmt(id, ret_type, param1, param2, param3, param4, param5) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState6<0, param1, param2, param3, param4, param5, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, std::string(buf)))); \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, p5, "%s!", buf)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_SETUP_PI5(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags) \ - void setuppi_##id() \ - { \ - \ - protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ - (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ - (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p3_type), p3_passtype, p3_flags, \ - (p3_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p4_type), p4_passtype, p4_flags, \ - (p4_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p5_type), p5_passtype, p5_flags, \ - (p5_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p5_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p5_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p5_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - } - - - -#define THGM_MAKE_TEST6_void(id, param1, param2, param3, param4, param5, param6) \ - struct TestClass##id; \ - typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - - -#define THGM_MAKE_TEST6(id, ret_type, param1, param2, param3, param4, param5, param6) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState6<0, param1, param2, param3, param4, param5, param6 > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - -#define THGM_MAKE_TEST6_vafmt_void(id, param1, param2, param3, param4, param5, param6) \ - struct TestClass##id; \ - typedef ParamState7<0, param1, param2, param3, param4, param5, param6, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6, std::string(buf)))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST6_vafmt(id, ret_type, param1, param2, param3, param4, param5, param6) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState7<0, param1, param2, param3, param4, param5, param6, std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6, std::string(buf)))); \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(p1, p2, p3, p4, p5, p6, buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - Increment::type>::Incr(p1);Increment::type>::Incr(p2);Increment::type>::Incr(p3);Increment::type>::Incr(p4);Increment::type>::Incr(p5);Increment::type>::Incr(p6); \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6, "%s!", buf)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_SETUP_PI6(id, p1_type, p1_passtype, p1_flags, p2_type, p2_passtype, p2_flags, p3_type, p3_passtype, p3_flags, p4_type, p4_passtype, p4_flags, p5_type, p5_passtype, p5_flags, p6_type, p6_passtype, p6_flags) \ - void setuppi_##id() \ - { \ - \ - protoinfo_##id.AddParam(sizeof(p1_type), p1_passtype, p1_flags, \ - (p1_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p1_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p2_type), p2_passtype, p2_flags, \ - (p2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p3_type), p3_passtype, p3_flags, \ - (p3_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p3_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p4_type), p4_passtype, p4_flags, \ - (p4_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p4_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p5_type), p5_passtype, p5_flags, \ - (p5_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p5_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p5_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p5_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - protoinfo_##id.AddParam(sizeof(p6_type), p6_passtype, p6_flags, \ - (p6_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p6_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p6_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p6_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - \ - } - - - -#define THGM_SETUP_RI(id, ret_type, ret_passtype, ret_flags) \ - void setupri_##id() \ - { \ - protoinfo_##id.SetReturnType(sizeof(ret_type), ret_passtype, ret_flags, \ - (ret_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (ret_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (ret_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (ret_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - } - -#define THGM_ADD_HOOK(id, num) \ - CAT4(hook, num, _, id) = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pTest##id), \ - 0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate(num)), num >= 3); - -#define THGM_REMOVE_HOOK(id, num) \ - g_SHPtr->RemoveHookByID(CAT4(hook, num, _, id)); - -#define THGM_CALLS_void(id, call_params) \ - pTest##id->Func call_params; \ - SH_CALL(pTest##id, &TestClass##id::Func) call_params; - -#define THGM_DO_TEST_void(id, call_params) \ - setuppi_##id(); \ - SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \ - CAutoReleaseHookMan arhm_##id(myhookman##id); \ - int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ - \ - TestClass##id::ms_DoRecall = false; \ - TestClass##id *pTest##id = new TestClass##id; \ - CAutoPtrDestruction apd##id(pTest##id); \ - \ - /* no hooks - no hooks */ \ - PtrBuf_Clear(); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part1"); \ - \ - /* hook1 - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part4"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 3); \ - \ - /* hook1, hook2 - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 2); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part5"); \ - /* hook1, hook2 - hook3, hook4 */ \ - THGM_ADD_HOOK(id, 4); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ - new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part6"); \ - \ - /* hook1 - hook3, hook4, with recalls! */ \ - \ - TestClass##id::ms_DoRecall = true; \ - THGM_REMOVE_HOOK(id, 2); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \ - new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \ - new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \ - /* sh_call one */ \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part7"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 3); \ - THGM_REMOVE_HOOK(id, 4); - -template -T ComparableRef(T x) -{ - return x; -} - -template -T* ComparableRef(T& x) -{ - return &x; -} - -#define THGM_CALLS(id, call_params, exp_ret_norm, exp_ret_shcall, err) \ - CHECK_COND(ComparableRef(pTest##id->Func call_params) == ComparableRef(MakeRet< RetType##id >::Do(exp_ret_norm)), err " /retcallnorm"); \ - CHECK_COND(ComparableRef(SH_CALL(pTest##id, &TestClass##id::Func) call_params) == ComparableRef(MakeRet< RetType##id >::Do(exp_ret_shcall)), err " /retcallshcall"); - -#define THGM_DO_TEST(id, call_params) \ - setuppi_##id(); \ - setupri_##id(); \ - SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \ - CAutoReleaseHookMan arhm_##id(myhookman##id); \ - int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ - \ - TestClass##id::ms_DoRecall = false; \ - TestClass##id *pTest##id = new TestClass##id; \ - CAutoPtrDestruction apd##id(pTest##id); \ - \ - /* no hooks - no hooks */ \ - PtrBuf_Clear(); \ - THGM_CALLS(id, call_params, 0, 0, "Part1"); \ - CHECK_STATES((&g_States, \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part1"); \ - \ - /* hook1 - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS(id, call_params, 0, 0, "Part4"); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part4"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 3); \ - \ - /* hook1, hook2 - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 2); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS(id, call_params, 2, 0, "Part5"); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part5"); \ - /* hook1, hook2 - hook3, hook4 */ \ - THGM_ADD_HOOK(id, 4); \ - THGM_CALLS(id, call_params, 4, 0, "Part6"); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ - new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part6"); \ - \ - /* hook1 - hook3, hook4, with recalls! */ \ - \ - TestClass##id::ms_DoRecall = true; \ - THGM_REMOVE_HOOK(id, 2); \ - THGM_CALLS(id, call_params, 4, 0, "Part7"); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \ - new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \ - new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \ - /* sh_call one */ \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part7"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 3); \ - THGM_REMOVE_HOOK(id, 4); diff --git a/sourcehook/test/testhookmangen.hxx b/sourcehook/test/testhookmangen.hxx deleted file mode 100644 index 8833eee..0000000 --- a/sourcehook/test/testhookmangen.hxx +++ /dev/null @@ -1,584 +0,0 @@ -struct CAutoReleaseHookMan -{ - SourceHook::HookManagerPubFunc m_Ptr; - CAutoReleaseHookMan(SourceHook::HookManagerPubFunc ptr) : m_Ptr(ptr) - { - } - ~CAutoReleaseHookMan() - { - g_HMAGPtr->ReleaseHookMan(m_Ptr); - } -}; - -// Strip & -template struct StripRef -{ - typedef T type; -}; - -template struct StripRef -{ - typedef T type; -}; - -// Address of constructor/destructor -// (using wrappers) -template -class Ctor_Thunk -{ -public: - void NormalConstructor() - { - new(this) T; - } - - void CopyConstructor(const T &other) - { - new(this) T(other); - } - - void Destructor() - { - reinterpret_cast(this)->~T(); - } - - const T& AssignOp(const T &other) - { - return (*reinterpret_cast(this) = other); - } -}; - - -template -void *FindFuncAddr(T mfp) -{ - union - { - T a; - void *b; - } u; - u.a = mfp; - return u.b; -} - -// Reference carrier -template struct MyRefCarrier -{ - typedef T type; -}; - -template struct MyRefCarrier -{ - class type - { - T *m_StoredRef; - public: - type() : m_StoredRef(NULL) - { - } - type(T& ref) : m_StoredRef(&ref) - { - } - - T& operator= (T& ref) - { - m_StoredRef = &ref; - return ref; - } - - operator T& () const - { - return *m_StoredRef; - } - - bool operator== (const typename MyRefCarrier::type &other) - { - return m_StoredRef == other.m_StoredRef; - } - - friend std::ostream& operator <<(std::ostream &os,const typename MyRefCarrier::type &obj) - { - os << *obj.m_StoredRef; - return os; - } - }; -}; - -#if SH_COMP==SH_COMP_GCC -#define NO_OPTIMIZE __attribute__((noinline)) -#else -#define NO_OPTIMIZE -#endif - -// Return value maker -template -struct MakeRet -{ - static T Do(int a) - { - return a; - } -}; - -template -struct MakeRet< POD > -{ - static POD Do(int a) - { - POD x; - memset(reinterpret_cast(x.x), a, SIZE); - return x; - } -}; - -// Stores parameter status -template -bool EqualToMyFmtString(T sth) -{ - return false; -} - -bool EqualToMyFmtString(std::string &sth) -{ - if (sth == "Hello %s%d%s") - sth = "Hello BA1L!"; - return true; -} - - -@[$1,0,$a: - -template -struct ParamState$1 -{ - @[$2,1,$1:typename MyRefCarrier::type m_$2; @] - - bool operator==(const ParamState$1 &other) - { - return true - @[$2,1,$1: && m_$1 == other.m_$1@] - ; - } - ParamState$1(@[$2,1,$1:p$2 a$2, @]...) @[$1!=0::@] @[$2,1,$1|, :m_$2(a$2)@] - { - @[$2,1,$1: - EqualToMyFmtString(m_$2); - @] - } - - ParamState$1 & operator() (int incrsteps) - { - @[$1!=0:int i;@] - @[$2,1,$1: - for (i = 0; i < incrsteps; ++i) - Increment::type >::Incr(m_$2); - @] - - return *this; - } -}; - -@[$1!=0:template<@[$2,1,$1|, :class p$2@]>@] -std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@]> &obj) -{ - @[$1!=0:os@] @[$2,1,$1:<< obj.m_$2@]; - return os; -} - -@] - -#define CAT2(a, b) a##b -#define CAT3(a, b, c) a##b##c -#define CAT4(a, b, c, d) a##b##c##d - -// hook1: pre ignore -// hook2: pre supercede -// hook3: post ignore -// hook4: post supercede - - -@[$1,0,$a: - -#define THGM_MAKE_TEST$1_void(id@[$2,1,$1:, param$2@]) \ - struct TestClass##id; \ - typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - - -#define THGM_MAKE_TEST$1(id, ret_type@[$2,1,$1:, param$2@]) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall); - -#define THGM_MAKE_TEST$1_vafmt_void(id@[$2,1,$1:, param$2@]) \ - struct TestClass##id; \ - typedef ParamState@($1+1)<0@[$2,1,$1:, param$2@], std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual void Func(@[$2,1,$1:param$2 p$2, @]const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1:p$2, @]std::string(buf)))); \ - g_Inside_LeafFunc = false; \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ - } \ - else \ - RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_MAKE_TEST$1_vafmt(id, ret_type@[$2,1,$1:, param$2@]) \ - struct TestClass##id; \ - typedef ret_type RetType##id; \ - typedef ParamState@($1+1)<0@[$2,1,$1:, param$2@], std::string > ParamState_m##id; \ - MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \ - MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \ - \ - struct TestClass##id \ - { \ - static bool ms_DoRecall; \ - \ - virtual ret_type Func(@[$2,1,$1:param$2 p$2, @]const char *fmt, ...) \ - { \ - g_Inside_LeafFunc = true; \ - \ - char buf[9999]; \ - va_list ap; \ - va_start(ap, fmt); \ - vsnprintf(buf, 9998, fmt, ap); \ - buf[9998] = 0; \ - va_end(ap); \ - \ - ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1:p$2, @]std::string(buf)))); \ - \ - return MakeRet< ret_type >::Do(0); \ - } \ - \ - struct Delegate : public MyDelegate \ - { \ - int m_DelegNumber; \ - Delegate(int num) : m_DelegNumber(num) { } \ - \ - virtual ret_type Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \ - { \ - g_Inside_LeafFunc = true; \ - ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \ - g_Inside_LeafFunc = false; \ - if (ms_DoRecall) \ - { \ - @[$2,1,$1:Increment::type>::Incr(p$2);@] \ - RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \ - } \ - else \ - RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \ - } \ - }; \ - }; \ - \ - bool TestClass##id::ms_DoRecall = false; \ - SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt); - -#define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \ - void setuppi_##id() \ - { \ - @[$2,1,$1: \ - protoinfo_##id.AddParam(sizeof(p$2_type), p$2_passtype, p$2_flags, \ - (p$2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (p$2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (p$2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (p$2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - @] \ - } - -@] - -#define THGM_SETUP_RI(id, ret_type, ret_passtype, ret_flags) \ - void setupri_##id() \ - { \ - protoinfo_##id.SetReturnType(sizeof(ret_type), ret_passtype, ret_flags, \ - (ret_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk::type>::NormalConstructor) : NULL, \ - (ret_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk::type>::CopyConstructor) : NULL, \ - (ret_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk::type>::Destructor) : NULL, \ - (ret_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk::type>::AssignOp) : NULL \ - ); \ - } - -#define THGM_ADD_HOOK(id, num) \ - CAT4(hook, num, _, id) = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast(pTest##id), \ - 0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate(num)), num >= 3); - -#define THGM_REMOVE_HOOK(id, num) \ - g_SHPtr->RemoveHookByID(CAT4(hook, num, _, id)); - -#define THGM_CALLS_void(id, call_params) \ - pTest##id->Func call_params; \ - SH_CALL(pTest##id, &TestClass##id::Func) call_params; - -#define THGM_DO_TEST_void(id, call_params) \ - setuppi_##id(); \ - SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \ - CAutoReleaseHookMan arhm_##id(myhookman##id); \ - int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ - \ - TestClass##id::ms_DoRecall = false; \ - TestClass##id *pTest##id = new TestClass##id; \ - CAutoPtrDestruction apd##id(pTest##id); \ - \ - /* no hooks - no hooks */ \ - PtrBuf_Clear(); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part1"); \ - \ - /* hook1 - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part4"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 3); \ - \ - /* hook1, hook2 - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 2); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part5"); \ - /* hook1, hook2 - hook3, hook4 */ \ - THGM_ADD_HOOK(id, 4); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ - new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part6"); \ - \ - /* hook1 - hook3, hook4, with recalls! */ \ - \ - TestClass##id::ms_DoRecall = true; \ - THGM_REMOVE_HOOK(id, 2); \ - THGM_CALLS_void(id, call_params); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \ - new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \ - new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \ - /* sh_call one */ \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part7"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 3); \ - THGM_REMOVE_HOOK(id, 4); - -template -T ComparableRef(T x) -{ - return x; -} - -template -T* ComparableRef(T& x) -{ - return &x; -} - -#define THGM_CALLS(id, call_params, exp_ret_norm, exp_ret_shcall, err) \ - CHECK_COND(ComparableRef(pTest##id->Func call_params) == ComparableRef(MakeRet< RetType##id >::Do(exp_ret_norm)), err " /retcallnorm"); \ - CHECK_COND(ComparableRef(SH_CALL(pTest##id, &TestClass##id::Func) call_params) == ComparableRef(MakeRet< RetType##id >::Do(exp_ret_shcall)), err " /retcallshcall"); - -#define THGM_DO_TEST(id, call_params) \ - setuppi_##id(); \ - setupri_##id(); \ - SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \ - CAutoReleaseHookMan arhm_##id(myhookman##id); \ - int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \ - \ - TestClass##id::ms_DoRecall = false; \ - TestClass##id *pTest##id = new TestClass##id; \ - CAutoPtrDestruction apd##id(pTest##id); \ - \ - /* no hooks - no hooks */ \ - PtrBuf_Clear(); \ - THGM_CALLS(id, call_params, 0, 0, "Part1"); \ - CHECK_STATES((&g_States, \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part1"); \ - \ - /* hook1 - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS(id, call_params, 0, 0, "Part4"); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part4"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 3); \ - \ - /* hook1, hook2 - hook3 */ \ - PtrBuf_Clear(); \ - THGM_ADD_HOOK(id, 1); \ - THGM_ADD_HOOK(id, 2); \ - THGM_ADD_HOOK(id, 3); \ - THGM_CALLS(id, call_params, 2, 0, "Part5"); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part5"); \ - /* hook1, hook2 - hook3, hook4 */ \ - THGM_ADD_HOOK(id, 4); \ - THGM_CALLS(id, call_params, 4, 0, "Part6"); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \ - new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \ - new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part6"); \ - \ - /* hook1 - hook3, hook4, with recalls! */ \ - \ - TestClass##id::ms_DoRecall = true; \ - THGM_REMOVE_HOOK(id, 2); \ - THGM_CALLS(id, call_params, 4, 0, "Part7"); \ - CHECK_STATES((&g_States, \ - new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \ - new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \ - new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \ - new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \ - /* sh_call one */ \ - new State_Func##id(pTest##id, ParamState_m##id call_params), \ - NULL), "Test" #id " Part7"); \ - THGM_REMOVE_HOOK(id, 1); \ - THGM_REMOVE_HOOK(id, 3); \ - THGM_REMOVE_HOOK(id, 4); diff --git a/sourcehook/test/testlist.cpp b/sourcehook/test/testlist.cpp deleted file mode 100644 index bbaa4d3..0000000 --- a/sourcehook/test/testlist.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include "sh_list.h" -#include "sh_stack.h" -#include "sh_tinyhash.h" -#include "sh_vector.h" -#include "testevents.h" - -// TEST LIST -// Tests sh_list, sh_tinyhash, sh_vector - -// :TODO: vector test, list insert test - -namespace -{ - struct Hmm - { - Hmm *m_This; - int m_Int; - Hmm(const Hmm &other) : m_Int(other.m_Int) - { - m_This = this; - } - Hmm(int i) : m_Int(i) - { - m_This = this; - } - Hmm() : m_Int(0) - { - m_This = this; - } - void operator = (const Hmm &other) - { - m_Int = other.m_Int; - } - operator int () const - { - return m_Int; - } - }; - - #define LIST_THIS_CHECK(lst, err) \ - for (ListType::iterator iter = lst.begin(); iter != lst.end(); ++iter) \ - CHECK_COND(&(*iter) == iter->m_This, err); - - bool DoTestList(std::string &error) - { - typedef SourceHook::List ListType; - ListType lst; - - CHECK_COND(lst.empty(), "Part1"); - - for (int i = 1; i <= 100; ++i) - lst.push_back(i); - - LIST_THIS_CHECK(lst, "PartA1"); - - CHECK_COND(!lst.empty(), "Part2"); - - lst.clear(); - - CHECK_COND(lst.empty(), "Part3"); - - for (int i = 1; i <= 100; ++i) - lst.push_back(i); - - CHECK_COND(lst.back() == 100, "Part4"); - LIST_THIS_CHECK(lst, "PartA2"); - - int ver = 1; - for (ListType::iterator iter = lst.begin(); iter != lst.end(); ++iter) - CHECK_COND(*iter == ver++, "Part5"); - - CHECK_COND(ver == 101, "Part 6"); - - ListType::iterator iter50 = lst.find(50); - CHECK_COND(*iter50 == 50, "Part7"); - - iter50 = lst.erase(iter50); - CHECK_COND(*iter50 == 51, "Part8"); - CHECK_COND(*--iter50 == 49, "Part8.2"); - - lst.remove(80); - - ver = 1; - for (ListType::iterator iter = lst.begin(); iter != lst.end(); ++iter) - { - CHECK_COND(*iter == ver++, "Part9"); - if (ver == 50 || ver == 80) - ++ver; - } - CHECK_COND(ver == 101, "Part10"); - LIST_THIS_CHECK(lst, "PartA3"); - - ListType lst2; - lst = lst2; - CHECK_COND(lst.empty(), "Part11"); - - for (int i = 1; i <= 100; ++i) - lst.push_back(i); - lst2 = lst; - CHECK_COND(lst2.size() == 100, "Part11.2"); - - LIST_THIS_CHECK(lst, "PartA4"); - LIST_THIS_CHECK(lst2, "PartA5"); - - ver = 1; - for (ListType::iterator iter = lst2.begin(); iter != lst2.end(); ++iter) - CHECK_COND(*iter == ver++, "Part12"); - - lst.clear(); - for (int i = 401; i <= 500; ++i) - lst.push_back(i); - lst = lst2; - CHECK_COND(lst2.size() == 100, "Part13"); - - ver = 1; - for (ListType::iterator iter = lst.begin(); iter != lst.end(); ++iter) - CHECK_COND(*iter == ver++, "Part14"); - - LIST_THIS_CHECK(lst, "PartA6"); - LIST_THIS_CHECK(lst2, "PartA7"); - - return true; - } - - bool DoTestTinyHash(std::string &error) - { - const int mymax = 5000; - - typedef SourceHook::THash HashType; - HashType hash; - - for (int i = 1; i <= mymax; ++i) - hash[i] = i + 5000; - - for (int i = 1; i <= mymax; ++i) - CHECK_COND(hash[i] == i + 5000, "Part1"); - - // Find - int ver = 1; - HashType::iterator iter; - for (iter = hash.begin(); iter != hash.end(); ++iter) - CHECK_COND(iter->key == ver && iter->val == (ver++) + 5000, "Part2"); - - CHECK_COND(ver == mymax+1, "Part2.1"); - - iter = hash.find(300); - CHECK_COND(iter != hash.end() && iter->val == 300+5000, "Part3.1"); - iter = hash.find(mymax+200); - CHECK_COND(iter == hash.end(), "Part3.2"); - - HashType hash2; - for (int i = 1; i <= mymax; ++i) - hash2[i] = i + 5000; - - hash2.erase(mymax - 100); - CHECK_COND(hash2.find(mymax - 101) != hash2.end(), "Part 4.1"); - CHECK_COND(hash2.find(mymax - 99) != hash2.end(), "Part 4.2"); - CHECK_COND(hash2.find(mymax - 100) == hash2.end(), "Part 4.3"); - hash2.erase(mymax - 99); - CHECK_COND(hash2.find(mymax - 101) != hash2.end(), "Part 4.4"); - CHECK_COND(hash2.find(mymax - 99) == hash2.end(), "Part 4.5"); - CHECK_COND(hash2.find(mymax - 100) == hash2.end(), "Part 4.6"); - - return true; - } - - bool DoTestStack(std::string &error) - { - typedef SourceHook::CStack IntStack; - IntStack stk; - int i; - - CHECK_COND(stk.size() == 0 && stk.empty(), "A0"); - - for (i = 0; i < 5000; ++i) - stk.push(i); - - CHECK_COND(stk.front() == 4999, "1"); - CHECK_COND(stk.size() == 5000 && !stk.empty(), "A1"); - - IntStack::iterator iter; - i = 0; - for (iter = stk.begin(); iter != stk.end(); ++iter, ++i) - CHECK_COND(*iter == i, "2"); - - i = 0; - for (iter = stk.begin(); iter != stk.end(); iter++, ++i) - CHECK_COND(*iter == i, "3"); - - --iter; - iter--; - *iter = 'g'+'a'+'b'+'e'+'n'; - stk.pop(); - - CHECK_COND(stk.size() == 4999 && !stk.empty(), "A2"); - CHECK_COND(stk.front() == 'g'+'a'+'b'+'e'+'n', "4"); - - IntStack stk2(stk); - CHECK_COND(stk2.size() == 4999 && !stk2.empty(), "A3"); - - IntStack::iterator iter2 = stk2.begin(); - for (iter = stk.begin(); iter != stk.end(); ++iter, iter2++) - CHECK_COND(*iter == *iter2, "5"); - - while (!stk2.empty()) - stk2.pop(); - CHECK_COND(stk2.size() == 0 && stk2.empty(), "A4"); - stk = stk2; - CHECK_COND(stk.size() == 0 && stk.empty(), "A5"); - - return true; - } - - bool DoTestVec(std::string &error) - { - typedef SourceHook::CVector IntVector; - IntVector vec1; - IntVector::iterator iter; - int i; - - CHECK_COND(vec1.size() == 0 && vec1.empty(), "V1"); - for (i = 0; i < 500; ++i) - vec1.push_back(i); - - CHECK_COND(vec1.size() == 500 && !vec1.empty(), "V2"); - - for (i = 0; i < 500; ++i) - CHECK_COND(vec1[i] == i, "V3"); - - for (i = 0, iter = vec1.begin(); iter != vec1.end(); ++iter, ++i) - CHECK_COND(*iter == i, "V4"); - - vec1.resize(1000); - for (i = 0; i < 500; ++i) - CHECK_COND(vec1[i] == i, "V5.1"); - for (i = 500; i < 1000; ++i) - CHECK_COND(vec1[i] == 0, "V5.2"); - - vec1.resize(200); - for (i = 0; i < 200; ++i) - CHECK_COND(vec1[i] == i, "V6"); - - vec1.resize(500, 0x12345678); - for (i = 0; i < 200; ++i) - CHECK_COND(vec1[i] == i, "V7.1"); - for (i = 200; i < 500; ++i) - CHECK_COND(vec1[i] == 0x12345678, "V7.2"); - - IntVector vec2(vec1); - CHECK_COND(vec2.size() == vec1.size() && vec2.empty() == vec1.empty(), "V8.0"); - for (i = 0; i < 200; ++i) - CHECK_COND(vec2[i] == i, "V8.1"); - for (i = 200; i < 500; ++i) - CHECK_COND(vec2[i] == 0x12345678, "V8.2"); - - - vec1.clear(); - CHECK_COND(vec1.size() == 0 && vec1.empty() && vec1.begin() == vec1.end(), "V9"); - vec2 = vec1; - CHECK_COND(vec2.size() == 0 && vec2.empty() && vec2.begin() == vec2.end(), "V9"); - - return true; - } -} - -bool TestList(std::string &error) -{ - if (!DoTestList(error)) - return false; - - if (!DoTestTinyHash(error)) - return false; - - if (!DoTestStack(error)) - return false; - - if (!DoTestVec(error)) - return false; - - return true; -} diff --git a/sourcehook/test/testmanual.cpp b/sourcehook/test/testmanual.cpp deleted file mode 100644 index aee0332..0000000 --- a/sourcehook/test/testmanual.cpp +++ /dev/null @@ -1,364 +0,0 @@ -#include -#include "sourcehook.h" -#include "sourcehook_test.h" -#include "testevents.h" - -// TESTMANUAL -// Test manual hooks -// :TODO: test more extensively - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - MAKE_STATE_1(State_Func1_Called, void*); // param1: This pointer - MAKE_STATE_2(State_Func2_Called, void*, int); // param1: This pointer; param2: parameter - MAKE_STATE_1(State_Func3_Called, void*); // param1: This pointer - MAKE_STATE_2(State_Func4_Called, void*, int); // param1: This pointer; param2: parameter - MAKE_STATE_1(State_Func5_Called, void*); // param1: This pointer - - MAKE_STATE_1(State_Func1H_Called, void*); - MAKE_STATE_2(State_Func2H_Called, void*, int); - MAKE_STATE_1(State_Func3H_Called, void*); - MAKE_STATE_2(State_Func4H_Called, void*, int); - - MAKE_STATE_1(State_Return, short); - - class TheWall - { - public: - virtual void Func1() - { - ADD_STATE(State_Func1_Called(reinterpret_cast(this))); - } - virtual void Func2(int x) - { - ADD_STATE(State_Func2_Called(reinterpret_cast(this), x)); - } - - virtual short Func3() - { - ADD_STATE(State_Func3_Called(reinterpret_cast(this))); - return 3; - } - virtual short Func4(int x) - { - ADD_STATE(State_Func4_Called(reinterpret_cast(this), x)); - return 4; - } - virtual void Func5() - { - ADD_STATE(State_Func5_Called(reinterpret_cast(this))); - } - }; - - SH_DECL_HOOK0_void(TheWall, Func1, SH_NOATTRIB, 0); - SH_DECL_HOOK1_void(TheWall, Func2, SH_NOATTRIB, 0, int); - SH_DECL_HOOK0(TheWall, Func3, SH_NOATTRIB, 0, short); - SH_DECL_HOOK1(TheWall, Func4, SH_NOATTRIB, 0, short, int); - - SH_DECL_MANUALHOOK0_void(TheWall_Func1, 0, 0, 0); - SH_DECL_MANUALHOOK1_void(TheWall_Func2, 1, 0, 0, int); - SH_DECL_MANUALHOOK0(TheWall_Func3, 2, 0, 0, short); - SH_DECL_MANUALHOOK1(TheWall_Func4, 3, 0, 0, short, int); - - SH_DECL_MANUALEXTERN0_void(TheWall_Func1); - SH_DECL_MANUALEXTERN1(TheWall_Func1, short, int); - - typedef void (SourceHook::EmptyClass::*MFP_Func1)(); - typedef void (SourceHook::EmptyClass::*MFP_Func2)(int); - typedef short (SourceHook::EmptyClass::*MFP_Func3)(); - typedef short (SourceHook::EmptyClass::*MFP_Func4)(int); - - void Handler_Func1() - { - ADD_STATE(State_Func1H_Called(META_IFACEPTR(void))); - } - void Handler_Func2(int x) - { - ADD_STATE(State_Func2H_Called(META_IFACEPTR(void), x)); - RETURN_META_MNEWPARAMS(MRES_IGNORED, TheWall_Func2, (0x87654321)); - } - short Handler_Func3() - { - ADD_STATE(State_Func3H_Called(META_IFACEPTR(void))); - return 0; - } - short Handler_Func4(int x) - { - ADD_STATE(State_Func4H_Called(META_IFACEPTR(void), x)); - - // newparams (recall) using the manual hook declaration! - RETURN_META_VALUE_MNEWPARAMS(MRES_IGNORED, 0, TheWall_Func4, (0x12345678)); - } - - struct AnotherBrick - { - void Handler_Func1() - { - ADD_STATE(State_Func1H_Called(META_IFACEPTR(void))); - RETURN_META(MRES_SUPERCEDE); - } - }; - - TheWall *MyInstanceFactory() - { - return new TheWall; - } -} - -bool TestManual(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1337; - - TheWall *p = MyInstanceFactory(); - CAutoPtrDestruction apd(p); - - SourceHook::ManualCallClass *cc = SH_GET_MCALLCLASS(p, sizeof(void*)); - - // 1) - // Call each function - p->Func1(); - p->Func2(200); - ADD_STATE(State_Return(p->Func3())); - ADD_STATE(State_Return(p->Func4(400))); - - CHECK_STATES((&g_States, - new State_Func1_Called(p), - new State_Func2_Called(p, 200), - new State_Func3_Called(p), - new State_Return(3), - new State_Func4_Called(p, 400), - new State_Return(4), - NULL), "Part 1"); - - // 1.1) - // Now call each function through the manual call class, using the hook decl and manually - SH_MCALL(cc, TheWall_Func1)(); - SH_MCALL2(cc, MFP_Func1(), 0, 0, 0)(); - SH_MCALL(cc, TheWall_Func2)(200); - SH_MCALL2(cc, MFP_Func2(), 1, 0, 0)(200); - ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func3)())); - ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func3(), 2, 0, 0)())); - ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func4)(400))); - ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func4(), 3, 0, 0)(400))); - - CHECK_STATES((&g_States, - new State_Func1_Called(p), - new State_Func1_Called(p), - new State_Func2_Called(p, 200), - new State_Func2_Called(p, 200), - new State_Func3_Called(p), - new State_Return(3), - new State_Func3_Called(p), - new State_Return(3), - new State_Func4_Called(p, 400), - new State_Return(4), - new State_Func4_Called(p, 400), - new State_Return(4), - NULL), "Part 1.1"); - - // 2) - // Hook each function normally, call them - SH_ADD_HOOK(TheWall, Func1, p, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(TheWall, Func2, p, SH_STATIC(Handler_Func2), false); - SH_ADD_HOOK(TheWall, Func3, p, SH_STATIC(Handler_Func3), false); - SH_ADD_HOOK(TheWall, Func4, p, SH_STATIC(Handler_Func4), false); - - p->Func1(); - p->Func2(200); - ADD_STATE(State_Return(p->Func3())); - ADD_STATE(State_Return(p->Func4(400))); - - CHECK_STATES((&g_States, - new State_Func1H_Called(p), - new State_Func1_Called(p), - new State_Func2H_Called(p, 200), - new State_Func2_Called(p, 0x87654321), - new State_Func3H_Called(p), - new State_Func3_Called(p), - new State_Return(3), - new State_Func4H_Called(p, 400), - new State_Func4_Called(p, 0x12345678), - new State_Return(4), - NULL), "Part 2"); - - // Call them through the mcallclass - // 2.1) - // Now call each function through the manual call class, using the hook decl and manually - SH_MCALL(cc, TheWall_Func1)(); - SH_MCALL2(cc, MFP_Func1(), 0, 0, 0)(); - SH_MCALL(cc, TheWall_Func2)(200); - SH_MCALL2(cc, MFP_Func2(), 1, 0, 0)(200); - ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func3)())); - ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func3(), 2, 0, 0)())); - ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func4)(400))); - ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func4(), 3, 0, 0)(400))); - - CHECK_STATES((&g_States, - new State_Func1_Called(p), - new State_Func1_Called(p), - new State_Func2_Called(p, 200), - new State_Func2_Called(p, 200), - new State_Func3_Called(p), - new State_Return(3), - new State_Func3_Called(p), - new State_Return(3), - new State_Func4_Called(p, 400), - new State_Return(4), - new State_Func4_Called(p, 400), - new State_Return(4), - NULL), "Part 2.1"); - - // Unhook them - SH_REMOVE_HOOK(TheWall, Func1, p, SH_STATIC(Handler_Func1), false); - SH_REMOVE_HOOK(TheWall, Func2, p, SH_STATIC(Handler_Func2), false); - SH_REMOVE_HOOK(TheWall, Func3, p, SH_STATIC(Handler_Func3), false); - SH_REMOVE_HOOK(TheWall, Func4, p, SH_STATIC(Handler_Func4), false); - - // 3) - // Hook each function manually, call them - - SH_ADD_MANUALHOOK(TheWall_Func1, p, SH_STATIC(Handler_Func1), false); - SH_ADD_MANUALHOOK(TheWall_Func2, p, SH_STATIC(Handler_Func2), false); - SH_ADD_MANUALHOOK(TheWall_Func3, p, SH_STATIC(Handler_Func3), false); - SH_ADD_MANUALHOOK(TheWall_Func4, p, SH_STATIC(Handler_Func4), false); - - p->Func1(); - p->Func2(200); - ADD_STATE(State_Return(p->Func3())); - ADD_STATE(State_Return(p->Func4(400))); - - CHECK_STATES((&g_States, - new State_Func1H_Called(p), - new State_Func1_Called(p), - new State_Func2H_Called(p, 200), - new State_Func2_Called(p, 0x87654321), - new State_Func3H_Called(p), - new State_Func3_Called(p), - new State_Return(3), - new State_Func4H_Called(p, 400), - new State_Func4_Called(p, 0x12345678), - new State_Return(4), - NULL), "Part 3"); - - // Now through the mcallclass - - // Call them through the mcallclass - // 3.1) - // Now call each function through the manual call class, using the hook decl and manually - SH_MCALL(cc, TheWall_Func1)(); - SH_MCALL2(cc, MFP_Func1(), 0, 0, 0)(); - SH_MCALL(cc, TheWall_Func2)(200); - SH_MCALL2(cc, MFP_Func2(), 1, 0, 0)(200); - ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func3)())); - ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func3(), 2, 0, 0)())); - ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func4)(400))); - ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func4(), 3, 0, 0)(400))); - - CHECK_STATES((&g_States, - new State_Func1_Called(p), - new State_Func1_Called(p), - new State_Func2_Called(p, 200), - new State_Func2_Called(p, 200), - new State_Func3_Called(p), - new State_Return(3), - new State_Func3_Called(p), - new State_Return(3), - new State_Func4_Called(p, 400), - new State_Return(4), - new State_Func4_Called(p, 400), - new State_Return(4), - NULL), "Part 3.1"); - - // Unhook them - SH_REMOVE_MANUALHOOK(TheWall_Func1, p, SH_STATIC(Handler_Func1), false); - SH_REMOVE_MANUALHOOK(TheWall_Func2, p, SH_STATIC(Handler_Func2), false); - SH_REMOVE_MANUALHOOK(TheWall_Func3, p, SH_STATIC(Handler_Func3), false); - SH_REMOVE_MANUALHOOK(TheWall_Func4, p, SH_STATIC(Handler_Func4), false); - - // 4) - // Hook each function manually, then normally, call, unhook - - AnotherBrick handler_inst; - - // Why this? - // 1) tests sh_add_manualhook - // 2) in my tests, the proto of the manual hook was not equal to the proto of the auto hook - // (because there are no attribs for manual hooks). - // sourcehook.cpp did a !strcmp(..), so it assigned a new hook manager even though there - // already was one for this vfnptr. This hook manager stored the pointer of the original - // hook manager's hookfunc as the orig pointer - everything seemingly worked. - // The problem with this is that returning MRES_SUPERCEDE (as AnotherBrick::Handler_Func1 - // does) will supercede the second hook func from being called - thus bypassing the call - // of the auto hook here. - SH_ADD_MANUALHOOK(TheWall_Func1, p, SH_MEMBER(&handler_inst, &AnotherBrick::Handler_Func1), false); - SH_ADD_MANUALHOOK(TheWall_Func2, p, SH_STATIC(Handler_Func2), false); - SH_ADD_MANUALHOOK(TheWall_Func3, p, SH_STATIC(Handler_Func3), false); - SH_ADD_MANUALHOOK(TheWall_Func4, p, SH_STATIC(Handler_Func4), false); - - SH_ADD_HOOK(TheWall, Func1, p, SH_STATIC(Handler_Func1), false); - SH_ADD_HOOK(TheWall, Func2, p, SH_STATIC(Handler_Func2), false); - SH_ADD_HOOK(TheWall, Func3, p, SH_STATIC(Handler_Func3), false); - SH_ADD_HOOK(TheWall, Func4, p, SH_STATIC(Handler_Func4), false); - - p->Func1(); - p->Func2(200); - ADD_STATE(State_Return(p->Func3())); - ADD_STATE(State_Return(p->Func4(400))); - - CHECK_STATES((&g_States, - new State_Func1H_Called(p), - new State_Func1H_Called(p), - //new State_Func1_Called(p), - new State_Func2H_Called(p, 200), - new State_Func2H_Called(p, 0x87654321), - new State_Func2_Called(p, 0x87654321), - new State_Func3H_Called(p), - new State_Func3H_Called(p), - new State_Func3_Called(p), - new State_Return(3), - new State_Func4H_Called(p, 400), - new State_Func4H_Called(p, 0x12345678), - new State_Func4_Called(p, 0x12345678), - new State_Return(4), - NULL), "Part 4"); - - SH_REMOVE_MANUALHOOK(TheWall_Func1, p, SH_MEMBER(&handler_inst, &AnotherBrick::Handler_Func1), false); - SH_REMOVE_MANUALHOOK(TheWall_Func2, p, SH_STATIC(Handler_Func2), false); - SH_REMOVE_MANUALHOOK(TheWall_Func3, p, SH_STATIC(Handler_Func3), false); - SH_REMOVE_MANUALHOOK(TheWall_Func4, p, SH_STATIC(Handler_Func4), false); - - SH_REMOVE_HOOK(TheWall, Func1, p, SH_STATIC(Handler_Func1), false); - SH_REMOVE_HOOK(TheWall, Func2, p, SH_STATIC(Handler_Func2), false); - SH_REMOVE_HOOK(TheWall, Func3, p, SH_STATIC(Handler_Func3), false); - SH_REMOVE_HOOK(TheWall, Func4, p, SH_STATIC(Handler_Func4), false); - - // 5) Reconfigure TheWall_Func1 to actually hook Func5: - SH_MANUALHOOK_RECONFIGURE(TheWall_Func1, 4, 0, 0); - SH_MANUALHOOK_RECONFIGURE(TheWall_Func1, 4, 0, 0); - SH_ADD_MANUALHOOK(TheWall_Func1, p, SH_STATIC(Handler_Func1), false); - - p->Func5(); - - CHECK_STATES((&g_States, - new State_Func1H_Called(p), - new State_Func5_Called(p), - NULL), "Part 5"); - - // 6) Test auto-remove on reconfig - SH_MANUALHOOK_RECONFIGURE(TheWall_Func1, 0, 0, 0); - - p->Func1(); - p->Func5(); - - CHECK_STATES((&g_States, - new State_Func1_Called(p), - new State_Func5_Called(p), - NULL), "Part 6"); - - return true; -} diff --git a/sourcehook/test/testmulti.cpp b/sourcehook/test/testmulti.cpp deleted file mode 100644 index af5555c..0000000 --- a/sourcehook/test/testmulti.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include "sourcehook.h" -#include "sourcehook_test.h" -#include "testevents.h" - -// This should probably be done the other way round! -#ifdef __linux__ -#define _snprintf snprintf -#endif - -namespace -{ - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - unsigned int g_callcount[10]; - - class VMultiTest - { - public: - VMultiTest(unsigned int index) : m_idx(index) - { - } - public: - virtual void HookTarget() - { - } - virtual void Notify() - { - g_callcount[this->m_idx]++; - } - private: - unsigned int m_idx; - }; - - void HookFunction() - { - VMultiTest *pv = META_IFACEPTR(VMultiTest); - pv->Notify(); - } - - SH_DECL_HOOK0_void(VMultiTest, HookTarget, SH_NOATTRIB, false); -}; - -bool TestMulti(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1337; - - VMultiTest **pv = new VMultiTest *[10]; - for (unsigned int i=0; i<10; i++) - pv[i] = new VMultiTest(i); - - - for (unsigned int i=0; i<10; i++) - SH_ADD_HOOK(VMultiTest, HookTarget, pv[i], SH_STATIC(HookFunction), false); - - pv[0]->HookTarget(); - - if (g_callcount[0] != 1) - { - error.assign("g_callcount[0] != 0"); - return false; - } - - for (unsigned int i=1; i<10; i++) - { - if (g_callcount[i]) - { - error.assign("g_callcount[n] != 0"); - return false; - } - } - - SH_REMOVE_HOOK(VMultiTest, HookTarget, pv[0], SH_STATIC(HookFunction), false); - - for (unsigned int i=1; i<10; i++) - pv[i]->HookTarget(); - - if (g_callcount[0] != 1) - { - error.assign("g_callcount[0] != 0"); - return false; - } - - for (unsigned int i=1; i<10; i++) - { - if (g_callcount[i] != 1) - { - char err[256]; - _snprintf(err, sizeof(err)-1, "g_callcount[%d] != 1", i); - error.assign(err); - return false; - } - } - - for (unsigned int i=1; i<10; i++) - { - SH_REMOVE_HOOK(VMultiTest, HookTarget, pv[1], SH_STATIC(HookFunction), false); - delete pv[i]; - } - - delete [] pv; - - return true; -} diff --git a/sourcehook/test/testrecall.cpp b/sourcehook/test/testrecall.cpp deleted file mode 100644 index 67ddc69..0000000 --- a/sourcehook/test/testrecall.cpp +++ /dev/null @@ -1,231 +0,0 @@ -#include -#include "sourcehook.h" -#include "sourcehook_test.h" -#include "testevents.h" - -// TESTRECALL -// Test modifying parameters from hook handlers - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - MAKE_STATE_1(State_Func1, int); - MAKE_STATE_1(State_H1_Func1, int); - MAKE_STATE_1(State_H2_Func1, int); - MAKE_STATE_2(State_HP_Func1, int, void*); - - MAKE_STATE_1(State_Func2, int); - MAKE_STATE_1(State_H1_Func2, int); - MAKE_STATE_1(State_H2_Func2, int); - MAKE_STATE_2(State_HP_Func2, int, int); - - MAKE_STATE_2(State_Func22, int, int); - MAKE_STATE_2(State_H1_Func22, int, int); - MAKE_STATE_2(State_HP1_Func22, int, int); - MAKE_STATE_2(State_HP2_Func22, int, int); - - struct Test - { - virtual void Func1(int a) - { - ADD_STATE(State_Func1(a)); - } - - virtual int Func2(int a) - { - ADD_STATE(State_Func2(a)); - return 1000; - } - - // Overloaded version - virtual int Func2(int a, int b) - { - ADD_STATE(State_Func22(a, b)); - return 0xDEADFC; - } - }; - - void Handler1_Func1(int a) - { - ADD_STATE(State_H1_Func1(a)); - RETURN_META_NEWPARAMS(MRES_IGNORED, &Test::Func1, (5)); - } - void Handler2_Func1(int a) - { - ADD_STATE(State_H2_Func1(a)); - RETURN_META_NEWPARAMS(MRES_IGNORED, &Test::Func1, (a - 5)); - } - void HandlerPost_Func1(int a) - { - ADD_STATE(State_HP_Func1(a, META_IFACEPTR(void))); - } - - - int Handler1_Func2(int a) - { - ADD_STATE(State_H1_Func2(a)); - // Pfeeehhh, ugly, I know, but I had to test it :) - RETURN_META_VALUE_NEWPARAMS(MRES_OVERRIDE, 500, - static_cast(&Test::Func2), (a - 10)); - } - - int Handler2_Func2(int a) - { - ADD_STATE(State_H2_Func2(a)); - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 0, - static_cast(&Test::Func2), (a - 10)); - } - - int HandlerPost_Func2(int a) - { - ADD_STATE(State_HP_Func2(a, META_RESULT_ORIG_RET(int))); - RETURN_META_VALUE(MRES_IGNORED, 0); - } - - int Handler1_Func22(int a, int b) - { - ADD_STATE(State_H1_Func22(a, b)); - RETURN_META_VALUE(MRES_IGNORED, 0); - } - - int HandlerPost1_Func22(int a, int b) - { - ADD_STATE(State_HP1_Func22(a, b)); - RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 0, static_cast(&Test::Func2), (1, 2)); - } - - int HandlerPost1A_Func22(int a, int b) - { - ADD_STATE(State_HP1_Func22(a, b)); - RETURN_META_VALUE_NEWPARAMS(MRES_OVERRIDE, 0, static_cast(&Test::Func2), (1, 2)); - } - - int HandlerPost2_Func22(int a, int b) - { - ADD_STATE(State_HP2_Func22(a, b)); - RETURN_META_VALUE(MRES_IGNORED, 0); - } - - SH_DECL_HOOK1_void(Test, Func1, SH_NOATTRIB, 0, int); - SH_DECL_HOOK1(Test, Func2, SH_NOATTRIB, 0, int, int); - SH_DECL_HOOK2(Test, Func2, SH_NOATTRIB, 1, int, int, int); - - Test *MyTestFactory() - { - return new Test; - } -} - -bool TestRecall(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1337; - - Test *ptr = MyTestFactory(); - CAutoPtrDestruction apd(ptr); - - SH_ADD_HOOK(Test, Func1, ptr, SH_STATIC(Handler1_Func1), false); - SH_ADD_HOOK(Test, Func1, ptr, SH_STATIC(Handler2_Func1), false); - SH_ADD_HOOK(Test, Func1, ptr, SH_STATIC(HandlerPost_Func1), true); - - ptr->Func1(77); - - CHECK_STATES((&g_States, - new State_H1_Func1(77), - new State_H2_Func1(5), - new State_Func1(0), - new State_HP_Func1(0, ptr), - NULL), "Part 1"); - - SH_REMOVE_HOOK(Test, Func1, ptr, SH_STATIC(Handler1_Func1), false); - SH_ADD_HOOK(Test, Func1, ptr, SH_STATIC(Handler2_Func1), false); - SH_ADD_HOOK(Test, Func1, ptr, SH_STATIC(Handler2_Func1), false); - SH_ADD_HOOK(Test, Func1, ptr, SH_STATIC(Handler2_Func1), false); - - ptr->Func1(77); - - CHECK_STATES((&g_States, - new State_H2_Func1(77), - new State_H2_Func1(72), - new State_H2_Func1(67), - new State_H2_Func1(62), - new State_Func1(57), - new State_HP_Func1(57, ptr), - NULL), "Part 2"); - - SH_REMOVE_HOOK(Test, Func1, ptr, SH_STATIC(Handler2_Func1), false); - SH_REMOVE_HOOK(Test, Func1, ptr, SH_STATIC(HandlerPost_Func1), true); - - ptr->Func1(77); - - CHECK_STATES((&g_States, - new State_Func1(77), - NULL), "Part 3"); - - // Func2 - - SH_ADD_HOOK(Test, Func2, ptr, SH_STATIC(Handler1_Func2), false); - SH_ADD_HOOK(Test, Func2, ptr, SH_STATIC(HandlerPost_Func2), true); - - int a = ptr->Func2(77); - CHECK_STATES((&g_States, - new State_H1_Func2(77), - new State_Func2(67), - new State_HP_Func2(67, 1000), // 1000 because it's the ORIG_RET - NULL), "Part 4"); - - CHECK_COND(a == 500, "Part 4.1"); - - // Func2, with other handler - SH_REMOVE_HOOK(Test, Func2, ptr, SH_STATIC(Handler1_Func2), false); - SH_ADD_HOOK(Test, Func2, ptr, SH_STATIC(Handler2_Func2), false); - - a = ptr->Func2(77); - CHECK_STATES((&g_States, - new State_H2_Func2(77), - new State_Func2(67), - new State_HP_Func2(67, 1000), // 1000 because it's the ORIG_RET - NULL), "Part 4.2"); - - CHECK_COND(a == 1000, "Part 4.2.1"); // Should return 1000 as well. - - // Func22 -> post recalls - - // 1) WITH OVERRIDE - - SH_ADD_HOOK(Test, Func2, ptr, SH_STATIC(Handler1_Func22), false); - SH_ADD_HOOK(Test, Func2, ptr, SH_STATIC(HandlerPost1A_Func22), true); - SH_ADD_HOOK(Test, Func2, ptr, SH_STATIC(HandlerPost2_Func22), true); - - a = ptr->Func2(10, 11); - CHECK_STATES((&g_States, - new State_H1_Func22(10, 11), - new State_Func22(10, 11), - new State_HP1_Func22(10, 11), - new State_HP2_Func22(1, 2), - NULL), "Part 5"); - - CHECK_COND(a == 0, "Part 5.1"); - - // 2) WITH IGNORE - SH_REMOVE_HOOK(Test, Func2, ptr, SH_STATIC(HandlerPost1A_Func22), true); - SH_REMOVE_HOOK(Test, Func2, ptr, SH_STATIC(HandlerPost2_Func22), true); - - SH_ADD_HOOK(Test, Func2, ptr, SH_STATIC(HandlerPost1_Func22), true); - SH_ADD_HOOK(Test, Func2, ptr, SH_STATIC(HandlerPost2_Func22), true); - - a = ptr->Func2(10, 11); - CHECK_STATES((&g_States, - new State_H1_Func22(10, 11), - new State_Func22(10, 11), - new State_HP1_Func22(10, 11), - new State_HP2_Func22(1, 2), - NULL), "Part 5"); - - CHECK_COND(a == 0xDEADFC, "Part 5.1"); - - return true; -} diff --git a/sourcehook/test/testreentr.cpp b/sourcehook/test/testreentr.cpp deleted file mode 100644 index f96f74a..0000000 --- a/sourcehook/test/testreentr.cpp +++ /dev/null @@ -1,599 +0,0 @@ -// Reentrancy test -// = calling hooks from hook handlers, etc - -#include -#include "sourcehook_test.h" -#include "testevents.h" - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - struct C1; - struct C2; - struct C3; - struct C4; - struct C5; - struct C6; - struct C7; - struct C8; - - C1 *g_pC1; - C2 *g_pC2; - C3 *g_pC3; - C4 *g_pC4; - C5 *g_pC5; - C6 *g_pC6; - C7 *g_pC7; - C8 *g_pC8; - - // param1: This pointer - MAKE_STATE_1(State_C1_F, C1*); - MAKE_STATE_1(State_C2_F, C2*); - MAKE_STATE_1(State_C3_F, C3*); - MAKE_STATE_1(State_C4_F, C4*); - MAKE_STATE_1(State_C5_F, C5*); - MAKE_STATE_1(State_C6_F, C6*); - MAKE_STATE_1(State_C7_F, C7*); - MAKE_STATE_1(State_C8_F, C8*); - - MAKE_STATE_1(State_C1_G, C1*); - MAKE_STATE_1(State_C2_G, C2*); - MAKE_STATE_1(State_C3_G, C3*); - MAKE_STATE_1(State_C4_G, C4*); - MAKE_STATE_1(State_C5_G, C5*); - MAKE_STATE_1(State_C6_G, C6*); - MAKE_STATE_1(State_C7_G, C7*); - MAKE_STATE_1(State_C8_G, C8*); - - MAKE_STATE_1(State_H_C1_F, C1*); - MAKE_STATE_1(State_H_C2_F, C2*); - MAKE_STATE_1(State_H_C3_F, C3*); - MAKE_STATE_1(State_H_C4_F, C4*); - MAKE_STATE_1(State_H_C5_F, C5*); - MAKE_STATE_1(State_H_C6_F, C6*); - MAKE_STATE_1(State_H_C7_F, C7*); - MAKE_STATE_1(State_H_C8_F, C8*); - - MAKE_STATE_1(State_H_C1_G, C1*); - MAKE_STATE_1(State_H_C2_G, C2*); - MAKE_STATE_1(State_H_C3_G, C3*); - MAKE_STATE_1(State_H_C4_G, C4*); - MAKE_STATE_1(State_H_C5_G, C5*); - MAKE_STATE_1(State_H_C6_G, C6*); - MAKE_STATE_1(State_H_C7_G, C7*); - MAKE_STATE_1(State_H_C8_G, C8*); - - MAKE_STATE_1(State_H2_C4_G, C4*); - - int g_TestID; - - struct C1 - { - virtual void F() - { - ADD_STATE(State_C1_F(this)); - } - virtual int G() - { - ADD_STATE(State_C1_G(this)); - return 1; - } - }; - struct C2 - { - virtual void F() - { - ADD_STATE(State_C2_F(this)); - } - virtual int G() - { - ADD_STATE(State_C2_G(this)); - return 2; - } - }; - struct C3 - { - virtual void F() - { - ADD_STATE(State_C3_F(this)); - } - virtual int G() - { - ADD_STATE(State_C3_G(this)); - return 3; - } - }; - struct C4 - { - virtual void F() - { - ADD_STATE(State_C4_F(this)); - } - virtual int G() - { - ADD_STATE(State_C4_G(this)); - return 4; - } - }; - struct C5 - { - virtual void F() - { - ADD_STATE(State_C5_F(this)); - } - virtual int G() - { - ADD_STATE(State_C5_G(this)); - return 5; - } - }; - struct C6 - { - virtual void F() - { - ADD_STATE(State_C6_F(this)); - } - virtual int G() - { - ADD_STATE(State_C6_G(this)); - return 6; - } - }; - struct C7 - { - virtual void F() - { - ADD_STATE(State_C7_F(this)); - } - virtual int G() - { - ADD_STATE(State_C7_G(this)); - return 7; - } - }; - struct C8 - { - virtual void F() - { - ADD_STATE(State_C8_F(this)); - } - virtual int G() - { - ADD_STATE(State_C8_G(this)); - return 8; - } - }; - - SH_DECL_HOOK0_void(C1, F, SH_NOATTRIB, 0); - SH_DECL_HOOK0(C1, G, SH_NOATTRIB, 0, int); - SH_DECL_HOOK0_void(C2, F, SH_NOATTRIB, 0); - SH_DECL_HOOK0(C2, G, SH_NOATTRIB, 0, int); - SH_DECL_HOOK0_void(C3, F, SH_NOATTRIB, 0); - SH_DECL_HOOK0(C3, G, SH_NOATTRIB, 0, int); - SH_DECL_HOOK0_void(C4, F, SH_NOATTRIB, 0); - SH_DECL_HOOK0(C4, G, SH_NOATTRIB, 0, int); - SH_DECL_HOOK0_void(C5, F, SH_NOATTRIB, 0); - SH_DECL_HOOK0(C5, G, SH_NOATTRIB, 0, int); - SH_DECL_HOOK0_void(C6, F, SH_NOATTRIB, 0); - SH_DECL_HOOK0(C6, G, SH_NOATTRIB, 0, int); - SH_DECL_HOOK0_void(C7, F, SH_NOATTRIB, 0); - SH_DECL_HOOK0(C7, G, SH_NOATTRIB, 0, int); - SH_DECL_HOOK0_void(C8, F, SH_NOATTRIB, 0); - SH_DECL_HOOK0(C8, G, SH_NOATTRIB, 0, int); - - void Handler_C1_F() - { - ADD_STATE(State_H_C1_F(META_IFACEPTR(C1))); - g_pC1->G(); - } - int Handler_C1_G() - { - ADD_STATE(State_H_C1_G(META_IFACEPTR(C1))); - g_pC2->F(); - return 1; - } - void Handler_C2_F() - { - ADD_STATE(State_H_C2_F(META_IFACEPTR(C2))); - g_pC2->G(); - } - int Handler_C2_G() - { - ADD_STATE(State_H_C2_G(META_IFACEPTR(C2))); - g_pC3->F(); - return 2; - } - void Handler_C3_F() - { - ADD_STATE(State_H_C3_F(META_IFACEPTR(C3))); - g_pC3->G(); - } - int Handler_C3_G() - { - ADD_STATE(State_H_C3_G(META_IFACEPTR(C3))); - g_pC4->F(); - return 3; - } - void Handler_C4_F() - { - ADD_STATE(State_H_C4_F(META_IFACEPTR(C4))); - g_pC4->G(); - } - int Handler_C4_G() - { - ADD_STATE(State_H_C4_G(META_IFACEPTR(C4))); - g_pC5->F(); - return 4; - } - int Handler2_C4_G() - { - ADD_STATE(State_H2_C4_G(META_IFACEPTR(C4))); - return 4; - } - void Handler_C5_F() - { - ADD_STATE(State_H_C5_F(META_IFACEPTR(C5))); - g_pC5->G(); - } - int Handler_C5_G() - { - ADD_STATE(State_H_C5_G(META_IFACEPTR(C5))); - g_pC6->F(); - return 5; - } - void Handler_C6_F() - { - ADD_STATE(State_H_C6_F(META_IFACEPTR(C6))); - g_pC6->G(); - } - int Handler_C6_G() - { - ADD_STATE(State_H_C6_G(META_IFACEPTR(C6))); - g_pC7->F(); - return 6; - } - void Handler_C7_F() - { - if (g_TestID == 1 || g_TestID == 2) - SH_REMOVE_HOOK(C4, G, g_pC4, SH_STATIC(Handler2_C4_G), false); - if (g_TestID == 2) - SH_REMOVE_HOOK(C4, G, g_pC4, SH_STATIC(Handler_C4_G), false); - - ADD_STATE(State_H_C7_F(META_IFACEPTR(C7))); - g_pC7->G(); - } - int Handler_C7_G() - { - ADD_STATE(State_H_C7_G(META_IFACEPTR(C7))); - g_pC8->F(); - return 7; - } - void Handler_C8_F() - { - ADD_STATE(State_H_C8_F(META_IFACEPTR(C8))); - g_pC8->G(); - } - int Handler_C8_G() - { - ADD_STATE(State_H_C8_G(META_IFACEPTR(C8))); - return 8; - } - - C1 g_C1; - C2 g_C2; - C3 g_C3; - C4 g_C4; - C5 g_C5; - C6 g_C6; - C7 g_C7; - C8 g_C8; -} - -bool TestReentr(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1337; - - g_pC1 = &g_C1; - g_pC2 = &g_C2; - g_pC3 = &g_C3; - g_pC4 = &g_C4; - g_pC5 = &g_C5; - g_pC6 = &g_C6; - g_pC7 = &g_C7; - g_pC8 = &g_C8; - - SH_ADD_HOOK(C1, F, g_pC1, SH_STATIC(Handler_C1_F), false); - SH_ADD_HOOK(C1, G, g_pC1, SH_STATIC(Handler_C1_G), false); - SH_ADD_HOOK(C2, F, g_pC2, SH_STATIC(Handler_C2_F), false); - SH_ADD_HOOK(C2, G, g_pC2, SH_STATIC(Handler_C2_G), false); - SH_ADD_HOOK(C3, F, g_pC3, SH_STATIC(Handler_C3_F), false); - SH_ADD_HOOK(C3, G, g_pC3, SH_STATIC(Handler_C3_G), false); - SH_ADD_HOOK(C4, F, g_pC4, SH_STATIC(Handler_C4_F), false); - SH_ADD_HOOK(C4, G, g_pC4, SH_STATIC(Handler_C4_G), false); - SH_ADD_HOOK(C5, F, g_pC5, SH_STATIC(Handler_C5_F), false); - SH_ADD_HOOK(C5, G, g_pC5, SH_STATIC(Handler_C5_G), false); - SH_ADD_HOOK(C6, F, g_pC6, SH_STATIC(Handler_C6_F), false); - SH_ADD_HOOK(C6, G, g_pC6, SH_STATIC(Handler_C6_G), false); - SH_ADD_HOOK(C7, F, g_pC7, SH_STATIC(Handler_C7_F), false); - SH_ADD_HOOK(C7, G, g_pC7, SH_STATIC(Handler_C7_G), false); - SH_ADD_HOOK(C8, F, g_pC8, SH_STATIC(Handler_C8_F), false); - SH_ADD_HOOK(C8, G, g_pC8, SH_STATIC(Handler_C8_G), false); - - g_pC1->F(); - - CHECK_STATES((&g_States, - new State_H_C1_F(g_pC1), - new State_H_C1_G(g_pC1), - new State_H_C2_F(g_pC2), - new State_H_C2_G(g_pC2), - new State_H_C3_F(g_pC3), - new State_H_C3_G(g_pC3), - new State_H_C4_F(g_pC4), - new State_H_C4_G(g_pC4), - new State_H_C5_F(g_pC5), - new State_H_C5_G(g_pC5), - new State_H_C6_F(g_pC6), - new State_H_C6_G(g_pC6), - new State_H_C7_F(g_pC7), - new State_H_C7_G(g_pC7), - new State_H_C8_F(g_pC8), - new State_H_C8_G(g_pC8), - new State_C8_G(g_pC8), - new State_C8_F(g_pC8), - new State_C7_G(g_pC7), - new State_C7_F(g_pC7), - new State_C6_G(g_pC6), - new State_C6_F(g_pC6), - new State_C5_G(g_pC5), - new State_C5_F(g_pC5), - new State_C4_G(g_pC4), - new State_C4_F(g_pC4), - new State_C3_G(g_pC3), - new State_C3_F(g_pC3), - new State_C2_G(g_pC2), - new State_C2_F(g_pC2), - new State_C1_G(g_pC1), - new State_C1_F(g_pC1), - NULL), "1"); - - - SH_ADD_HOOK(C4, G, g_pC4, SH_STATIC(Handler2_C4_G), false); - - g_pC1->F(); - - CHECK_STATES((&g_States, - new State_H_C1_F(g_pC1), - new State_H_C1_G(g_pC1), - new State_H_C2_F(g_pC2), - new State_H_C2_G(g_pC2), - new State_H_C3_F(g_pC3), - new State_H_C3_G(g_pC3), - new State_H_C4_F(g_pC4), - new State_H_C4_G(g_pC4), - new State_H_C5_F(g_pC5), - new State_H_C5_G(g_pC5), - new State_H_C6_F(g_pC6), - new State_H_C6_G(g_pC6), - new State_H_C7_F(g_pC7), - new State_H_C7_G(g_pC7), - new State_H_C8_F(g_pC8), - new State_H_C8_G(g_pC8), - new State_C8_G(g_pC8), - new State_C8_F(g_pC8), - new State_C7_G(g_pC7), - new State_C7_F(g_pC7), - new State_C6_G(g_pC6), - new State_C6_F(g_pC6), - new State_C5_G(g_pC5), - new State_C5_F(g_pC5), - new State_H2_C4_G(g_pC4), - new State_C4_G(g_pC4), - new State_C4_F(g_pC4), - new State_C3_G(g_pC3), - new State_C3_F(g_pC3), - new State_C2_G(g_pC2), - new State_C2_F(g_pC2), - new State_C1_G(g_pC1), - new State_C1_F(g_pC1), - NULL), "2"); - - g_pC1->F(); - - CHECK_STATES((&g_States, - new State_H_C1_F(g_pC1), - new State_H_C1_G(g_pC1), - new State_H_C2_F(g_pC2), - new State_H_C2_G(g_pC2), - new State_H_C3_F(g_pC3), - new State_H_C3_G(g_pC3), - new State_H_C4_F(g_pC4), - new State_H_C4_G(g_pC4), - new State_H_C5_F(g_pC5), - new State_H_C5_G(g_pC5), - new State_H_C6_F(g_pC6), - new State_H_C6_G(g_pC6), - new State_H_C7_F(g_pC7), - new State_H_C7_G(g_pC7), - new State_H_C8_F(g_pC8), - new State_H_C8_G(g_pC8), - new State_C8_G(g_pC8), - new State_C8_F(g_pC8), - new State_C7_G(g_pC7), - new State_C7_F(g_pC7), - new State_C6_G(g_pC6), - new State_C6_F(g_pC6), - new State_C5_G(g_pC5), - new State_C5_F(g_pC5), - new State_H2_C4_G(g_pC4), - new State_C4_G(g_pC4), - new State_C4_F(g_pC4), - new State_C3_G(g_pC3), - new State_C3_F(g_pC3), - new State_C2_G(g_pC2), - new State_C2_F(g_pC2), - new State_C1_G(g_pC1), - new State_C1_F(g_pC1), - NULL), "3"); - - g_TestID = 1; - - g_pC1->F(); - - CHECK_STATES((&g_States, - new State_H_C1_F(g_pC1), - new State_H_C1_G(g_pC1), - new State_H_C2_F(g_pC2), - new State_H_C2_G(g_pC2), - new State_H_C3_F(g_pC3), - new State_H_C3_G(g_pC3), - new State_H_C4_F(g_pC4), - new State_H_C4_G(g_pC4), - new State_H_C5_F(g_pC5), - new State_H_C5_G(g_pC5), - new State_H_C6_F(g_pC6), - new State_H_C6_G(g_pC6), - new State_H_C7_F(g_pC7), - new State_H_C7_G(g_pC7), - new State_H_C8_F(g_pC8), - new State_H_C8_G(g_pC8), - new State_C8_G(g_pC8), - new State_C8_F(g_pC8), - new State_C7_G(g_pC7), - new State_C7_F(g_pC7), - new State_C6_G(g_pC6), - new State_C6_F(g_pC6), - new State_C5_G(g_pC5), - new State_C5_F(g_pC5), - new State_C4_G(g_pC4), - new State_C4_F(g_pC4), - new State_C3_G(g_pC3), - new State_C3_F(g_pC3), - new State_C2_G(g_pC2), - new State_C2_F(g_pC2), - new State_C1_G(g_pC1), - new State_C1_F(g_pC1), - NULL), "4"); - - g_pC1->F(); - - CHECK_STATES((&g_States, - new State_H_C1_F(g_pC1), - new State_H_C1_G(g_pC1), - new State_H_C2_F(g_pC2), - new State_H_C2_G(g_pC2), - new State_H_C3_F(g_pC3), - new State_H_C3_G(g_pC3), - new State_H_C4_F(g_pC4), - new State_H_C4_G(g_pC4), - new State_H_C5_F(g_pC5), - new State_H_C5_G(g_pC5), - new State_H_C6_F(g_pC6), - new State_H_C6_G(g_pC6), - new State_H_C7_F(g_pC7), - new State_H_C7_G(g_pC7), - new State_H_C8_F(g_pC8), - new State_H_C8_G(g_pC8), - new State_C8_G(g_pC8), - new State_C8_F(g_pC8), - new State_C7_G(g_pC7), - new State_C7_F(g_pC7), - new State_C6_G(g_pC6), - new State_C6_F(g_pC6), - new State_C5_G(g_pC5), - new State_C5_F(g_pC5), - new State_C4_G(g_pC4), - new State_C4_F(g_pC4), - new State_C3_G(g_pC3), - new State_C3_F(g_pC3), - new State_C2_G(g_pC2), - new State_C2_F(g_pC2), - new State_C1_G(g_pC1), - new State_C1_F(g_pC1), - NULL), "5"); - - - - SH_ADD_HOOK(C4, G, g_pC4, SH_STATIC(Handler2_C4_G), false); - - g_TestID = 2; - - g_pC1->F(); - - CHECK_STATES((&g_States, - new State_H_C1_F(g_pC1), - new State_H_C1_G(g_pC1), - new State_H_C2_F(g_pC2), - new State_H_C2_G(g_pC2), - new State_H_C3_F(g_pC3), - new State_H_C3_G(g_pC3), - new State_H_C4_F(g_pC4), - new State_H_C4_G(g_pC4), - new State_H_C5_F(g_pC5), - new State_H_C5_G(g_pC5), - new State_H_C6_F(g_pC6), - new State_H_C6_G(g_pC6), - new State_H_C7_F(g_pC7), - new State_H_C7_G(g_pC7), - new State_H_C8_F(g_pC8), - new State_H_C8_G(g_pC8), - new State_C8_G(g_pC8), - new State_C8_F(g_pC8), - new State_C7_G(g_pC7), - new State_C7_F(g_pC7), - new State_C6_G(g_pC6), - new State_C6_F(g_pC6), - new State_C5_G(g_pC5), - new State_C5_F(g_pC5), - new State_C4_G(g_pC4), - new State_C4_F(g_pC4), - new State_C3_G(g_pC3), - new State_C3_F(g_pC3), - new State_C2_G(g_pC2), - new State_C2_F(g_pC2), - new State_C1_G(g_pC1), - new State_C1_F(g_pC1), - NULL), "6"); - - g_pC1->F(); - - CHECK_STATES((&g_States, - new State_H_C1_F(g_pC1), - new State_H_C1_G(g_pC1), - new State_H_C2_F(g_pC2), - new State_H_C2_G(g_pC2), - new State_H_C3_F(g_pC3), - new State_H_C3_G(g_pC3), - new State_H_C4_F(g_pC4), - new State_C4_G(g_pC4), - new State_C4_F(g_pC4), - new State_C3_G(g_pC3), - new State_C3_F(g_pC3), - new State_C2_G(g_pC2), - new State_C2_F(g_pC2), - new State_C1_G(g_pC1), - new State_C1_F(g_pC1), - NULL), "7"); - - SH_REMOVE_HOOK(C1, F, g_pC1, SH_STATIC(Handler_C1_F), false); - SH_REMOVE_HOOK(C1, G, g_pC1, SH_STATIC(Handler_C1_G), false); - SH_REMOVE_HOOK(C2, F, g_pC2, SH_STATIC(Handler_C2_F), false); - SH_REMOVE_HOOK(C2, G, g_pC2, SH_STATIC(Handler_C2_G), false); - SH_REMOVE_HOOK(C3, F, g_pC3, SH_STATIC(Handler_C3_F), false); - SH_REMOVE_HOOK(C3, G, g_pC3, SH_STATIC(Handler_C3_G), false); - SH_REMOVE_HOOK(C4, F, g_pC4, SH_STATIC(Handler_C4_F), false); - SH_REMOVE_HOOK(C4, G, g_pC4, SH_STATIC(Handler_C4_G), false); - SH_REMOVE_HOOK(C5, F, g_pC5, SH_STATIC(Handler_C5_F), false); - SH_REMOVE_HOOK(C5, G, g_pC5, SH_STATIC(Handler_C5_G), false); - SH_REMOVE_HOOK(C6, F, g_pC6, SH_STATIC(Handler_C6_F), false); - SH_REMOVE_HOOK(C6, G, g_pC6, SH_STATIC(Handler_C6_G), false); - SH_REMOVE_HOOK(C7, F, g_pC7, SH_STATIC(Handler_C7_F), false); - SH_REMOVE_HOOK(C7, G, g_pC7, SH_STATIC(Handler_C7_G), false); - SH_REMOVE_HOOK(C8, F, g_pC8, SH_STATIC(Handler_C8_F), false); - SH_REMOVE_HOOK(C8, G, g_pC8, SH_STATIC(Handler_C8_G), false); - - return true; -} diff --git a/sourcehook/test/testref.cpp b/sourcehook/test/testref.cpp deleted file mode 100644 index 97d5789..0000000 --- a/sourcehook/test/testref.cpp +++ /dev/null @@ -1,227 +0,0 @@ -#include "testevents.h" -#include "sourcehook_test.h" - -// References and private copy constructors and stuff like that! - -/* -BAILOPAN, 29.04.2006 21:51 : -onoto-san, interesting error from VS -we have this function: -void GabHaben(ISomething &sth); - -SomethingDerived sth; -and SH_CALL(cc, &WHAT::GabHaben)(sth); -"No copy constructor available for class 'SomethingDerived'" -*/ - - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - MAKE_STATE_1(State_Result, int); - MAKE_STATE_1(State_Result_InHook, int); - - MAKE_STATE_2(State_F2_Called, int, int); - MAKE_STATE_2(State_F2_Handler_Called, int, int); - - struct POD - { - int a; - int b; - int c; - int d; - int e; - int f; - }; - - class CBase - { - // Private copy constructor! - CBase(CBase &other) - { - } - public: - CBase() - { - } - - virtual int Func() - { - return 0; - } - }; - - class CDerived : public CBase - { - virtual int Func() - { - return 10; - } - }; - - // Complicated derived shit ! - class COtherWeirdBase - { - int member; - }; - class CDerived2 : private COtherWeirdBase, public CBase - { - int m_Return; - public: - CDerived2(int a) : m_Return(a) - { - } - - virtual int Func() - { - return m_Return; - } - }; - - class CHello - { - public: - virtual int Func(CBase &sth) - { - return sth.Func(); - } - - virtual void F2(POD a) - { - } - }; - - - class Test2 - { - public: - virtual void F1(){} - virtual void F2(POD &a) - { - ADD_STATE(State_F2_Called(a.a, a.b)); - } - }; - - class CHook - { - public: - virtual int Func(CBase &sth) - { - ADD_STATE(State_Result_InHook(sth.Func())); - RETURN_META_VALUE(MRES_SUPERCEDE, 20); - } - - virtual void F2(POD &a) - { - ADD_STATE(State_F2_Handler_Called(a.a, a.b)); - } - - virtual void F21(POD a) - { - } - }; - - SH_DECL_HOOK1(CHello, Func, SH_NOATTRIB, 0, int, CBase&); - SH_DECL_HOOK1_void(CHello, F2, SH_NOATTRIB, 0, POD); - SH_DECL_HOOK1_void(Test2, F2, SH_NOATTRIB, 0, POD&); - - CHello *MyInstanceFactory() - { - return new CHello; - } -} - - -bool TestRef(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1; - - CBase base; - CDerived der; - CDerived2 der2(11); - CDerived2 der3(12); - CHello *pHello = MyInstanceFactory(); - Test2 *pTest2 = new Test2; - CAutoPtrDestruction apd(pHello); - CAutoPtrDestruction apd2(pTest2); - CHook hook; - - SourceHook::CallClass *cc = SH_GET_CALLCLASS(pHello); - - ADD_STATE(State_Result(pHello->Func(base))); - ADD_STATE(State_Result(pHello->Func(der))); - ADD_STATE(State_Result(pHello->Func(der2))); - ADD_STATE(State_Result(pHello->Func(der3))); - - CHECK_STATES((&g_States, - new State_Result(0), - new State_Result(10), - new State_Result(11), - new State_Result(12), - NULL), "Part 1"); - - ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(base))); - ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der))); - ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der2))); - ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der3))); - - CHECK_STATES((&g_States, - new State_Result(0), - new State_Result(10), - new State_Result(11), - new State_Result(12), - NULL), "Part 2"); - - SH_ADD_HOOK(CHello, Func, pHello, SH_MEMBER(&hook, &CHook::Func), false); - - ADD_STATE(State_Result(pHello->Func(base))); - ADD_STATE(State_Result(pHello->Func(der))); - ADD_STATE(State_Result(pHello->Func(der2))); - ADD_STATE(State_Result(pHello->Func(der3))); - - CHECK_STATES((&g_States, - new State_Result_InHook(0), - new State_Result(20), - new State_Result_InHook(10), - new State_Result(20), - new State_Result_InHook(11), - new State_Result(20), - new State_Result_InHook(12), - new State_Result(20), - NULL), "Part 3"); - - ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(base))); - ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der))); - ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der2))); - ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der3))); - - CHECK_STATES((&g_States, - new State_Result(0), - new State_Result(10), - new State_Result(11), - new State_Result(12), - NULL), "Part 4"); - - // Check for correct ref proto handling - - SH_ADD_HOOK(CHello, F2, pHello, SH_MEMBER(&hook, &CHook::F21), false); - SH_ADD_HOOK(Test2, F2, pTest2, SH_MEMBER(&hook, &CHook::F2), false); - - POD pod = { 1, 2 }; - pTest2->F2(pod); - - int a = 5; - - pHello->F2(pod); - - CHECK_STATES((&g_States, - new State_F2_Handler_Called(1, 2), - new State_F2_Called(1, 2), - NULL), "Part 5"); - - return true; -} diff --git a/sourcehook/test/testrefret.cpp b/sourcehook/test/testrefret.cpp deleted file mode 100644 index 597c0bd..0000000 --- a/sourcehook/test/testrefret.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include "testevents.h" -#include "sourcehook_test.h" - -// Tests support for functions which return references - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - MAKE_STATE_1(State_Func1_Pre1, int*); // p1: the ref Func1_Pre1 is going to return - MAKE_STATE_3(State_Func1_Pre2, META_RES, int*, int*); // p1: current status - // p2: override ret - // p3: what this handler is going to supercede with - MAKE_STATE_1(State_Func1, int*); // p1: the ref Func1 is going to return - MAKE_STATE_2(State_Func1_Post1, int*, int*); // p1: orig_ret; p2: override_ret - MAKE_STATE_1(State_Func1_Post2, int*); // p1: what it's going to return - MAKE_STATE_1(State_Func1_Ret, int*); // p1: the ref it returned - - - MAKE_STATE_2(State_Func2_Pre1, int, const int*); // p1: func's p1; p2: what it's going to ret - MAKE_STATE_2(State_Func2, int, const int*); // p1: func's p1; p2: what it's going to ret - MAKE_STATE_3(State_Func2_Post1, int, const int*, const int*); // p1: func's p1; p2: orig ret; p3: override ret - MAKE_STATE_1(State_Func2_Ret, const int*); // p1: ret - - int g_Var; - - class Test - { - public: - int m_Var1; - int m_Var2; - - Test() : m_Var1(87) - { - } - - virtual int& Func1() - { - ADD_STATE(State_Func1(&m_Var1)); - return m_Var1; - } - virtual const int& Func2(int p1) - { - ADD_STATE(State_Func2(p1, &m_Var2)); - m_Var2 = p1; - return m_Var2; - } - }; - - class CHook - { - public: - int m_Var; - virtual int& Func1_Pre1() - { - ADD_STATE(State_Func1_Pre1(&m_Var)); - RETURN_META_VALUE(MRES_OVERRIDE, m_Var); - } - virtual int &Func1_Pre2() - { - int &overrideret = META_RESULT_OVERRIDE_RET(int&); - overrideret = 1337; - ADD_STATE(State_Func1_Pre2(META_RESULT_STATUS, &overrideret, &g_Var)); - RETURN_META_VALUE(MRES_SUPERCEDE, g_Var); - } - virtual int& Func1_Post1() - { - ADD_STATE(State_Func1_Post1(&META_RESULT_ORIG_RET(int&), &META_RESULT_OVERRIDE_RET(int&))); - RETURN_META_NOREF(MRES_IGNORED, int&); - } - virtual int& Func1_Post2() - { - ADD_STATE(State_Func1_Post2(&m_Var)); - RETURN_META_VALUE(MRES_OVERRIDE, m_Var); - } - - virtual const int& Func2_Pre1(int p1) - { - ADD_STATE(State_Func2_Pre1(p1, &m_Var)); - RETURN_META_VALUE_NEWPARAMS(MRES_OVERRIDE, m_Var, static_cast(&Test::Func2), (1337)); - } - - virtual const int& Func2_Post1(int p1) - { - ADD_STATE(State_Func2_Post1(p1, &META_RESULT_ORIG_RET(int&), &META_RESULT_OVERRIDE_RET(int&))); - RETURN_META_NOREF(MRES_IGNORED, const int&); - } - }; - - SH_DECL_HOOK0(Test, Func1, SH_NOATTRIB, 0, int&); - SH_DECL_HOOK1(Test, Func2, SH_NOATTRIB, 0, const int&, int); - - Test *MyTestFactory() - { - return new Test; - } -} - -bool TestRefRet(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1; - - Test *pTest = MyTestFactory(); - CAutoPtrDestruction apd(pTest); - CHook hook; - - int &ret1 = pTest->Func1(); - ADD_STATE(State_Func1_Ret(&ret1)); - - CHECK_STATES((&g_States, - new State_Func1(&pTest->m_Var1), - new State_Func1_Ret(&pTest->m_Var1), - NULL), "Part 1"); - - // Now add Func1_Pre1, which supercedes and returns hook.m_Var - SH_ADD_HOOK(Test, Func1, pTest, SH_MEMBER(&hook, &CHook::Func1_Pre1), false); - - int &ret2 = pTest->Func1(); - ADD_STATE(State_Func1_Ret(&ret2)); - - CHECK_STATES((&g_States, - new State_Func1_Pre1(&hook.m_Var), // Pre1 says that it's going to override with hook.m_Var - new State_Func1(&pTest->m_Var1), // Function says that it's going to return pTest->m_Var1 - new State_Func1_Ret(&hook.m_Var), // hook.m_Var is returned - NULL), "Part 2"); - - // Now add Func1_Post1, which only reports orig ret and override ret - SH_ADD_HOOK(Test, Func1, pTest, SH_MEMBER(&hook, &CHook::Func1_Post1), true); - - int &ret3 = pTest->Func1(); - ADD_STATE(State_Func1_Ret(&ret3)); - - CHECK_STATES((&g_States, - new State_Func1_Pre1(&hook.m_Var), // Pre1 says that it's going to override with hook.m_Var - new State_Func1(&pTest->m_Var1), // Function says that it's going to return pTest->m_Var1 - new State_Func1_Post1(&pTest->m_Var1, &hook.m_Var), // origret(=p1) is what it wanted to - // return, overrideret(=p2) is pre1's var - new State_Func1_Ret(&hook.m_Var), // hook.m_Var is returned - NULL), "Part 3"); - - // Now add Func1_Pre2, which supercedes and returns g_Var (it also sets the override ret from pre1 to 1337) - // and add Func1_Post2, which overrides and returns hook.m_Var again. - - SH_ADD_HOOK(Test, Func1, pTest, SH_MEMBER(&hook, &CHook::Func1_Pre2), false); - SH_ADD_HOOK(Test, Func1, pTest, SH_MEMBER(&hook, &CHook::Func1_Post2), true); - - int &ret4 = pTest->Func1(); - ADD_STATE(State_Func1_Ret(&ret4)); - - CHECK_STATES((&g_States, - new State_Func1_Pre1(&hook.m_Var), // Pre1 says that it's going to override with hook.m_Var - new State_Func1_Pre2(MRES_OVERRIDE, // current status - &hook.m_Var, // override ret (which it set to 1337) - &g_Var), // what it's going to ret, AND supercede with - - new State_Func1_Post1(&g_Var, &g_Var), // origret(=p1) is what pre2 superceded with, - // so overrideret(=p2) has to be the same - new State_Func1_Post2(&hook.m_Var), // post2 is going to override with hook.m_Var again - new State_Func1_Ret(&hook.m_Var), // ==>>> hook.m_Var is returned - NULL), "Part 4"); - - CHECK_COND(hook.m_Var == 1337, "Part 4.1"); - - // Through a callclass - SourceHook::CallClass *cc1 = SH_GET_CALLCLASS(pTest); - int &ret5 = SH_CALL(cc1, &Test::Func1)(); - ADD_STATE(State_Func1_Ret(&ret5)); - - CHECK_STATES((&g_States, - new State_Func1(&pTest->m_Var1), - new State_Func1_Ret(&pTest->m_Var1), - NULL), "Part 5"); - - SH_RELEASE_CALLCLASS(cc1); - - //////////////////////////////////////////////////////////////////////////////////////// - // Func2 tests - const int &ret21 = pTest->Func2(500); - ADD_STATE(State_Func2_Ret(&ret21)); - - CHECK_STATES((&g_States, - new State_Func2(500, &pTest->m_Var2), - new State_Func2_Ret(&pTest->m_Var2), - NULL), "Part 6"); - - SH_ADD_HOOK(Test, Func2, pTest, SH_MEMBER(&hook, &CHook::Func2_Pre1), false); - SH_ADD_HOOK(Test, Func2, pTest, SH_MEMBER(&hook, &CHook::Func2_Post1), true); - - const int &ret22 = pTest->Func2(500); - ADD_STATE(State_Func2_Ret(&ret22)); - - CHECK_STATES((&g_States, - new State_Func2_Pre1(500, &hook.m_Var), // p1 was 500; it's going to override with hook.m_Var; and also change p1 to 1337 - new State_Func2(1337, &pTest->m_Var2), // p1 was 1337; it's going to ret pTest->m_Var2 - new State_Func2_Post1(1337, // p1 was 1337 - &pTest->m_Var2, // orig ret was pTest->m_Var2 - &hook.m_Var), // override ret was hook.m_Var - new State_Func2_Ret(&hook.m_Var), // really returned hook.m_Var - NULL), "Part 7"); - - return true; -} diff --git a/sourcehook/test/testvphooks.cpp b/sourcehook/test/testvphooks.cpp deleted file mode 100644 index acbeff8..0000000 --- a/sourcehook/test/testvphooks.cpp +++ /dev/null @@ -1,260 +0,0 @@ -#include -#include "sourcehook.h" -#include "sourcehook_test.h" -#include "testevents.h" - -// TEST VP HOOKS -// Test vfnptr-wide hooks - -namespace -{ - StateList g_States; - SourceHook::ISourceHook *g_SHPtr; - SourceHook::Plugin g_PLID; - - class IBase; - - MAKE_STATE_1(State_D1_Func1, IBase *); - MAKE_STATE_1(State_D2_Func1, IBase *); - MAKE_STATE_1(State_Func1_Pre, IBase *); - MAKE_STATE_1(State_Func1_Post, IBase *); - - MAKE_STATE_1(State_D1_Func2, IBase *); - MAKE_STATE_1(State_D2_Func2, IBase *); - MAKE_STATE_1(State_Func2_Pre, IBase *); - MAKE_STATE_1(State_Func2_Post, IBase *); - - MAKE_STATE_2(State_D1_Func3, IBase *, int); - MAKE_STATE_2(State_D2_Func3, IBase *, int); - MAKE_STATE_2(State_Func3_Pre, IBase *, int); - MAKE_STATE_2(State_Func3_Post, IBase *, int); - - class IBase - { - public: - virtual void Func1() = 0; - virtual void Func2() = 0; - virtual void Func3(int x) = 0; - }; - - class CDerived1 : public IBase - { - public: - virtual void Func1() - { - ADD_STATE(State_D1_Func1(this)); - } - virtual void Func2() - { - ADD_STATE(State_D1_Func2(this)); - } - virtual void Func3(int x) - { - ADD_STATE(State_D1_Func3(this, x)); - } - }; - - class CDerived2 : public IBase - { - public: - virtual void Func1() - { - ADD_STATE(State_D2_Func1(this)); - } - virtual void Func2() - { - ADD_STATE(State_D2_Func2(this)); - } - virtual void Func3(int x) - { - ADD_STATE(State_D2_Func3(this, x)); - } - }; - - void Handler_Func1_Pre() - { - ADD_STATE(State_Func1_Pre(META_IFACEPTR(IBase))); - } - void Handler_Func1_Post() - { - ADD_STATE(State_Func1_Post(META_IFACEPTR(IBase))); - } - int g_F2_Pre_HookToRemove = 0; - void Handler_Func2_Pre() - { - ADD_STATE(State_Func2_Pre(META_IFACEPTR(IBase))); - SH_REMOVE_HOOK_ID(g_F2_Pre_HookToRemove); - } - void Handler_Func2_Post() - { - ADD_STATE(State_Func2_Post(META_IFACEPTR(IBase))); - } - - - void Handler_Func3_Pre(int x) - { - ADD_STATE(State_Func3_Pre(META_IFACEPTR(IBase), x)); - - RETURN_META_NEWPARAMS(MRES_IGNORED, &IBase::Func3, (x+1)); - } - void Handler_Func3_Post(int x) - { - ADD_STATE(State_Func3_Post(META_IFACEPTR(IBase), x)); - } - - SH_DECL_HOOK0_void(IBase, Func1, SH_NOATTRIB, 0); - SH_DECL_HOOK0_void(IBase, Func2, SH_NOATTRIB, 0); - SH_DECL_HOOK1_void(IBase, Func3, SH_NOATTRIB, 0, int); - - SH_DECL_MANUALHOOK1_void(IBase_Func3_Manual, 2, 0, 0, int); -} - -bool TestVPHooks(std::string &error) -{ - GET_SHPTR(g_SHPtr); - g_PLID = 1337; - - CDerived1 d1i1; - CDerived1 d1i2; - CDerived2 d2i1; - - IBase *p_d1i1 = &d1i1; - IBase *p_d1i2 = &d1i2; - IBase *p_d2i1 = &d2i1; - - int hook1 = SH_ADD_VPHOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false); - - p_d1i1->Func1(); - p_d1i2->Func1(); - p_d2i1->Func1(); - - CHECK_STATES((&g_States, - new State_Func1_Pre(p_d1i1), - new State_D1_Func1(p_d1i1), - - new State_Func1_Pre(p_d1i2), - new State_D1_Func1(p_d1i2), - - new State_D2_Func1(p_d2i1), - NULL), "Part 1"); - - SH_REMOVE_HOOK_ID(hook1); - - p_d1i1->Func1(); - p_d1i2->Func1(); - p_d2i1->Func1(); - - CHECK_STATES((&g_States, - new State_D1_Func1(p_d1i1), - - new State_D1_Func1(p_d1i2), - - new State_D2_Func1(p_d2i1), - NULL), "Part 2"); - - - // Normal hook, then vp hook - - int hook2 = SH_ADD_HOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false); - hook1 = SH_ADD_VPHOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false); - - p_d1i1->Func1(); - p_d1i2->Func1(); - p_d2i1->Func1(); - - CHECK_STATES((&g_States, - new State_Func1_Pre(p_d1i1), - new State_Func1_Pre(p_d1i1), - new State_D1_Func1(p_d1i1), - - new State_Func1_Pre(p_d1i2), - new State_D1_Func1(p_d1i2), - - new State_D2_Func1(p_d2i1), - NULL), "Part 3"); - - SH_REMOVE_HOOK_ID(hook1); - - p_d1i1->Func1(); - p_d1i2->Func1(); - p_d2i1->Func1(); - - CHECK_STATES((&g_States, - new State_Func1_Pre(p_d1i1), - new State_D1_Func1(p_d1i1), - - new State_D1_Func1(p_d1i2), - - new State_D2_Func1(p_d2i1), - NULL), "Part 4"); - - SH_REMOVE_HOOK_ID(hook2); - - p_d1i1->Func1(); - p_d1i2->Func1(); - p_d2i1->Func1(); - - CHECK_STATES((&g_States, - new State_D1_Func1(p_d1i1), - - new State_D1_Func1(p_d1i2), - - new State_D2_Func1(p_d2i1), - NULL), "Part 5"); - - // Test this: - // Normal hook AND vp hook on Func2 - // Func2's pre handler removes the VP hook. - - hook1 = SH_ADD_VPHOOK(IBase, Func2, p_d1i1, SH_STATIC(Handler_Func2_Pre), false); - hook2 = SH_ADD_HOOK(IBase, Func2, p_d1i1, SH_STATIC(Handler_Func2_Pre), false); - - g_F2_Pre_HookToRemove = hook1; - p_d1i1->Func2(); - p_d1i1->Func2(); - - CHECK_STATES((&g_States, - new State_Func2_Pre(p_d1i1), - new State_D1_Func2(p_d1i1), - - new State_Func2_Pre(p_d1i1), - new State_D1_Func2(p_d1i1), - - NULL), "Part 6"); - - SH_REMOVE_HOOK_ID(hook1); - - // Hook function 3: - // Using manualhook, VP - hook1 = SH_ADD_MANUALVPHOOK(IBase_Func3_Manual, p_d1i1, SH_STATIC(Handler_Func3_Pre), false); - - // Normally, VP - hook2 = SH_ADD_VPHOOK(IBase, Func3, p_d1i1, SH_STATIC(Handler_Func3_Pre), false); - - // Normally, no VP - int hook3 = SH_ADD_HOOK(IBase, Func3, p_d1i1, SH_STATIC(Handler_Func3_Pre), false); - - p_d1i1->Func3(1); - - CHECK_STATES((&g_States, - new State_Func3_Pre(p_d1i1, 1), // manual vp hook - new State_Func3_Pre(p_d1i1, 2), // normal vp hook - new State_Func3_Pre(p_d1i1, 3), // normal non-vp hook - - new State_D1_Func3(p_d1i1, 4), // function - - NULL), "Part 7.1"); - - p_d1i2->Func3(1); - - CHECK_STATES((&g_States, - new State_Func3_Pre(p_d1i2, 1), // manual vp hook - new State_Func3_Pre(p_d1i2, 2), // normal vp hook - - new State_D1_Func3(p_d1i2, 3), // function - - NULL), "Part 7.2"); - - return true; -} - diff --git a/sourcemm/IPluginManager.h b/sourcemm/IPluginManager.h deleted file mode 100644 index b84dd5f..0000000 --- a/sourcemm/IPluginManager.h +++ /dev/null @@ -1,159 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_IPLUGINMANAGER_H -#define _INCLUDE_METAMOD_IPLUGINMANAGER_H - -/** - * @brief Plugin Manager interface - * @file IPluginManager.h - */ - -namespace SourceMM -{ - /** - * @brief Used to uniquel identify plugins. - */ - typedef int PluginId; - - /** - * @brief Load sources - */ - enum - { - Pl_BadLoad=0, - Pl_Console=-1, - Pl_File=-2, - Pl_MinId=1, - }; - - /** - * @brief Status of a plugin at runtime - */ - enum Pl_Status - { - Pl_NotFound=-4, - Pl_Error=-3, - Pl_Refused=-2, - Pl_Paused=-1, - Pl_Running=0, - }; - - class ISmmPluginManager - { - public: - /** - * @brief Loads a plugin and returns its id. If this is called before DLLInit(), - * then the plugin is considered to be "hot" - it might refuse its own load later! - * Also, a hot plugin might not have an error message. - * - * @param file String containing file name - * @param source Specifies who loaded the plugin - * @param status Status of the plugin - * @param ismm Pointer to Smm API - * @param error String buffer for error messages - * @param maxlen Maximum length of buffer - * @return Id of plugin - */ - virtual PluginId Load(const char *file, PluginId source, bool &already, char *error, size_t maxlen) =0; - - /** - * @brief Unloads a plugin - * - * @param id Id of plugin - * @param error String buffer for error messages - * @param maxlen Maximum length of buffer - * @return True on success, false otherwise - */ - virtual bool Unload(PluginId id, bool force, char *error, size_t maxlen) =0; - - /** - * @brief Pauses a plugin - * - * @param id Id of plugin - * @param error String buffer for error messages - * @param maxlen Maximum length of buffer - * @return True on success, false otherwise - */ - virtual bool Pause(PluginId id, char *error, size_t maxlen) =0; - - /** - * @brief Unpauses a plugin - * - * @param id Id of plugin - * @param force If true, forces the plugin to unload - * @param error String buffer for error messages - * @param maxlen Maximum length of buffer - * @return True on success, false otherwise - */ - virtual bool Unpause(PluginId id, char *error, size_t maxlen) =0; - - /** - * @brief Unloads all plugins forcefully - * - * @return True on success, false otherwise - */ - virtual bool UnloadAll() =0; - - /** - * @brief Returns information about a plugin - * - * @param id Id of plugin - * @param file Pointer to store filename pointer, or NULL to ignore. - * @param status Pointer to store status, or NULL to ignore. - * @param source Pointer to store source, or NULL to ignore. - * @return True on success, false if not found - */ - virtual bool Query(PluginId id, const char **file, Pl_Status *status, PluginId *source) =0; - - /** - * @brief Checks another plugin's QueryRunning() status. - * - * @param id Id of plugin - * @param error Message buffer - * @param maxlen Size of error buffer - * @return Status value - */ - virtual bool QueryRunning(PluginId id, char *error, size_t maxlength) =0; - - /** - * @brief Returns the handle of a plugin (OS dependent meaning) - * - * @param id Id of plugin - * @param handle Pointer to store handle pointer, or NULL to ignore. - * @return True if plugin id is valid, false otherwise - */ - virtual bool QueryHandle(PluginId id, void **handle) =0; - }; -} - -#if !defined METAMOD_NO_AUTO_NAMESPACE -using namespace SourceMM; -#endif - -#endif //_INCLUDE_PLUGINMANAGER_H - diff --git a/sourcemm/ISmmAPI.h b/sourcemm/ISmmAPI.h deleted file mode 100644 index b405579..0000000 --- a/sourcemm/ISmmAPI.h +++ /dev/null @@ -1,405 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_ISMM_API_H -#define _INCLUDE_ISMM_API_H - -/** - * @brief External API interface - * @file ISmmAPI.h - */ - -#include -#include -#include -#include -#include -#include -#include - -#if defined __GNUC__ -#if ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4)) || (__GNUC__ < 3) -#error "You must compile with at least GCC 3.4! If you know what you are doing, you can remove this message." -#endif //version check -#endif //__GNUC__ - -#define MMIFACE_SOURCEHOOK "ISourceHook" /**< ISourceHook Pointer */ -#define MMIFACE_PLMANAGER "IPluginManager" /**< SourceMM Plugin Functions */ -#define MMIFACE_SH_HOOKMANAUTOGEN "IHookManagerAutoGen" /**< SourceHook::IHookManagerAutoGen Pointer */ -#define IFACE_MAXNUM 999 /**< Maximum interface version */ - -namespace SourceMM -{ - class ISmmPlugin; - class IMetamodListener; - - class ISmmAPI - { - public: - /** - * @brief Logs a message through the HL2 log system. - * Note: Newlines are appended automatically. - * - * @param pl Plugin API pointer (used for tagging message) - * @param msg Formatted string. - */ - virtual void LogMsg(ISmmPlugin *pl, const char *msg, ...) =0; - - /** - * @brief Returns an interface factory for the HL2 engine. - * - * @param syn If syn is true, the synthetic wrapper is returned. - * If syn is false, the true function is returned. - * @return CreateInterfaceFn function pointer. - */ - virtual CreateInterfaceFn GetEngineFactory(bool syn=true) =0; - - /** - * @brief Returns an interface factory for the HL2 physics engine. - * - * @param syn If syn is true, the synthetic wrapper is returned. - * If syn is false, the true function is returned. - * @return CreateInterfaceFn function pointer. - */ - virtual CreateInterfaceFn GetPhysicsFactory(bool syn=true) =0; - - /** - * @brief Returns an interface factory for the HL2 file system. - * - * @param syn If syn is true, the synthetic wrapper is returned. - * If syn is false, the true function is returned. - * @return CreateInterfaceFn function pointer. - */ - virtual CreateInterfaceFn GetFileSystemFactory(bool syn=true) =0; - - /** - * @brief Returns an interface factory for the GameDLL. - * - * If syn is false, the true function is returned. - * @return CreateInterfaceFn function pointer. - */ - virtual CreateInterfaceFn GetServerFactory(bool syn=true) =0; - - /** - * @brief Returns a CGlobalVars pointer from the HL2 Engine. - * - * @return CGlobalVars pointer. - */ - virtual CGlobalVars *GetCGlobals() =0; - - /** - * @brief Registers a ConCommandBase. - * - * @param plugin Parent plugin API pointer. - * @param pCommand ConCommandBase to register. - * @return True if successful, false otherwise. - */ - virtual bool RegisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand) =0; - - /** - * @brief Unregisters a ConCommandBase. - * - * @param plugin Parent plugin API pointer. - * @param pCommand ConCommandBase to unlink. - */ - virtual void UnregisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand) =0; - - /** - * @brief Prints an unformatted string to the remote server console. - * - * Note: Newlines are not added automatically. - * - * @param str Message string. - */ - virtual void ConPrint(const char *str) =0; - - /** - * @brief Prints a formatted message to the remote server console. - * - * Note: Newlines are not added automatically. - * - * @param fmt Formatted message. - */ - virtual void ConPrintf(const char *fmt, ...) =0; - - /** - * @brief Returns the Metamod Version numbers as major version and - * minor (API) version. Changes to minor version are guaranteed to be - * backwards compatible. Changes to major version are not. - * - * @param major Filled with the major API version number. - * @param minor Filled with the minor API version number. - * @param plvers Filled with the current plugin API version number. - * @param plmin Filled with the minimum plugin API version number - * supported. - */ - virtual void GetApiVersions(int &major, int &minor, int &plvers, int &plmin) =0; - - /** - * @brief Returns sourcehook API version and implementation version. - * - * @param shvers Filled with the SourceHook API version number. - * @param shimpl Filled with the SourceHook implementation number. - */ - virtual void GetShVersions(int &shvers, int &shimpl) =0; - - /** - * @brief Adds a Metamod listener. - * - * @param plugin Plugin interface pointer. - * @param pListener Listener interface pointer to add. - */ - virtual void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener) =0; - - /** - * @brief Queries the metamod factory - * - * @param iface String containing interface name - * @param ret Optional pointer to store return status - * @param id Optional pointer to store id of plugin that - * overrode interface, 0 if none - * @return Returned pointer - */ - virtual void *MetaFactory(const char *iface, int *ret, PluginId *id) =0; - - /** - * @brief Given a base interface name, such as ServerGameDLL or - * ServerGameDLL003, reformats the string to increase the number, then - * returns the new number. This is the base function to InterfaceSearch() - * and VInterfaceMatch(). - * - * @param iface Input/output interface name. Must be writable. - * @param maxlength Maximum length of iface buffer. Must be at least - * strlen(iface)+4 chars. - * @return The newly incremented iface version number. - */ - virtual int FormatIface(char iface[], unsigned int maxlength) =0; - - /** - * @brief Searches for an interface, eliminating the need to loop - * through FormatIface(). - * - * @param fn InterfaceFactory function. - * @param iface Interface string name. - * @param max Maximum version to look up. - * @param ret Last return code from interface factory function. - * @return Interface pointer, or NULL if not found. - */ - virtual void *InterfaceSearch(CreateInterfaceFn fn, - const char *iface, - int max, - int *ret) =0; - - /** - * @brief Returns the base directory of the game/server, equivalent to - * IVEngineServer::GetGameDir(), except the path is absolute. - * - * @return Static pointer to game's absolute basedir. - */ - virtual const char *GetBaseDir() =0; - - /** - * @brief Formats a file path to the local OS. - * - * Does not include any base directories. Note that all slashes and - * black slashes are reverted to the local OS's expectancy. - * - * @param buffer Destination buffer to store path. - * @param len Maximum length of buffer, including null - * terminator. - * @param fmt Formatted string. - * @param ... Arguments in the string. - * @return Number of bytes written, not including the null - * terminator. - */ - virtual size_t PathFormat(char *buffer, size_t len, const char *fmt, ...) =0; - - /** - * @brief Prints text in the specified client's console. Same as - * IVEngineServer::ClientPrintf except that it allows for string - * formatting. - * - * @param client Client edict pointer. - * @param fmt Formatted string to print to the client. - */ - virtual void ClientConPrintf(edict_t *client, const char *fmt, ...) =0; - - /** - * @brief Wrapper around InterfaceSearch(). Assumes no maximum. - * This is designed to replace the fact that searches only went upwards. - * The "V" is intended to convey that this is for Valve formatted - * interface strings. - * - * @param fn Interface factory function. - * @param iface Interface string. - * @param min Minimum value to search from. If zero, searching - * begins from the first available version regardless - * of the interface. Note that this can return - * interfaces EARLIER than the version specified. A - * value of -1 (default) specifies the string version - * as the minimum. Any other value specifices the - * minimum value to search from. - * @return Interface pointer, or NULL if not found. - */ - virtual void *VInterfaceMatch(CreateInterfaceFn fn, - const char *iface, - int min=-1) =0; - - /** - * @brief Tells SourceMM to add VSP hooking capability to plugins. - * - * Since this potentially uses more resources than it would otherwise, - * plugins have to explicitly enable the feature. Whether requested or - * not, if it is enabled, all plugins will get a pointer to the VSP - * listener through IMetamodListener. This will not be called more than - * once for a given plugin; if it is requested more than once, each - * successive call will only give the pointer to plugins which have not - * yet received it. - */ - virtual void EnableVSPListener() =0; - - /** - * @brief Returns the interface version of the GameDLL's IServerGameDLL - * implementation. - * - * @return Interface version of the loaded IServerGameDLL. - */ - virtual int GetGameDLLVersion() =0; - - /** - * @brief Returns the number of user messages in the GameDLL. - * - * @return Number of user messages, or -1 if SourceMM has - * failed to get user message list. - */ - virtual int GetUserMessageCount() =0; - - /** - * @brief Returns the index of the specified user message. - * - * @param name User message name. - * @param size Optional pointer to store size of user message. - * @return Message index, or -1 on failure. - */ - virtual int FindUserMessage(const char *name, int *size=NULL) =0; - - /** - * @brief Returns the name of the specified user message. - * - * @param index User message index. - * @param size Optional pointer to store size of user message. - * @return Message name, or NULL on failure. - */ - virtual const char *GetUserMessage(int index, int *size=NULL) =0; - - /** - * @brief Returns the highest interface version of IServerPluginCallbacks - * that the engine supports. This is useful for games that run on older - * versions of the Source engine, such as The Ship. - * - * @return Highest interface version of IServerPluginCallbacks. - * Returns 0 if SourceMM's VSP listener isn't - * currently enabled. - */ - virtual int GetVSPVersion() =0; - - /** - * @brief Returns the engine interface that MM:S is using as a backend. - * - * The values will be one of the SOURCE_ENGINE_* constants from the top - * of this file. - * - * @return A SOURCE_ENGINE_* constant value. - */ - virtual int GetSourceEngineBuild() =0; - - /** - * @brief Returns the VSP listener loaded. - * - * This is useful for late-loading plugins which need to decide whether - * to add a listener or not (or need to get the pointer at all). - * - * @param Optional pointer to store the VSP version. - * @return IServerPluginCallbacks pointer, or NULL if an - * IMetamodListener event has yet to occur for - * EnableVSPListener(). - */ - virtual IServerPluginCallbacks *GetVSPInfo(int *pVersion) =0; - - /** - * @brief Formats a string. This is a platform safe wrapper around - * snprintf/_snprintf. - * - * @param buffer Buffer to write to. - * @param maxlength Maximum length of the buffer. - * @param format Format specifiers. - * @param ... Format arguments. - * @return Number of bytes actually written, not including - * the null terminator. - */ - virtual size_t Format(char *buffer, - size_t maxlength, - const char *format, - ...) =0; - - /** - * @brief Formats a string. This is a platform safe wrapper around - * vsnprintf/_vsnprintf. - * - * @param buffer Buffer to write to. - * @param maxlength Maximum length of the buffer. - * @param format Format specifiers. - * @param ap Format argument list. - * @return Number of bytes actually written, not including the - * null terminator. - */ - virtual size_t FormatArgs(char *buffer, - size_t maxlength, - const char *format, - va_list ap) =0; - }; -} - -#if !defined METAMOD_NO_AUTO_NAMESPACE -using namespace SourceMM; -#endif - -/** - * Version History - * - * 1.1.0 Bumped API to 1:0. The breaking changes occurred in SourceHook and the plugin API. - * 1.1.2 Added API call for generating iface names. - * 1.2 Added API more helper functions and new SourceHook version. - * 1.2.2 Added API for printing to client console (with string formatting). - * 1.3 Added new interface search API. - * 1.4 Added VSP listener and user message API. - * 1.5.0 Added API for getting highest supported version of IServerPluginCallbacks. - * 1.6.0 Added API for Orange Box. Broke backwards compatibility. - */ - -#endif //_INCLUDE_ISMM_API_H - diff --git a/sourcemm/ISmmPlugin.h b/sourcemm/ISmmPlugin.h deleted file mode 100644 index 89a7248..0000000 --- a/sourcemm/ISmmPlugin.h +++ /dev/null @@ -1,505 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_ISMM_PLUGIN_H -#define _INCLUDE_ISMM_PLUGIN_H - -/** - * @brief Plugin API interface - * @file ISmmPlugin.h - */ - -#include -#include -#include -#include -#include - -namespace SourceMM -{ - class ISmmAPI; - - /** - * @brief Callbacks that a plugin must expose. - */ - class ISmmPlugin - { - public: - /** - * @brief Called to request the plugin's API version. - * - * This is the first callback invoked, and always remains at the top - * of the virtual table. - * - * @return Plugin API version. - */ - virtual int GetApiVersion() - { - return METAMOD_PLAPI_VERSION; - } - - /** - * @brief Virtual destructor so GCC doesn't complain. - */ - virtual ~ISmmPlugin() - { - } - - public: - /** - * @brief Called on plugin load. - * - * This is called as DLLInit() executes - after the parameters are - * known, but before the original GameDLL function is called. - * Therefore, you cannot hook it, but you don't need to - Load() is - * basically your hook. You can override factories before the engine - * and gamedll exchange them. However, take care to note that if your - * plugin is unloaded, and the gamedll/engine have cached an interface - * you've passed, something will definitely crash. Be careful. - * - * @param id Internal id of plugin. Saved globally by PLUGIN_SAVEVARS() - * @param ismm External API for SourceMM. Saved globally by PLUGIN_SAVEVARS() - * @param error Error message buffer - * @param maxlength Size of error message buffer - * @param late Set to true if your plugin was loaded late (not at server load). - * @return True if successful, return false to reject the load. - */ - virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late) =0; - - /** - * @brief Called when all plugins have been loaded. - * - * This is called after DLLInit(), and thus the mod has been mostly initialized. - * It is also safe to assume that all other (automatically loaded) plugins are now - * ready to start interacting, because they are all loaded. - */ - virtual void AllPluginsLoaded() - { - } - - /** - * @brief Called when your plugin is "queried". - * - * This is useful for rejecting a loaded state. For example, if your - * plugin wants to stop operating, it can simply return false and copy - * an error message. This will notify other plugins or MM:S of - * something bad that happened. MM:S will not cache the return state, - * so if you return false, your plugin will not actually be paused or - * unloaded. This callback will be called when: - * - Another plugin requests it - * - Someone types "meta list", it will show up as "REFUSED" - * - When Metamod need to re-check the plugin's status - * - If the plugin does something like overload a factory, Metamod - * will make sure the Query() returns true before calling it. - * Also note that this query will only override Metamod when the - * plugin is running and not paused. - * - * @param error Buffer for error message, or NULL if none. - * @param maxlen Maximum length of error buffer. - * @return Status code - true for okay, false for badness. - */ - virtual bool QueryRunning(char *error, size_t maxlen) - { - return true; - } - - /** - * @brief Called on plugin unload. You can return false if you know - * your plugin is not capable of restoring critical states it modifies. - * - * @param error Error message buffer - * @param maxlen Size of error message buffer - * @return True on success, return false to request no unload. - */ - virtual bool Unload(char *error, size_t maxlen) - { - return true; - } - - /** - * @brief Called on plugin pause. - * - * @param error Error message buffer - * @param maxlen Size of error message buffer - * @return True on success, return false to request no pause. - */ - virtual bool Pause(char *error, size_t maxlen) - { - return true; - } - - /** - * @brief Called on plugin unpause. - * - * @param error Error message buffer - * @param maxlen Size of error message buffer - * @return True on success, return false to request no unpause. - */ - virtual bool Unpause(char *error, size_t maxlen) - { - return true; - } - public: - /** @brief Return author as string */ - virtual const char *GetAuthor() =0; - - /** @brief Return plugin name as string */ - virtual const char *GetName() =0; - - /** @brief Return a description as string */ - virtual const char *GetDescription() =0; - - /** @brief Return a URL as string */ - virtual const char *GetURL() =0; - - /** @brief Return quick license code as string */ - virtual const char *GetLicense() =0; - - /** @brief Return version as string */ - virtual const char *GetVersion() =0; - - /** @brief Return author as string */ - virtual const char *GetDate() =0; - - /** @brief Return author as string */ - virtual const char *GetLogTag() =0; - }; - - /** - * @brief Various events that Metamod can fire. - */ - class IMetamodListener - { - public: - /** - * @brief Called when a plugin is loaded. - * - * @param id Id of the plugin. - */ - virtual void OnPluginLoad(PluginId id) - { - } - - /** - * @brief Called when a plugin is unloaded. - * - * @param id Id of the plugin. - */ - virtual void OnPluginUnload(PluginId id) - { - } - - /** - * @brief Called when a plugin is paused. - * - * @param id Id of the plugin. - */ - virtual void OnPluginPause(PluginId id) - { - } - - /** - * @brief Called when a plugin is unpaused. - * - * @param id Id of the plugin. - */ - virtual void OnPluginUnpause(PluginId id) - { - } - - /** - * @brief Called when the level is loaded (after GameInit, before - * ServerActivate). - * - * To override this, hook IServerGameDLL::LevelInit(). - * - * @param pMapName Name of the map. - * @param pMapEntities Lump string of the map entities, in KeyValues - * format. - * @param pOldLevel Unknown. - * @param pLandmarkName Unknown. - * @param loadGame Unknown. - * @param background Unknown. - */ - virtual void OnLevelInit(char const *pMapName, - char const *pMapEntities, - char const *pOldLevel, - char const *pLandmarkName, - bool loadGame, - bool background) - { - } - - /** - * @brief Called when the level is shut down. May be called more than - * once. - */ - virtual void OnLevelShutdown() - { - } - - /** - * @brief Called when engineFactory() is used through Metamod:Source's - * wrapper. This can be used to provide interfaces to other plugins or - * the GameDLL. - * - * If ret is passed, you should fill it with IFACE_OK or IFACE_FAILED. - * - * @param iface Interface string. - * @param ret Optional pointer to store return code. - * @return Generic pointer to the interface, or NULL if - * not found. - */ - virtual void *OnEngineQuery(const char *iface, int *ret) - { - if (ret) - { - *ret = IFACE_FAILED; - } - - return NULL; - } - - /** - * @brief Called when the physics factory is used through - * Metamod:Source's wrapper. This can be used to provide interfaces to - * other plugins. - * - * If ret is passed, you should fill it with IFACE_OK or IFACE_FAILED. - * - * @param iface Interface string. - * @param ret Optional pointer to store return code. - * @return Generic pointer to the interface, or NULL if - * not found. - */ - virtual void *OnPhysicsQuery(const char *iface, int *ret) - { - if (ret) - { - *ret = IFACE_FAILED; - } - - return NULL; - } - - /** - * @brief Called when the filesystem factory is used through - * Metamod:Source's wrapper. This can be used to provide interfaces to - * other plugins. - * - * If ret is passed, you should fill it with IFACE_OK or IFACE_FAILED. - * - * @param iface Interface string. - * @param ret Optional pointer to store return code. - * @return Generic pointer to the interface, or NULL if not - * found. - */ - virtual void *OnFileSystemQuery(const char *iface, int *ret) - { - if (ret) - { - *ret = IFACE_FAILED; - } - - return NULL; - } - - /** - * @brief Called when the server DLL's factory is used through - * Metamod:Source's wrapper. This can be used to provide interfaces to - * other plugins. - * - * If ret is passed, you should fill it with IFACE_OK or IFACE_FAILED. - * - * @param iface Interface string. - * @param ret Optional pointer to store return code. - * @return Generic pointer to the interface, or NULL if not - * found. - */ - virtual void *OnGameDLLQuery(const char *iface, int *ret) - { - if (ret) - { - *ret = IFACE_FAILED; - } - - return NULL; - } - - /** - * @brief Called when Metamod's own factory is invoked. - * This can be used to provide interfaces to other plugins. - * - * If ret is passed, you should fill it with IFACE_OK or IFACE_FAILED. - * - * @param iface Interface string. - * @param ret Optional pointer to store return code. - * @return Generic pointer to the interface, or NULL if not - * found. - */ - virtual void *OnMetamodQuery(const char *iface, int *ret) - { - if (ret) - { - *ret = IFACE_FAILED; - } - - return NULL; - } - - /** - * @brief Called when Metamod:Source acquires a valid - * IServerPluginCallbacks pointer to be used for hooking by plugins. - * - * This will only be called after a call to ISmmAPI::EnableVSPListener(). - * If called before GameInit, this callback will occur before LevelInit. - * Otherwise, it will be called on the first call after that. - * - * This callback is provided to all plugins regardless of which (or how - * many) called EnableVSPListener(), but only if at least one did in - * fact enable it, and only once for all plugins. That is, a late - * loading plugin should use ISmmAPI::GetVSPInfo() before relying on - * this callback. - * - * @param iface Interface pointer. If NULL, then the VSP - * listening construct failed to initialize and - * is not available. - */ - virtual void OnVSPListening(IServerPluginCallbacks *iface) - { - } - - /** - * @brief Called when Metamod:Source is about to remove a concommand or - * convar. This can also be called if ISmmAPI::UnregisterConCmdBase is - * used by a plugin. - * - * @param id Id of the plugin that created the concommand or - * convar. - * @param pCommand Pointer to concommand or convar that is being - * removed. - */ - virtual void OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand) - { - } - }; -} - -#if !defined METAMOD_NO_AUTO_NAMESPACE -using namespace SourceMM; -#endif - -#define PL_EXPOSURE CreateInterface -#define PL_EXPOSURE_C "CreateInterface" - -#define PLUGIN_EXPOSE(name, var) \ - ISmmAPI *g_SMAPI = NULL; \ - ISmmPlugin *g_PLAPI = NULL; \ - PluginId g_PLID = (PluginId)0; \ - SourceHook::ISourceHook *g_SHPtr = NULL; \ - SMM_API void *PL_EXPOSURE(const char *name, int *code) { \ - if (name && !strcmp(name, METAMOD_PLAPI_NAME)) { \ - return static_cast(&var); \ - } \ - return NULL; \ - } - -#define PLUGIN_GLOBALVARS() \ - extern SourceHook::ISourceHook *g_SHPtr; \ - extern ISmmAPI *g_SMAPI; \ - extern ISmmPlugin *g_PLAPI; \ - extern PluginId g_PLID; - -#define PLUGIN_SAVEVARS() \ - g_SMAPI = ismm; \ - g_SHPtr = static_cast(ismm->MetaFactory(MMIFACE_SOURCEHOOK, NULL, NULL)); \ - g_PLAPI = static_cast(this); \ - g_PLID = id; - -#define META_LOG g_SMAPI->LogMsg -#define META_REGCMD(name) g_SMAPI->RegisterConCommandBase(g_PLAPI, name##_command) -#define META_REGCVAR(var) g_SMAPI->RegisterConCommandBase(g_PLAPI, var) -#define META_UNREGCMD(name) g_SMAPI->UnregisterConCommandBase(g_PLAPI, name##_command) -#define META_UNREGCVAR(var) g_SMAPI->UnregisterConCommandBase(g_PLAPI, var) -#define META_CONPRINT g_SMAPI->ConPrint -#define META_CONPRINTF g_SMAPI->ConPrintf - -/* Probably should use this up above someday */ -#define CONCMD_VARNAME(name) name##_command - -#if !defined SMM_API -#if defined __WIN32__ || defined _WIN32 || defined WIN32 - #define SMM_API extern "C" __declspec(dllexport) -#elif defined __GNUC__ - #if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) - #define SMM_API extern "C" __attribute__ ((visibility("default"))) - #else - #define SMM_API extern "C" - #endif -#endif -#endif //!defined SMM_API - -/** - * @brief Macro for automatically getting a current or newer Valve interface. - * - * @param v_factory Factory method to use from ISmmAPI (such as engineFactory). - * @param v_var Variable name to store into. - * @param v_type Interface type (do not include the pointer/asterisk). - * @param v_name Interface name. - */ -#define GET_V_IFACE_CURRENT(v_factory, v_var, v_type, v_name) \ - v_var = (v_type *)ismm->VInterfaceMatch(ismm->v_factory(), v_name); \ - if (!v_var) \ - { \ - if (error && maxlen) \ - { \ - ismm->Format(error, maxlen, "Could not find interface: %s", v_name); \ - } \ - return false; \ - } - - /** - * @brief Same as GET_V_IFACE, except searches for any. - * - * @param v_factory Factory method to use from ISmmAPI (such as engineFactory). - * @param v_var Variable name to store into. - * @param v_type Interface type (do not include the pointer/asterisk). - * @param v_name Interface name. - */ -#define GET_V_IFACE_ANY(v_factory, v_var, v_type, v_name) \ - v_var = (v_type *)ismm->VInterfaceMatch(ismm->v_factory(), v_name, 0); \ - if (!v_var) \ - { \ - if (error && maxlen) \ - { \ - ismm->Format(error, maxlen, "Could not find interface: %s", v_name); \ - } \ - return false; \ - } - -#endif //_INCLUDE_ISMM_PLUGIN_H - diff --git a/sourcemm/ISmmPluginExt.h b/sourcemm/ISmmPluginExt.h deleted file mode 100644 index 4d27726..0000000 --- a/sourcemm/ISmmPluginExt.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_PLUGIN_EXT_H_ -#define _INCLUDE_METAMOD_SOURCE_PLUGIN_EXT_H_ - -#define SOURCE_ENGINE_UNKNOWN 0 /**< Could not determine the engine version */ -#define SOURCE_ENGINE_ORIGINAL 1 /**< Original Source Engine (used by The Ship) */ -#define SOURCE_ENGINE_EPISODEONE 2 /**< Episode 1 Source Engine (second major SDK) */ -#define SOURCE_ENGINE_ORANGEBOX 3 /**< Orange Box Source Engine (third major SDK) */ - -#define METAMOD_PLAPI_VERSION 14 /**< Version of this header file */ -#define METAMOD_PLAPI_NAME "ISmmPlugin" /**< Name of the plugin interface */ - -namespace SourceMM -{ - class ISmmPlugin; -} - -typedef SourceMM::ISmmPlugin METAMOD_PLUGIN; - -/** - * @file ISmmPluginExt.h Definitions for extended plugin exposure syntax. - * @brief Provides an alternate method for loading plugins, without needing to - * include the default headers and all their Half-Life baggage. - */ - -/** - * @brief Contains version information. - */ -struct MetamodVersionInfo -{ - int api_major; /**< ISmmAPI major version */ - int api_minor; /**< ISmmAPI minor version */ - int sh_iface; /**< SourceHook interface version */ - int sh_impl; /**< SourceHook implementation version */ - int pl_min; /**< Plugin API minimum version */ - int pl_max; /**< Plugin API maximum version */ - int source_engine; /**< Source Engine version (SOURCE_* constants) */ -}; - -/** - * @brief Contains information about loading a plugin. - */ -struct MetamodLoaderInfo -{ - const char *pl_file; /**< File path to the plugin being loaded. */ - const char *pl_path; /**< Folder path containing the plugin. */ -}; - -/** - * @brief If a function of this type is exposed as "CreateInterface_MMS", then - * Metamod:Source will attempt to call this function before calling - * CreateInterface. If this function returns a valid ISmmPlugin pointer, then - * CreateInterface will not be called. - * - * This is useful for implementing a mini-loader plugin for multiple versions. - * - * @param mvi MetamodVersionInfo structure. - * @param mli MetamodLoaderInfo structure. - * @return ISmmAPI pointer, or NULL if none. - */ -typedef METAMOD_PLUGIN *(*METAMOD_FN_LOAD)(const MetamodVersionInfo *mvi, - const MetamodLoaderInfo *mli); - -/** - * @brief If a function of this type is exposed as "UnloadInterface_MMS", then - * Metamod:Source will attempt to call this function after calling - * ISmmAPI::Unload(), and before closing the library. This lets loader plugins - * clean up before exiting. - * - * Note: This function will be ignored unless CreateInterfce_MMS was exposed. - * It may be called even if ISmmAPI::Unload() could not be called. - */ -typedef void (*METAMOD_FN_UNLOAD)(); - -/** - * @brief Original type of load function. CreateInterfaceFn from Valve. - * - * Plugins will expose this as "CreateInterface". - */ -typedef void *(*METAMOD_FN_ORIG_LOAD)(const char *, int *); - -#endif //INCLUDE_METAMOD_SOURCE_PLUGIN_EXT_H_ - diff --git a/sourcemm/LICENSE.txt b/sourcemm/LICENSE.txt deleted file mode 100644 index bf9f1fd..0000000 --- a/sourcemm/LICENSE.txt +++ /dev/null @@ -1,29 +0,0 @@ -The software is Copyright (C) 2004-2007, Metamod:Source Development Team. - -Metamod:Source is distributed under the "zLib/libpng" license, which is reproduced -below: - ------------------------------------------------------------------------------ - -This software is provided "as-is", without any express or implied warranty. -In no event will the authors be held liable for any damages arising from -the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software in - a product, an acknowledgment in the product documentation would be - appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. - ------------------------------------------------------------------------------ - -The zLib/libpng license has been approved by the "Open Source Initiative" -organization. diff --git a/sourcemm/Makefile.ep1 b/sourcemm/Makefile.ep1 deleted file mode 100644 index e4ecee9..0000000 --- a/sourcemm/Makefile.ep1 +++ /dev/null @@ -1,78 +0,0 @@ -#(C)2004-2007 Metamod:Source Development Team -# Makefile written by David "BAILOPAN" Anderson - -HL2SDK = ../../hl2sdk -SMM_ROOT = .. -SRCDS = ~/srcds - -### EDIT BELOW FOR OTHER PROJECTS ### - -OPT_FLAGS = -O2 -funroll-loops -s -pipe -GCC4_FLAGS = -fvisibility=hidden -fvisibility-inlines-hidden -DEBUG_FLAGS = -g -ggdb3 -CPP = gcc-4.1 -BINARY = server_i486.so - -HL2PUB = $(HL2SDK)/public -HL2LIB = $(HL2SDK)/linux_sdk - -OBJECTS = metamod.cpp metamod_util.cpp metamod_console.cpp metamod_oslink.cpp metamod_plugins.cpp \ - sourcehook.cpp episode1/console.cpp episode1/provider_ep1.cpp episode1/vsp_listener.cpp - -LINK = $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so -static-libgcc - -INCLUDE = -I. -I$(HL2PUB) -I$(HL2PUB)/dlls -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 \ - -I$(HL2PUB)/vstdlib -I$(HL2SDK)/tier1 -I$(SMM_ROOT) -I$(SMM_ROOT)/sourcehook - -ifeq "$(DEBUG)" "true" - BIN_DIR = Debug - CFLAGS = $(DEBUG_FLAGS) -else - BIN_DIR = Release - CFLAGS = $(OPT_FLAGS) -endif - -GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) - -CFLAGS += -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp \ - -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca \ - -Dstrcmpi=strcasecmp -Wall -Wno-non-virtual-dtor -Werror -fPIC -fno-exceptions -fno-rtti -msse \ - -Wno-uninitialized - -ifeq "$(GCC_VERSION)" "4" - CFLAGS += $(GCC4_FLAGS) -endif - -OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) - -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< - -all: - mkdir -p $(BIN_DIR) - mkdir -p $(BIN_DIR)/episode1 - rm -f vstdlib_i486.so - rm -f tier0_i486.so - ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so - ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so - ln -sf $(SMM_ROOT)/sourcehook/sourcehook.cpp sourcehook.cpp - $(MAKE) -f Makefile.ep1 sourcemm - rm -rf $(BINARY) - ln -sf $(BIN_DIR)/$(BINARY) $(BINARY) - -sourcemm: $(OBJ_LINUX) - $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) - -debug: - $(MAKE) -f Makefile.ep1 all DEBUG=true - -default: all - -clean: - rm -rf Release/episode1/*.o - rm -rf Release/*.o - rm -rf Release/$(BINARY) - rm -rf Debug/episode1/*.o - rm -rf Debug/*.o - rm -rf Debug/$(BINARY) - diff --git a/sourcemm/Makefile.ep2 b/sourcemm/Makefile.ep2 deleted file mode 100644 index bff129a..0000000 --- a/sourcemm/Makefile.ep2 +++ /dev/null @@ -1,78 +0,0 @@ -#(C)2004-2007 Metamod:Source Development Team -# Makefile written by David "BAILOPAN" Anderson - -HL2SDK = ../../hl2sdk-ob -SMM_ROOT = .. -SRCDS = ~/srcds/orangebox - -### EDIT BELOW FOR OTHER PROJECTS ### - -OPT_FLAGS = -O2 -funroll-loops -s -pipe -GCC4_FLAGS = -fvisibility=hidden -fvisibility-inlines-hidden -DEBUG_FLAGS = -g -ggdb3 -CPP = gcc-4.1 -BINARY = server_i486.so - -HL2PUB = $(HL2SDK)/public -HL2LIB = $(HL2SDK)/linux_sdk - -OBJECTS = metamod.cpp metamod_util.cpp metamod_console.cpp metamod_oslink.cpp metamod_plugins.cpp \ - sourcehook.cpp episode2/console.cpp episode2/provider_ep2.cpp episode2/vsp_listener.cpp - -LINK = $(HL2SDK)/linux_sdk/tier1_i486.a vstdlib_i486.so tier0_i486.so -static-libgcc - -INCLUDE = -I. -I$(HL2PUB) -I$(HL2PUB)/dlls -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 \ - -I$(HL2PUB)/vstdlib -I$(HL2SDK)/tier1 -I$(SMM_ROOT) -I$(SMM_ROOT)/sourcehook - -ifeq "$(DEBUG)" "true" - BIN_DIR = Debug - CFLAGS = $(DEBUG_FLAGS) -else - BIN_DIR = Release - CFLAGS = $(OPT_FLAGS) -endif - -GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) - -CFLAGS += -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp \ - -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca \ - -Dstrcmpi=strcasecmp -Wall -Wno-non-virtual-dtor -Werror -fPIC -fno-exceptions -fno-rtti -msse \ - -fno-strict-aliasing -Wno-uninitialized - -ifeq "$(GCC_VERSION)" "4" - CFLAGS += $(GCC4_FLAGS) -endif - -OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) - -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< - -all: - mkdir -p $(BIN_DIR) - mkdir -p $(BIN_DIR)/episode2 - rm -f vstdlib_i486.so - rm -f tier0_i486.so - ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so - ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so - ln -sf $(SMM_ROOT)/sourcehook/sourcehook.cpp sourcehook.cpp - $(MAKE) -f Makefile.ep2 sourcemm - rm -rf $(BINARY) - ln -sf $(BIN_DIR)/$(BINARY) $(BINARY) - -sourcemm: $(OBJ_LINUX) - $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) - -debug: - $(MAKE) -f Makefile.ep2 all DEBUG=true - -default: all - -clean: - rm -rf Release/episode2/*.o - rm -rf Release/*.o - rm -rf Release/$(BINARY) - rm -rf Debug/episode2/*.o - rm -rf Debug/*.o - rm -rf Debug/$(BINARY) - diff --git a/sourcemm/changelog.txt b/sourcemm/changelog.txt deleted file mode 100644 index f479ba2..0000000 --- a/sourcemm/changelog.txt +++ /dev/null @@ -1,157 +0,0 @@ -2007/??/?? 1.6.0: - - Added new version of SourceHook with the following changes: - - Added API for hooking functions on a virtual table to all instances. - - SH_ADD_HOOK macros now return non-zero hook IDs. Additionally, - the old hook adding/removing syntax is deprecated (but still supported). - - Added SH_REMOVE_HOOK_ID to remove hooks by ID. - - CallClasses have been deprecated. The SH_CALL macro can now take a class - instance pointer rather than a callclass pointer. - - Metamod:Source has now received a large internal rewrite to improve coding - standards and to separate internal logic from engine specifics. - - Added API for getting highest supported IServerPluginCallbacks interface - version. - - Added API for detecting the engine version. - - Added API for getting the VSP-simulation interface upon late loading. - - Added OnUnlinkConCommandBase to IMetamodListner to notify when Metamod:Source - is about to remove a concommand or convar. - - The output of the "meta list" command has been reformatted in order to allow - more space for plugins' name, version, and author fields. - -2007/06/26 1.4.2: - - Fixed a bug where unloading all plugins could crash if one plugin had child - plugins. - -2007/05/16 1.4.1: - - The client version of the "meta" command should now work with games using the - latest Source beta (srcds0407). - - Fixed amb233 (VSP listener didn't work with Steam dedicated version). - - Fixed amb277 (failed to get user message list in Kreedz Climbing). - -2007/04/05 1.4.0: - - Added API functions for retrieving User Message info without potentially - crashing. - - Added API functions for letting SourceMM plugins use Valve Server Plugin - callbacks. - - Added plugin status to client version of "meta list" command. Previously, it - did not differentiate between running and paused plugins. - - An experimental automatic gameinfo.txt fixer is now available. - - Changed version numbering to include the build number (SVN revision). - - Fixed amb93 (improved mod path detection). - - Fixed various rare string inconsistencies. - -2006/11/29 1.3d: - - Updated Metamod:Source to recognize the latest Source Engine version - (ServerGameDLL006) - -2006/09/06 1.3a: - - Fixed a building issue on Linux which caused unresolved symbol errors when - trying to load Metamod:Source on a game using an older set of engine - libraries. This fix should now allow Metamod:Source to run with The Ship on - Linux. - -2006/08/16 1.3: - - Added SourceHook support for functions that return references. - - Added some extra information to the "meta game" command: Description and - Interface. For example, CS:S would display "Counter-Strike: Source" and - "ServerGameDLL004." - - Added some extra functionality to ISmmPluginManager. - - Added compiling support for MSVC 8.0 (Visual Studio 2005) and GCC 4.x. - - Added another API helper function for formatting and searching for - interfaces. - - Updated project files and source tree to use the latest HL2SDK. - - Updated the sample plugins to be a bit cleaner and use newer API. - - Fixed bug where Metamod:Source could load the wrong GameDLL and/or load more - than one GameDLL. This issue occured in HL2 CTF, SourceForts, or any other - mod that relied on files from another mod directory. - - Fixed bug where ISmmAPI::MetaFactory() would return the wrong interface when - trying to retrieve ISmmPluginManager. - - Fixed bug where returning false in Load() after adding a Metamod event - listener or hooking a function could cause a crash instead of rejecting the - plugin. - - Fixed bug where trying to load Metamod:Source a second time as a SourceMM or - Valve server plugin could cause a crash. - - Fixed a bug in FormatIface() that caused InterfaceSearch() to infinite loop. - -2006/06/14 1.2.3: - - Added SourceHook API for manual recalls: RETURN_META_(VALUE_)MNEWPARAMS - - Added support for ServerGameDLL005 (latest HL2DM update) - -2006/05/25 1.2.2: - - Added the ability to "alias" plugin names in metaplugins.ini. - - Added "meta alias" command. - - Added SourceHook API for manual callclasses. - - Added support for the latest Source engine (ServerGameDLL005). - - Added API for printing text in a client's console with ClientConPrintf. This - does the same thing as IVEngineServer::ClientPrintf except that it allows - string formatting. - - Added client version of "meta" command in order to allow clients to view - version information and a list of loaded plugins. - - Fixed a bug causing old mods on newer engines to fail loading. - - Fixed issues with SourceHook's SH_CALL and reference parameters. - - Fixed a bug where the mm_pluginsfile cvar was being ignored. - - Fixed a memory leak when using ISmmAPI::InterfaceSearch. - -2006/02/15 1.2.1: - - Fixed bug where returning newparams in a post hook would cause infinite - recursion. - - Fixed bug where "meta load" could load the same plugin multiple times. - - Fixed bug where unloading a plugin could crash internal hook states. - - Fixed bug where unhooking a single hook would clear the hook chain. - -2006/01/07 1.2: - - Added SourceHook API for modifying parameters in the hook chain. - - Added SourceHook API for declaring and hooking manual vtable hooks. - - Added better API for querying an interface factory. - - Added API for formatting an OS-independent path. - - Added Listen Server Launcher to the graphical installer. - - Fixed bug where failed plugins could crash the plugin list. - - NOTE: SourceHook changes may require plugins to be recompiled against the new - API. - -2005/12/06 1.1.2: - - Added interface overriding/sharing examples to sample plugins. - - Added API to help guessing at Valve interface versions. - - Fixed various memory leaks. - - Fixed memory corruption bug on vector copying. - - Fixed other various template bugs. - -2005/10/21 1.1.1: - - Fixed a bug where AllPluginsLoaded() was not called after DLLInit(). - -2005/10/21 1.1: - - Rewrote GameDLL loading code to be API version generic. As such, SourceMM - will now easily support new API releases without an SDK release, such as the - case with Day of Defeat:Source. - - Added more flexibility to plugin control by supplying an event system. - - Removed dependency on libstdc++.so by supplying a small template library. - - SourceHook internal API is now interface-based, meaning that future updates - to the API will not break older plugins. This update, however, breaks older - plugins. - - SourceHook is now re-entrant. - - Added a basic automated installer (by Basic-Master). - - Fixed a bug where games with changing game names would not work. - - Fixed various bugs, including a cvarlist corruption bug on unloading plugins. - -2005/07/07 1.00-RC2: - - Added API for dealing with ConCommandBase registration (cvars/concmds). This - is to fix the fact that Valve API provides no way to unlist a cvar/cmd. - - Added two new commands - "meta cmds" and "meta cvars". - - Added API calls for correctly printing to the console such that rcon will - also receive messages that a plugin prints. This problem was mentioned on - hlcoders and Valve offered no reply. - - Added event hooking and cvar samples to sample_mm. - - Added new cvar, mm_pluginsfile, which defaults to - "addons/metamod/metaplugins.ini". - - Fixed a bug where multiple vtable patches on the same hook were not - re-patched when removed. This caused a crash when two hooks were declared on - one function, the first was removed, and the original function was then - called. - - Fixed "meta clear" not unloading all plugins. - - Fixed Metamod:Source loading plugins with a higher current API version. - - Fixed whitespace being parsed in metaplugins.ini. - - Fixed bug where SourceHook tried to patch already destroyed/unavailable - memory. - - Bumped Plugin API version to 6. - -2005/05/06 1.00-RC1: - - Initial release. diff --git a/sourcemm/episode1/console.cpp b/sourcemm/episode1/console.cpp deleted file mode 100644 index 64cb498..0000000 --- a/sourcemm/episode1/console.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#include "console.h" -#include "provider_ep1.h" - -using namespace SourceHook; - -SMConVarAccessor g_SMConVarAccessor; - -class CAlwaysRegisterableCommand : public ConCommandBase -{ -public: - CAlwaysRegisterableCommand() - { - Create("metamod_eternal", NULL, FCVAR_UNREGISTERED|FCVAR_GAMEDLL); - } - bool IsRegistered( void ) const - { - return false; - } - void BringToFront() - { - // First, let's try to find us! - ConCommandBase *pPtr = icvar->GetCommands(); - - if (pPtr == this) - { - // We are already at the beginning; Nothing to do - return; - } - - while (pPtr) - { - if (pPtr == this) - { - break; - } - ConCommandBase *pPrev = NULL; - while (pPtr) - { - if (pPtr == this) - { - break; - } - pPrev = pPtr; - pPtr = const_cast(pPtr->GetNext()); - } - if (pPrev && pPtr == this) - { - pPrev->SetNext(m_pNext); // Remove us from the list - } - // Now, register us - SetNext(NULL); - icvar->RegisterConCommandBase(this); - } - } -} s_EternalCommand; - -bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand) -{ - m_RegisteredCommands.push_back(pCommand); - pCommand->SetNext(NULL); - icvar->RegisterConCommandBase(pCommand); - - return true; -} - -bool SMConVarAccessor::Register(ConCommandBase *pCommand) -{ - pCommand->SetNext(NULL); - icvar->RegisterConCommandBase(pCommand); - - return true; -} - -void SMConVarAccessor::MarkCommandsAsGameDLL() -{ - for (List::iterator iter = m_RegisteredCommands.begin(); - iter != m_RegisteredCommands.end(); ++iter) - { - (*iter)->AddFlags(FCVAR_GAMEDLL); - } -} - -void SMConVarAccessor::UnregisterGameDLLCommands() -{ - ConCommandBase *begin = icvar->GetCommands(); - ConCommandBase *iter = begin; - ConCommandBase *prev = NULL; - while (iter) - { - /* Watch out for the ETERNAL COMMAND! */ - if (iter != &s_EternalCommand && iter->IsBitSet(FCVAR_GAMEDLL)) - { - /* Remove it! */ - if (iter == begin) - { - s_EternalCommand.BringToFront(); - iter = const_cast(iter->GetNext()); - s_EternalCommand.SetNext(iter); - prev = &s_EternalCommand; - continue; - } - else - { - iter = const_cast(iter->GetNext()); - prev->SetNext(iter); - continue; - } - } - prev = iter; - iter = const_cast(iter->GetNext()); - } -} - -void SMConVarAccessor::Unregister(ConCommandBase *pCommand) -{ - ConCommandBase *ptr = icvar->GetCommands(); - - if (ptr == pCommand) - { - s_EternalCommand.BringToFront(); - s_EternalCommand.SetNext(const_cast(pCommand->GetNext())); - } - else - { - /* Find us and unregister us */ - ConCommandBase *pPrev = NULL; - while (ptr) - { - if (ptr == pCommand) - { - break; - } - pPrev = ptr; - ptr = const_cast(ptr->GetNext()); - } - if (pPrev && ptr == pCommand) - { - pPrev->SetNext(const_cast(pCommand->GetNext())); - } - } -} - diff --git a/sourcemm/episode1/console.h b/sourcemm/episode1/console.h deleted file mode 100644 index a446be6..0000000 --- a/sourcemm/episode1/console.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_CONSOLE_MMS_H_ -#define _INCLUDE_CONSOLE_MMS_H_ - -#include -#include -#include "convar_smm.h" -#include - -class SMConVarAccessor : public IConCommandBaseAccessor -{ -public: - bool RegisterConCommandBase(ConCommandBase *pCommand); - bool Register(ConCommandBase *pCommand); - void MarkCommandsAsGameDLL(); - void Unregister(ConCommandBase *pCommand); - void UnregisterGameDLLCommands(); -private: - SourceHook::List m_RegisteredCommands; -}; - -extern SMConVarAccessor g_SMConVarAccessor; - -#endif //_INCLUDE_CONSOLE_MMS_H_ - diff --git a/sourcemm/episode1/convar_smm.h b/sourcemm/episode1/convar_smm.h deleted file mode 100644 index 8e5dd82..0000000 --- a/sourcemm/episode1/convar_smm.h +++ /dev/null @@ -1,523 +0,0 @@ -//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $Workfile: $ -// $Date: 2007-02-08 04:19:19 -0500 (Thu, 08 Feb 2007) $ -// -//----------------------------------------------------------------------------- -// $NoKeywords: $ -//=============================================================================// - -#ifndef CONVAR_H -#define CONVAR_H -#if _WIN32 -#pragma once -#endif - -#include "tier0/dbg.h" - -#ifdef _WIN32 -#define FORCEINLINE_CVAR FORCEINLINE -#elif _LINUX -#define FORCEINLINE_CVAR __inline__ FORCEINLINE -#else -#error "implement me" -#endif - -// The default, no flags at all -#define FCVAR_NONE 0 - -// Command to ConVars and ConCommands -// ConVar Systems -#define FCVAR_UNREGISTERED (1<<0) // If this is set, don't add to linked list, etc. -#define FCVAR_LAUNCHER (1<<1) // defined by launcher -#define FCVAR_GAMEDLL (1<<2) // defined by the game DLL -#define FCVAR_CLIENTDLL (1<<3) // defined by the client DLL -#define FCVAR_MATERIAL_SYSTEM (1<<4) // Defined by the material system. -#define FCVAR_DATACACHE (1<<19) // Defined by the datacache system. -#define FCVAR_STUDIORENDER (1<<15) // Defined by the studiorender system. -#define FCVAR_FILESYSTEM (1<<21) // Defined by the file system. -#define FCVAR_PLUGIN (1<<18) // Defined by a 3rd party plugin. -#define FCVAR_TOOLSYSTEM (1<<20) // Defined by an IToolSystem library -#define FCVAR_SOUNDSYSTEM (1<<23) // Defined by the soundsystem library -#define FCVAR_INPUTSYSTEM (1<<25) // Defined by the inputsystem dll -#define FCVAR_NETWORKSYSTEM (1<<26) // Defined by the network system -// NOTE!! if you add a cvar system, add it here too!!!! -// the engine lacks a cvar flag, but needs it for xbox -// an engine cvar is thus a cvar not marked with any other system -#define FCVAR_NON_ENGINE ((FCVAR_LAUNCHER|FCVAR_GAMEDLL|FCVAR_CLIENTDLL|FCVAR_MATERIAL_SYSTEM|FCVAR_DATACACHE|FCVAR_STUDIORENDER|FCVAR_FILESYSTEM|FCVAR_PLUGIN|FCVAR_TOOLSYSTEM|FCVAR_SOUNDSYSTEM|FCVAR_INPUTSYSTEM|FCVAR_NETWORKSYSTEM)) - -// ConVar only -#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value -#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server. -#define FCVAR_ARCHIVE (1<<7) // set to cause it to be saved to vars.rc -#define FCVAR_NOTIFY (1<<8) // notifies players when changed -#define FCVAR_USERINFO (1<<9) // changes the client's info string -#define FCVAR_CHEAT (1<<14) // Only useable in singleplayer / debug / multiplayer & sv_cheats - -#define FCVAR_PRINTABLEONLY (1<<10) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ). -#define FCVAR_UNLOGGED (1<<11) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log -#define FCVAR_NEVER_AS_STRING (1<<12) // never try to print that cvar - -// It's a ConVar that's shared between the client and the server. -// At signon, the values of all such ConVars are sent from the server to the client (skipped for local -// client, of course ) -// If a change is requested it must come from the console (i.e., no remote client changes) -// If a value is changed while a server is active, it's replicated to all connected clients -#define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time -#define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file -#define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles - -#define FCVAR_NOT_CONNECTED (1<<22) // cvar cannot be changed by a client that is connected to a server - -#define FCVAR_ARCHIVE_XBOX (1<<24) // cvar written to config.cfg on the Xbox - - -// #define FCVAR_AVAILABLE (1<<27) -// #define FCVAR_AVAILABLE (1<<28) -// #define FCVAR_AVAILABLE (1<<29) -// #define FCVAR_AVAILABLE (1<<30) -// #define FCVAR_AVAILABLE (1<<31) - - -class ConVar; -class ConCommand; -class ConCommandBase; - -// Any executable that wants to use ConVars need to implement one of -// these to hook up access to console variables. -class IConCommandBaseAccessor -{ -public: - // Flags is a combination of FCVAR flags in cvar.h. - // hOut is filled in with a handle to the variable. - virtual bool RegisterConCommandBase( ConCommandBase *pVar )=0; -}; - - -// You don't have to instantiate one of these, just call its -// OneTimeInit function when your executable is initializing. -class ConCommandBaseMgr -{ -public: - // Call this ONCE when the executable starts up. - static void OneTimeInit( IConCommandBaseAccessor *pAccessor ); -#ifdef _XBOX - static bool Fixup( ConCommandBase* pConCommandBase ); -#ifndef _RETAIL - static void PublishCommands( bool bForce ); -#endif -#endif -}; - -// Called when a ConVar changes value -typedef void ( *FnChangeCallback )( ConVar *var, char const *pOldString ); - -// Called when a ConCommand needs to execute -typedef void ( *FnCommandCallback )( void ); - -#define COMMAND_COMPLETION_MAXITEMS 64 -#define COMMAND_COMPLETION_ITEM_LENGTH 64 - -// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings -typedef int ( *FnCommandCompletionCallback )( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] ); - -//----------------------------------------------------------------------------- -// Purpose: The base console invoked command/cvar interface -//----------------------------------------------------------------------------- -class ConCommandBase -{ - friend class ConCommandBaseMgr; - friend class CCvar; - friend class ConVar; - friend class ConCommand; - -public: - ConCommandBase( void ); - ConCommandBase( char const *pName, char const *pHelpString = 0, - int flags = 0 ); - - virtual ~ConCommandBase( void ); - - virtual bool IsCommand( void ) const; - - // Check flag - virtual bool IsBitSet( int flag ) const; - // Set flag - virtual void AddFlags( int flags ); - - // Return name of cvar - virtual char const *GetName( void ) const; - - // Return help text for cvar - virtual char const *GetHelpText( void ) const; - - // Deal with next pointer - const ConCommandBase *GetNext( void ) const; - void SetNext( ConCommandBase *next ); - - virtual bool IsRegistered( void ) const; - - // Global methods - static ConCommandBase const *GetCommands( void ); - static void AddToList( ConCommandBase *var ); - static void RemoveFlaggedCommands( int flag ); - static void RevertFlaggedCvars( int flag ); - static ConCommandBase const *FindCommand( char const *name ); - -protected: - virtual void Create( char const *pName, char const *pHelpString = 0, - int flags = 0 ); - - // Used internally by OneTimeInit to initialize. - virtual void Init(); - - // Internal copy routine ( uses new operator from correct module ) - char *CopyString( char const *from ); - - // Next ConVar in chain - ConCommandBase *m_pNext; - -private: - // Has the cvar been added to the global list? - bool m_bRegistered; - - // Static data - char const *m_pszName; - char const *m_pszHelpString; - - // ConVar flags - int m_nFlags; - -protected: - - // ConVars add themselves to this list for the executable. Then ConVarMgr::Init() runs through - // all the console variables and registers them. - static ConCommandBase *s_pConCommandBases; - - // ConVars in this executable use this 'global' to access values. - static IConCommandBaseAccessor *s_pAccessor; -}; - -//----------------------------------------------------------------------------- -// Purpose: The console invoked command -//----------------------------------------------------------------------------- -class ConCommand : public ConCommandBase -{ -friend class ConCommandBaseMgr; -friend class CCvar; -#ifdef _STATIC_LINKED -friend class G_ConCommand; -friend class C_ConCommand; -friend class M_ConCommand; -friend class S_ConCommand; -friend class D_ConCommand; -#endif - -public: - typedef ConCommandBase BaseClass; - - ConCommand( void ); - ConCommand( char const *pName, FnCommandCallback callback, - char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - - virtual ~ConCommand( void ); - - virtual bool IsCommand( void ) const; - - virtual int AutoCompleteSuggest( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] ); - - virtual bool CanAutoComplete( void ); - - // Invoke the function - virtual void Dispatch( void ); -private: - virtual void Create( char const *pName, FnCommandCallback callback, - char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ); - - // Call this function when executing the command - FnCommandCallback m_fnCommandCallback; - - FnCommandCompletionCallback m_fnCompletionCallback; - bool m_bHasCompletionCallback; -public: - FnCommandCallback GetCallback() { return m_fnCommandCallback; } -}; - -//----------------------------------------------------------------------------- -// Purpose: A console variable -//----------------------------------------------------------------------------- -class ConVar : public ConCommandBase -{ -friend class ConCommandBaseMgr; -friend class CCvar; -friend class CDefaultCvar; -#ifdef _STATIC_LINKED -friend class G_ConVar; -friend class C_ConVar; -friend class M_ConVar; -friend class S_ConVar; -friend class D_ConVar; -#endif - -public: - typedef ConCommandBase BaseClass; - - ConVar( char const *pName, char const *pDefaultValue, int flags = 0); - - ConVar( char const *pName, char const *pDefaultValue, int flags, - char const *pHelpString ); - ConVar( char const *pName, char const *pDefaultValue, int flags, - char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ); - ConVar( char const *pName, char const *pDefaultValue, int flags, - char const *pHelpString, FnChangeCallback callback ); - ConVar( char const *pName, char const *pDefaultValue, int flags, - char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, - FnChangeCallback callback ); - - virtual ~ConVar( void ); - - virtual bool IsBitSet( int flag ) const; - virtual char const* GetHelpText( void ) const; - virtual bool IsRegistered( void ) const; - virtual char const *GetName( void ) const; - virtual void AddFlags( int flags ); - virtual bool IsCommand( void ) const; - - // Install a change callback (there shouldn't already be one....) - void InstallChangeCallback( FnChangeCallback callback ); - - // Retrieve value - FORCEINLINE_CVAR float GetFloat( void ) const; - FORCEINLINE_CVAR int GetInt( void ) const; - FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); } - FORCEINLINE_CVAR char const *GetString( void ) const; - - // Any function that allocates/frees memory needs to be virtual or else you'll have crashes - // from alloc/free across dll/exe boundaries. - - // These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue). - virtual void SetValue( char const *value ); - virtual void SetValue( float value ); - virtual void SetValue( int value ); - - // Reset to default value - void Revert( void ); - - // True if it has a min/max setting - bool GetMin( float& minVal ) const; - bool GetMax( float& maxVal ) const; - char const *GetDefault( void ) const; - - static void RevertAll( void ); -private: - // Called by CCvar when the value of a var is changing. - virtual void InternalSetValue(char const *value); - // For CVARs marked FCVAR_NEVER_AS_STRING - virtual void InternalSetFloatValue( float fNewValue ); - virtual void InternalSetIntValue( int nValue ); - - virtual bool ClampValue( float& value ); - virtual void ChangeStringValue( char const *tempVal ); - - virtual void Create( char const *pName, char const *pDefaultValue, int flags = 0, - char const *pHelpString = 0, bool bMin = false, float fMin = 0.0, - bool bMax = false, float fMax = false, FnChangeCallback callback = 0 ); - - // Used internally by OneTimeInit to initialize. - virtual void Init(); - -private: - - // This either points to "this" or it points to the original declaration of a ConVar. - // This allows ConVars to exist in separate modules, and they all use the first one to be declared. - // m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar). - ConVar *m_pParent; - - // Static data - char const *m_pszDefaultValue; - - // Value - // Dynamically allocated - char *m_pszString; - int m_StringLength; - - // Values - float m_fValue; - int m_nValue; - - // Min/Max values - bool m_bHasMin; - float m_fMinVal; - bool m_bHasMax; - float m_fMaxVal; - - // Call this function when ConVar changes - FnChangeCallback m_fnChangeCallback; -}; - - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a float -// Output : float -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR float ConVar::GetFloat( void ) const -{ - return m_pParent->m_fValue; -} - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as an int -// Output : int -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR int ConVar::GetInt( void ) const -{ - return m_pParent->m_nValue; -} - - -//----------------------------------------------------------------------------- -// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc. -// Output : char const * -//----------------------------------------------------------------------------- -FORCEINLINE_CVAR char const *ConVar::GetString( void ) const -{ - if ( m_nFlags & FCVAR_NEVER_AS_STRING ) - { - return "FCVAR_NEVER_AS_STRING"; - } - - return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : ""; -} - - -#ifdef _STATIC_LINKED -// identifies subsystem via piggybacking constructors with flags -class G_ConCommand : public ConCommand -{ -public: - G_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_GAMEDLL, completionFunc) {} -}; - -class C_ConCommand : public ConCommand -{ -public: - C_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_CLIENTDLL, completionFunc) {} -}; - -class M_ConCommand : public ConCommand -{ -public: - M_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_MATERIAL_SYSTEM, completionFunc) {} -}; - -class S_ConCommand : public ConCommand -{ -public: - S_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_STUDIORENDER, completionFunc) {} -}; - -class D_ConCommand : public ConCommand -{ -public: - D_ConCommand(char const *pName, FnCommandCallback callback, char const *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 ) : ConCommand(pName, callback, pHelpString, flags|FCVAR_DATACACHE, completionFunc) {} -}; - -typedef void ( *G_FnChangeCallback )( G_ConVar *var, char const *pOldString ); -typedef void ( *C_FnChangeCallback )( C_ConVar *var, char const *pOldString ); -typedef void ( *M_FnChangeCallback )( M_ConVar *var, char const *pOldString ); -typedef void ( *S_FnChangeCallback )( S_ConVar *var, char const *pOldString ); -typedef void ( *D_FnChangeCallback )( D_ConVar *var, char const *pOldString ); - -class G_ConVar : public ConVar -{ -public: - G_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL) {} - G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString ) {} - G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, bMin, fMin, bMax, fMax) {} - G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, G_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, (FnChangeCallback)callback ) {} - G_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, G_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_GAMEDLL, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} -}; - -class C_ConVar : public ConVar -{ -public: - C_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL) {} - C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString ) {} - C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, bMin, fMin, bMax, fMax) {} - C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, C_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, (FnChangeCallback)callback ) {} - C_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, C_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_CLIENTDLL, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} -}; - -class M_ConVar : public ConVar -{ -public: - M_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM) {} - M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString ) {} - M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, bMin, fMin, bMax, fMax) {} - M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, (FnChangeCallback)callback ) {} - M_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_MATERIAL_SYSTEM, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} -}; - -class S_ConVar : public ConVar -{ -public: - S_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER) {} - S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString ) {} - S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, bMin, fMin, bMax, fMax) {} - S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, (FnChangeCallback)callback ) {} - S_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, S_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_STUDIORENDER, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} -}; - -class D_ConVar : public ConVar -{ -public: - D_ConVar( char const *pName, char const *pDefaultValue, int flags = 0) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE) {} - D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString ) {} - D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, bMin, fMin, bMax, fMax) {} - D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, M_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, (FnChangeCallback)callback ) {} - D_ConVar( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax, D_FnChangeCallback callback ) : ConVar(pName, pDefaultValue, flags|FCVAR_DATACACHE, pHelpString, bMin, fMin, bMax, fMax, (FnChangeCallback)callback ) {} -}; - -// redirect these declarations to their specific subsystem -#ifdef GAME_DLL -#define ConCommand G_ConCommand -#define ConVar G_ConVar -#endif -#ifdef CLIENT_DLL -#define ConCommand C_ConCommand -#define ConVar C_ConVar -#endif -#ifdef MATERIALSYSTEM_DLL -#define ConCommand M_ConCommand -#define ConVar M_ConVar -#endif -#ifdef STUDIORENDER_DLL -#define ConCommand S_ConCommand -#define ConVar S_ConVar -#endif -#ifdef DATACACHE_DLL -#define ConCommand D_ConCommand -#define ConVar D_ConVar -#endif -#endif // _STATIC_LINKED - -//----------------------------------------------------------------------------- -// Purpose: Utility to quicky generate a simple console command -//----------------------------------------------------------------------------- -#define CON_COMMAND( name, description ) \ - static void name(); \ - static ConCommand name##_command( #name, name, description ); \ - static void name() - -//----------------------------------------------------------------------------- -// Purpose: Utility to quicky generate a simple console command -//----------------------------------------------------------------------------- -#define CON_COMMAND_F( name, description, flags ) \ - static void name(); \ - static ConCommand name##_command( #name, name, description, flags ); \ - static void name() - - -#endif // CONVAR_H diff --git a/sourcemm/episode1/msvc8/sourcemm.sln b/sourcemm/episode1/msvc8/sourcemm.sln deleted file mode 100644 index b338452..0000000 --- a/sourcemm/episode1/msvc8/sourcemm.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sourcemm", "sourcemm.vcproj", "{F7D47743-73B3-49B5-9D76-2333C5DFD565}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Debug|Win32.ActiveCfg = Debug|Win32 - {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Debug|Win32.Build.0 = Debug|Win32 - {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Release|Win32.ActiveCfg = Release|Win32 - {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/sourcemm/episode1/msvc8/sourcemm.vcproj b/sourcemm/episode1/msvc8/sourcemm.vcproj deleted file mode 100644 index 48d4c33..0000000 --- a/sourcemm/episode1/msvc8/sourcemm.vcproj +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sourcemm/episode1/provider_ep1.cpp b/sourcemm/episode1/provider_ep1.cpp deleted file mode 100644 index 81a8825..0000000 --- a/sourcemm/episode1/provider_ep1.cpp +++ /dev/null @@ -1,602 +0,0 @@ - -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#include -#include "convar_smm.h" -#include -#include -#include -#include -#include -#include "../metamod_util.h" -#include "provider_ep1.h" -#include "console.h" -#include "metamod_console.h" -#include "vsp_listener.h" - -/* Types */ -typedef void (*CONPRINTF_FUNC)(const char *, ...); -struct UsrMsgInfo -{ - int size; - String name; -}; -/* Imports */ -#undef CommandLine -DLL_IMPORT ICommandLine *CommandLine(); -/* Functions */ -CONPRINTF_FUNC ExtractRemotePrinter(); -bool CacheUserMessages(); -void ClientCommand(edict_t *pEdict); -void _ServerCommand(); -/* Variables */ -bool usermsgs_extracted = false; -CVector usermsgs_list; -CONPRINTF_FUNC echo_msg_func = NULL; -ICvar *icvar = NULL; -ISmmAPI *metamod_api = NULL; -IVEngineServer *engine = NULL; -IServerGameClients *gameclients = NULL; -VSPListener g_VspListener; -BaseProvider g_Ep1Provider; -IMetamodSourceProvider *provider = &g_Ep1Provider; - -SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *); - -void BaseProvider::ConsolePrint(const char *str) -{ - if (echo_msg_func != NULL) - { - echo_msg_func("%s", str); - } - else - { - Msg("%s", str); - } -} - -void BaseProvider::Notify_DLLInit_Pre(void *gamedll, - CreateInterfaceFn engineFactory, - CreateInterfaceFn serverFactory) -{ - server = (IServerGameDLL *)gamedll; - engine = (IVEngineServer *)((engineFactory)(INTERFACEVERSION_VENGINESERVER, NULL)); - if (!engine) - { - Error("Could not find IVEngineServer! Metamod cannot load."); - return; - } - icvar = (ICvar *)((engineFactory)(VENGINE_CVAR_INTERFACE_VERSION, NULL)); - if (!icvar) - { - Error("Could not find ICvar! Metamod cannot load."); - return; - } - - if ((gameclients = (IServerGameClients *)(serverFactory("ServerGameClients003", NULL))) - == NULL) - { - gameclients = (IServerGameClients *)(serverFactory("ServerGameClients004", NULL)); - } - - echo_msg_func = ExtractRemotePrinter(); - usermsgs_extracted = CacheUserMessages(); - - if (gameclients) - { - SH_ADD_HOOK_STATICFUNC(IServerGameClients, ClientCommand, gameclients, ClientCommand, false); - } - - ConCommandBaseMgr::OneTimeInit(&g_SMConVarAccessor); -} - -void BaseProvider::Notify_DLLShutdown_Pre() -{ - g_SMConVarAccessor.MarkCommandsAsGameDLL(); - g_SMConVarAccessor.UnregisterGameDLLCommands(); -} - -bool BaseProvider::IsRemotePrintingAvailable() -{ - return (echo_msg_func != NULL); -} - -void BaseProvider::ClientConsolePrint(edict_t *client, const char *message) -{ - engine->ClientPrintf(client, message); -} - -void BaseProvider::ServerCommand(const char *cmd) -{ - engine->ServerCommand(cmd); -} - -const char *BaseProvider::GetConVarString(ConVar *convar) -{ - return convar->GetString(); -} - -bool BaseProvider::IsConCommandBaseACommand(ConCommandBase *pCommand) -{ - return pCommand->IsCommand(); -} - - -bool BaseProvider::IsSourceEngineBuildCompatible(int build) -{ - return (build == SOURCE_ENGINE_ORIGINAL - || build == SOURCE_ENGINE_EPISODEONE); -} - -const char *BaseProvider::GetCommandLineValue(const char *key, const char *defval) -{ - if (key[0] == '-' || key[0] == '+') - { - return CommandLine()->ParmValue(key, defval); - } - else - { - const char *val; - if ((val = icvar->GetCommandLineValue(key)) == NULL) - { - return defval; - } - - return val; - } -} - -int BaseProvider::TryServerGameDLL(const char *iface) -{ - if (strncmp(iface, "ServerGameDLL", 13) != 0) - { - return 0; - } - - return atoi(&iface[13]); -} - -bool BaseProvider::LogMessage(const char *buffer) -{ - if (!engine) - { - return false; - } - - engine->LogPrint(buffer); - - return true; -} - -bool BaseProvider::GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInfo) -{ - SourceHook::MemFuncInfo mfi = {true, -1, 0, 0}; - - if (hook == ProvidedHook_LevelInit) - { - SourceHook::GetFuncInfo(&IServerGameDLL::LevelInit, mfi); - } - else if (hook == ProvidedHook_LevelShutdown) - { - SourceHook::GetFuncInfo(&IServerGameDLL::LevelShutdown, mfi); - } - else if (hook == ProvidedHook_GameInit) - { - SourceHook::GetFuncInfo(&IServerGameDLL::GameInit, mfi); - } - else if (hook == ProvidedHook_DLLShutdown) - { - SourceHook::GetFuncInfo(&IServerGameDLL::DLLShutdown, mfi); - } - else if (hook == ProvidedHook_DLLInit) - { - SourceHook::GetFuncInfo(&IServerGameDLL::DLLInit, mfi); - } - - *pInfo = mfi; - - return (mfi.thisptroffs >= 0); -} - -void BaseProvider::DisplayError(const char *fmt, ...) -{ - va_list ap; - char buffer[2048]; - - va_start(ap, fmt); - UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); - va_end(ap); - - Error(buffer); -} - -void BaseProvider::DisplayWarning(const char *fmt, ...) -{ - va_list ap; - char buffer[2048]; - - va_start(ap, fmt); - UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); - va_end(ap); - - Warning(buffer); -} - -IConCommandBaseAccessor *BaseProvider::GetConCommandBaseAccessor() -{ - return &g_SMConVarAccessor; -} - -bool BaseProvider::RegisterConCommandBase(ConCommandBase *pCommand) -{ - return g_SMConVarAccessor.Register(pCommand); -} - -void BaseProvider::UnregisterConCommandBase(ConCommandBase *pCommand) -{ - return g_SMConVarAccessor.Unregister(pCommand); -} - -int BaseProvider::GetUserMessageCount() -{ - if (!usermsgs_extracted) - { - return -1; - } - - return (int)usermsgs_list.size(); -} - -int BaseProvider::FindUserMessage(const char *name, int *size) -{ - for (size_t i = 0; i < usermsgs_list.size(); i++) - { - if (usermsgs_list[i].name.compare(name) == 0) - { - if (size) - { - *size = usermsgs_list[i].size; - } - return (int)i; - } - } - - return -1; -} - -const char *BaseProvider::GetUserMessage(int index, int *size) -{ - if (!usermsgs_extracted || index < 0 || index >= (int)usermsgs_list.size()) - { - return NULL; - } - - if (size) - { - *size = usermsgs_list[index].size; - } - - return usermsgs_list[index].name.c_str(); -} - -const char *BaseProvider::GetGameDescription() -{ - return server->GetGameDescription(); -} - -int BaseProvider::DetermineSourceEngine(const char *game) -{ - if (strcmp(game, "ship") == 0) - { - return SOURCE_ENGINE_ORIGINAL; - } - else - { - return SOURCE_ENGINE_EPISODEONE; - } -} - -ConVar *BaseProvider::CreateConVar(const char *name, - const char *defval, - const char *help, - int flags) -{ - int newflags = 0; - if (flags & ConVarFlag_Notify) - { - newflags |= FCVAR_NOTIFY; - } - if (flags & ConVarFlag_Replicated) - { - newflags |= FCVAR_REPLICATED; - } - if (flags & ConVarFlag_SpOnly) - { - newflags |= FCVAR_SPONLY; - } - - return new ConVar(name, defval, newflags, help); -} - -IServerPluginCallbacks *BaseProvider::GetVSPCallbacks(const char *iface) -{ - g_VspListener.SetLoadable(true); - return &g_VspListener; -} - -class GlobCommand : public IMetamodSourceCommandInfo -{ -public: - unsigned int GetArgCount() - { - return engine->Cmd_Argc() - 1; - } - - const char *GetArg(unsigned int num) - { - return engine->Cmd_Argv(num); - } - - const char *GetArgString() - { - return engine->Cmd_Args(); - } -}; - -CON_COMMAND(meta, "Metamod:Source control commands") -{ - GlobCommand cmd; - Command_Meta(&cmd); -} - -void ClientCommand(edict_t *pEdict) -{ - GlobCommand cmd; - - if (strcmp(cmd.GetArg(0), "meta") == 0) - { - Command_ClientMeta(pEdict, &cmd); - } -} - -////////////////////////////////////////////////////////////////////////// -//THERE BE HAX HERE!!!! DON'T TELL ALFRED, BUT GABE WANTED IT THAT WAY. // -// (note: you can find the offset by looking for the text // -// "Echo text to console", you'll find the callback cmd pushed on the // -// stack.) // -////////////////////////////////////////////////////////////////////////// - -#define SIGLEN 8 -#define ENGINE486_SIG "\x55\x89\xE5\x53\x83\xEC\x14\xBB" -#define ENGINE486_OFFS 40 -#define ENGINE686_SIG "\x53\x83\xEC\x08\xBB\x01\x00\x00" -#define ENGINE686_OFFS 50 -#define ENGINEAMD_SIG "\x53\x51\xBB\x01\x00\x00\x00\x51" -#define ENGINEAMD_OFFS 47 -#define ENGINEW32_SIG "\xA1\x2A\x2A\x2A\x2A\x56\xBE\x01" -#define ENGINEW32_OFFS 38 -#define IA32_CALL 0xE8 - -bool vcmp(const void *_addr1, const void *_addr2, size_t len) -{ - unsigned char *addr1 = (unsigned char *)_addr1; - unsigned char *addr2 = (unsigned char *)_addr2; - - for (size_t i=0; iGetCommands(); - unsigned char *ptr = NULL; - FnCommandCallback callback = NULL; - int offs = 0; - - while (pBase) - { - if (strcmp(pBase->GetName(), "echo") == 0) - { - callback = ((ConCommand *)pBase)->GetCallback(); - ptr = (unsigned char *)callback; -#ifdef OS_LINUX - if (vcmp(ptr, ENGINE486_SIG, SIGLEN)) - { - offs = ENGINE486_OFFS; - } - else if (vcmp(ptr, ENGINE686_SIG, SIGLEN)) - { - offs = ENGINE686_OFFS; - } - else if (vcmp(ptr, ENGINEAMD_SIG, SIGLEN)) - { - offs = ENGINEAMD_OFFS; - } -#elif defined OS_WIN32 // Only one Windows engine binary so far... - if (vcmp(ptr, ENGINEW32_SIG, SIGLEN)) - { - offs = ENGINEW32_OFFS; - } -#endif - - if (!offs || ptr[offs - 1] != IA32_CALL) - { - return NULL; - } - //get the relative offset - void *addr = *((void **)(ptr + offs)); - //add the base offset, to the ip (which is the address+offset + 4 bytes for next instruction) - return (CONPRINTF_FUNC)((unsigned long)addr + (unsigned long)(ptr + offs) + 4); - } - pBase = const_cast(pBase->GetNext()); - } - - return NULL; -} - -////////////////////////////////////////////////////////////////////// -// EVEN MORE HACKS HERE! YOU HAVE BEEN WARNED! // -// Signatures necessary in finding the pointer to the CUtlDict that // -// stores user message information. // -// IServerGameDLL::GetUserMessageInfo() normally crashes with bad // -// message indices. This is our answer to it. Yuck! <:-( // -////////////////////////////////////////////////////////////////////// -#ifdef OS_WIN32 - /* General Windows sig */ - #define MSGCLASS_SIGLEN 7 - #define MSGCLASS_SIG "\x8B\x0D\x2A\x2A\x2A\x2A\x56" - #define MSGCLASS_OFFS 2 - - /* Dystopia Wimdows hack */ - #define MSGCLASS2_SIGLEN 16 - #define MSGCLASS2_SIG "\x56\x8B\x74\x24\x2A\x85\xF6\x7C\x2A\x3B\x35\x2A\x2A\x2A\x2A\x7D" - #define MSGCLASS2_OFFS 11 - - /* Windows frame pointer sig */ - #define MSGCLASS3_SIGLEN 18 - #define MSGCLASS3_SIG "\x55\x8B\xEC\x51\x89\x2A\x2A\x8B\x2A\x2A\x50\x8B\x0D\x2A\x2A\x2A\x2A\xE8" - #define MSGCLASS3_OFFS 13 -#elif defined OS_LINUX - /* No frame pointer sig */ - #define MSGCLASS_SIGLEN 14 - #define MSGCLASS_SIG "\x53\x83\xEC\x2A\x8B\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x89" - #define MSGCLASS_OFFS 9 - - /* Frame pointer sig */ - #define MSGCLASS2_SIGLEN 16 - #define MSGCLASS2_SIG "\x55\x89\xE5\x53\x83\xEC\x2A\x8B\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x89" - #define MSGCLASS2_OFFS 11 -#endif - -struct UserMessage -{ - int size; - const char *name; -}; - -typedef CUtlDict UserMsgDict; - -/* This is the ugliest function in all of SourceMM */ -bool CacheUserMessages() -{ - /* Get address of original GetUserMessageInfo() */ - char *vfunc = (char *)SH_GET_ORIG_VFNPTR_ENTRY(server, &IServerGameDLL::GetUserMessageInfo); - - /* Oh dear, we have a relative jump on our hands - * PVK II on Windows made me do this, but I suppose it doesn't hurt to check this on Linux too... - */ - if (*vfunc == '\xE9') - { - /* Get address from displacement... - * - * Add 5 because it's relative to next instruction: - * Opcode <1 byte> + 32-bit displacement <4 bytes> - */ - vfunc += *reinterpret_cast(vfunc + 1) + 5; - } - - CUtlDict *dict = NULL; - - if (vcmp(vfunc, MSGCLASS_SIG, MSGCLASS_SIGLEN)) - { - /* Get address of CUserMessages instance */ - char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS_OFFS); - - /* Get address of CUserMessages::m_UserMessages */ - dict = reinterpret_cast(*userMsgClass); - } - else if (vcmp(vfunc, MSGCLASS2_SIG, MSGCLASS2_SIGLEN)) - { - #ifdef OS_WIN32 - /* If we get here, the code is possibly inlined like in Dystopia */ - - /* Get the address of the CUtlRBTree */ - char *rbtree = *reinterpret_cast(vfunc + MSGCLASS2_OFFS); - - /* CUtlDict should be 8 bytes before the CUtlRBTree (hacktacular!) */ - dict = reinterpret_cast(rbtree - 8); - #elif defined OS_LINUX - /* Get address of CUserMessages instance */ - char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS2_OFFS); - - /* Get address of CUserMessages::m_UserMessages */ - dict = reinterpret_cast(*userMsgClass); - #endif - #ifdef OS_WIN32 - } - else if (vcmp(vfunc, MSGCLASS3_SIG, MSGCLASS3_SIGLEN)) - { - /* Get address of CUserMessages instance */ - char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS3_OFFS); - - /* Get address of CUserMessages::m_UserMessages */ - dict = reinterpret_cast(*userMsgClass); - #endif - } - - if (dict) - { - int msg_count = dict->Count(); - - /* Ensure that count is within bounds of an unsigned byte, because that's what engine supports */ - if (msg_count < 0 || msg_count > 255) - { - return false; - } - - UserMessage *msg; - UsrMsgInfo u_msg; - - /* Cache messages in our CUtlDict */ - for (int i = 0; i < msg_count; i++) - { - msg = dict->Element(i); - u_msg.name = msg->name; - u_msg.size = msg->size; - usermsgs_list.push_back(u_msg); - } - - return true; - } - - return false; -} - diff --git a/sourcemm/episode1/provider_ep1.h b/sourcemm/episode1/provider_ep1.h deleted file mode 100644 index 3400571..0000000 --- a/sourcemm/episode1/provider_ep1.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ -#define _INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ - -#include -#include -#include -#include "ISmmAPI.h" -#include "metamod_provider.h" -#include "metamod_oslink.h" - -using namespace SourceMM; -using namespace SourceHook; - -class BaseProvider : public IMetamodSourceProvider -{ -public: - virtual bool IsSourceEngineBuildCompatible(int build); - virtual bool GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInfo); - virtual bool LogMessage(const char *buffer); - virtual const char *GetCommandLineValue(const char *key, const char *defval); - virtual void ConsolePrint(const char *msg); - virtual bool IsRemotePrintingAvailable(); - virtual void ClientConsolePrint(edict_t *client, const char *msg); - virtual IServerPluginCallbacks *GetVSPCallbacks(const char *iface); - virtual void DisplayError(const char *fmt, ...); - virtual void DisplayWarning(const char *fmt, ...); - virtual int TryServerGameDLL(const char *iface); - virtual void Notify_DLLInit_Pre(void *gamedll, - CreateInterfaceFn engineFactory, - CreateInterfaceFn serverFactory); - void Notify_DLLShutdown_Pre(); - virtual void ServerCommand(const char *cmd); - virtual ConVar *CreateConVar(const char *name, - const char *defval, - const char *help, - int flags); - virtual const char *GetConVarString(ConVar *convar); - virtual const char *GetGameDescription(); - virtual IConCommandBaseAccessor *GetConCommandBaseAccessor(); - virtual bool RegisterConCommandBase(ConCommandBase *pCommand); - virtual void UnregisterConCommandBase(ConCommandBase *pCommand); - virtual bool IsConCommandBaseACommand(ConCommandBase *pCommand); - virtual int GetUserMessageCount(); - virtual int FindUserMessage(const char *name, int *size=NULL); - virtual const char *GetUserMessage(int index, int *size=NULL); - virtual int DetermineSourceEngine(const char *game); -}; - -extern IVEngineServer *engine; -extern IServerGameDLL *server; -extern IServerGameClients *gameclients; -extern ICvar *icvar; - -#endif //_INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ - diff --git a/sourcemm/episode1/vsp_listener.cpp b/sourcemm/episode1/vsp_listener.cpp deleted file mode 100644 index 370a66d..0000000 --- a/sourcemm/episode1/vsp_listener.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#include "vsp_listener.h" -#include "svn_version.h" -#include "metamod.h" - -using namespace SourceMM; - -VSPListener::VSPListener() -{ - m_bLoaded = false; - m_bLoadable = false; -} - -void VSPListener::ClientActive(edict_t *pEntity) -{ -} - -PLUGIN_RESULT VSPListener::ClientCommand(edict_t *pEntity) -{ - return PLUGIN_CONTINUE; -} - -PLUGIN_RESULT VSPListener::ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) -{ - return PLUGIN_CONTINUE; -} - -void VSPListener::ClientDisconnect(edict_t *pEntity) -{ -} - -void VSPListener::ClientPutInServer(edict_t *pEntity, char const *playername) -{ -} - -void VSPListener::ClientSettingsChanged(edict_t *pEdict) -{ -} - -void VSPListener::SetCommandClient(int index) -{ -} - -void VSPListener::GameFrame(bool simulating) -{ -} - -const char *VSPListener::GetPluginDescription() -{ - return "Metamod:Source Interface v" SVN_FILE_VERSION_STRING; -} - -bool VSPListener::IsLoaded() -{ - return m_bLoaded; -} - -void VSPListener::LevelInit(char const *pMapName) -{ -} - -void VSPListener::LevelShutdown() -{ -} - -PLUGIN_RESULT VSPListener::NetworkIDValidated(const char *pszUserName, const char *pszNetworkID) -{ - return PLUGIN_CONTINUE; -} - -void VSPListener::Pause() -{ -} - -void VSPListener::UnPause() -{ -} - -void VSPListener::ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) -{ -} - -void VSPListener::Unload() -{ -} - -void VSPListener::SetLoadable(bool set) -{ - m_bLoadable = set; -} - -bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) -{ - if (!m_bLoadable) - { - Warning("Do not manually load Metamod:Source as a Valve Server Plugin\n"); - return false; - } - - if (m_bLoaded) - { - return false; - } - - m_bLoaded = true; - SetLoadable(false); - - g_Metamod.NotifyVSPListening(this); - - return true; -} - diff --git a/sourcemm/episode1/vsp_listener.h b/sourcemm/episode1/vsp_listener.h deleted file mode 100644 index 8b5af85..0000000 --- a/sourcemm/episode1/vsp_listener.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ -#define _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ - -#include "iserverplugin.h" - -class VSPListener : public IServerPluginCallbacks -{ -public: - VSPListener(); -public: - virtual bool Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory); - virtual void Unload(); - virtual void Pause(); - virtual void UnPause(); - virtual const char *GetPluginDescription(); - virtual void LevelInit(char const *pMapName); - virtual void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); - virtual void GameFrame(bool simulating); - virtual void LevelShutdown(void); - virtual void ClientActive(edict_t *pEntity); - virtual void ClientDisconnect(edict_t *pEntity); - virtual void ClientPutInServer(edict_t *pEntity, char const *playername); - virtual void SetCommandClient(int index); - virtual void ClientSettingsChanged(edict_t *pEdict); - virtual PLUGIN_RESULT ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen); - virtual PLUGIN_RESULT ClientCommand(edict_t *pEntity); - virtual PLUGIN_RESULT NetworkIDValidated(const char *pszUserName, const char *pszNetworkID); -public: - bool IsLoaded(); - void SetLoadable(bool loadable); -private: - bool m_bLoaded; - bool m_bLoadable; -}; - -#endif //_INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ - diff --git a/sourcemm/episode2/console.cpp b/sourcemm/episode2/console.cpp deleted file mode 100644 index ca0e9db..0000000 --- a/sourcemm/episode2/console.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#include "console.h" -#include "provider_ep2.h" - -using namespace SourceHook; - -SMConVarAccessor g_SMConVarAccessor; - -bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand) -{ - pCommand->SetNext(NULL); - icvar->RegisterConCommand(pCommand); - - return true; -} - -bool SMConVarAccessor::Register(ConCommandBase *pCommand) -{ - pCommand->SetNext(NULL); - icvar->RegisterConCommand(pCommand); - - return true; -} - -void SMConVarAccessor::Unregister(ConCommandBase *pCommand) -{ - icvar->UnregisterConCommand(pCommand); -} - diff --git a/sourcemm/episode2/console.h b/sourcemm/episode2/console.h deleted file mode 100644 index 004cb8f..0000000 --- a/sourcemm/episode2/console.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_CONSOLE_MMS_H_ -#define _INCLUDE_CONSOLE_MMS_H_ - -#if defined _DEBUG -#define DEBUG2 -#undef _DEBUG -#endif -#include -#include -#include "convar.h" -#include -#if defined DEBUG2 -#undef DEBUG2 -#define _DEBUG -#endif - -class SMConVarAccessor : public IConCommandBaseAccessor -{ -public: - bool RegisterConCommandBase(ConCommandBase *pCommand); - bool Register(ConCommandBase *pCommand); - void Unregister(ConCommandBase *pCommand); -}; - -extern SMConVarAccessor g_SMConVarAccessor; - -#endif //_INCLUDE_CONSOLE_MMS_H_ - diff --git a/sourcemm/episode2/msvc8/sourcemm.sln b/sourcemm/episode2/msvc8/sourcemm.sln deleted file mode 100644 index b338452..0000000 --- a/sourcemm/episode2/msvc8/sourcemm.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sourcemm", "sourcemm.vcproj", "{F7D47743-73B3-49B5-9D76-2333C5DFD565}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Debug|Win32.ActiveCfg = Debug|Win32 - {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Debug|Win32.Build.0 = Debug|Win32 - {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Release|Win32.ActiveCfg = Release|Win32 - {F7D47743-73B3-49B5-9D76-2333C5DFD565}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/sourcemm/episode2/msvc8/sourcemm.vcproj b/sourcemm/episode2/msvc8/sourcemm.vcproj deleted file mode 100644 index 0645613..0000000 --- a/sourcemm/episode2/msvc8/sourcemm.vcproj +++ /dev/null @@ -1,338 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sourcemm/episode2/provider_ep2.cpp b/sourcemm/episode2/provider_ep2.cpp deleted file mode 100644 index ce824c7..0000000 --- a/sourcemm/episode2/provider_ep2.cpp +++ /dev/null @@ -1,570 +0,0 @@ - -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#if defined _DEBUG -#define DEBUG2 -#undef _DEBUG -#endif -#include -#include -#include -#include -#include -#include -#include -#include "../metamod_util.h" -#include "provider_ep2.h" -#include "console.h" -#include "metamod_console.h" -#include "vsp_listener.h" -#if defined DEBUG2 -#undef DEBUG2 -#define _DEBUG -#endif - -/* Types */ -typedef void (*CONPRINTF_FUNC)(const char *, ...); -struct UsrMsgInfo -{ - int size; - String name; -}; -/* Imports */ -#undef CommandLine -DLL_IMPORT ICommandLine *CommandLine(); -/* Functions */ -bool CacheUserMessages(); -void ClientCommand(edict_t *pEdict, const CCommand &args); -void LocalCommand_Meta(const CCommand &args); -void _ServerCommand(); -/* Variables */ -bool usermsgs_extracted = false; -CVector usermsgs_list; -ICvar *icvar = NULL; -ISmmAPI *metamod_api = NULL; -IVEngineServer *engine = NULL; -IServerGameClients *gameclients = NULL; -VSPListener g_VspListener; -BaseProvider g_Ep1Provider; -IMetamodSourceProvider *provider = &g_Ep1Provider; -List conbases_unreg; -ConCommand meta_local_cmd("meta", LocalCommand_Meta, "Metamod:Source control options"); - -SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &); - -void BaseProvider::ConsolePrint(const char *str) -{ - ConMsg("%s", str); -} - -void BaseProvider::Notify_DLLInit_Pre(void *gamedll, - CreateInterfaceFn engineFactory, - CreateInterfaceFn serverFactory) -{ - server = (IServerGameDLL *)gamedll; - engine = (IVEngineServer *)((engineFactory)(INTERFACEVERSION_VENGINESERVER, NULL)); - if (!engine) - { - DisplayError("Could not find IVEngineServer! Metamod cannot load."); - return; - } - icvar = (ICvar *)((engineFactory)(CVAR_INTERFACE_VERSION, NULL)); - if (!icvar) - { - DisplayError("Could not find ICvar! Metamod cannot load."); - return; - } - - if ((gameclients = (IServerGameClients *)(serverFactory("ServerGameClients003", NULL))) - == NULL) - { - gameclients = (IServerGameClients *)(serverFactory("ServerGameClients004", NULL)); - } - - RegisterConCommandBase(&meta_local_cmd); - conbases_unreg.push_back(&meta_local_cmd); - - usermsgs_extracted = CacheUserMessages(); - - if (gameclients) - { - SH_ADD_HOOK_STATICFUNC(IServerGameClients, ClientCommand, gameclients, ClientCommand, false); - } -} - -void BaseProvider::Notify_DLLShutdown_Pre() -{ - List::iterator iter; - - for (iter = conbases_unreg.begin(); - iter != conbases_unreg.end(); - iter++) - { - UnregisterConCommandBase((*iter)); - } -} - -bool BaseProvider::IsRemotePrintingAvailable() -{ - return true; -} - -void BaseProvider::ClientConsolePrint(edict_t *client, const char *message) -{ - engine->ClientPrintf(client, message); -} - -void BaseProvider::ServerCommand(const char *cmd) -{ - engine->ServerCommand(cmd); -} - -const char *BaseProvider::GetConVarString(ConVar *convar) -{ - if (convar == NULL) - { - return NULL; - } - - return convar->GetString(); -} - -bool BaseProvider::IsConCommandBaseACommand(ConCommandBase *pCommand) -{ - return pCommand->IsCommand(); -} - - -bool BaseProvider::IsSourceEngineBuildCompatible(int build) -{ - return (build == SOURCE_ENGINE_ORIGINAL - || build == SOURCE_ENGINE_EPISODEONE); -} - -const char *BaseProvider::GetCommandLineValue(const char *key, const char *defval) -{ - if (key[0] == '-' || key[0] == '+') - { - return CommandLine_Tier0()->ParmValue(key, defval); - } - else if (icvar) - { - const char *val; - if ((val = icvar->GetCommandLineValue(key)) == NULL) - { - return defval; - } - - return val; - } - - return NULL; -} - -int BaseProvider::TryServerGameDLL(const char *iface) -{ - if (strncmp(iface, "ServerGameDLL", 13) != 0) - { - return 0; - } - - return atoi(&iface[13]); -} - -bool BaseProvider::LogMessage(const char *buffer) -{ - if (!engine) - { - return false; - } - - engine->LogPrint(buffer); - - return true; -} - -bool BaseProvider::GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInfo) -{ - SourceHook::MemFuncInfo mfi = {true, -1, 0, 0}; - - if (hook == ProvidedHook_LevelInit) - { - SourceHook::GetFuncInfo(&IServerGameDLL::LevelInit, mfi); - } - else if (hook == ProvidedHook_LevelShutdown) - { - SourceHook::GetFuncInfo(&IServerGameDLL::LevelShutdown, mfi); - } - else if (hook == ProvidedHook_GameInit) - { - SourceHook::GetFuncInfo(&IServerGameDLL::GameInit, mfi); - } - else if (hook == ProvidedHook_DLLShutdown) - { - SourceHook::GetFuncInfo(&IServerGameDLL::DLLShutdown, mfi); - } - else if (hook == ProvidedHook_DLLInit) - { - SourceHook::GetFuncInfo(&IServerGameDLL::DLLInit, mfi); - } - - *pInfo = mfi; - - return (mfi.thisptroffs >= 0); -} - -void BaseProvider::DisplayError(const char *fmt, ...) -{ - va_list ap; - char buffer[2048]; - - va_start(ap, fmt); - UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); - va_end(ap); - - Error(buffer); -} - -void BaseProvider::DisplayWarning(const char *fmt, ...) -{ - va_list ap; - char buffer[2048]; - - va_start(ap, fmt); - UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); - va_end(ap); - - Warning(buffer); -} - -IConCommandBaseAccessor *BaseProvider::GetConCommandBaseAccessor() -{ - return &g_SMConVarAccessor; -} - -bool BaseProvider::RegisterConCommandBase(ConCommandBase *pCommand) -{ - return g_SMConVarAccessor.Register(pCommand); -} - -void BaseProvider::UnregisterConCommandBase(ConCommandBase *pCommand) -{ - return g_SMConVarAccessor.Unregister(pCommand); -} - -int BaseProvider::GetUserMessageCount() -{ - if (!usermsgs_extracted) - { - return -1; - } - - return (int)usermsgs_list.size(); -} - -int BaseProvider::FindUserMessage(const char *name, int *size) -{ - for (size_t i = 0; i < usermsgs_list.size(); i++) - { - if (usermsgs_list[i].name.compare(name) == 0) - { - if (size) - { - *size = usermsgs_list[i].size; - } - return (int)i; - } - } - - return -1; -} - -const char *BaseProvider::GetUserMessage(int index, int *size) -{ - if (!usermsgs_extracted || index < 0 || index >= (int)usermsgs_list.size()) - { - return NULL; - } - - if (size) - { - *size = usermsgs_list[index].size; - } - - return usermsgs_list[index].name.c_str(); -} - -const char *BaseProvider::GetGameDescription() -{ - return server->GetGameDescription(); -} - -int BaseProvider::DetermineSourceEngine(const char *game) -{ - return SOURCE_ENGINE_ORANGEBOX; -} - -ConVar *BaseProvider::CreateConVar(const char *name, - const char *defval, - const char *help, - int flags) -{ - int newflags = 0; - if (flags & ConVarFlag_Notify) - { - newflags |= FCVAR_NOTIFY; - } - if (flags & ConVarFlag_Replicated) - { - newflags |= FCVAR_REPLICATED; - } - if (flags & ConVarFlag_SpOnly) - { - newflags |= FCVAR_SPONLY; - } - - ConVar *pVar = new ConVar(name, defval, newflags, help); - - RegisterConCommandBase(pVar); - conbases_unreg.push_back(pVar); - - return pVar; -} - -IServerPluginCallbacks *BaseProvider::GetVSPCallbacks(const char *iface) -{ - g_VspListener.SetLoadable(true); - return &g_VspListener; -} - -class GlobCommand : public IMetamodSourceCommandInfo -{ -public: - GlobCommand(const CCommand *cmd) : m_cmd(cmd) - { - } -public: - unsigned int GetArgCount() - { - return m_cmd->ArgC(); - } - - const char *GetArg(unsigned int num) - { - return m_cmd->Arg(num); - } - - const char *GetArgString() - { - return m_cmd->ArgS(); - } -private: - const CCommand *m_cmd; -}; - -void LocalCommand_Meta(const CCommand &args) -{ - GlobCommand cmd(&args); - Command_Meta(&cmd); -} - -void ClientCommand(edict_t *pEdict, const CCommand &_cmd) -{ - GlobCommand cmd(&_cmd); - - if (strcmp(cmd.GetArg(0), "meta") == 0) - { - Command_ClientMeta(pEdict, &cmd); - } -} - -bool vcmp(const void *_addr1, const void *_addr2, size_t len) -{ - unsigned char *addr1 = (unsigned char *)_addr1; - unsigned char *addr2 = (unsigned char *)_addr2; - - for (size_t i=0; i UserMsgDict; - -/* This is the ugliest function in all of SourceMM */ -bool CacheUserMessages() -{ - /* Get address of original GetUserMessageInfo() */ - char *vfunc = (char *)SH_GET_ORIG_VFNPTR_ENTRY(server, &IServerGameDLL::GetUserMessageInfo); - - /* Oh dear, we have a relative jump on our hands - * PVK II on Windows made me do this, but I suppose it doesn't hurt to check this on Linux too... - */ - if (*vfunc == '\xE9') - { - /* Get address from displacement... - * - * Add 5 because it's relative to next instruction: - * Opcode <1 byte> + 32-bit displacement <4 bytes> - */ - vfunc += *reinterpret_cast(vfunc + 1) + 5; - } - - CUtlDict *dict = NULL; - - if (vcmp(vfunc, MSGCLASS_SIG, MSGCLASS_SIGLEN)) - { - /* Get address of CUserMessages instance */ - char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS_OFFS); - - /* Get address of CUserMessages::m_UserMessages */ - dict = reinterpret_cast(*userMsgClass); - } - else if (vcmp(vfunc, MSGCLASS2_SIG, MSGCLASS2_SIGLEN)) - { - #ifdef OS_WIN32 - /* If we get here, the code is possibly inlined like in Dystopia */ - - /* Get the address of the CUtlRBTree */ - char *rbtree = *reinterpret_cast(vfunc + MSGCLASS2_OFFS); - - /* CUtlDict should be 8 bytes before the CUtlRBTree (hacktacular!) */ - dict = reinterpret_cast(rbtree - 8); - #elif defined OS_LINUX - /* Get address of CUserMessages instance */ - char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS2_OFFS); - - /* Get address of CUserMessages::m_UserMessages */ - dict = reinterpret_cast(*userMsgClass); - #endif - #ifdef OS_WIN32 - } - else if (vcmp(vfunc, MSGCLASS3_SIG, MSGCLASS3_SIGLEN)) - { - /* Get address of CUserMessages instance */ - char **userMsgClass = *reinterpret_cast(vfunc + MSGCLASS3_OFFS); - - /* Get address of CUserMessages::m_UserMessages */ - dict = reinterpret_cast(*userMsgClass); - #endif - } - - #if !defined OS_WIN32 - if (dict == NULL) - { - char path[255]; - if (GetFileOfAddress(vfunc, path, sizeof(path))) - { - void *handle = dlopen(path, RTLD_NOW); - if (handle != NULL) - { - void *addr = dlsym(handle, "usermessages"); - dict = (UserMsgDict *)*(void **)addr; - dlclose(handle); - } - } - } - #endif - - if (dict != NULL) - { - int msg_count = dict->Count(); - - /* Ensure that count is within bounds of an unsigned byte, because that's what engine supports */ - if (msg_count < 0 || msg_count > 255) - { - return false; - } - - UserMessage *msg; - UsrMsgInfo u_msg; - - /* Cache messages in our CUtlDict */ - for (int i = 0; i < msg_count; i++) - { - msg = dict->Element(i); - u_msg.name = msg->name; - u_msg.size = msg->size; - usermsgs_list.push_back(u_msg); - } - - return true; - } - - return false; -} - diff --git a/sourcemm/episode2/provider_ep2.h b/sourcemm/episode2/provider_ep2.h deleted file mode 100644 index 634865e..0000000 --- a/sourcemm/episode2/provider_ep2.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ -#define _INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ - -#if defined _DEBUG -#define DEBUG2 -#undef _DEBUG -#endif -#include -#include -#include -#include "ISmmAPI.h" -#include "metamod_provider.h" -#include "metamod_oslink.h" -#if defined DEBUG2 -#undef DEBUG2 -#define _DEBUG -#endif - -using namespace SourceMM; -using namespace SourceHook; - -class BaseProvider : public IMetamodSourceProvider -{ -public: - virtual bool IsSourceEngineBuildCompatible(int build); - virtual bool GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInfo); - virtual bool LogMessage(const char *buffer); - virtual const char *GetCommandLineValue(const char *key, const char *defval); - virtual void ConsolePrint(const char *msg); - virtual bool IsRemotePrintingAvailable(); - virtual void ClientConsolePrint(edict_t *client, const char *msg); - virtual IServerPluginCallbacks *GetVSPCallbacks(const char *iface); - virtual void DisplayError(const char *fmt, ...); - virtual void DisplayWarning(const char *fmt, ...); - virtual int TryServerGameDLL(const char *iface); - virtual void Notify_DLLInit_Pre(void *gamedll, - CreateInterfaceFn engineFactory, - CreateInterfaceFn serverFactory); - void Notify_DLLShutdown_Pre(); - virtual void ServerCommand(const char *cmd); - virtual ConVar *CreateConVar(const char *name, - const char *defval, - const char *help, - int flags); - virtual const char *GetConVarString(ConVar *convar); - virtual const char *GetGameDescription(); - virtual IConCommandBaseAccessor *GetConCommandBaseAccessor(); - virtual bool RegisterConCommandBase(ConCommandBase *pCommand); - virtual void UnregisterConCommandBase(ConCommandBase *pCommand); - virtual bool IsConCommandBaseACommand(ConCommandBase *pCommand); - virtual int GetUserMessageCount(); - virtual int FindUserMessage(const char *name, int *size=NULL); - virtual const char *GetUserMessage(int index, int *size=NULL); - virtual int DetermineSourceEngine(const char *game); -}; - -extern IVEngineServer *engine; -extern IServerGameDLL *server; -extern IServerGameClients *gameclients; -extern ICvar *icvar; - -#endif //_INCLUDE_METAMOD_SOURCE_BASE_PROVIDER_H_ - diff --git a/sourcemm/episode2/vsp_listener.cpp b/sourcemm/episode2/vsp_listener.cpp deleted file mode 100644 index 3adf2b5..0000000 --- a/sourcemm/episode2/vsp_listener.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#include "vsp_listener.h" -#include "svn_version.h" -#include "metamod.h" - -using namespace SourceMM; - -VSPListener::VSPListener() -{ - m_bLoaded = false; - m_bLoadable = false; -} - -void VSPListener::ClientActive(edict_t *pEntity) -{ -} - -PLUGIN_RESULT VSPListener::ClientCommand(edict_t *pEntity, const CCommand &cmd) -{ - return PLUGIN_CONTINUE; -} - -PLUGIN_RESULT VSPListener::ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) -{ - return PLUGIN_CONTINUE; -} - -void VSPListener::ClientDisconnect(edict_t *pEntity) -{ -} - -void VSPListener::ClientPutInServer(edict_t *pEntity, char const *playername) -{ -} - -void VSPListener::ClientSettingsChanged(edict_t *pEdict) -{ -} - -void VSPListener::SetCommandClient(int index) -{ -} - -void VSPListener::GameFrame(bool simulating) -{ -} - -const char *VSPListener::GetPluginDescription() -{ - return "Metamod:Source Interface v" SVN_FILE_VERSION_STRING; -} - -bool VSPListener::IsLoaded() -{ - return m_bLoaded; -} - -void VSPListener::LevelInit(char const *pMapName) -{ -} - -void VSPListener::LevelShutdown() -{ -} - -PLUGIN_RESULT VSPListener::NetworkIDValidated(const char *pszUserName, const char *pszNetworkID) -{ - return PLUGIN_CONTINUE; -} - -void VSPListener::Pause() -{ -} - -void VSPListener::UnPause() -{ -} - -void VSPListener::ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) -{ -} - -void VSPListener::Unload() -{ -} - -void VSPListener::SetLoadable(bool set) -{ - m_bLoadable = set; -} - -bool VSPListener::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) -{ - if (!m_bLoadable) - { - provider->DisplayWarning("Do not manually load Metamod:Source as a Valve Server Plugin\n"); - return false; - } - - if (m_bLoaded) - { - return false; - } - - m_bLoaded = true; - SetLoadable(false); - - g_Metamod.NotifyVSPListening(this); - - return true; -} - -void VSPListener::OnQueryCvarValueFinished(QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ) -{ -} diff --git a/sourcemm/episode2/vsp_listener.h b/sourcemm/episode2/vsp_listener.h deleted file mode 100644 index 443606f..0000000 --- a/sourcemm/episode2/vsp_listener.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ -#define _INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ - -#if defined _DEBUG -#define DEBUG2 -#undef _DEBUG -#endif -#include "iserverplugin.h" -#if defined DEBUG2 -#undef DEBUG2 -#define _DEBUG -#endif - -class VSPListener : public IServerPluginCallbacks -{ -public: - VSPListener(); -public: - virtual bool Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory); - virtual void Unload(); - virtual void Pause(); - virtual void UnPause(); - virtual const char *GetPluginDescription(); - virtual void LevelInit(char const *pMapName); - virtual void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); - virtual void GameFrame(bool simulating); - virtual void LevelShutdown(void); - virtual void ClientActive(edict_t *pEntity); - virtual void ClientDisconnect(edict_t *pEntity); - virtual void ClientPutInServer(edict_t *pEntity, char const *playername); - virtual void SetCommandClient(int index); - virtual void ClientSettingsChanged(edict_t *pEdict); - virtual PLUGIN_RESULT ClientConnect(bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen); - virtual PLUGIN_RESULT ClientCommand(edict_t *pEntity, const CCommand &cmd); - virtual PLUGIN_RESULT NetworkIDValidated(const char *pszUserName, const char *pszNetworkID); - virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ); -public: - bool IsLoaded(); - void SetLoadable(bool loadable); -private: - bool m_bLoaded; - bool m_bLoadable; -}; - -#endif //_INCLUDE_METAMOD_SOURCE_VSP_LISTENER_H_ - diff --git a/sourcemm/metamod.cpp b/sourcemm/metamod.cpp deleted file mode 100644 index 1cbb159..0000000 --- a/sourcemm/metamod.cpp +++ /dev/null @@ -1,1272 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#if defined _DEBUG -#define DEBUG2 -#undef _DEBUG -#endif -#include -#include -#include "metamod.h" -#include "metamod_provider.h" -#include "metamod_plugins.h" -#include "metamod_util.h" -#include "metamod_console.h" -#include "metamod_oslink.h" -#if defined DEBUG2 -#undef DEBUG2 -#define _DEBUG -#endif - -using namespace SourceMM; -using namespace SourceHook; -using namespace SourceHook::Impl; - -/** - * @brief Implementation of main SourceMM GameDLL functionality - * @file sourcemm.cpp - */ - -SH_DECL_MANUALHOOK4(SGD_DLLInit, 0, 0, 0, bool, CreateInterfaceFn, CreateInterfaceFn, CreateInterfaceFn, CGlobalVars *); -SH_DECL_MANUALHOOK0(SGD_GameInit, 0, 0, 0, bool); -SH_DECL_MANUALHOOK6(SGD_LevelInit, 0, 0, 0, bool, const char *, const char *, const char *, const char *, bool, bool); -SH_DECL_MANUALHOOK0_void(SGD_LevelShutdown, 0, 0, 0); -SH_DECL_MANUALHOOK0_void(SGD_DLLShutdown, 0, 0, 0); - -bool Handler_DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals); -bool Handler_DLLInit_Post(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals); -void Handler_DLLShutdown(); -void Handler_LevelShutdown(); -bool Handler_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background); -bool Handler_GameInit(); -void InitializeVSP(); - -struct game_dll_t -{ - HINSTANCE lib; - CreateInterfaceFn factory; -}; - -String mod_path; -String metamod_path; -String full_bin_path; -bool parsed_game_info = false; -int vsp_version = 0; -int gamedll_version = 0; -int engine_build = SOURCE_ENGINE_UNKNOWN; -List gamedll_list; -bool is_gamedll_loaded = false; -bool in_first_level = true; -bool is_game_init = false; -bool vsp_load_attempted = false; -bool vsp_load_requested = false; -bool vsp_loaded = false; -game_dll_t gamedll_info; -ConVar *metamod_version = NULL; -ConVar *mm_pluginsfile = NULL; -IServerGameDLL *server = NULL; -CreateInterfaceFn engine_factory = NULL; -CreateInterfaceFn physics_factory = NULL; -CreateInterfaceFn filesystem_factory = NULL; -CGlobalVars *gpGlobals = NULL; -CSourceHookImpl g_SourceHook; -CHookManagerAutoGen g_SH_HookManagerAutoGen(&g_SourceHook); -ISourceHook *g_SHPtr = &g_SourceHook; -PluginId g_PLID = Pl_Console; -META_RES last_meta_res; -IServerPluginCallbacks *vsp_callbacks = NULL; - -MetamodSource g_Metamod; - -void ClearGamedllList(); - -/* Helper Macro */ -#define IFACE_MACRO(orig,nam) \ - CPluginManager::CPlugin *pl; \ - SourceHook::List::iterator event; \ - IMetamodListener *api; \ - int mret = 0; \ - void *val = NULL; \ - for (PluginIter iter = g_PluginMngr._begin(); iter != g_PluginMngr._end(); iter++) { \ - pl = (*iter); \ - for (event=pl->m_Events.begin(); event!=pl->m_Events.end(); event++) { \ - api = (*event); \ - mret = IFACE_FAILED; \ - if ( (val=api->On##nam##Query(iface, &mret)) != NULL ) { \ - if (ret) *ret = mret; \ - return val; \ - } \ - } \ - } \ - return (orig)(iface, ret); - -#define ITER_EVENT(evn, args) \ - CPluginManager::CPlugin *pl; \ - SourceHook::List::iterator event; \ - IMetamodListener *api; \ - for (PluginIter iter = g_PluginMngr._begin(); iter != g_PluginMngr._end(); iter++) { \ - pl = (*iter); \ - for (event=pl->m_Events.begin(); event!=pl->m_Events.end(); event++) { \ - api = (*event); \ - api->evn args; \ - } \ - } - -/* Initialize everything here */ -void InitMainStates() -{ - char full_path[PATH_SIZE] = {0}; - GetFileOfAddress((void *)gamedll_info.factory, full_path, sizeof(full_path)); - full_bin_path.assign(full_path); - - /* Like Metamod, reload plugins at the end of the map. - * This is so plugins can hook everything on load, BUT, new plugins will be reloaded - * if the server is shut down (silly, but rare case). - */ - in_first_level = true; - - SourceHook::MemFuncInfo info; - - if (!provider->GetHookInfo(ProvidedHook_DLLInit, &info)) - { - provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::DLLInit"); - } - SH_MANUALHOOK_RECONFIGURE(SGD_DLLInit, info.vtblindex, info.vtbloffs, info.thisptroffs); - SH_ADD_MANUALHOOK_STATICFUNC(SGD_DLLInit, server, Handler_DLLInit, false); - SH_ADD_MANUALHOOK_STATICFUNC(SGD_DLLInit, server, Handler_DLLInit_Post, true); - - if (!provider->GetHookInfo(ProvidedHook_GameInit, &info)) - { - provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::GameInit"); - } - SH_MANUALHOOK_RECONFIGURE(SGD_GameInit, info.vtblindex, info.vtbloffs, info.thisptroffs); - SH_ADD_MANUALHOOK_STATICFUNC(SGD_GameInit, server, Handler_GameInit, false); - - if (!provider->GetHookInfo(ProvidedHook_LevelInit, &info)) - { - provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::LevelInit"); - } - SH_MANUALHOOK_RECONFIGURE(SGD_LevelInit, info.vtblindex, info.vtbloffs, info.thisptroffs); - SH_ADD_MANUALHOOK_STATICFUNC(SGD_LevelInit, server, Handler_LevelInit, true); - - if (!provider->GetHookInfo(ProvidedHook_LevelShutdown, &info)) - { - provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::LevelShutdown"); - } - SH_MANUALHOOK_RECONFIGURE(SGD_LevelShutdown, info.vtblindex, info.vtbloffs, info.thisptroffs); - SH_ADD_MANUALHOOK_STATICFUNC(SGD_LevelShutdown, server, Handler_LevelShutdown, true); - - if (!provider->GetHookInfo(ProvidedHook_DLLShutdown, &info)) - { - provider->DisplayError("Metamod:Source could not find a valid hook for IServerGameDLL::DLLShutdown"); - } - SH_MANUALHOOK_RECONFIGURE(SGD_DLLShutdown, info.vtblindex, info.vtbloffs, info.thisptroffs); - SH_ADD_MANUALHOOK_STATICFUNC(SGD_DLLShutdown, server, Handler_DLLShutdown, false); -} - -/* This is where the magic happens */ -SMM_API void *CreateInterface(const char *iface, int *ret) -{ - /* Prevent loading of self as a SourceMM plugin or Valve server plugin :x */ - if (strcmp(iface, METAMOD_PLAPI_NAME) == 0) - { - provider->DisplayWarning("Do not try loading Metamod:Source as a plugin.\n"); - - if (ret) - { - *ret = IFACE_FAILED; - } - - return NULL; - } - - if (strncmp(iface, "ISERVERPLUGINCALLBACKS", 22) == 0) - { - vsp_callbacks = provider->GetVSPCallbacks(iface); - - if (vsp_callbacks != NULL && vsp_version == 0) - { - vsp_version = atoi(&iface[22]); - } - - if (ret) - { - *ret = (vsp_callbacks != NULL) ? IFACE_OK : IFACE_FAILED; - } - - return vsp_callbacks; - } - - if (!parsed_game_info) - { - parsed_game_info = true; - const char *game_dir = NULL; - char game_path[PATH_SIZE]; - char mm_path[PATH_SIZE]; - - /* Get path to SourceMM DLL */ - if (!GetFileOfAddress((void *)CreateInterface, mm_path, sizeof(mm_path))) - { - provider->DisplayError("GetFileOfAddress() failed! Metamod cannot load.\n"); - return NULL; - } - - metamod_path.assign(mm_path); - - /* Get value of -game from command line, defaulting to hl2 as engine seems to do */ - game_dir = provider->GetCommandLineValue("-game", "hl2"); - - engine_build = provider->DetermineSourceEngine(game_dir);; - - /* Get absolute path */ - abspath(game_path, game_dir); - mod_path.assign(game_path); - - char temp_path[PATH_SIZE]; - - /* Path to gameinfo.txt */ - g_Metamod.PathFormat(temp_path, PATH_SIZE, "%s/%s", mod_path.c_str(), "gameinfo.txt"); - - FILE *fp = fopen(temp_path, "rt"); - - if (!fp) - { - provider->DisplayError("Unable to open gameinfo.txt! Metamod cannot load.\n"); - return NULL; - } - - char buffer[255]; - char key[128], val[128]; - bool search = false; - bool gamebin = false; - char *ptr; - const char *lptr; - char cur_path[PATH_SIZE]; - - getcwd(cur_path, PATH_SIZE); - - while (!feof(fp) && fgets(buffer, sizeof(buffer), fp) != NULL) - { - UTIL_TrimComments(buffer); - UTIL_TrimLeft(buffer); - UTIL_TrimRight(buffer); - - if (stricmp(buffer, "SearchPaths") == 0) - { - search = true; - } - - if (!search) - { - continue; - } - - UTIL_KeySplit(buffer, key, sizeof(key) - 1, val, sizeof(val) - 1); - if (stricmp(key, "Game") == 0 || stricmp(key, "GameBin") == 0) - { - if (stricmp(key, "Game") == 0) - { - gamebin = false; - } - else - { - gamebin = true; - } - - if (strncmp(val, "|gameinfo_path|", sizeof("|gameinfo_path|") - 1) == 0) - { - ptr = &(val[sizeof("|gameinfo_path|") - 1]); - if (ptr[0] == '.') - { - ptr++; - } - lptr = mod_path.c_str(); - } else { - ptr = val; - lptr = cur_path; - } - - size_t ptr_len = strlen(ptr); - if (ptr[ptr_len] == '/' || ptr[ptr_len] == '\\') - { - ptr[--ptr_len] = '\0'; - } - - /* No need to append "bin" if key is GameBin */ - if (gamebin) - { - g_Metamod.PathFormat(temp_path, PATH_SIZE, "%s/%s/%s", lptr, ptr, SERVER_DLL); - } - else if (!ptr[0]) - { - g_Metamod.PathFormat(temp_path, PATH_SIZE, "%s/%s/%s", lptr, "bin", SERVER_DLL); - } - else - { - g_Metamod.PathFormat(temp_path, PATH_SIZE, "%s/%s/%s/%s", lptr, ptr, "bin", SERVER_DLL); - } - - /* If not path to SourceMM... */ - if (!UTIL_PathCmp(mm_path, temp_path)) - { - FILE *temp_fp = fopen(temp_path, "rb"); - if (!temp_fp) - { - continue; - } - fclose(temp_fp); - - /* Search for a matching game dll */ - List::iterator iter; - game_dll_t *pCheck; - bool found = false; - for (iter = gamedll_list.begin(); iter != gamedll_list.end(); iter++) - { - pCheck = (*iter); - if (GetFileOfAddress((void *)pCheck->factory, buffer, sizeof(buffer))) - { - if (UTIL_PathCmp(temp_path, buffer)) - { - found = true; - break; - } - } - } - - if (found) - { - continue; - } - - HINSTANCE gamedll = dlmount(temp_path); - if (gamedll == NULL) - { - continue; - } - - CreateInterfaceFn fn = (CreateInterfaceFn)dlsym(gamedll, "CreateInterface"); - if (fn == NULL) - { - dlclose(gamedll); - continue; - } - - game_dll_t *pInfo = new game_dll_t; - pInfo->factory = fn; - pInfo->lib = gamedll; - gamedll_list.push_back(pInfo); - break; - } - } - } - fclose(fp); - } - - if (!is_gamedll_loaded) - { - if (strncmp(iface, "ServerGameDLL", 13) == 0) - { - List::iterator iter; - game_dll_t *pInfo; - for (iter=gamedll_list.begin(); iter!=gamedll_list.end(); iter++) - { - pInfo = (*iter); - if ((server = (IServerGameDLL *)((pInfo->factory)(iface, ret))) != NULL) - { - if ((gamedll_version = provider->TryServerGameDLL(iface)) != 0) - { - /* We have a match. Erase us from the list and save our info. */ - gamedll_list.erase(iter); - gamedll_info = *pInfo; - delete pInfo; - is_gamedll_loaded = true; - break; - } - /* :TODO: error otherwise? */ - } - } - - if (is_gamedll_loaded) - { - ClearGamedllList(); - InitMainStates(); - } - else - { - if (ret) - { - *ret = IFACE_FAILED; - } - return NULL; - } - } - else - { - /* wtf do we do... */ - /* :TODO: .. something a bit more intelligent? */ - provider->DisplayError("Engine requested unknown interface before GameDLL was known!\n"); - return NULL; - } - } - - /* If we got here, there's definitely a GameDLL */ - IFACE_MACRO(gamedll_info.factory, GameDLL); -} - -void ClearGamedllList() -{ - List::iterator iter; - - game_dll_t *pInfo; - for (iter = gamedll_list.begin(); iter != gamedll_list.end(); iter++) - { - pInfo = (*iter); - dlclose(pInfo->lib); - delete pInfo; - } - - gamedll_list.clear(); -} - -int LoadPluginsFromFile(const char *_file) -{ - FILE *fp; - int total = 0, skipped=0; - PluginId id; - bool already; - - fp = fopen(_file, "rt"); - if (!fp) - { - LogMessage("[META] Could not open plugins file %s\n", _file); - return -1; - } - - char buffer[255], error[255], full_path[255]; - const char *ptr, *ext, *file; - size_t length; - while (!feof(fp) && fgets(buffer, sizeof(buffer), fp) != NULL) - { - UTIL_TrimLeft(buffer); - UTIL_TrimRight(buffer); - - length = strlen(buffer); - if (!length) - { - continue; - } - - if (buffer[0] == '\0' || buffer[0] == ';' || strncmp(buffer, "//", 2) == 0) - { - continue; - } - - file = buffer; - if (buffer[0] == '"') - { - char *cptr = buffer; - file = ++cptr; - - while (*cptr) - { - if (*cptr == '"') - { - *cptr = '\0'; - break; - } - cptr++; - } - } - else - { - char *cptr = buffer; - while (*cptr) - { - if (isspace(*cptr)) - { - char *optr = cptr; - while (*cptr && isspace(*cptr)) - { - cptr++; - } - *optr = '\0'; - UTIL_TrimRight(cptr); - if (*cptr && isalpha(*cptr)) - { - g_PluginMngr.SetAlias(buffer, cptr); - file = cptr; - } - break; - } - cptr++; - } - } - if (!file[0]) - { - continue; - } - /* First find if it's an absolute path or not... */ - if (file[0] == '/' || strncmp(&(file[1]), ":\\", 2) == 0) - { - /* If we're in an absolute path, ignore our normal heuristics */ - id = g_PluginMngr.Load(file, Pl_File, already, error, sizeof(error)); - if (id < Pl_MinId || g_PluginMngr.FindById(id)->m_Status < Pl_Paused) - { - LogMessage("[META] Failed to load plugin %s. %s", buffer, error); - } - else - { - if (already) - { - skipped++; - } - else - { - total++; - } - } - } - else - { - /* Attempt to find a file extension */ - ptr = UTIL_GetExtension(file); - /* Add an extension if there's none there */ - if (!ptr) - { -#if defined WIN32 || defined _WIN32 - ext = ".dll"; -#else - ext = "_i486.so"; -#endif - } - else - { - ext = ""; - } - /* Format the new path */ - g_Metamod.PathFormat(full_path, sizeof(full_path), "%s/%s%s", mod_path.c_str(), file, ext); - id = g_PluginMngr.Load(full_path, Pl_File, already, error, sizeof(error)); - if (id < Pl_MinId || g_PluginMngr.FindById(id)->m_Status < Pl_Paused) - { - LogMessage("[META] Failed to load plugin %s. %s", buffer, error); - } - else - { - if (already) - { - skipped++; - } - else - { - total++; - } - } - } - } - fclose(fp); - - if (skipped) - { - LogMessage("[META] Loaded %d plugins from file (%d already loaded)", total, skipped); - } - else - { - LogMessage("[META] Loaded %d plugins from file.", total); - } - - return total; -} - -void InitializeVSP() -{ - size_t len; - char engine_file[PATH_SIZE]; - char engine_path[PATH_SIZE]; - char rel_path[PATH_SIZE * 2]; - - GetFileOfAddress((void *)engine_factory, engine_file, sizeof(engine_file)); - - /* Chop off the "engine" file part */ - len = strlen(engine_file); - for (size_t i = len - 1; i >= 0 && i < len; i--) - { - if (engine_file[i] == '/' || engine_file[i] == '\\') - { - engine_file[i] = '\0'; - break; - } - } - abspath(engine_path, engine_file); - - const char *usepath = metamod_path.c_str(); - if (UTIL_Relatize(rel_path, sizeof(rel_path), engine_path, metamod_path.c_str())) - { - usepath = rel_path; - } - - char command[PATH_SIZE * 2]; - UTIL_Format(command, sizeof(command), "plugin_load \"%s\"\n", usepath); - provider->ServerCommand(command); -} - -/* Wrapper function. This is called when the GameDLL thinks it's using - * the engine's real engineFactory. - */ -void *EngineFactory(const char *iface, int *ret) -{ - IFACE_MACRO(engine_factory, Engine); -} - -/* Wrapper function. This is called when the GameDLL thinks it's using - * the engine's real physicsFactory. - */ -void *PhysicsFactory(const char *iface, int *ret) -{ - IFACE_MACRO(physics_factory, Physics); -} - -/* Wrapper function. This is called when the GameDLL thinks it's using - * the engine's real fileSystemFactory. - */ -void *FileSystemFactory(const char *iface, int *ret) -{ - IFACE_MACRO(filesystem_factory, FileSystem); -} - -void LogMessage(const char *msg, ...) -{ - va_list ap; - static char buffer[2048]; - - va_start(ap, msg); - size_t len = vsnprintf(buffer, sizeof(buffer) - 2, msg, ap); - va_end(ap); - - buffer[len++] = '\n'; - buffer[len] = '\0'; - - if (!provider->LogMessage(buffer)) - { - fprintf(stdout, "%s", buffer); - } -} - -bool Handler_DLLInit(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals) -{ - engine_factory = engineFactory; - filesystem_factory = filesystemFactory; - physics_factory = physicsFactory; - gpGlobals = pGlobals; - - provider->Notify_DLLInit_Pre(server, engineFactory, gamedll_info.factory); - - metamod_version = provider->CreateConVar("metamod_version", - SOURCEMM_VERSION, - "Metamod:Source Version", - ConVarFlag_Notify|ConVarFlag_Replicated|ConVarFlag_SpOnly); - - mm_pluginsfile = provider->CreateConVar("mm_pluginsfile", -#if defined WIN32 || defined _WIN32 - "addons\\metamod\\metaplugins.ini", -#else - "addons/metamod/metaplugins.ini", -#endif - "Metamod:Source Plugins File", - ConVarFlag_SpOnly); - - const char *pluginFile = provider->GetCommandLineValue("mm_pluginsfile", NULL); - if (!pluginFile) - { - pluginFile = provider->GetConVarString(mm_pluginsfile); - if (pluginFile == NULL) - { - pluginFile = "addons/metamod/metaplugins.ini"; - } - } - - char full_path[260]; - g_Metamod.PathFormat(full_path, sizeof(full_path), "%s/%s", mod_path.c_str(), pluginFile); - - LoadPluginsFromFile(full_path); - - in_first_level = true; - - RETURN_META_VALUE(MRES_IGNORED, true); -} - -bool Handler_GameInit() -{ - if (is_game_init) - { - return true; - } - - if (vsp_load_requested) - { - InitializeVSP(); - } - - is_game_init = true; - - RETURN_META_VALUE(MRES_IGNORED, true); -} - -bool Handler_DLLInit_Post(CreateInterfaceFn engineFactory, CreateInterfaceFn physicsFactory, CreateInterfaceFn filesystemFactory, CGlobalVars *pGlobals) -{ - g_PluginMngr.SetAllLoaded(); - RETURN_META_VALUE(MRES_IGNORED, true); -} - -void Handler_DLLShutdown() -{ - /* Unload plugins */ - g_PluginMngr.UnloadAll(); - - provider->Notify_DLLShutdown_Pre(); - - SH_CALL(server, &IServerGameDLL::DLLShutdown)(); - - g_SourceHook.CompleteShutdown(); - - if (is_gamedll_loaded && gamedll_info.lib) - { - dlclose(gamedll_info.lib); - is_gamedll_loaded = false; - } - - RETURN_META(MRES_SUPERCEDE); -} - -void Handler_LevelShutdown(void) -{ - if (!in_first_level) - { - char full_path[255]; - g_Metamod.PathFormat(full_path, - sizeof(full_path), - "%s/%s", - mod_path.c_str(), - provider->GetConVarString(mm_pluginsfile)); - - LoadPluginsFromFile(full_path); - } - else - { - in_first_level = false; - } - - ITER_EVENT(OnLevelShutdown, ()); - - RETURN_META(MRES_IGNORED); -} - -bool Handler_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background) -{ - ITER_EVENT(OnLevelInit, (pMapName, pMapEntities, pOldLevel, pLandmarkName, loadGame, background)); - - RETURN_META_VALUE(MRES_IGNORED, false); -} - -void MetamodSource::LogMsg(ISmmPlugin *pl, const char *msg, ...) -{ - va_list ap; - char buffer[2048]; - - va_start(ap, msg); - UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - LogMessage("[%s] %s", pl->GetLogTag(), buffer); -} - -CreateInterfaceFn MetamodSource::GetEngineFactory(bool syn/* =true */) -{ - if (syn) - { - return EngineFactory; - } - - return engine_factory; -} - -CreateInterfaceFn MetamodSource::GetPhysicsFactory(bool syn/* =true */) -{ - if (syn) - { - return PhysicsFactory; - } - - return physics_factory; -} - -CreateInterfaceFn MetamodSource::GetFileSystemFactory(bool syn/* =true */) -{ - if (syn) - { - return FileSystemFactory; - } - - return filesystem_factory; -} - -CreateInterfaceFn MetamodSource::GetServerFactory(bool syn/* =true */) -{ - if (syn) - { - return CreateInterface; - } - - return gamedll_info.factory; -} - -CGlobalVars *MetamodSource::GetCGlobals() -{ - return gpGlobals; -} - -void MetamodSource::SetLastMetaReturn(META_RES res) -{ - last_meta_res = res; -} - -META_RES MetamodSource::GetLastMetaReturn() -{ - return last_meta_res; -} - -void MetamodSource::ConPrint(const char *str) -{ - provider->ConsolePrint(str); -} - -void MetamodSource::ConPrintf(const char *fmt, ...) -{ - va_list ap; - char buffer[2048]; - - va_start(ap, fmt); - UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); - va_end(ap); - - provider->ConsolePrint(buffer); -} - -void MetamodSource::GetApiVersions(int &major, int &minor, int &plvers, int &plmin) -{ - major = METAMOD_API_MAJOR; - minor = METAMOD_API_MINOR; - plvers = METAMOD_PLAPI_VERSION; - plmin = PLAPI_MIN_VERSION; -} - -void MetamodSource::GetShVersions(int &shvers, int &shimpl) -{ - shvers = SH_IFACE_VERSION; - shimpl = SH_IMPL_VERSION; -} - -int MetamodSource::FormatIface(char iface[], unsigned int maxlength) -{ - int length = (int)strlen(iface); - int i; - int num = 0; - - for (i = length - 1; i >= 0; i--) - { - if (!isdigit(iface[i])) - { - if (i != length - 1) - { - num = 1; - } - break; - } - } - - if ( (num && ((int)maxlength <= length)) || (!num && ((int)maxlength <= length + 3)) ) - { - return -1; - } - - if (i != length - 1) - { - num = atoi(&(iface[++i])); - } - - num++; - - snprintf(&(iface[i]), 4, "%03d", num); - - return num; -} - -void *MetamodSource::InterfaceSearch(CreateInterfaceFn fn, const char *iface, int max, int *ret) -{ - char _if[256]; /* assume no interface goes beyond this */ - size_t len = strlen(iface); - int num = 0; - void *pf = NULL; - - if (max > 999) - { - max = 999; - } - - if (len + 4 > sizeof(_if)) - { - if (ret) - { - *ret = IFACE_FAILED; - } - return NULL; - } - - strcpy(_if, iface); - - do - { - if ((pf = (fn)(_if, ret)) != NULL) - { - break; - } - if (num > max) - { - break; - } - } while ((num = FormatIface(_if, len+1))); - - return pf; -} - -void *MetamodSource::VInterfaceMatch(CreateInterfaceFn fn, const char *iface, int min) -{ - char buffer[256]; /* assume no interface will go beyond this */ - size_t len = strlen(iface); - int ret; /* just in case something doesn't handle NULL properly */ - - if (len > sizeof(buffer) - 4) - { - return NULL; - } - - strcpy(buffer, iface); - - if (min != -1) - { - char *ptr = &buffer[len - 1]; - int digits = 0; - while (isdigit(*ptr) && digits <=3) - { - *ptr = '\0'; - digits++; - ptr--; - } - if (digits != 3) - { - /* for now, assume this is an error */ - strcpy(buffer, iface); - } - else - { - char num[4]; - min = (min == 0) ? 1 : min; - snprintf(num, sizeof(num), "%03d", min); - strcat(buffer, num); - } - } - - return InterfaceSearch(fn, buffer, IFACE_MAXNUM, &ret); -} - -const char *MetamodSource::GetBaseDir() -{ - return mod_path.c_str(); -} - -size_t MetamodSource::PathFormat(char *buffer, size_t len, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - size_t mylen = UTIL_FormatArgs(buffer, len, fmt, ap); - va_end(ap); - - for (size_t i = 0; i < mylen; i++) - { - if (buffer[i] == ALT_SEP_CHAR) - { - buffer[i] = PATH_SEP_CHAR; - } - } - - return mylen; -} - -void MetamodSource::ClientConPrintf(edict_t *client, const char *fmt, ...) -{ - va_list ap; - char buffer[2048]; - - va_start(ap, fmt); - UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); - va_end(ap); - - provider->ClientConsolePrint(client, buffer); -} - -void MetamodSource::EnableVSPListener() -{ - if (is_game_init && !vsp_load_requested && !vsp_loaded) - { - InitializeVSP(); - } - - vsp_load_requested = true; -} - -int MetamodSource::GetVSPVersion() -{ - return vsp_version; -} - -int MetamodSource::GetGameDLLVersion() -{ - return gamedll_version; -} - -bool MetamodSource::RemotePrintingAvailable() -{ - return provider->IsRemotePrintingAvailable(); -} - -void *MetamodSource::MetaFactory(const char *iface, int *ret, PluginId *id) -{ - if (id) - { - *id = 0; - } - - if (!iface) - { - return NULL; - } - - /* First check ours... we get first chance! */ - if (strcmp(iface, MMIFACE_SOURCEHOOK) == 0) - { - if (ret) - { - *ret = IFACE_OK; - } - return static_cast(static_cast(&g_SourceHook)); - } - else if (strcmp(iface, MMIFACE_PLMANAGER) == 0) - { - if (ret) - { - *ret = IFACE_OK; - } - return static_cast(static_cast(&g_PluginMngr)); - } - else if (strcmp(iface, MMIFACE_SH_HOOKMANAUTOGEN) == 0) - { - if (ret) - { - *ret = IFACE_OK; - } - return static_cast(static_cast(&g_SH_HookManagerAutoGen)); - } - - CPluginManager::CPlugin *pl; - List::iterator event; - IMetamodListener *api; - void *value; - - int subret = 0; - for (PluginIter iter = g_PluginMngr._begin(); - iter != g_PluginMngr._end(); - iter++) - { - pl = (*iter); - for (event = pl->m_Events.begin(); event != pl->m_Events.end(); event++) - { - api = (*event); - subret = IFACE_FAILED; - if ((value = api->OnMetamodQuery(iface, &subret)) != NULL) - { - if (ret) - { - *ret = subret; - } - if (id) - { - *id = pl->m_Id; - } - return value; - } - } - } - - if (ret) - { - *ret = IFACE_FAILED; - } - - return NULL; -} - -void MetamodSource::AddListener(ISmmPlugin *plugin, IMetamodListener *pListener) -{ - CPluginManager::CPlugin *pl = g_PluginMngr.FindByAPI(plugin); - - pl->m_Events.push_back(pListener); -} - -const char *MetamodSource::GetGameBinaryPath() -{ - return full_bin_path.c_str(); -} - -const char *MetamodSource::GetPluginsFile() -{ - return provider->GetConVarString(mm_pluginsfile); -} - -IConCommandBaseAccessor *MetamodSource::GetCvarBaseAccessor() -{ - return provider->GetConCommandBaseAccessor(); -} - -bool MetamodSource::RegisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand) -{ - if (provider->IsConCommandBaseACommand(pCommand)) - { - g_PluginMngr.AddPluginCmd(plugin, pCommand); - } - else - { - g_PluginMngr.AddPluginCvar(plugin, pCommand); - } - - return provider->RegisterConCommandBase(pCommand); -} - -void MetamodSource::UnregisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand) -{ - if (provider->IsConCommandBaseACommand(pCommand)) - { - g_PluginMngr.RemovePluginCmd(plugin, pCommand); - } - else - { - g_PluginMngr.RemovePluginCvar(plugin, pCommand); - } - - CPluginManager::CPlugin *pOrig = g_PluginMngr.FindByAPI(plugin); - UnregisterConCommandBase(pOrig ? pOrig->m_Id : 0, pCommand); -} - -void MetamodSource::UnregisterConCommandBase(PluginId id, ConCommandBase *pCommand) -{ - PluginIter iter; - CPluginManager::CPlugin *pPlugin; - List::iterator event; - IMetamodListener *pML; - for (iter=g_PluginMngr._begin(); iter!=g_PluginMngr._end(); iter++) - { - pPlugin = (*iter); - if (pPlugin->m_Status < Pl_Paused) - { - continue; - } - /* Only valid for plugins >= 12 (v1:6, SourceMM 1.5) */ - if (pPlugin->m_API->GetApiVersion() < 12) - { - continue; - } - for (event=pPlugin->m_Events.begin(); - event!=pPlugin->m_Events.end(); - event++) - { - pML = (*event); - pML->OnUnlinkConCommandBase(id, pCommand); - } - } - - return provider->UnregisterConCommandBase(pCommand); -} - -int MetamodSource::GetUserMessageCount() -{ - return provider->GetUserMessageCount(); -} - -int MetamodSource::FindUserMessage(const char *name, int *size/* =NULL */) -{ - return provider->FindUserMessage(name, size); -} - -const char *MetamodSource::GetUserMessage(int index, int *size/* =NULL */) -{ - return provider->GetUserMessage(index, size); -} - -int MetamodSource::GetSourceEngineBuild() -{ - return engine_build; -} - -void MetamodSource::NotifyVSPListening(IServerPluginCallbacks *callbacks) -{ - ITER_EVENT(OnVSPListening, (callbacks)); -} - -IServerPluginCallbacks *MetamodSource::GetVSPInfo(int *pVersion) -{ - if (pVersion) - { - *pVersion = vsp_version; - } - - return vsp_callbacks; -} - -size_t MetamodSource::Format(char *buffer, size_t maxlength, const char *format, ...) -{ - va_list ap; - size_t result; - - va_start(ap, format); - result = FormatArgs(buffer, maxlength, format, ap); - va_end(ap); - - return result; -} - -size_t MetamodSource::FormatArgs(char *buffer, size_t maxlength, const char *format, va_list ap) -{ - return UTIL_FormatArgs(buffer, maxlength, format, ap); -} diff --git a/sourcemm/metamod.h b/sourcemm/metamod.h deleted file mode 100644 index 56eafd2..0000000 --- a/sourcemm/metamod.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_SOURCEMM_H -#define _INCLUDE_SOURCEMM_H - -/** - * @brief SourceMM main functionality for GameDLL interception - * @file sourcemm.h - */ - -#include -#include -#include -#include -#include -#include -#include "metamod_provider.h" -#include "svn_version.h" - -using namespace SourceMM; - -/** - * Versioning - * increase api_major when API breaks - * increase api_minor when new functions are added (non-breaking) - */ -#define SOURCEMM_VERSION SVN_FILE_VERSION_STRING -#define SOURCEMM_DATE __DATE__ -#define METAMOD_API_MAJOR 2 /* increase this on a breaking change */ -#define METAMOD_API_MINOR 0 /* increase this on a non-breaking API change */ - -class MetamodSource : public ISmmAPI -{ -public: - void LogMsg(ISmmPlugin *pl, const char *msg, ...); - CreateInterfaceFn GetEngineFactory(bool syn=true); - CreateInterfaceFn GetPhysicsFactory(bool syn=true); - CreateInterfaceFn GetFileSystemFactory(bool syn=true); - CreateInterfaceFn GetServerFactory(bool syn=true); - CGlobalVars *GetCGlobals(); - void SetLastMetaReturn(META_RES res); - META_RES GetLastMetaReturn(); - IConCommandBaseAccessor *GetCvarBaseAccessor(); - bool RegisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand); - void UnregisterConCommandBase(ISmmPlugin *plugin, ConCommandBase *pCommand); - void ConPrint(const char *str); - void ConPrintf(const char *fmt, ...); - bool RemotePrintingAvailable(); - void GetApiVersions(int &major, int &minor, int &plvers, int &plmin); - void GetShVersions(int &shvers, int &shimpl); - void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener); - void *MetaFactory(const char *iface, int *ret, PluginId *id); - int FormatIface(char iface[], unsigned int maxlength); - void *InterfaceSearch(CreateInterfaceFn fn, const char *iface, int max, int *ret); - const char *GetBaseDir(); - size_t PathFormat(char *buffer, size_t len, const char *fmt, ...); - void ClientConPrintf(edict_t *client, const char *fmt, ...); - void *VInterfaceMatch(CreateInterfaceFn fn, const char *iface, int min=-1); - void EnableVSPListener(); - int GetGameDLLVersion(); - int GetUserMessageCount(); - int FindUserMessage(const char *name, int *size=NULL); - const char *GetUserMessage(int index, int *size=NULL); - int GetVSPVersion(); - int GetSourceEngineBuild(); - IServerPluginCallbacks *GetVSPInfo(int *pVersion); - size_t Format(char *buffer, size_t maxlength, const char *format, ...); - size_t FormatArgs(char *buffer, size_t maxlength, const char *format, va_list ap); -public: - const char *GetGameBinaryPath(); - const char *GetPluginsFile(); - void UnregisterConCommandBase(PluginId id, ConCommandBase *pCommand); - void NotifyVSPListening(IServerPluginCallbacks *callbacks); -}; - -void LogMessage(const char *msg, ...); -int LoadPluginsFromFile(const char *_file); - -extern MetamodSource g_Metamod; -extern SourceHook::Impl::CSourceHookImpl g_SourceHook; - -#endif //_INCLUDE_SOURCEMM_H - diff --git a/sourcemm/metamod_console.cpp b/sourcemm/metamod_console.cpp deleted file mode 100644 index caf2abd..0000000 --- a/sourcemm/metamod_console.cpp +++ /dev/null @@ -1,747 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#if defined _DEBUG -#define DEBUG2 -#undef _DEBUG -#endif -#include -#include "metamod.h" -#include "metamod_util.h" -#include "metamod_console.h" -#include "metamod_plugins.h" -#if defined DEBUG2 -#undef DEBUG2 -#define _DEBUG -#endif - -using namespace SourceMM; -using namespace SourceHook; - -/** - * @brief Console Command Implementations - * @file concommands.cpp - */ - -#define CONMSG g_Metamod.ConPrintf -#define CLIENT_CONMSG g_Metamod.ClientConPrintf - -bool Command_Meta(IMetamodSourceCommandInfo *info) -{ - unsigned int args = info->GetArgCount(); - - if (args >= 1) - { - const char *command = info->GetArg(1); - if (strcmp(command, "credits") == 0) - { - CONMSG("Metamod:Source was developed by:\n"); - CONMSG(" SourceHook: Pavol \"PM OnoTo\" Marko\n"); - CONMSG(" GameDLL/Plugins: David \"BAILOPAN\" Anderson\n"); - CONMSG(" GameDLL: Scott \"Damaged Soul\" Ehlert\n"); - CONMSG("For more information, see the official website\n"); - CONMSG("http://www.sourcemm.net/\n"); - - return true; - } - else if (strcmp(command, "version") == 0) - { - CONMSG("Metamod:Source version %s\n", SOURCEMM_VERSION); - CONMSG("Compiled on: %s\n", SOURCEMM_DATE); - CONMSG("Plugin interface version: %d:%d\n", METAMOD_PLAPI_VERSION, PLAPI_MIN_VERSION); - CONMSG("SourceHook version: %d:%d\n", g_SHPtr->GetIfaceVersion(), g_SHPtr->GetImplVersion()); - CONMSG("http://www.sourcemm.net/\n"); - - return true; - } - else if (strcmp(command, "game") == 0) - { - CONMSG("GameDLL Information\n"); - CONMSG(" Description: %s\n", provider->GetGameDescription()); - CONMSG(" Mod Path: %s\n", g_Metamod.GetBaseDir()); - CONMSG(" DLL Path: %s\n", g_Metamod.GetGameBinaryPath()); - CONMSG(" Interface: ServerGameDLL%03d\n", g_Metamod.GetGameDLLVersion()); - - int engine = g_Metamod.GetSourceEngineBuild(); - if (engine == SOURCE_ENGINE_ORIGINAL) - { - CONMSG(" Engine: Original (pre-Episode 1)\n"); - } - else if (engine == SOURCE_ENGINE_EPISODEONE) - { - CONMSG(" Engine: Episode 1 (2004)\n"); - } - else if (engine == SOURCE_ENGINE_ORANGEBOX) - { - CONMSG(" Engine: Episode 2 (Orange Box, 2007)\n"); - } - - // Display user messages - int messages = g_Metamod.GetUserMessageCount(); - if (messages != -1) - { - const char *msgname; - int msgsize; - - if (messages > 0) - { - CONMSG(" User Messages: %-32.31s %-5s %-5s\n", "Name", "Index", "Size"); - - for (int i = 0; i < messages; i++) - { - msgname = g_Metamod.GetUserMessage(i, &msgsize); - - CONMSG(" %-32.31s %-5d %-5d\n", msgname, i, msgsize); - } - - CONMSG(" %d user message%s in total\n", messages, (messages > 1) ? "s" : ""); - } - else - { - CONMSG(" User Messages: None\n"); - } - } - else - { - CONMSG(" User Messages: Failed to get list of user messages\n"); - } - - return true; - } - else if (strcmp(command, "refresh") == 0) - { - char full_path[255]; - g_Metamod.PathFormat(full_path, - sizeof(full_path), - "%s/%s", - g_Metamod.GetBaseDir(), - g_Metamod.GetPluginsFile()); - - LoadPluginsFromFile(full_path); - - return true; - } - else if (strcmp(command, "list") == 0) - { - CPluginManager::CPlugin *pl; - ISmmPlugin *plapi; - const char *plname; - PluginIter i; - char buffer[256]; - int len; - int plnum = g_PluginMngr.GetPluginCount(); - - if (!plnum) - { - CONMSG("No plugins loaded.\n"); - return true; - } else { - CONMSG("Listing %d plugin%s:\n", plnum, (plnum > 1) ? "s" : ""); - } - - for (i = g_PluginMngr._begin(); i != g_PluginMngr._end(); i++) - { - pl = (*i); - if (!pl) - { - break; - } - - len = 0; - - if (pl->m_Status != Pl_Running) - { - len += UTIL_Format(buffer, sizeof(buffer), " [%02d] <%s>", pl->m_Id, g_PluginMngr.GetStatusText(pl)); - } else { - len += UTIL_Format(buffer, sizeof(buffer), " [%02d]", pl->m_Id); - } - - if ((plapi = pl->m_API)) - { - plname = IS_STR_FILLED(plapi->GetName()) ? plapi->GetName() : pl->m_File.c_str(); - len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " %s", plname); - - if (IS_STR_FILLED(plapi->GetVersion())) - { - len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", plapi->GetVersion()); - } - if (IS_STR_FILLED(plapi->GetAuthor())) - { - UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", plapi->GetAuthor()); - } - } - - CONMSG("%s\n", buffer); - } - - return true; - } - else if (strcmp(command, "cmds") == 0) - { - if (args >= 2) - { - int id = atoi(info->GetArg(2)); - CPluginManager::CPlugin *pl = g_PluginMngr.FindById(id); - - if (!pl) - { - CONMSG("Plugin %d not found.\n", id); - return true; - } - - if (!pl->m_API) - { - CONMSG("Plugin %d is not loaded.\n", id); - } - else - { - CONMSG("Console commands for %s:\n", pl->m_API->GetName()); - List::iterator ci; - size_t count = 0; - - for (ci=pl->m_Cmds.begin(); ci!=pl->m_Cmds.end(); ci++) - { - count++; - CONMSG(" [%5d] %-s\n", count, (*ci)->GetName()); - } - } - } - else - { - CONMSG("Usage: meta cmds \n"); - } - - return true; - } - else if (strcmp(command, "cvars") == 0) - { - if (args >= 2) - { - int id = atoi(info->GetArg(2)); - CPluginManager::CPlugin *pl = g_PluginMngr.FindById(id); - - if (!pl) - { - CONMSG("Plugin %d not found.\n", id); - return true; - } - - if (!pl->m_API) - { - CONMSG("Plugin %d is not loaded.\n", id); - } - else - { - CONMSG("Registered cvars for %s:\n", pl->m_API->GetName()); - List::iterator ci; - size_t count = 0; - - for (ci=pl->m_Cvars.begin(); ci!=pl->m_Cvars.end(); ci++) - { - count++; - CONMSG(" [%5d] %-s\n", count, (*ci)->GetName()); - } - } - } - else - { - CONMSG("Usage: meta cvars \n"); - } - - return true; - } - else if (strcmp(command, "info") == 0) - { - if (args >= 2) - { - int id = atoi(info->GetArg(2)); - CPluginManager::CPlugin *pl = g_PluginMngr.FindById(id); - if (!pl) - { - CONMSG("Plugin %d not found.\n", id); - return true; - } - - if (!pl->m_API) - { - CONMSG("Plugin %d is not loaded.\n", id); - } - else - { - if (pl->m_Status == Pl_Paused) - { - CONMSG("Plugin %d is paused.\n", id); - } - else if (pl->m_Status == Pl_Running) - { - char run_msg[255]; - bool run = false; - if (pl->m_API && pl->m_API->QueryRunning(run_msg, sizeof(run_msg)-1)) - { - run = true; - } - if (run) - { - CONMSG("Plugin %d is running.\n", id); - } - else - { - CONMSG("Plugin %d is stopped: %s\n", id, run_msg); - } - } - CONMSG(" Name: \"%s\" by %s\n", pl->m_API->GetName(), pl->m_API->GetAuthor()); - CONMSG(" Version: %s\n", pl->m_API->GetVersion()); - CONMSG(" Description: %s\n", pl->m_API->GetDescription()); - CONMSG(" License: %s\n", pl->m_API->GetLicense()); - CONMSG(" URL: %s\n", pl->m_API->GetURL()); - CONMSG(" Details: API %03d, Date: %s\n", pl->m_API->GetApiVersion(), pl->m_API->GetDate()); - } - CONMSG("File: %s\n\n", pl->m_File.c_str()); - - return true; - } - else - { - CONMSG("Usage: meta info \n"); - - return true; - } - } - else if (strcmp(command, "pause") == 0) - { - if (args >= 2) - { - int id = atoi(info->GetArg(2)); - - char error[255]; - - if (!g_PluginMngr.Pause(id, error, sizeof(error))) - { - CONMSG("Pause failed: %s\n", error); - return true; - } - - CONMSG("Plugin %d has been paused.\n", id); - - return true; - } - else - { - CONMSG("Usage: meta pause \n"); - - return true; - } - } - else if (strcmp(command, "unpause") == 0) - { - if (args >= 2) - { - int id = atoi(info->GetArg(2)); - char error[255]; - - if (!g_PluginMngr.Unpause(id, error, sizeof(error))) - { - CONMSG("Unpause failed: %s\n", error); - return true; - } - - CONMSG("Plugin %d has been unpaused.\n", id); - - return true; - } - else - { - CONMSG("Usage: meta unpause \n"); - - return true; - } - } - else if (strcmp(command, "load") == 0) - { - if (args >= 2) - { - const char *file = info->GetArg(2); - char full_path[255]; - - const char *alias = g_PluginMngr.LookupAlias(file); - if (alias) - { - file = alias; - } - - if (file[0] == '/' || strcmp(&(file[1]), ":\\") == 0) - { - g_Metamod.PathFormat(full_path, sizeof(full_path), "%s", file); - } - else - { - const char *ext = UTIL_GetExtension(file); -#if defined WIN32 || defined _WIN32 - ext = ext ? "" : ".dll"; -#else - ext = ext ? "" : "_i486.so"; -#endif - g_Metamod.PathFormat(full_path, - sizeof(full_path), - "%s/%s%s", - g_Metamod.GetBaseDir(), - file, - ext); - } - - char error[255]={0}; - bool already; - CPluginManager::CPlugin *pl; - - PluginId id = g_PluginMngr.Load(full_path, Pl_Console, already, error, sizeof(error)); - pl = g_PluginMngr.FindById(id); - if (!pl || id < Pl_MinId || (pl->m_Status < Pl_Paused)) - { - CONMSG("Failed to load plugin %s (%s).\n", file, error); - return true; - } - - if (!already) - { - CONMSG("Plugin \"%s\" loaded with id %d.\n", pl->m_API->GetName(), pl->m_Id); - } else { - CONMSG("Plugin \"%s\" is already loaded as %d.\n", pl->m_API->GetName(), pl->m_Id); - } - - return true; - } - else - { - CONMSG("Usage: meta load \n"); - - return true; - } - } - else if ( (strcmp(command, "alias") == 0) || - (strcmp(command, "aliases") == 0) ) - { - if (args >= 3) - { - const char *alias = info->GetArg(2); - const char *value = info->GetArg(3); - - g_PluginMngr.SetAlias(alias, value); - if (value == NULL || value[0] == '\0') - { - CONMSG("Deleted alias: %s.\n", alias); - } else { - CONMSG("Set alias \"%s\" to: %s\n", alias, value); - } - } - else if (args >= 2) - { - const char *alias = info->GetArg(2); - const char *value = g_PluginMngr.LookupAlias(alias); - if (value) - { - CONMSG("Alias \"%s\" is set to: %s\n", alias, value); - } else { - CONMSG("Alias \"%s\" was not found.\n", alias); - } - } - else - { - List::iterator iter, end; - CNameAlias *p; - - iter = g_PluginMngr._alias_begin(); - end = g_PluginMngr._alias_end(); - size_t total = 0; - if (iter != end) - { - CONMSG("%-10.9s %s\n", "Alias", "File"); - CONMSG(" --- \n"); - for (; iter!=end; iter++) - { - p = (*iter); - CONMSG("%-10.9s %s\n", p->alias.c_str(), p->value.c_str()); - total++; - } - CONMSG(" --- \n"); - CONMSG("%d aliases total.\n", total); - } - else - { - CONMSG("No aliases found.\n"); - } - } - return true; - } - else if (strcmp(command, "unload") == 0) - { - if (args >= 2) - { - const char *file = info->GetArg(2); - int id = atoi(file); - char error[255]={0}; - - if (id == 0 && isalpha(file[0])) - { - char full_path[255]; - const char *alias = g_PluginMngr.LookupAlias(file); - - if (alias) - { - file = alias; - } - - /* first check if it's a known filename */ - if (file[0] == '/' || strcmp(&(file[1]), ":\\") == 0) - { - g_Metamod.PathFormat(full_path, sizeof(full_path), "%s", file); - } - else - { - const char *ext = UTIL_GetExtension(file); -#if defined WIN32 || defined _WIN32 - ext = ext ? "" : ".dll"; -#else - ext = ext ? "" : "_i486.so"; -#endif - g_Metamod.PathFormat(full_path, - sizeof(full_path), - "%s/%s%s", - g_Metamod.GetBaseDir(), - file, - ext); - } - - List::iterator iter, end; - CPluginManager::CPlugin *pl; - iter = g_PluginMngr._begin(); - end = g_PluginMngr._end(); - for (; iter!=end; iter++) - { - pl = (*iter); - if (strcmp(pl->m_File.c_str(), full_path) == 0) - { - id = pl->m_Id; - break; - } - } - if (id == 0) - { - CONMSG("Plugin \"%s\" not found.\n", full_path); - return true; - } - } - - if (!g_PluginMngr.Unload(id, false, error, sizeof(error))) - { - CONMSG("Unload failed: %s\n", error); - return true; - } - - CONMSG("Plugin %d unloaded.\n", id); - } - else - { - CONMSG("Usage: meta unload \n"); - } - return true; - } - else if (strcmp(command, "force_unload") == 0) - { - if (args >= 2) - { - int id = atoi(info->GetArg(2)); - char error[255]={0}; - - if (!g_PluginMngr.Unload(id, false, error, sizeof(error))) - { - CONMSG("Force unload failed: %s\n", error); - return true; - } - - CONMSG("Plugin %d force unloaded.\n", id); - - return true; - } - else - { - CONMSG("Usage: meta force_unload \n"); - - return true; - } - } - else if (strcmp(command, "clear") == 0) - { - if (!g_PluginMngr.UnloadAll()) - { - CONMSG("One or more plugins resisted removal (cleaned anyway).\n"); - return true; - } - - CONMSG("All plugins unloaded.\n"); - - return true; - } - else if (strcmp(command, "retry") == 0) - { - if (args >= 2) - { - int id = atoi(info->GetArg(2)); - char error[255]; - - if (!g_PluginMngr.Retry(id, error, sizeof(error))) - { - CONMSG("Error reloading plugin: %s\n", error); - return true; - } - - CONMSG("Plugin %d successfully reloaded.\n", id); - - return true; - } - else - { - CONMSG("Usage: meta retry \n"); - - return true; - } - } - } - - CONMSG("Metamod:Source Menu\n"); - CONMSG("usage: meta [arguments]\n"); - CONMSG(" alias - List or set an alias\n"); - CONMSG(" clear - Unload all plugins forcefully\n"); - CONMSG(" cmds - Show plugin commands\n"); - CONMSG(" cvars - Show plugin cvars\n"); - CONMSG(" credits - About Metamod:Source\n"); - CONMSG(" force_unload - Forcefully unload a plugin\n"); - CONMSG(" game - Information about GameDLL\n"); - CONMSG(" info - Information about a plugin\n"); - CONMSG(" list - List plugins\n"); - CONMSG(" load - Load a plugin\n"); - CONMSG(" pause - Pause a running plugin\n"); - CONMSG(" refresh - Reparse plugins file\n"); - CONMSG(" retry - Attempt to reload a plugin\n"); - CONMSG(" unload - Unload a loaded plugin\n"); - CONMSG(" unpause - Unpause a paused plugin\n"); - CONMSG(" version - Version information\n"); - - return true; -} - -bool Command_ClientMeta(edict_t *client, IMetamodSourceCommandInfo *info) -{ - const char *cmd = info->GetArg(0); - - if (strcmp(cmd, "meta") == 0) - { - unsigned int args = info->GetArgCount(); - if (args == 1) - { - const char *subcmd = info->GetArg(1); - - if (strcmp(subcmd, "credits") == 0) - { - CLIENT_CONMSG(client, "Metamod:Source was developed by:\n"); - CLIENT_CONMSG(client, " SourceHook: Pavol \"PM OnoTo\" Marko\n"); - CLIENT_CONMSG(client, " GameDLL/Plugins: David \"BAILOPAN\" Anderson\n"); - CLIENT_CONMSG(client, " GameDLL: Scott \"Damaged Soul\" Ehlert\n"); - CLIENT_CONMSG(client, "For more information, see the official website\n"); - CLIENT_CONMSG(client, "http://www.sourcemm.net/\n"); - - return true; - } - else if(strcmp(subcmd, "version") == 0) - { - CLIENT_CONMSG(client, "Metamod:Source version %s\n", SOURCEMM_VERSION); - CLIENT_CONMSG(client, "Compiled on: %s\n", SOURCEMM_DATE); - CLIENT_CONMSG(client, "Plugin interface version: %d:%d\n", METAMOD_PLAPI_VERSION, PLAPI_MIN_VERSION); - CLIENT_CONMSG(client, "SourceHook version: %d:%d\n", g_SHPtr->GetIfaceVersion(), g_SHPtr->GetImplVersion()); - CLIENT_CONMSG(client, "http://www.sourcemm.net/\n"); - - return true; - } - else if(strcmp(subcmd, "list") == 0) - { - CPluginManager::CPlugin *pl; - ISmmPlugin *plapi; - const char *plname; - PluginIter i; - char buffer[256]; - int len = 0; - int plnum = 0; - - for (i = g_PluginMngr._begin(); i != g_PluginMngr._end(); i++, len=0) - { - pl = (*i); - if (pl && pl->m_Status == Pl_Running) - { - plapi = pl->m_API; - if (!plapi || !plapi->QueryRunning(NULL, 0)) - { - continue; - } - plnum++; - - len += UTIL_Format(buffer, sizeof(buffer), " [%02d]", plnum); - - plname = IS_STR_FILLED(plapi->GetName()) ? plapi->GetName() : pl->m_File.c_str(); - len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " %s", plname); - - if (IS_STR_FILLED(plapi->GetVersion())) - { - len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", plapi->GetVersion()); - } - if (IS_STR_FILLED(plapi->GetAuthor())) - { - UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", plapi->GetAuthor()); - } - - CLIENT_CONMSG(client, "%s\n", buffer); - } - } - - if (!plnum) - { - CLIENT_CONMSG(client, "No active plugins loaded.\n"); - } - - return true; - } - } - - CLIENT_CONMSG(client, "Metamod:Source Menu\n"); - CLIENT_CONMSG(client, "usage: meta \n"); - CLIENT_CONMSG(client, " credits - About Metamod:Source\n"); - CLIENT_CONMSG(client, " list - List plugins\n"); - CLIENT_CONMSG(client, " version - Version information\n"); - - return true; - } - - return false; -} diff --git a/sourcemm/metamod_console.h b/sourcemm/metamod_console.h deleted file mode 100644 index de5c868..0000000 --- a/sourcemm/metamod_console.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_CONCOMMANDS_H -#define _INCLUDE_CONCOMMANDS_H - -#include "metamod_provider.h" - -bool Command_Meta(IMetamodSourceCommandInfo *info); -bool Command_ClientMeta(edict_t *client, IMetamodSourceCommandInfo *info); - -#endif //_INCLUDE_CONCOMMANDS_H diff --git a/sourcemm/metamod_oslink.cpp b/sourcemm/metamod_oslink.cpp deleted file mode 100644 index 42f1517..0000000 --- a/sourcemm/metamod_oslink.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#include "metamod_oslink.h" -#include -#ifdef __linux -#include -#include -#endif - -#if defined __WIN32__ || defined _WIN32 || defined WIN32 -const char *dlerror() -{ - static char buf[1024]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &buf, 0, NULL); - return buf; -} -#endif - -#if defined __linux__ -int GetLastError() -{ - return errno; -} - -extern "C" void __cxa_guard_acquire(void) -{ -} - -extern "C" void __cxa_guard_release(void) -{ -} -#endif - -bool GetFileOfAddress(void *pAddr, char *buffer, size_t maxlength) -{ -#if defined WIN32 || defined _WIN32 - MEMORY_BASIC_INFORMATION mem; - if (!VirtualQuery(pAddr, &mem, sizeof(mem))) - return false; - if (mem.AllocationBase == NULL) - return false; - HMODULE dll = (HMODULE)mem.AllocationBase; - GetModuleFileName(dll, (LPTSTR)buffer, maxlength); -#elif defined __linux__ - Dl_info info; - if (!dladdr(pAddr, &info)) - return false; - if (!info.dli_fbase || !info.dli_fname) - return false; - const char *dllpath = info.dli_fname; - snprintf(buffer, maxlength, "%s", dllpath); -#endif - return true; -} - -#if defined __GNUC__ && (__GNUC__ == 3 || __GNUC__ == 4) -void * operator new(size_t size) { - return malloc(size); -} - -void * operator new[](size_t size) { - return malloc(size); -} - -void operator delete(void * ptr) { - free(ptr); -} - -void operator delete[](void * ptr) { - free(ptr); -} -#endif - diff --git a/sourcemm/metamod_oslink.h b/sourcemm/metamod_oslink.h deleted file mode 100644 index 2e6a311..0000000 --- a/sourcemm/metamod_oslink.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_OSLINK_H -#define _INCLUDE_OSLINK_H - -/** - * @brief Defines OS-independent information - * @file oslink.h - */ - -#if defined __WIN32__ || defined _WIN32 || defined WIN32 - #define WIN32_LEAN_AND_MEAN - #define OS_WIN32 - #if defined _MSC_VER && _MSC_VER >= 1400 - #undef ARRAYSIZE - #else - #define mkdir(a) _mkdir(a) - #endif - #include - #include - #include - #define dlmount(x) LoadLibrary(x) - #define dlsym(x, s) GetProcAddress(x, s) - #define dlclose(x) FreeLibrary(x) - const char* dlerror(); - #define abspath(x, s) _fullpath(x, s, sizeof(x)) - #define PATH_SEP_STR "\\" - #define PATH_SEP_CHAR '\\' - #define ALT_SEP_CHAR '/' - #define PATH_SIZE MAX_PATH - #define SERVER_DLL "server.dll" - #define strcasecmp stricmp - inline bool _IsPathSepChar(char c) { return (c == '/' || c == '\\'); } -#elif defined __linux__ - #define OS_LINUX - #include - #include - #include - #include - typedef void* HINSTANCE; - #define dlmount(x) dlopen(x,RTLD_NOW) - #define abspath(x, s) realpath(s, x) - #define PATH_SEP_STR "/" - #define PATH_SEP_CHAR '/' - #define ALT_SEP_CHAR '\\' - #define PATH_SIZE PATH_MAX - #define stricmp strcasecmp - #define strnicmp strncasecmp - #define SERVER_DLL "server_i486.so" - inline bool _IsPathSepChar(char c) { return (c == '/'); } -#endif - -#if defined __linux__ - extern int errno; - int GetLastError(); -#endif - -bool GetFileOfAddress(void *pAddr, char *buffer, size_t maxlength); - -#if defined __WIN32__ || defined _WIN32 || defined WIN32 - #define SMM_API extern "C" __declspec(dllexport) -#elif defined __GNUC__ - #if (__GNUC__ == 4) - #define SMM_API extern "C" __attribute__ ((visibility("default"))) - #else - #define SMM_API extern "C" - #endif -#endif - -#if defined __WIN32__ || defined _WIN32 || defined WIN32 - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; -#elif defined __GNUC__ -#include -#if !__GLIBC_HAVE_LONG_LONG - typedef long long int64_t; - typedef unsigned long long uint64_t; -#endif -#endif - -#ifndef __linux__ - #define snprintf _snprintf - #define vsnprintf _vsnprintf -#endif - -#endif //_INCLUDE_OSLINK_H diff --git a/sourcemm/metamod_plugins.cpp b/sourcemm/metamod_plugins.cpp deleted file mode 100644 index 1814956..0000000 --- a/sourcemm/metamod_plugins.cpp +++ /dev/null @@ -1,832 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#if defined _DEBUG -#define DEBUG2 -#undef _DEBUG -#endif -#include "metamod.h" -#include "metamod_plugins.h" -#include "metamod_util.h" -#if defined DEBUG2 -#undef DEBUG2 -#define _DEBUG -#endif - -/** - * @brief Implements functions from CPlugin.h - * @file CPlugin.cpp - */ - -using namespace SourceMM; - -#define ITER_PLEVENT(evn, plid) \ - CPluginManager::CPlugin *_Xpl; \ - SourceHook::List::iterator event; \ - IMetamodListener *api; \ - for (PluginIter iter = g_PluginMngr._begin(); iter != g_PluginMngr._end(); iter++) { \ - _Xpl = (*iter); \ - if (_Xpl->m_Id == plid) \ - continue; \ - for (event=_Xpl->m_Events.begin(); event!=_Xpl->m_Events.end(); event++) { \ - api = (*event); \ - api->evn(plid); \ - } \ - } - -CPluginManager g_PluginMngr; - -MetamodVersionInfo GlobVersionInfo = -{ - METAMOD_API_MAJOR, - METAMOD_API_MINOR, - SH_IFACE_VERSION, - SH_IMPL_VERSION, - PLAPI_MIN_VERSION, - METAMOD_PLAPI_VERSION, - SOURCE_ENGINE_UNKNOWN -}; - -CPluginManager::CPluginManager() -{ - m_LastId = Pl_MinId; - m_AllLoaded = false; -} - -CPluginManager::~CPluginManager() -{ - SourceHook::List::iterator iter; - - for (iter = m_Aliases.begin(); iter != m_Aliases.end(); iter++) - { - delete (*iter); - } - - m_Aliases.clear(); -} - -const char *CPluginManager::LookupAlias(const char *alias) -{ - SourceHook::List::iterator iter; - CNameAlias *p; - - for (iter = m_Aliases.begin(); iter != m_Aliases.end(); iter++) - { - p = (*iter); - if (p->alias.compare(alias) == 0) - { - return p->value.c_str(); - } - } - - return NULL; -} - -SourceHook::List::iterator CPluginManager::_alias_begin() -{ - return m_Aliases.begin(); -} - -SourceHook::List::iterator CPluginManager::_alias_end() -{ - return m_Aliases.end(); -} - -void CPluginManager::SetAlias(const char *alias, const char *value) -{ - SourceHook::List::iterator iter; - CNameAlias *p; - - for (iter = m_Aliases.begin(); iter != m_Aliases.end(); iter++) - { - p = (*iter); - if (p->alias.compare(alias) == 0) - { - if (value[0] == '\0') - { - iter = m_Aliases.erase(iter); - return; - } - else - { - p->value.assign(value); - return; - } - } - } - - if (value[0] != '\0') - { - p = new CNameAlias; - - p->alias.assign(alias); - p->value.assign(value); - - m_Aliases.push_back(p); - } -} - -CPluginManager::CPlugin::CPlugin() : m_Id(0), m_Source(0), m_API(NULL), m_Lib(NULL), m_UnloadFn(NULL) -{ - -} - -PluginId CPluginManager::Load(const char *file, PluginId source, bool &already, char *error, size_t maxlen) -{ - already = false; - //Check if we're about to reload an old plugin - PluginIter i = m_Plugins.begin(); - while (i != m_Plugins.end()) - { - if ((*i) && UTIL_PathCmp(file, (*i)->m_File.c_str())) - { - if ((*i)->m_Status < Pl_Paused) - { - //Attempt to load the plugin again - already = true; - i = m_Plugins.erase(i); - continue; - } - else - { - //No need to load it - already = true; - return (*i)->m_Id; - } - } - i++; - } - - CPlugin *pl = _Load(file, source, error, maxlen); - - if (!pl) - { - return Pl_BadLoad; - } - - ITER_PLEVENT(OnPluginLoad, pl->m_Id); - - return pl->m_Id; -} - -CPluginManager::CPlugin *CPluginManager::FindById(PluginId id) -{ - PluginIter i; - - for (i=m_Plugins.begin(); i!=m_Plugins.end(); i++) - { - if ( (*i)->m_Id == id )\ - { - return (*i); - } - } - - return NULL; -} - -void CPluginManager::SetAllLoaded() -{ - m_AllLoaded = true; - PluginIter i; - - for (i=m_Plugins.begin(); i!=m_Plugins.end(); i++) - { - if ( (*i) && (*i)->m_Status == Pl_Running && (*i)->m_API ) - { - //API 4 is when we added this callback - //Min version is now 5, so we ignore this check - //if ( (*i)->m_API->GetApiVersion() >= 004 ) - (*i)->m_API->AllPluginsLoaded(); - } - } -} - -bool CPluginManager::Pause(PluginId id, char *error, size_t maxlen) -{ - CPlugin *pl = FindById(id); - - if (!pl) - { - UTIL_Format(error, maxlen, "Plugin id not found"); - return false; - } - - bool ret; - - if ((ret=_Pause(pl, error, maxlen)) == true) - { - ITER_PLEVENT(OnPluginPause, pl->m_Id); - } - - return ret; -} - -bool CPluginManager::Unpause(PluginId id, char *error, size_t maxlen) -{ - CPlugin *pl = FindById(id); - - if (!pl) - { - UTIL_Format(error, maxlen, "Plugin id not found"); - return false; - } - - bool ret; - - if ( (ret=_Unpause(pl, error, maxlen)) == true ) - { - ITER_PLEVENT(OnPluginUnpause, pl->m_Id); - } - - return ret; -} - -bool CPluginManager::Unload(PluginId id, bool force, char *error, size_t maxlen) -{ - CPlugin *pl = FindById(id); - - if (!pl) - { - UTIL_Format(error, maxlen, "Plugin %d not found", id); - return false; - } - - bool ret; - PluginId old_id = pl->m_Id; - if ( (ret=_Unload(pl, force, error, maxlen)) == true ) - { - ITER_PLEVENT(OnPluginUnload, old_id); - } - - return ret; -} - -bool CPluginManager::Retry(PluginId id, char *error, size_t len) -{ - PluginIter i; - char buffer[64]; - for (i=m_Plugins.begin(); i!=m_Plugins.end(); i++) - { - if ( (*i) && (*i)->m_Id == id ) - { - if ( (*i)->m_Status >= Pl_Paused) - { - UTIL_Format(error, len, "Plugin %d is already running.", id); - return false; - } - CPlugin *pl = _Load((*i)->m_File.c_str(), Pl_Console, error, len); - if (!pl) - { - return false; - } - if (pl->m_Status >= Pl_Paused) - { - //Now it gets crazy... unload the original copy. - _Unload( (*i), true, buffer, sizeof(buffer)-1 ); - - //Set the new copy's id - pl->m_Id = id; - - //We just wasted an id... reclaim it - m_LastId--; - - return true; - } - else - { - //don't really care about the buffer here - _Unload(pl, true, buffer, sizeof(buffer)-1); - - //We just wasted an id... reclaim it - m_LastId--; - return false; - } - } - } - - UTIL_Format(error, len, "Plugin %d not found,", id); - return false; -} - -CPluginManager::CPlugin *CPluginManager::FindByAPI(ISmmPlugin *api) -{ - PluginIter i; - - //don't find bad plugins! - if (!api) - { - return NULL; - } - - for (i=m_Plugins.begin(); i!=m_Plugins.end(); i++) - { - if ((*i)->m_API == api) - { - return (*i); - } - } - - return NULL; -} - -int CPluginManager::GetPluginCount() -{ - return (int)m_Plugins.size(); -} - -const char *CPluginManager::GetStatusText(CPlugin *pl) -{ - switch (pl->m_Status) - { - case Pl_NotFound: - return "NOFILE"; - case Pl_Error: - return "ERROR"; - case Pl_Refused: - return "FAILED"; - case Pl_Paused: - return "PAUSED"; - case Pl_Running: - { - if (pl->m_API && pl->m_API->QueryRunning(NULL, 0)) - { - return "STOPPED"; - } else { - return "RUNNING"; - } - } - default: - return "-"; - } -} - -CPluginManager::CPlugin *CPluginManager::_Load(const char *file, PluginId source, char *error, size_t maxlen) -{ - FILE *fp; - CPlugin *pl; - - pl = new CPlugin(); - *error = '\0'; - - //Add plugin to list - pl->m_Id = m_LastId; - pl->m_File.assign(file); - m_Plugins.push_back(pl); - m_LastId++; - - //Check if the file even exists - fp = fopen(file, "r"); - if (!fp) - { - if (error) - { - UTIL_Format(error, maxlen, "File not found: %s", file); - } - pl->m_Status = Pl_NotFound; - } - - if (fp) - { - fclose(fp); - fp = NULL; - - //Load the file - pl->m_Lib = dlmount(file); - if (!pl->m_Lib) - { - if (error) - { - UTIL_Format(error, maxlen, "%s", dlerror()); - } - pl->m_Status = Pl_Error; - } - else - { - pl->m_API = NULL; - - /** - * First, try the new "advanced" interface - */ - METAMOD_FN_LOAD fnLoad = (METAMOD_FN_LOAD)dlsym(pl->m_Lib, "CreateInterface_MMS"); - if (fnLoad != NULL) - { - if (GlobVersionInfo.source_engine == SOURCE_ENGINE_UNKNOWN) - { - GlobVersionInfo.source_engine = g_Metamod.GetSourceEngineBuild(); - } - - /* Build path information */ - char file_path[256]; - size_t len = g_Metamod.PathFormat(file_path, sizeof(file_path), "%s", file); - - for (size_t i = len - 1; i >= 0 && i < len; i--) - { - if (_IsPathSepChar(file_path[i])) - { - file_path[i] = '\0'; - break; - } - } - - MetamodLoaderInfo info; - info.pl_file = file; - info.pl_path = file_path; - - pl->m_API = fnLoad(&GlobVersionInfo, &info); - pl->m_UnloadFn = (METAMOD_FN_UNLOAD)dlsym(pl->m_Lib, "UnloadInterface_MMS"); - } - - /** - * If we didn't get anything, try the normal/simple interface. - */ - if (pl->m_API == NULL) - { - CreateInterfaceFn pfn = (CreateInterfaceFn)(dlsym(pl->m_Lib, PL_EXPOSURE_C)); - if (!pfn) - { - if (error) - { - UTIL_Format(error, maxlen, "Function %s not found", PL_EXPOSURE_C); - } - pl->m_Status = Pl_Error; - } - else - { - pl->m_API = static_cast((pfn)(METAMOD_PLAPI_NAME, NULL)); - - if (!pl->m_API) - { - if (error) - { - UTIL_Format(error, maxlen, "Failed to get API"); - } - pl->m_Status = Pl_Error; - } - } - } - - if (pl->m_API != NULL) - { - int api = pl->m_API->GetApiVersion(); - if (api < PLAPI_MIN_VERSION) - { - if (error) - { - if (api == 13) - { - UTIL_Format(error, maxlen, "Plugin uses experimental Metamod build, probably 1.6.x (%d < %d)", api, PLAPI_MIN_VERSION); - } - else if (api <= 12 && api >= 7) - { - UTIL_Format(error, maxlen, "Older Metamod version required, probably 1.4.x (%d < %d)", api, PLAPI_MIN_VERSION); - } - else - { - UTIL_Format(error, maxlen, "Older Metamod version required, probably 1.0 (%d < %d)", api, PLAPI_MIN_VERSION); - } - } - pl->m_Status = Pl_Error; - } - else if (api > METAMOD_PLAPI_VERSION) - { - if (error) - { - UTIL_Format(error, maxlen, "Plugin requires newer Metamod version (%d > %d)", api, METAMOD_PLAPI_VERSION); - } - pl->m_Status = Pl_Error; - } - else - { - if (pl->m_API->Load(pl->m_Id, &g_Metamod, error, maxlen, m_AllLoaded)) - { - pl->m_Status = Pl_Running; - if (m_AllLoaded) - { - pl->m_API->AllPluginsLoaded(); - } - } - else - { - pl->m_Status = Pl_Refused; - } - } - } - } - } - - if (pl->m_Lib && (pl->m_Status < Pl_Paused)) - { - pl->m_Events.clear(); - g_SourceHook.UnloadPlugin(pl->m_Id); - UnregAllConCmds(pl); - - if (pl->m_UnloadFn != NULL) - { - pl->m_UnloadFn(); - } - - dlclose(pl->m_Lib); - pl->m_Lib = NULL; - pl->m_API = NULL; - } - - return pl; -} - -bool CPluginManager::_Unload(CPluginManager::CPlugin *pl, bool force, char *error, size_t maxlen) -{ - if (error) - { - *error = '\0'; - } - - if (pl->m_API && pl->m_Lib) - { - //Note, we'll always tell the plugin it will be unloading... - if (pl->m_API->Unload(error, maxlen) || force) - { - //Make sure to detach it from sourcehook! - g_SourceHook.UnloadPlugin(pl->m_Id); - - pl->m_Events.clear(); - - UnregAllConCmds(pl); - - if (pl->m_UnloadFn != NULL) - { - pl->m_UnloadFn(); - } - - //Clean up the DLL - dlclose(pl->m_Lib); - pl->m_Lib = NULL; - pl->m_API = NULL; - - //Remove the plugin from the list - PluginIter i; - for (i=m_Plugins.begin(); i!=m_Plugins.end(); i++) - { - if ( (*i)->m_Id == pl->m_Id ) - { - i = m_Plugins.erase(i); - break; - } - } - //Free its memory - delete pl; - - return true; - } - } else { - //The plugin is not valid, and let's just remove it from the list anyway - PluginIter i; - for (i=m_Plugins.begin(); i!=m_Plugins.end(); i++) - { - if ( (*i)->m_Id == pl->m_Id ) - { - i = m_Plugins.erase(i); - break; - } - } - delete pl; - - return true; - } - - return false; -} - -bool CPluginManager::_Pause(CPluginManager::CPlugin *pl, char *error, size_t maxlen) -{ - if (error) - { - *error = '\0'; - } - - if (pl->m_Status != Pl_Running || !pl->m_API) - { - if (error) - { - UTIL_Format(error, maxlen, "Plugin cannot be paused"); - } - } - else - { - if (pl->m_API->Pause(error, maxlen)) - { - g_SourceHook.PausePlugin(pl->m_Id); - pl->m_Status = Pl_Paused; - - return true; - } - } - - return false; -} - -bool CPluginManager::_Unpause(CPluginManager::CPlugin *pl, char *error, size_t maxlen) -{ - if (error) - { - *error = '\0'; - } - - if (pl->m_Status != Pl_Paused || !pl->m_API) - { - if (error) - { - UTIL_Format(error, maxlen, "Plugin cannot be unpaused"); - } - } - else - { - if (pl->m_API->Unpause(error, maxlen)) - { - g_SourceHook.UnpausePlugin(pl->m_Id); - pl->m_Status = Pl_Running; - - return true; - } - } - - return false; -} - -bool CPluginManager::UnloadAll() -{ - PluginIter i; - - char error[128]; - bool status = true; - - while ((i = m_Plugins.begin()) != m_Plugins.end()) - { - if ( !_Unload( (*i), true, error, sizeof(error)) ) - { - status = false; - } - } - - return status; -} - -bool CPluginManager::Query(PluginId id, const char **file, Pl_Status *status, PluginId *source) -{ - CPlugin *pl = FindById(id); - - if (!pl) - { - return false; - } - - if (file != NULL) - { - *file = pl->m_File.c_str(); - } - - if (status != NULL) - { - *status = pl->m_Status; - } - - if (source != NULL) - { - *source = pl->m_Source; - } - - return true; -} - -bool CPluginManager::QueryRunning(PluginId id, char *error, size_t maxlength) -{ - CPlugin *pl = FindById(id); - - if (!pl || !pl->m_API) - { - if (error) - { - UTIL_Format(error, maxlength, "Plugin not valid"); - } - return false; - } - - return pl->m_API->QueryRunning(error, maxlength); -} - -bool CPluginManager::QueryHandle(PluginId id, void **handle) -{ - CPlugin *pl = FindById(id); - - if (!pl) - { - return false; - } - - if (handle) - { - *handle = static_cast(pl->m_Lib); - } - - return true; -} - -PluginIter CPluginManager::_begin() -{ - return m_Plugins.begin(); -} - -PluginIter CPluginManager::_end() -{ - return m_Plugins.end(); -} - -void CPluginManager::AddPluginCvar(ISmmPlugin *api, ConCommandBase *pCvar) -{ - CPlugin *pl = FindByAPI(api); - - if (!pl) - { - return; - } - - pl->m_Cvars.push_back(pCvar); -} - -void CPluginManager::AddPluginCmd(ISmmPlugin *api, ConCommandBase *pCmd) -{ - CPlugin *pl = FindByAPI(api); - - if (!pl) - { - return; - } - - pl->m_Cmds.push_back(pCmd); -} - -void CPluginManager::RemovePluginCvar(ISmmPlugin *api, ConCommandBase *pCvar) -{ - CPlugin *pl = FindByAPI(api); - - if (!pl) - { - return; - } - - pl->m_Cvars.remove(pCvar); -} - -void CPluginManager::RemovePluginCmd(ISmmPlugin *api, ConCommandBase *pCmd) -{ - CPlugin *pl = FindByAPI(api); - - if (!pl) - { - return; - } - - pl->m_Cmds.remove(pCmd); -} - -void CPluginManager::UnregAllConCmds(CPlugin *pl) -{ - SourceHook::List::iterator i; - - /* :TODO: */ - for (i=pl->m_Cvars.begin(); i!=pl->m_Cvars.end(); i++) - { - g_Metamod.UnregisterConCommandBase(pl->m_Id, (*i) ); - } - pl->m_Cvars.clear(); - - for (i=pl->m_Cmds.begin(); i!=pl->m_Cmds.end(); i++) - { - g_Metamod.UnregisterConCommandBase(pl->m_Id, (*i) ); - } - pl->m_Cmds.clear(); -} - diff --git a/sourcemm/metamod_plugins.h b/sourcemm/metamod_plugins.h deleted file mode 100644 index bd7ddca..0000000 --- a/sourcemm/metamod_plugins.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_CPLUGIN_H -#define _INCLUDE_CPLUGIN_H - -/** - * @brief Implementation of Plugin API and Management routines - * @file CPlugin.cpp - */ - -#include -#include -#include -#include -#include -#include -#include -#include "metamod_oslink.h" - -/** - * History of plugin versions: (M=min, C=current) - * 1: Initial interface - * 2: Added GetLogTag() - * 3: Moved GetApiVersion() to top (2005-04-16) - * 4: Added AllPluginsLoaded() callback (2005-04-18) - * 5: Bumped version for SourceHook V4 (2005-05-01) - * 6: Added functions for console printing (2005-05-26) - * 7: Changed template libraries (2005-08-11) - * New loading structure mechanism - * New SourceHook version - * 8: New SourceHook version (2005-12-23) - * New ISmmAPI additions - * 9: New ISmmPluginManager additions - * 10: Added VSP listen functions to ISmmAPI and IMetamodListener (2007-02-09) - * 11: New SourceHook version v4.5 (May, 2007) - * 12: Orange Box API - * 13: Breaking of API for next SH version and other API changes - * MC 14: ABI stability reached for 1.6.0 changes - */ - -#define PLAPI_MIN_VERSION 14 - -struct CNameAlias -{ - SourceHook::String alias; - SourceHook::String value; -}; -/** - * @brief Implements Plugin Manager API - */ -class CPluginManager : public ISmmPluginManager -{ -public: - /** - * @brief Internal structure for holding plugin data - */ - class CPlugin - { - public: - CPlugin(); - public: - PluginId m_Id; - SourceHook::String m_File; - Pl_Status m_Status; - PluginId m_Source; - ISmmPlugin *m_API; - HINSTANCE m_Lib; - SourceHook::List m_Cvars; - SourceHook::List m_Cmds; - SourceHook::List m_Events; - METAMOD_FN_UNLOAD m_UnloadFn; - }; -public: - CPluginManager(); - ~CPluginManager(); - void SetAllLoaded(); -public: - PluginId Load(const char *file, PluginId source, bool &already, char *error, size_t maxlen); - bool Unload(PluginId id, bool force, char *error, size_t maxlen); - bool Pause(PluginId id, char *error, size_t maxlen); - bool Unpause(PluginId id, char *error, size_t maxlen); - bool UnloadAll(); - void SetAlias(const char *alias, const char *value); -public: - bool Query(PluginId id, const char **file, Pl_Status *status, PluginId *source); - bool QueryRunning(PluginId id, char *error, size_t maxlength); - bool QueryHandle(PluginId id, void **handle); - - void AddPluginCvar(ISmmPlugin *api, ConCommandBase *pCvar); - void AddPluginCmd(ISmmPlugin *api, ConCommandBase *pCmd); - void RemovePluginCvar(ISmmPlugin *api, ConCommandBase *pCvar); - void RemovePluginCmd(ISmmPlugin *api, ConCommandBase *pCmd); - - /** - * @brief Finds a plugin by Id - * - * @param id Id of plugin - * @return CPlugin on success, NULL otherwise - */ - CPlugin *FindById(PluginId id); - - CPlugin *FindByAPI(ISmmPlugin *api); - - /** - * @brief Attempts to reload a failed plugin - * - * @param id Id of plugin - * @param error Error message buffer - * @param len Maximum length of buffer - * @return True on success, false otherwise - */ - bool Retry(PluginId id, char *error, size_t len); - - int GetPluginCount(); - const char *GetStatusText(CPlugin *pl); - - //get alias info - const char *LookupAlias(const char *alias); - SourceHook::List::iterator _alias_begin(); - SourceHook::List::iterator _alias_end(); - - //Internal iterators - SourceHook::List::iterator _begin(); - SourceHook::List::iterator _end(); -private: - //These are identical internal functions for the wrappers above. - CPlugin *_Load(const char *file, PluginId source, char *error, size_t maxlen); - bool _Unload(CPlugin *pl, bool force, char *error, size_t maxlen); - bool _Pause(CPlugin *pl, char *error, size_t maxlen); - bool _Unpause(CPlugin *pl, char *error, size_t maxlen); - void UnregAllConCmds(CPlugin *pl); -private: - PluginId m_LastId; - SourceHook::List m_Plugins; - SourceHook::List m_Aliases; - bool m_AllLoaded; -}; - -typedef SourceHook::List::iterator PluginIter; - -/** @brief Singleton for plugin manager */ -extern CPluginManager g_PluginMngr; - -#endif //_INCLUDE_CPLUGIN_H - diff --git a/sourcemm/metamod_provider.h b/sourcemm/metamod_provider.h deleted file mode 100644 index 94458d7..0000000 --- a/sourcemm/metamod_provider.h +++ /dev/null @@ -1,302 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_SUPPORT_H_ -#define _INCLUDE_METAMOD_SOURCE_SUPPORT_H_ - -namespace SourceMM -{ - enum - { - ConVarFlag_None, - ConVarFlag_Notify, - ConVarFlag_Replicated, - ConVarFlag_SpOnly - }; - - enum ProvidedHooks - { - ProvidedHook_LevelInit = 0, /**< IServerGameDLL::LevelInit */ - ProvidedHook_LevelShutdown = 1, /**< IServerGameDLL::LevelShutdown */ - ProvidedHook_DLLInit = 2, /**< IServerGameDLL::DLLInit */ - ProvidedHook_DLLShutdown = 3, /**< IServerGameDLL::DLLShutdown */ - ProvidedHook_GameInit = 4, /**< IServerGameDLL::GameInit */ - }; - - /** - * @brief Abstracts command information, since the new engine fixes the - * re-entrancy problems in the tokenization system. - */ - class IMetamodSourceCommandInfo - { - public: - /** - * @brief Returns the argument count such that arguments - * 1 to N are valid arguments, and 0 is the command name. - * - * @return Argument count. - */ - virtual unsigned int GetArgCount() =0; - - /** - * @brief Returns the string of an argument number. - * - * @param num Argument number. - * @return Argument text. - */ - virtual const char *GetArg(unsigned int num) =0; - - /** - * @brief Returns the entire command argument string. - * - * @return Argument string. - */ - virtual const char *GetArgString() =0; - }; - - class IMetamodSourceProvider - { - public: - /** - * @brief Returns whether source engine build is compatible. - * - * @param build Source engine build. - * @return True if compatible, false otherwise. - */ - virtual bool IsSourceEngineBuildCompatible(int build) =0; - - /** - * @brief Retrieves hook information for each callback. Each hook - * must be implemented. - * - * @param hook Hook information to provide. - * @param pInfo Non-NULL pointer to fill with information - * about the hook's virtual location. - * @return True if supported, false to fail, which - * will cause Metamod:Source to fail. - */ - virtual bool GetHookInfo(ProvidedHooks hook, SourceHook::MemFuncInfo *pInfo) =0; - - /** - * @brief Logs a message via IVEngineServer::LogPrint. - * - * @param buffer Buffer to print. - * @return True on success, false if not supported, - * or IVEngineServer is not yet known. - */ - virtual bool LogMessage(const char *buffer) =0; - - /** - * @brief Returns the command line value of a parameter. If ICvar - * is not yet loaded, this uses an equivalent function. - * - * @param key Parameter to look up. - * @param val Default string to return if none found. - * @return Parameter value. - */ - virtual const char *GetCommandLineValue(const char *key, const char *defval) =0; - - /** - * @brief Prints a string to the remote server console. - * - * Note: new lines are not appended. - * - * @param msg Message string. - */ - virtual void ConsolePrint(const char *msg) =0; - - /** - * @brief Returns whether remote printing is available. - * - * @return True if remote printing is available, - * otherwise returns false. - */ - virtual bool IsRemotePrintingAvailable() =0; - - /** - * @brief Prints text in the specified client's console. - * - * @param client Client edict pointer. - * @param msg Message string. - */ - virtual void ClientConsolePrint(edict_t *client, const char *msg) =0; - - /** - * @brief Returns a server plugin helper for the given interface - * string. - * - * @param iface Interface version - * @return IServerPluginCallbacks pointer. - */ - virtual IServerPluginCallbacks *GetVSPCallbacks(const char *iface) =0; - - /** - * @brief Halts the server with a fatal error message. - * - * No newline is appended. - * - * @param fmt Formatted message string. - * @param ... Format parameters. - */ - virtual void DisplayError(const char *fmt, ...) =0; - - /** - * @brief Sends the server a warning message. - * - * No newline is appended. - * - * @param fmt Formatted message string. - * @param ... Format parameters. - */ - virtual void DisplayWarning(const char *fmt, ...) =0; - - /** - * @brief Attempts to notify the provider of the gamedll version being - * used. - * - * @param iface Interface string. - * @return Version number on success, 0 otherwise. - */ - virtual int TryServerGameDLL(const char *iface) =0; - - /** - * @brief Notifies the provider that the DLLInit pre-hook is almost done. - */ - virtual void Notify_DLLInit_Pre(void *gamedll, - CreateInterfaceFn engineFactory, - CreateInterfaceFn serverFactory) =0; - - virtual void Notify_DLLShutdown_Pre() =0; - - /** - * @brief Wrapper around IVEngineServer::ServerCommand() - * - * @param cmd Command string. - */ - virtual void ServerCommand(const char *cmd) =0; - - /** - * @brief Creates a ConVar pointer. - * - * @param name ConVar name. - * @param defval Default value string. - * @param flags ConVar flags. - * @param help Help text. - * @return ConVar pointer. - */ - virtual ConVar *CreateConVar(const char *name, - const char *defval, - const char *help, - int flags) =0; - - /** - * @brief Returns the string value of a ConVar. - * - * @param convar ConVar pointer. - * @return String value. - */ - virtual const char *GetConVarString(ConVar *convar) =0; - - /** - * @brief Retrieves the game description. - * - * @return Game description. - */ - virtual const char *GetGameDescription() =0; - - /** - * @brief Returns the ConCommandBase accessor. - * - * @return An IConCommandBaseAccessor pointer. - */ - virtual IConCommandBaseAccessor *GetConCommandBaseAccessor() =0; - - /** - * @brief Registers a ConCommandBase. - * - * @param pCommand ConCommandBase to register. - * @return True if successful, false otherwise. - */ - virtual bool RegisterConCommandBase(ConCommandBase *pCommand) =0; - - /** - * @brief Unregisters a ConCommandBase. - * - * @param pCommand ConCommandBase to unlink. - */ - virtual void UnregisterConCommandBase(ConCommandBase *pCommand) =0; - - /** - * @brief Returns whether a ConCommandBase is a command or not. - * - * @param pCommand ConCommandBase pointer. - * @return True if a command, false otherwise. - */ - virtual bool IsConCommandBaseACommand(ConCommandBase *pCommand) =0; - - /** - * @brief Returns the number of user messages in the GameDLL. - * - * @return Number of user messages, or -1 if SourceMM has - * failed to get user message list. - */ - virtual int GetUserMessageCount() =0; - - /** - * @brief Returns the index of the specified user message. - * - * @param name User message name. - * @param size Optional pointer to store size of user message. - * @return Message index, or -1 on failure. - */ - virtual int FindUserMessage(const char *name, int *size=NULL) =0; - - /** - * @brief Returns the name of the specified user message. - * - * @param index User message index. - * @param size Optional pointer to store size of user message. - * @return Message name, or NULL on failure. - */ - virtual const char *GetUserMessage(int index, int *size=NULL) =0; - - /** - * @brief Returns the Source Engine build. - * - * @param game Game folder. - * @return SOURCE_ENGINE constant. - */ - virtual int DetermineSourceEngine(const char *game) =0; - }; -}; - -extern PluginId g_PLID; -extern SourceHook::ISourceHook *g_SHPtr; -extern SourceMM::IMetamodSourceProvider *provider; - -#endif //_INCLUDE_METAMOD_SOURCE_SUPPORT_H_ - diff --git a/sourcemm/metamod_util.cpp b/sourcemm/metamod_util.cpp deleted file mode 100644 index 730eddf..0000000 --- a/sourcemm/metamod_util.cpp +++ /dev/null @@ -1,425 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#include -#include -#include -#include "metamod_util.h" -#include "metamod_oslink.h" - -/** - * @brief Utility functions - * @file util.cpp - */ - -const char *UTIL_GetExtension(const char *file) -{ - int len = strlen(file); - int i = 0; - - for (i = len - 1; i >= 0; i--) - { - if (file[i] == '/' || file[i] == '\\') - { - return NULL; - } - - if ((file[i] == '.') && (i != len - 1)) - { - return (const char *)&(file[i + 1]); - } - } - - return NULL; -} - -void UTIL_TrimLeft(char *buffer) -{ - /* Let's think of this as our iterator */ - char *i = buffer; - - /* Make sure the buffer isn't null */ - if (i && *i) - { - /* Add up number of whitespace characters */ - while(isspace((unsigned char) *i)) - { - i++; - } - - /* If whitespace chars in buffer then adjust string so first non-whitespace char is at start of buffer */ - if (i != buffer) - { - memmove(buffer, i, (strlen(i) + 1) * sizeof(char)); - } - } -} - -void UTIL_TrimRight(char *buffer) -{ - /* Make sure buffer isn't null */ - if (buffer) - { - size_t len = strlen(buffer); - - /* Loop through buffer backwards while replacing whitespace chars with null chars */ - for (size_t i = len - 1; i >= 0; i--) - { - if (isspace((unsigned char) buffer[i])) - { - buffer[i] = '\0'; - } else { - break; - } - } - } -} - -/* :TODO: this should skip string literals */ -void UTIL_TrimComments(char *buffer) -{ - int num_sc = 0; - size_t len = strlen(buffer); - if (buffer) - { - for (int i = len - 1; i >= 0; i--) - { - if (buffer[i] == '/') - { - if (++num_sc >= 2 && i==0) - { - buffer[i] = '\0'; - return; - } - } else { - if (num_sc >= 2) - { - buffer[i] = '\0'; - return; - } - num_sc = 0; - } - /* size_t won't go below 0, manually break out */ - if (i == 0) - { - break; - } - } - } -} - -void UTIL_KeySplit(const char *str, char *buf1, size_t len1, char *buf2, size_t len2) -{ - size_t start; - size_t len = strlen(str); - - for (start = 0; start < len; start++) - { - if (!isspace(str[start])) - { - break; - } - } - - size_t end; - for (end = start; end < len; end++) - { - if (isspace(str[end])) - { - break; - } - } - - size_t i, c = 0; - for (i = start; i < end; i++, c++) - { - if (c >= len1) - { - break; - } - buf1[c] = str[i]; - } - buf1[c] = '\0'; - - for (start = end; start < len; start++) - { - if (!isspace(str[start])) - { - break; - } - } - - for (c = 0; start < len; start++, c++) - { - if (c >= len2) - { - break; - } - buf2[c] = str[start]; - } - buf2[c] = '\0'; -} - -bool UTIL_PathCmp(const char *path1, const char *path2) -{ - size_t pos1 = 0, pos2 = 0; - - while (true) - { - if (path1[pos1] == '\0' || path2[pos2] == '\0') - { - return (path1[pos1] == path2[pos2]); - } - - if (path1[pos1] == PATH_SEP_CHAR) - { - if (path2[pos2] != PATH_SEP_CHAR) - { - return false; - } - - /* Look for extra path chars */ - while (path1[++pos1]) - { - if (path1[pos1] != PATH_SEP_CHAR) - { - break; - } - } - while (path2[++pos2]) - { - if (path2[pos2] != PATH_SEP_CHAR) - { - break; - } - } - continue; - } - - /* If we're at a different non-alphanumeric, the next character MUST match */ - if (!isalpha(path1[pos1]) && (path1[pos1] != path2[pos2])) - { - return false; - } - - #ifdef WIN32 - if (toupper(path1[pos1]) != toupper(path2[pos2])) - #else - if (path1[pos1] != path2[pos2]) - #endif - { - return false; - } - - pos1++; - pos2++; - } -} - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - size_t len = vsnprintf(buffer, maxlength, fmt, ap); - va_end(ap); - - if (len >= maxlength) - { - len = maxlength - 1; - buffer[len] = '\0'; - } - - return len; -} - -size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list params) -{ - size_t len = vsnprintf(buffer, maxlength, fmt, params); - - if (len >= maxlength) - { - len = maxlength - 1; - buffer[len] = '\0'; - } - - return len; -} - -inline bool pathchar_isalpha(char a) -{ - return (((a & 1<<7) == 0) && isalpha(a)); -} - -inline bool pathchar_sep(char a) -{ -#if defined WIN32 - return (a == '/' || a == '\\'); -#elif defined __linux__ - return (a == '/'); -#endif -} - -inline bool pathstr_isabsolute(const char *str) -{ -#if defined WIN32 - return (pathchar_isalpha(str[0]) - && str[1] == ':' - && pathchar_sep(str[2])); -#elif defined __linux__ - return (str[0] == '/'); -#endif -} - -inline bool pathchar_cmp(char a, char b) -{ -#if defined WIN32 - if (pathchar_isalpha(a) && pathchar_isalpha(b)) - { - return (tolower(a) == tolower(b)); - } - /* Either path separator is acceptable */ - if (pathchar_sep(a)) - { - return pathchar_sep(b); - } -#endif - return (a == b); -} - -/** - * @brief Forms a relative path given two absolute paths. - * - * @param buffer Buffer to store relative path in. - * @param maxlength Maximum length of the output buffer. - * @param relTo Destination folder to use as a working directory. - * Final folder name should not be pathchar-terminated. - * @param relFrom Source file or folder to use as a target. - * @return True on success, false on failure. - */ -bool UTIL_Relatize(char buffer[], - size_t maxlength, - const char *relTo, - const char *relFrom) -{ - /* We don't allow relative paths in here, force - * the user to resolve these himself! - */ - if (!pathstr_isabsolute(relTo) - || !pathstr_isabsolute(relFrom)) - { - return false; - } - -#if defined WIN32 - /* Relative paths across drives are not possible */ - if (!pathchar_cmp(relTo[0], relFrom[0])) - { - return false; - } - /* Get rid of the drive and semicolon part */ - relTo = &relTo[2]; - relFrom = &relFrom[2]; -#endif - - /* Eliminate the common root between the paths */ - const char *rootTo = NULL; - const char *rootFrom = NULL; - while (*relTo != '\0' && *relFrom != '\0') - { - /* If we get to a new path sequence, start over */ - if (pathchar_sep(*relTo) - && pathchar_sep(*relFrom)) - { - rootTo = relTo; - rootFrom = relFrom; - /* If the paths don't compare, stop looking for a common root */ - } else if (!pathchar_cmp(*relTo, *relFrom)) { - break; - } - relTo++; - relFrom++; - } - - /* NULLs shouldn't happen! */ - if (rootTo == NULL - || rootFrom == NULL) - { - return false; - } - - size_t numLevels = 0; - - /* The root case is special! - * Don't count anything from it. - */ - if (*(rootTo + 1) != '\0') - { - /* Search for how many levels we need to go up. - * Since the root pointer points to a '/', we increment - * the initial pointer by one. - */ - while (*rootTo != '\0') - { - if (pathchar_sep(*rootTo)) - { - /* Check for an improper trailing slash, - * just to be nice even though the user - * should NOT have done this! - */ - if (*(rootTo + 1) == '\0') - { - break; - } - numLevels++; - } - rootTo++; - } - } - - /* Now build the new relative path. */ - size_t len, total = 0; - while (numLevels--) - { - len = _snprintf(&buffer[total], maxlength - total, ".." PATH_SEP_STR); - if (len >= maxlength - total) - { - /* Not enough space in the buffer */ - return false; - } - total += len; - } - - /* Add the absolute path. */ - len = _snprintf(&buffer[total], maxlength - total, "%s", &rootFrom[1]); - if (len >= maxlength - total) - { - return false; - } - - return true; -} diff --git a/sourcemm/metamod_util.h b/sourcemm/metamod_util.h deleted file mode 100644 index de507ee..0000000 --- a/sourcemm/metamod_util.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source - * Copyright (C) 2004-2007 AlliedModders LLC and authors. - * All rights reserved. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software in a - * product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_UTIL_H -#define _INCLUDE_UTIL_H - -#include - -/** - * @brief Utility functions - * @file util.h - */ - -/** - * @brief Returns true is string is not blank, false otherwise. - */ -#define IS_STR_FILLED(var) (var != NULL && var[0] != '\0') - -/** - * @brief Returns a pointer to the extension in a file name. - */ -const char *UTIL_GetExtension(const char *file); - -/** - * @brief Removes C-style comments from string. - */ -void UTIL_TrimComments(char *buffer); - -/** - * @brief Removes whitespace characters from left side of string. - */ -void UTIL_TrimLeft(char *buffer); - -/** - * @brief Removes whitespace characters from right side of string. - */ -void UTIL_TrimRight(char *buffer); - -/** - * @brief Breaks a string at the first space until it reaches a non-space. - */ -void UTIL_KeySplit(const char *str, char *buf1, size_t len1, char *buf2, size_t len2); - -/** - * @brief Compares two file paths. - */ -bool UTIL_PathCmp(const char *path1, const char *path2); - -/** - * @brief Same as snprintf except that it ensures the string buffer is null terminated. - */ -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); - -/** - * @brief Same as vsnprintf except that it ensures the string buffer is null terminated. - */ -size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list params); - -/** - * @brief Forms a relative path given two absolute paths. - * - * @param buffer Buffer to store relative path in. - * @param maxlength Maximum length of the output buffer. - * @param relTo Destination folder to use as a working directory. - * Final folder name should not be pathchar-terminated. - * @param relFrom Source file or folder to use as a target. - * @return True on success, false on failure. - */ -bool UTIL_Relatize(char buffer[], - size_t maxlength, - const char *relTo, - const char *relFrom); - -#endif //_INCLUDE_UTIL_H diff --git a/sourcemm/svn_version.h b/sourcemm/svn_version.h deleted file mode 100644 index 2d7e2fa..0000000 --- a/sourcemm/svn_version.h +++ /dev/null @@ -1,13 +0,0 @@ -/** This file is autogenerated by build scripts */ - -#ifndef _INCLUDE_SVN_VERSION_H_ -#define _INCLUDE_SVN_VERSION_H_ - -#define SVN_PRODUCT_VERSION "1.6.0" - -#define SVN_REVISION 423 -#define SVN_REVISION_STRING "423" -#define SVN_FILE_VERSION 1,6,0,423 -#define SVN_FILE_VERSION_STRING "1.6.0.423" - -#endif //_INCLUDE_SVN_VERSION_H_ diff --git a/sourcemm/svn_version.tpl b/sourcemm/svn_version.tpl deleted file mode 100644 index 9b93d57..0000000 --- a/sourcemm/svn_version.tpl +++ /dev/null @@ -1,13 +0,0 @@ -/** This file is autogenerated by build scripts */ - -#ifndef _INCLUDE_SVN_VERSION_H_ -#define _INCLUDE_SVN_VERSION_H_ - -#define SVN_PRODUCT_VERSION "$PMAJOR$.$PMINOR$.$PREVISION$" - -#define SVN_REVISION $GLOBAL_BUILD$ -#define SVN_REVISION_STRING "$GLOBAL_BUILD$" -#define SVN_FILE_VERSION $PMAJOR$,$PMINOR$,$PREVISION$,$GLOBAL_BUILD$ -#define SVN_FILE_VERSION_STRING "$PMAJOR$.$PMINOR$.$PREVISION$.$GLOBAL_BUILD$" - -#endif //_INCLUDE_SVN_VERSION_H_ diff --git a/sourcemm/version.rc b/sourcemm/version.rc deleted file mode 100755 index 67529d4..0000000 --- a/sourcemm/version.rc +++ /dev/null @@ -1,101 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" -#include "svn_version.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION SVN_FILE_VERSION - PRODUCTVERSION SVN_FILE_VERSION - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Comments", "Metamod: Source" - VALUE "FileDescription", "Metamod: Source" - VALUE "FileVersion", SVN_FILE_VERSION_STRING - VALUE "InternalName", "sourcemm" - VALUE "LegalCopyright", "Copyright (c) 2004-2007, Metamod: Source Development Team" - VALUE "OriginalFilename", "server.dll" - VALUE "ProductName", "Metamod: Source" - VALUE "ProductVersion", SVN_PRODUCT_VERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/stub_mm/Makefile.ep2 b/stub_mm/Makefile.ep2 deleted file mode 100644 index 3db605c..0000000 --- a/stub_mm/Makefile.ep2 +++ /dev/null @@ -1,68 +0,0 @@ -#(C)2004-2007 SourceMM Development Team -# Makefile written by David "BAILOPAN" Anderson - -HL2SDK = ../../hl2sdk-ob -SMM_ROOT = .. -SRCDS = ~/srcds/orangebox - -### EDIT BELOW FOR OTHER PROJECTS ### - -OPT_FLAGS = -O3 -funroll-loops -s -pipe -GCC4_FLAGS = -fvisibility=hidden -fvisibility-inlines-hidden -DEBUG_FLAGS = -g -ggdb3 -CPP = gcc-4.1 -BINARY = stub_mm_i486.so - -HL2PUB = $(HL2SDK)/public - -OBJECTS = stub_mm.cpp - -LINK = vstdlib_i486.so tier0_i486.so -static-libgcc - -INCLUDE = -I. -I.. -I$(HL2PUB) -I$(HL2PUB)/dlls -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 \ - -I$(HL2PUB)/vstdlib -I$(HL2SDK)/tier1 -I$(SMM_ROOT) -I$(SMM_ROOT)/sourcehook -I$(SMM_ROOT)/sourcemm - -ifeq "$(DEBUG)" "true" - BIN_DIR = Debug - CFLAGS = $(DEBUG_FLAGS) -else - BIN_DIR = Release - CFLAGS = $(OPT_FLAGS) -endif - -GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) - -CFLAGS += -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Wno-non-virtual-dtor -Werror -fPIC -fno-exceptions -fno-rtti -msse - -ifeq "$(GCC_VERSION)" "4" - CFLAGS += $(GCC4_FLAGS) -endif - -OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) - -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< - -all: - mkdir -p $(BIN_DIR) - rm -f vstdlib_i486.so - rm -f tier0_i486.so - ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so - ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so - $(MAKE) -f Makefile.ep2 stub_mm - rm -rf $(BINARY) - ln -sf $(BIN_DIR)/$(BINARY) $(BINARY) - -stub_mm: $(OBJ_LINUX) - $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) - -debug: - $(MAKE) -f Makefile.ep2 all DEBUG=true - -default: all - -clean: - rm -rf Release/*.o - rm -rf Release/$(BINARY) - rm -rf Debug/*.o - rm -rf Debug/$(BINARY) diff --git a/stub_mm/msvc8/stub_mm.sln b/stub_mm/msvc8/stub_mm.sln deleted file mode 100644 index e0f1898..0000000 --- a/stub_mm/msvc8/stub_mm.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stub_mm", "stub_mm.vcproj", "{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug|Win32.ActiveCfg = Debug|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug|Win32.Build.0 = Debug|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release|Win32.ActiveCfg = Release|Win32 - {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/stub_mm/msvc8/stub_mm.vcproj b/stub_mm/msvc8/stub_mm.vcproj deleted file mode 100644 index 6c7214e..0000000 --- a/stub_mm/msvc8/stub_mm.vcproj +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stub_mm/stub_mm.cpp b/stub_mm/stub_mm.cpp deleted file mode 100644 index efdcd95..0000000 --- a/stub_mm/stub_mm.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source Stub Plugin - * Written by AlliedModders LLC. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * This stub plugin is public domain. - * - * Version: $Id$ - */ - -#include -#include "stub_mm.h" - -SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int); - -StubPlugin g_StubPlugin; -IServerGameDLL *server = NULL; - -PLUGIN_EXPOSE(StubPlugin, g_StubPlugin); -bool StubPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) -{ - PLUGIN_SAVEVARS(); - - GET_V_IFACE_ANY(GetServerFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); - - SH_ADD_HOOK(IServerGameDLL, ServerActivate, server, SH_STATIC(Hook_ServerActivate), true); - - return true; -} - -bool StubPlugin::Unload(char *error, size_t maxlen) -{ - SH_REMOVE_HOOK(IServerGameDLL, ServerActivate, server, SH_STATIC(Hook_ServerActivate), true); - - return true; -} - -void Hook_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) -{ - META_LOG(g_PLAPI, "ServerActivate() called: edictCount = %d, clientMax = %d", edictCount, clientMax); -} - -void StubPlugin::AllPluginsLoaded() -{ - /* This is where we'd do stuff that relies on the mod or other plugins - * being initialized (for example, cvars added and events registered). - */ -} - -bool StubPlugin::Pause(char *error, size_t maxlen) -{ - return true; -} - -bool StubPlugin::Unpause(char *error, size_t maxlen) -{ - return true; -} - -const char *StubPlugin::GetLicense() -{ - return "Public Domain"; -} - -const char *StubPlugin::GetVersion() -{ - return "1.0.0.0"; -} - -const char *StubPlugin::GetDate() -{ - return __DATE__; -} - -const char *StubPlugin::GetLogTag() -{ - return "STUB"; -} - -const char *StubPlugin::GetAuthor() -{ - return "AlliedModders LLC"; -} - -const char *StubPlugin::GetDescription() -{ - return "Sample empty plugin"; -} - -const char *StubPlugin::GetName() -{ - return "Stub Plugin"; -} - -const char *StubPlugin::GetURL() -{ - return "http://www.sourcemm.net/"; -} diff --git a/stub_mm/stub_mm.h b/stub_mm/stub_mm.h deleted file mode 100644 index c6e559e..0000000 --- a/stub_mm/stub_mm.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * vim: set ts=4 : - * ====================================================== - * Metamod:Source Stub Plugin - * Written by AlliedModders LLC. - * ====================================================== - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the authors be held liable for any damages arising from - * the use of this software. - * - * This stub plugin is public domain. - * - * Version: $Id$ - */ - -#ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ -#define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ - -#include - -class StubPlugin : public ISmmPlugin -{ -public: - bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); - bool Unload(char *error, size_t maxlen); - bool Pause(char *error, size_t maxlen); - bool Unpause(char *error, size_t maxlen); - void AllPluginsLoaded(); -public: - const char *GetAuthor(); - const char *GetName(); - const char *GetDescription(); - const char *GetURL(); - const char *GetLicense(); - const char *GetVersion(); - const char *GetDate(); - const char *GetLogTag(); -}; - -void Hook_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); - -extern StubPlugin g_StubPlugin; - -PLUGIN_GLOBALVARS(); - -#endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ diff --git a/update_tool/Makefile b/update_tool/Makefile deleted file mode 100644 index 02273b2..0000000 --- a/update_tool/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -#(C)2004-2007 SourceMM Development Team -# Makefile written by David "BAILOPAN" Anderson - -HL2SDK = ../../hl2sdk -SMM_ROOT = .. -SRCDS = ~/srcds - -### EDIT BELOW FOR OTHER PROJECTS ### - -OPT_FLAGS = -O2 -funroll-loops -s -pipe -GCC4_FLAGS = -fvisibility=hidden -fvisibility-inlines-hidden -DEBUG_FLAGS = -g -ggdb3 -CPP = gcc-4.1 -BINARY = sourcemm_update_tool_i486.so - -HL2PUB = $(HL2SDK)/public -HL2LIB = $(HL2SDK)/linux_sdk - -OBJECTS = update_tool.cpp - -LINK = vstdlib_i486.so tier0_i486.so -static-libgcc - -INCLUDE = -I. -I$(HL2PUB) -I$(HL2PUB)/dlls -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 \ - -I$(HL2PUB)/vstdlib -I$(HL2SDK)/tier1 -I$(SMM_ROOT) -I$(SMM_ROOT)/sourcehook - -ifeq "$(DEBUG)" "true" - BIN_DIR = Debug - CFLAGS = $(DEBUG_FLAGS) -else - BIN_DIR = Release - CFLAGS = $(OPT_FLAGS) -endif - -GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) - -CFLAGS += -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Wno-non-virtual-dtor -Werror -fPIC -fno-exceptions -fno-rtti -msse - -ifeq "$(GCC_VERSION)" "4" - CFLAGS += $(GCC4_FLAGS) -endif - -OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) - -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< - -all: - mkdir -p $(BIN_DIR) - ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so - ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so - nasm api_link.asm -f elf -o $(BIN_DIR)/api_link.o -DLINUX - $(MAKE) sourcemm - rm -rf $(BINARY) - ln -sf $(BIN_DIR)/$(BINARY) $(BINARY) - -sourcemm: $(OBJ_LINUX) - $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(BIN_DIR)/api_link.o $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) - -debug: - $(MAKE) all DEBUG=true - -default: all - -clean: - rm -rf Release/*.o - rm -rf Release/$(BINARY) - rm -rf Debug/*.o - rm -rf Debug/$(BINARY) diff --git a/update_tool/README.txt b/update_tool/README.txt deleted file mode 100644 index 9c974a4..0000000 --- a/update_tool/README.txt +++ /dev/null @@ -1,90 +0,0 @@ -This is the README file for sourcemm_update_tool. - -This tool will automatically correct gameinfo.txt when your server gets updated, and Valve's updater overwrites Metamod:Source's changes. This tool is experimental, and is thus a separate download for now. - -1. INSTALLATION - - a. Extract the entire package to your mod folder. The structure should look like: - - /addons/metamod/bin/sourcemm_update_tool.dll - /addons/metamod/bin/sourcemm_update_tool_i486.so - /addons/metamod/README.txt - /addons/sourcemm_update_tool.vdf - /sourcemm_updater.conf - - b. Open /sourcemm_updater.conf with your favorite text editor. Change the - "cstrike" folder to match your mod folder. - -2. CONFIGURATION - - The sourcemm_updater.conf file has two configuration options. - - mmpath - Set this to the path Metamod:Source is located in. - This defaults to addons/metamod/bin - restart - Set this to how the server should be restarted when - gameinfo.txt is patched. There are three options: - - quit - Execute "quit" in the console. Currently does not work. - never - Do not restart. - error - Generate an error message. Because of a bug in SourceDS, - this will generate a crash dump on Windows, but the server - will successfully quit. - -3. USAGE - - You do not need to do anything to use the updater tool. When your server starts, - it silently checks to see if Metamod:Source is loaded. If not, it will make sure - gameinfo.txt is correctly set. Then, depending on how it's configured, it will - kill the server. Most game server provides have auto-restart functionality on their - servers; if not, you will need to manually restart the server. - - The update tool unloads itself immediately after the server starts, so it will not - use any resources, and will not display when you type 'plugin_print'. - -4. TROUBLESHOOTING - - This tool is currently experimental. There are two possible problems. For - any issue you encounter, you should post a report here: - - http://bugs.alliedmods.net/index.php?project=4 - - a. The updater tool does not patch gameinfo.txt - - Verify that the tool is loading. You can do this by opening up the - sourcemm_update_tool.vdf file and copying its file path. Then, enter - the following command in your server console: - - plugin_load - - Example: - - plugin_load cstrike\addons\metamod\bin\sourcemm_update_tool - - If you get the following reply: - - Failed to load plugin "cstrike\addons\sourcemm_update_tool" - Unable to load plugin "cstrike\addons\sourcemm_update_tool" - - Then the tool is working, and you should post a bug report. If instead, - you get: - - Unable to load plugin "cstrike\addons\sourcemm_update_tool" - Unable to load plugin "cstrike\addons\sourcemm_update_tool" - - Then the tool is not loading properly, and the path you are trying to use - is not correct. - - b. The server always dies, and you can't start it at all - - The updater tool is either crashing or not repairing Metamod:Source - correctly. First, try changing the 'restart' line in sourcemm_updater.conf - to the following line: - - restart = never - - If that does not fix the problem, remove the .vdf file so the updater tool - will not be loaded. - - In either case, you should post a bug report containing your mod name and - your gameinfo.txt as an attachment. - \ No newline at end of file diff --git a/update_tool/api_link.asm b/update_tool/api_link.asm deleted file mode 100644 index 6f94053..0000000 --- a/update_tool/api_link.asm +++ /dev/null @@ -1,138 +0,0 @@ -;;;; -;; (C)2005-2007 AlliedModders LLC -;; By the Metamod:Source Development Team -;; This software is licensed under the zlib/libpng free software license. -;; -;; This assembly file is a short thunk wrapper to let us load as a VSP and exit quietly, -;; without any overhead of the rest of the interface, and also to prevent linking against -;; tierX or vstdlib -;;;; - -;;Exports: -;; void GetBaseDir(char *buffer, maxlength); -;; void *GetThisPointer(); -;;Imports: -;; void LoadFunction(); - -section .text - -global GetThisPointer, GetGameDir, ServerCommand -global _GetThisPointer, _GetGameDir, _ServerCommand -global _GetICvar, GetICvar -extern _LoadFunction - -GetICvar: -_GetICvar: - mov eax, [icvar] - ret - -GetThisPointer: -_GetThisPointer: - mov eax, GLOBAL_POINTER - ret - -GetGameDir: -_GetGameDir: - push ebp - mov ebp, esp - - mov ecx, [engine] ;get this pointer - mov edx, [ecx] ;get the vtable - push dword [ebp+12] ;push maxlenth - push dword [ebp+8] ;push buffer - %ifdef LINUX - push ecx ;push this pointer - %endif - call dword [edx+216] ;call IVEngineServer::GetGameDir - %ifdef LINUX - add esp, 12 ;correct stack - %endif - - pop ebp - ret - -ServerCommand -_ServerCommand: - push ebp - mov ebp, esp - - mov ecx, [engine] ;get this pointer - mov edx, [ecx] ;get the vtable - push dword [ebp+8] ;push string - %ifdef LINUX - push ecx ;push this pointer - %endif - call dword [edx+144] ;call IVEngineServer::ServerCommand - %ifdef LINUX - add esp, 8 ;correct stack - %endif - - pop ebp - ret - -thisLoadFunction: - push ebp - mov ebp, esp - - push edi - - ;get factory - %ifdef LINUX - mov edi, [ebp+12] - %else - mov edi, [ebp+8] - %endif - - push dword 0 ;NULL - push dword VENGINESERVER ;iface name - call edi ;call factory - add esp, 8 ;correct stack - - test eax, eax ;do we have a valid pointer? - jz .end ;no, bail out - - mov [engine], eax ;store the engine pointer - - push dword 0 ;NULL - push dword VENGINECVAR ;iface name - call edi ;call factory - add esp, 8 ;correct stack - - test eax, eax ;do we have a valid pointer? - jz .end ;no, bail out - - mov [icvar], eax ;store the icvar pointer - - call _LoadFunction - -.end: - ;We never load, never ever ever! - xor eax, eax - - pop edi - - pop ebp - %ifdef LINUX - ret - %else - retn 8 - %endif - -thisUnloadFunction: - ret - -section .data - INTERFACE_NAME DB "ISERVERPLUGINCALLBACKS001", 0 - VENGINESERVER DB "VEngineServer021", 0 - VENGINECVAR DB "VEngineCvar003", 0 - - VIRTUAL_TABLE DD thisLoadFunction - DD thisUnloadFunction - ;We don't need any more of the vtable here - - GLOBAL_POINTER DD VIRTUAL_TABLE - - temp_ret DD 0 - temp_ptr DD temp_ret - engine DD 0 - icvar DD 0 diff --git a/update_tool/msvc8/update_tool.sln b/update_tool/msvc8/update_tool.sln deleted file mode 100644 index 5250f8a..0000000 --- a/update_tool/msvc8/update_tool.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "update_tool", "update_tool.vcproj", "{DDD1563F-7EE2-4E76-BE57-ED84A2664A51}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DDD1563F-7EE2-4E76-BE57-ED84A2664A51}.Debug|Win32.ActiveCfg = Debug|Win32 - {DDD1563F-7EE2-4E76-BE57-ED84A2664A51}.Debug|Win32.Build.0 = Debug|Win32 - {DDD1563F-7EE2-4E76-BE57-ED84A2664A51}.Release|Win32.ActiveCfg = Release|Win32 - {DDD1563F-7EE2-4E76-BE57-ED84A2664A51}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/update_tool/msvc8/update_tool.vcproj b/update_tool/msvc8/update_tool.vcproj deleted file mode 100644 index 825e521..0000000 --- a/update_tool/msvc8/update_tool.vcproj +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/update_tool/sourcemm_update_tool.vdf b/update_tool/sourcemm_update_tool.vdf deleted file mode 100644 index 79a505c..0000000 --- a/update_tool/sourcemm_update_tool.vdf +++ /dev/null @@ -1,6 +0,0 @@ -//This is a sample VDF file. You need to edit "cstrike" to point to the mod you use. - -"Plugin" -{ - "file" "cstrike/addons/metamod/bin/sourcemm_update_tool" -} diff --git a/update_tool/sourcemm_updater.conf b/update_tool/sourcemm_updater.conf deleted file mode 100644 index bdf1eea..0000000 --- a/update_tool/sourcemm_updater.conf +++ /dev/null @@ -1,9 +0,0 @@ -;Use this to configure where Metamod resides, if you have -;changed its location -;mmpath = addons/metamod/bin - -;Use this to specify how the updater tool restarts SourceDS -; never - don't restart -; error - restart by generating a fatal error message -; quit - restart by issuing a "quit" server command -restart = error diff --git a/update_tool/update_tool.cpp b/update_tool/update_tool.cpp deleted file mode 100644 index ef6dbfe..0000000 --- a/update_tool/update_tool.cpp +++ /dev/null @@ -1,366 +0,0 @@ -#include -#include -#include -#include - -#if defined _MSC_VER -#define SEPCHAR "\\" -#define MMPATH "addons\\metamod\\bin" -#define WINDOWS_LEAN_AND_MEAN -#include -#elif defined __linux__ -#define SEPCHAR "/" -#define MMPATH "addons/metamod/bin" -#include -#endif - -#include - -extern "C" void GetGameDir(char *buffer, int maxlength); -extern "C" void *GetThisPointer(); -extern "C" void ServerCommand(const char *command); -extern "C" ICvar *GetICvar(); - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); -bool s_isspace(char c); -bool RenameFile(const char *old, const char *newf); -bool RemoveFile(const char *file); - -/* This will be called by the thunk */ -#if defined _MSC_VER -extern "C" void LoadFunction() -#elif defined __linux__ -extern "C" void _LoadFunction() -#endif -{ - ICvar *pCvar = GetICvar(); - if (pCvar->FindVar("metamod_version") != NULL) - { - /* Already exists, bail out */ - return; - } - - char gamedir[260]; - char mmpath[260]; - - enum RestartMode - { - Restart_Never, - Restart_Error, - Restart_Quit, - }; - - RestartMode mode = Restart_Error; - - GetGameDir(gamedir, sizeof(gamedir)); - - /* Defaults */ - UTIL_Format(mmpath, sizeof(mmpath), "|gameinfo_path|%s", MMPATH); - - /* Read config */ - char config[260]; - UTIL_Format(config, sizeof(config), "%s" SEPCHAR "sourcemm_updater.conf", gamedir); - FILE *fpCfg = fopen(config, "rt"); - if (fpCfg) - { - char cfgLine[512]; - while (!feof(fpCfg) && fgets(cfgLine, sizeof(cfgLine), fpCfg) != NULL) - { - char key[255]; - - size_t keyLen = 0; - - /* Strip whitespace */ - char *input = cfgLine; - while (*input != '\0' && s_isspace(*input)) - { - input++; - } - - /* Strip ending whitespace */ - size_t len = strlen(input); - for (size_t i = len - 1; - i >= 0 && i < len; - i--) - { - if (s_isspace(input[i])) - { - input[i] = '\0'; - len--; - } else { - break; - } - } - - /* Eat stuff until we find a key */ - while (*input != '\0' && !s_isspace(*input)) - { - if (keyLen < sizeof(key)) - { - key[keyLen++] = *input; - } - input++; - } - key[keyLen] = '\0'; - - /* Eat spaces until we hit an = sign */ - while (*input != '\0' && *input != '=') - { - input++; - } - - if (*input == '=') - { - input++; - } - - /* Eat spaces again */ - while (*input != '\0' && s_isspace(*input)) - { - input++; - } - - /* Ignore comments */ - if (key[0] == ';') - { - continue; - } - - /* The rest is our key */ - if (strcmp(key, "mmpath") == 0) - { - UTIL_Format(mmpath, sizeof(mmpath), "%s", input); - } else if (strcmp(key, "restart") == 0) { - if (strcmp(input, "never") == 0) - { - mode = Restart_Never; - } else if (strcmp(input, "error") == 0) { - mode = Restart_Error; - } else if (strcmp(input, "quit") == 0) { - mode = Restart_Quit; - } - } - } - fclose(fpCfg); - } - - char old_path[260]; - char new_path[260]; - - UTIL_Format(old_path, sizeof(old_path), "%s" SEPCHAR "gameinfo.txt", gamedir); - UTIL_Format(new_path, sizeof(new_path), "%s" SEPCHAR "gameinfo.new.txt", gamedir); - - FILE *fp = fopen(old_path, "rt"); - - if (!fp) - { - return; - } - - FILE *op = fopen(new_path, "wt"); - if (!op) - { - fclose(fp); - return; - } - - enum ParseState - { - Parse_None, - Parse_Root, - Parse_GameInfo, - Parse_FileSystem, - Parse_SearchPaths, - }; - - ParseState ps = Parse_Root; - - char input[1024]; - char backup[1024]; - - bool bWroteOutput = false; - - while (!feof(fp) && fgets(input, sizeof(input), fp) != NULL) - { - UTIL_Format(backup, sizeof(backup), "%s", input); - - if (ps != Parse_None) - { - char *inbuf = input; - - /* Strip beginning whitespace */ - while (*inbuf != '\0' && s_isspace(*inbuf)) - { - inbuf++; - } - - /* Strip ending whitespace */ - size_t len = strlen(inbuf); - for (size_t i = len - 1; - i >= 0 && i < len; - i--) - { - if (s_isspace(inbuf[i])) - { - inbuf[i] = '\0'; - len--; - } else { - break; - } - } - - /* Strip quotation marks */ - if (inbuf[0] == '"' - && inbuf[len-1] == '"') - { - inbuf[len - 1] = '\0'; - inbuf = &inbuf[1]; - len -= 2; - } - - /* Do tests */ - if (ps == Parse_Root && strcmp(inbuf, "GameInfo") == 0) - { - ps = Parse_GameInfo; - } else if (ps == Parse_GameInfo && strcmp(inbuf, "FileSystem") == 0) { - ps = Parse_FileSystem; - } else if (ps == Parse_FileSystem && strcmp(inbuf, "SearchPaths") == 0) { - ps = Parse_SearchPaths; - } else if (ps == Parse_SearchPaths) { - const char *game = strstr(inbuf, "Game"); - if (game) - { - if (strstr(game, "GameBin") != NULL - && strstr(game, mmpath) != NULL) - { - fclose(op); - op = NULL; - break; /* Nothing more to do! */ - } else { - fputs("\t\t\tGameBin\t\t\t", op); - fputs(mmpath, op); - fputs("\n", op); - ps = Parse_None; - bWroteOutput = true; - } - } - } - } - - fputs(backup, op); - } - - if (!op) - { - /* Well, we can't really do anything else. Give up. */ - fclose(fp); - return; - } - - /* Close all streams */ - fclose(op); - fclose(fp); - - /* If we didn't change anything, abort here */ - if (!bWroteOutput) - { - RemoveFile(new_path); - return; - } - - /* Move the old file to a backup name */ - char backup_name[260]; - UTIL_Format(backup_name, sizeof(backup_name), "%s" SEPCHAR "gameinfo.backup.txt", gamedir); - - if (!RenameFile(old_path, backup_name)) - { - /* If we can't rename, just bail out. - * We don't want to overwrite the client's default - * without backing it up first! - */ - return; - } - if (!RenameFile(new_path, old_path)) - { - /* Since this failed, we really have no choice. - * Try and rename the old back. - */ - RenameFile(backup_name, old_path); - return; - } - RemoveFile(new_path); - - if (mode == Restart_Error) - { - Error("Server is restarting to load Metamod:Source"); - } else if (mode == Restart_Quit) { - ServerCommand("quit\n"); - } -} - -bool RemoveFile(const char *file) -{ -#if defined _MSC_VER - return (_unlink(file) == 0); -#else - return (unlink(file) == 0); -#endif -} - -bool s_isspace(char c) -{ - if ((unsigned)c & 0x80) - { - return false; - } else { - return isspace(c) ? true : false; - } -} - -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - size_t len = vsnprintf(buffer, maxlength, fmt, ap); - va_end(ap); - - if (len >= maxlength) - { - len = maxlength - 1; - buffer[len] = '\0'; - } - - return len; -} - -bool RenameFile(const char *old, const char *newf) -{ -#if defined __linux__ - return (rename(old, newf) == 0); -#elif defined WIN32 - return (MoveFileA(old, newf) != 0); -#endif -} - -#if defined _MSC_VER -extern "C" __declspec(dllexport) void *CreateInterface(const char *iface, int *ret) -#elif defined __linux__ -extern "C" __attribute__((visibility("default"))) void *CreateInterface(const char *iface, int *ret) -#endif -{ - if (strcmp(iface, "ISERVERPLUGINCALLBACKS001") == 0) - { - if (ret) - { - *ret = 0; - } - return GetThisPointer(); - } - - if (ret) - { - *ret = 1; - } - return NULL; -}

    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%0DRK ziwCroHO}0}2sj_78Hdq*@P&E|;}?qkfnTre^uyqxIO~r~9{L>e;=}Jtm`Ik2VH>f$ zt3do|P=zrl+&6%aLmO2wLBZ4+Z&?4h)b0%-na2dg=tq@5L;T|vy!?p1CT5OQ-eQtE zC&7b1Qn;`@TRD0k5*|ju!eEz?yEJk=VwiMN9thJ>{u=;53Z1Q4=h66dW9fYJvliqV zJW>z>rPyF?Y-rC*hPqsLbpIeZ%NpkXjQnrsFwI}<*^egm7fFU2aEP9prq_ zwA)z=Hl>?36*WDWYPzqj^+CBJM@$iYFcrN=r1~BOq+|D_Vh?sl9|4Z)q%$r^<0BhX z&${S?k<4c`ppWTmY(u~OoxFy!c~=HNu^DN4ga+WCO|5d_$t^W0OP~_gCAY!^tV>59 zNtc>MMl=@H@|aq#meTU*x^Ac87+cphpO)|F`!Fl2f5?~RM&v_Q&4<#_O@^48(y{w& z^}CO#x~2zPKa`H%$Hjv9HR;$UEvg)!zMI72te+3d!0mnMLb@_eSF*mGmySJT2GJfG zHHele-JOc9qe4JRo9%U;Ho<~iUfj20Ol4@1Um4EaiXxe3=_=0R5TDR|Q@|nLI_eT> zH;JTLRNSWXISG*0>Zp-3DPX)%AUS7p>wl!0)~2Itsa+MdOGVcwTi1`oKah^CXIiMj zoV_Jm9}eLWLzP>vrT^i!=XFS$e5p{!XX~U=g9&I52(7&=rXU`6_DYj4V`r7x=(e7j z(pyJsbRy=5%pw}^VhRV3Rw?TXn87rPX6SN7@GCs>r%GSYl2l%sjmn-_$Z zY#?8#eo1PYev|#BS6_Qw>Z9IM*MwnFe=w3t9B6y>rb*oMIgd@PlB6f-P-A3ws&zQo zRh<2)sWg2%{ZUV;TZb_NsNilW^O97VGTivV54?V@^7@1Nt$MxsHBTO`U%c#(P`_(0 zyI|&fFPk~j=x>-_VlZxi{|z6US3H4cM%w?LZwWPFiKD~po>G?$r0g z%S))j zD^+gG$kpCcMo+^xSnv)0XfCcfX(LsLe``4(RJVsXyngX6IKB zKfyi7I?UYJIJqfEyro$<=RIw$E>6zfEH*4YVWd(I&7wQrMi)1pXwOOpep~-ksJw6g zxBprnk@IKUiOW#Z*HK_y#rGaWMuS2{Au1FIUSi?8((fpU5e5vxLe(k$RvuIV9Wyd5 z|Mx?rFxCs^sla>j+Zr_A4(DO*TM)GGV(ie`Sws$k_oDT*P9=uZ72gxo#=!X~)KAuE z`_vl08j;mfVe5(>@Ewx1_rmT|jYA!hWfb1v4Y^^=+^bhpWq|ov?Mh@dOAgJseMZJl z`*9bH=0j#-;dfxl0*7J}yKJx>KN~)b#Vqs_4yd42b+g`bppnY_f&3v^-rN#QaX$1UEDagg{?F4G_NqrZ@PsN!Y5Bv5nLUz*|wx0ugg(cX)R*d(& z#Z0%K1CJBK1)KWj9$e?Sji~6K&A_VUP(h+#R~HvrO*WaiS1NbhZ$FegwJW^dd*2pA zicChY+@J8%d;5L7>YVH-l%M>&E*L#W#L_=N8#16!(Vlv5WQWlJA~B-nCu}+ZDJ%8q z(a*mtdh~=!`ly#~w+C!3WYk26(7r}*r)3NKL}*{V_x-1>e$CZ19UU~Rg1G>0DX@bA$Nt~l^pLwx3|4^xFv1`16-ZwV=mk&!xVX8d6S zM87r&(_ng7D^q29evKI{{MHJ2kzvSK%`8_x;_YzlmyfDXiVs`YRUY`usz)jAxNfAf z$7v2T`TQwxWCAj7eqZzWnDfi!###shEb)=@s=VafeVU??)f}sZTB6NW%n6dOpdfY2O3ZKn`DY@1BmJh%;IJQ1P3F&p`h8=^RoeS@ zQXq;kxwMrEX!PFaud}360EbKO=q^!?wPSKkIW*VVE?0Mn^62jk+^gioZsf6& z6U=edP~@?)3O%s{lIc`CtvXM)%}~tRTHM%jzDc?Yy!I!BCgqcja)W=!H5ytjkR*zp zZO)67-dAaT%PdHL1Cj5^ixgOtBQEs8o|hLXuoVq0Z}-7Y$%_=&s`{39_+SU07+WD3 zGQ7x#`CML%VAeFWyw!*KWL~6TPOWdL^MQ6KG-|+A_ew}hL(5xU_X=> zDX{hREtmUX7v@C@>@|%o@A1K&lNTwl?`>$g!UsDkFH&HyuWyO@VE^@B4()`S8e6XP z!S2qB6xbyVEgVZ4(ta~9Qed0wTW0%UznB-P+TPOG!X0QEvQOnj3hb>7EtmLUug{AV z*m!+Qoe%cXyhwq)qp@X<5B99QNP%6^&@$HtTap(U4VSEfJk+<~Slb5e7q+qm(-Y@4 zTctM8*m9{4yDKj~7H-?pL3~3C;vnmcujR!9UP9jbmia#T&*nu7yeMpA%K{(#U*yFL z{5=L9{R9L5uDp1_-)G>b`{1YNMGO2o1OFBud^j&&;MW`YGhlv2f4t3OkpS?U41A5~ zIMF-uq6J>k@y6yN?k7OW<+tZ+c}Y~l!z!WqI3-abAupMiL|UoCsg8$81xI?U%;z75 zMffibRqK~lsFJ={khW`^qdVmd-oM!*5!N#8+=>1)7ohvv=ox-57oaTV4c-&E0A;DD z_x?T?pe$7!Y2*UPg8IUm+`Dqr)O(-G1t`bVMt=!ZHB`v-2JgCD3T2s5?=8v&D9g-7 z@9nt&Ww{Uo$GHGysm4)FEb>4vfU+#afq5=KSr(&V zn+s4WSHMi?0+gk`(OZ`bP?l>NymT%=S>9XkeL5GQEY~-BAIk+O%S{d5dvgKGvZUU7 zS1v$Vnj5`$3@^onu;%5q18=a#^r`77$Z=WVS}09n4U zO4Ho?UM`GW9iod3-s8D2%KD6GVZHa&T$u8T05*DG$b~7dh+c!&nhR525jxBb=fad% z)UDBL%7rPfC>pA$xiIBjZ+Xwng(Qb^Zx( za&C`!-UKI@d-V`mJ(I0R%g39i8xP+y6Czz~n>rZyLFoc;;Yyp6zU%l-zkMol%*RW4 zPqz;K=Bqxm$Z9m^I7llw-k4qXO@j?B$NP)MH~-0BG&m7Pn2c&)aea#%8*0h;VqT=Q zmSid0Uo1W~HWJZ{L}5R*!Li)}Vzu|%f@RFKWWrh@7DGm+Q&qMYS)@6G8wMA`c7vyb z>B=EJ>gM%ex@=g_7#yfniyFPV0=OHt(Jl2}$U!Dss!Sp2N`0p+b#~SUWvcfYf=p>k z)8Os2wJY3RqIebDU7~FIa|NXfIrg&4AKfJvq8z85oz;2cf1)f;`#ET-)1bN;;%;g! zGgnMyX6v}`<%?HximLczAMCR3goxR)3nyr!yEJtPG`P`#X5`1ck6`L>iT%js#BS*( zO*Va$Yk9C96=pv`5$GS5sbA$uT?-MHe6D>=_ywB)?JBObF^*61*9X?Ei~ML3b9b&p z!*0<^jyiOei$40v9?U0y{%9iEjEb!OlGe+cnlBukNZ&I2ICLWYPtxUP-z#7M6DRB@ zPN2xdm5(i@4K0=a6uR{rhfX29>PY)mQ|RivNKK)N#uhnP62JA1yhwqqYG^sx2YX6h zq-JJyeM^-OcK9F0mMO3`jV<*)*q`M^3hdN|7KBX3C2q}&6xiwYE%*bVwjuAUd65G9 zmc|wkjM|30j=V^LeQQI@H3l~1-JBOGu(kCqO+MHw^CAUyMq|shKG^f~A_ex`h89eU z7`s`K7b&pk)weYIU=M!%&`x+;W6RY(*yqMZ#+fgWr}r8<1?1^lj~Hq?`YA@&2vl{0 z_ZL2aiWn(Po^vw1`|qqc_WsR_dy{veF=0$vF(I7z4bzuChFcR&tQ_KmO6M z*!cdMx{`_@TEJ@>y&w6}NGm#dfSg1eH}UY&k6 z9iLipuuI24c%CUwOy1I0=*-k-&sj4e*;UXn5jQa07?0QDPv&hdW#a#)pCw)5L&={P z;gu$rj1(6ovjvHN#p6r)2R?Y?w-0s;aQvhINMyBmP#2nb!2yZ8NV2{7fe$)YG3IMV zWq!puoS6_foH+^Q0_Wgn9}Z_`;Be-2-{DNDb2yXOmO43Gh0Y0QvpgN|v`=^{p7o4D z#VY`COJ{YaXjd`Mi5F=^qyF+UVCw0b;Lysu( z_r+7QzfLE@>5(-P2rH$(BO8mSF8g(65sP%q2X`E1!5(;=57m!wI^xr8Kg+Nq}3b<@r~M7H7Z2u zvfU(3#ZZy0(raa}UeTkCvPC@3$Ru}T_9a{QIV-DAQyixzb+M}W1v)6oX00`$$h})KrQcIGSq(=j2TZGS z7e;qo{jvtkKXlk7uhDka{n>xyZ0Vz&I#`N!nn{gad!CoEmZoiuUe`u76Op$&maDeq zP8u}c2mY7tYHU;0{8%hvpmy3U^{wW4#wcN2puVNhTWd53R%x3h(KV3|J0qMaSrp&J zanm+*2%K|UbVaz971Un#+e2~e8>vHg`w7EncnLYMT!=Av*O{v9bX&CP%)L5b&V2Nd z(Q~Ok&GV?&o1Dxa`8S$74-PVvI6Lq$GHJsmYyFT;aEI3aRn$(1%aqE*JCnTMOlDK} zQw9RUo~oQfgfaH>HeSdhXESB`We0%PYDKf2TTW`;{=%Y=ce(gi#=E43K>a1>Dt9Qp zY=eH?PU0_;bCo9)uSi!qKwOB4PxPK7GqwPJF;UqJK;n{SWowz&+}RKGexdj_IS4vy z6vUXiO!PkOKx_m=_RJv7i5pxgx(71RdkhDZlu}L;gHoiBYxm3~ms~}y8@=-tJ?hXs z5_t?Zbfj{<(G;7mJ4gqzl})9BAk@0im~W`vx-~Ej61a4O5-hcw154AD)9s~!*;|U5 z!SGUS+?kF(8VIG4#|r0Ggc+$5o4w!Y)Rooy0-HeL>=_ahmp3*SAPhB#R7L}ag0kkr zr9?}OeqKX!p~R(D4m4v-lIj+AXXPboo)m5xyz&h;H*HED<%a9^5bh0*H~iIknW$2* z|A`LOMN3zH*xZ3$k8m27fA`mJ-Gc{1r1Yt;r-ilYHEA4H+R=D`24SGrTPSmACJ?ihMo0S_?+Sk@E;oTVj^7Y<}{#0p~ zzHZAMnb;~!>#9vsv~Am8f>oKet-{L2v?UqE+=|i4xP8#8RMzF!jBWHr9#T(XS|ieK zqNqDE(N);cQU@J;_Ou;s&ld{#7EKD=tE>D`oIecs1_8JHqA6%f1i%yL`JJ`17!EFF z9p|dLQPVYDrtg$Z^gcNjbg7g3;T^xkD++GJhvM(wpkItmsQoGeVX3Y15Uj*pHv-!W zH>&&78PzpqfP=JsUpB0$D-jef{#aja6jo#}aziVlq%-_xdbdtAWPlc);)5<22egj^ zG^_395Z{s2p94D>q~D_--v@-T{rLXB&kd3|ji4`uc&;x4jDCw%v`qMERpp)@t-}v& z&>ed1`^=awZ3;SP*WZrqoOeQZ9V&S{&_^{4!ETqs{~dyl9z3u{3ozVZTddxkdNkF@ ze$20R;-+AHuS-{IXt*pW9CSEz)>l<84KV7B!O*-tSEr*Y$_-y{u@MR=v-goNnlYR= zUjH;Vk^e*<#?Z^`12({U^l~f-^!xj*ERQ}3M3>FR0~&Z!CZK^qU;b`%ZhZQ7lACF% zJo;uN$mpAqpsgZ7uTS4}DR?Y>IO9Qo>Lj88x>b(i_P;V=9d1txW{A-vTihKoyY_A` zw)r$J&Xx&h8!}C+8vT{&fBap5vX_9eMu-}`&x|R`pDQYAgT9Og`4nhJv71>zKj(1v z8-M*rz*)w}Sh;%diTm@>Mazv4;qw6^1QfG)EGE33py3GPk1CFEE^qvgYJHn>$oiJO ze(d6Q*4Ki;pB+%M2OwP(1yMh`5kG7grvKINGYslq(akblt~Qh!seA~|;;?1#2pvg& z^qT_a!0a%c!N$RH{gutdgD|zSGxGNPf|gHj3CjpmbFr9KTMl8R=TQZpue~CJG_xt3 zo!uN#W?7;b`kNs0*<{vf5_h|Wr=v^1IN}q4>+DuFcq=v;wurV){DO7RVWNhkqKMYM z@KUO=l=CY1Gp4g$G4t=}a+77!vQr|DnJIzDW2MoD*b~+5F%ErVw&!&@?ZfczTDBeG zX(L*=AKTuxL)IuGkL^j>40Ve*)WS{Syl%Tp^WD3F6&P%~7}E;p+J595p9CCm5$Sk4 zE$o|j%m6RyzHk$}{z&^Ex!4|Yo0%(jlb4^V@5t&Dp*$7D&*Qr&emUP0<4gPGWU7r| z@FzZv2l1Klck&>NiZ^HD4t(2|CBR0DS$4gLZhmG)`ZKpEfE%XB^HqViEw}n9<_9U_ zeu|kviaY!i=)4F<+tw8dz$^*(Er)LIoKdpc<*>a8Mq(-oS_=ig0?`}the6~I<(v!} zqlb{EyeL+oE9!<9S@w5UF&tQZMjf$?Z3$My*_I4zTjFd~4D@|d`m%=@!x^d6h8})? zYkBCX5cv&C#Ux)|x)R%A(N~h* zIUUhgvehnj{)!V_?4p&ET{sMW3EehzcE zM+ACkAC!Fl*U2qYBHxfdx%Fmwtsgt7%OuwLmZpvQmMw_4rladq(M>_&oAL|SOycTg zQS=eg$Wrk0vK<@Wlh)1FP3hUj5a_E9F z5ft)Xnt>IKxrMt&vaz<36OH#S4ONsZ9|4j@oCA{%>{`wGEJN5 zQu*BT!?BD(I6}XDbUV~^AI2uI?L5Mb4)fuFr~w(1cjH=H4QvJ@Zr&G4OgC{c;&sWS zSaMjz0|_e$dYpXt%K**Mf}Wgw_%9w1;y+^YVNh!~w-kK&@a{(MYZ(4}gxSJtH5M zD!ZiHGQ+dSdZH>6f19;2R!yoZx~+#CyG@KO`&P0r09OVQOJv`-&hNg&G-Yxbd&syO zB}Lcc&Ln|#PW+S28%Q5in@buTzCU669je`H^870ehFz`brQjpNN}No?W4*96wqkSN zr5Dhl?D76EVw6MM;wW#&^`|HHK3 zpE&3wg*p6a*7!&1+o4S6R>@hoINZL32X$3Y9i9QHGnd_F>xSn= zX%{Qi1_Gr~x&2<7e90%RZ|qEoNbk&h6dY#pkj!mtEacfMaYJiy^g$!-+Anms zUqk6y>tJ|Nnd^B`4=b>-`3m@RF+Vc7=l$C1R{>cy?W~>3a<9^N6$0fZ9tbh>_j(o? zvcTk%dM%D*WciluvQ(t*JU5+D=$eX{is-oa1H7~pM;>k0L%r9Rwzj0&>v_%AzINhO z*1_1sSK{Q8`qp8GHHE{Do1cL-F}Rs43U|92cTD2yY)M}uNm&SsWR5L1=>6U5qgf4( z3dR4ZiEKSAWvfsu6NjZmAg1_r#<(zk65o~aa=uTBV+AT4iL}dHg~gFLT$#8C8X3JHa-FW(zl-w=rMda{g&)2ghPjUuD};p(_rM$ z&-|aS0A*_X4t~;Q?*#%=nS+v4rJl31H(akEt-z(JGCgDJr1B<(aaA;0x>1j;X=O_k zM;-oM!T6)%ja8sQb#j`Kk>O}gU*I%C*^>xYPcuHUfuitAwM%47 zyx{3P6<{DNFdj!wHDcnM&1JCrJqEF+)rT{7@WX?hH2jbWor>k3#GDQIk^Vcwk7fL@ z>$Lh}OA>!x!&#JC2dtve0c${Z5dlI7xNfU?_U!}+8(0!umZ^pT|5F$*vznATkc%@) zm31wJg@QQhc+{Fbk-LmfiF633m_1;VCPZ!D}}x4v1D8LxHitJ<1FjnX$%q3Gg9B=yljOp#%U;eZCnbc90Q z0@A04K(qFd$m&a>Iq9p4H*6O&URPE7>-NsniKG{~jI{Ugz2R1(bP85MQtzJ;g12{W zR9Iwnp)$WoM)jLF!DG~q{E(tX1fFK8$N}Fz!+C$v%w5IT-g5oInRD^HFq}%{)qXiCU`GrQcOP z>zSqL`U$gsvb6mfj5I{fz?}dalD{(*$L_EDvGwIe^gsv zT326w8>Zm~E?Zjn+-=XMqX$NTyF9h=Eu~l=NhNwCt9vPFvp5uQ-{%;hZ5cME8L`?; zgPGXghV)fc^_=PKu5bPUx4PLxsq@fB(&pf+V1Jy2}J7Hk2_{R*F!++Obh&^=VcF*7GB)%Xu_= z7M+YH1uf(!%|bJjfi1hPKGiyqm-Bg{$72&`{RDKmVKDN!E$YyPUn!0}Rx!J%I}=}9 zoGJYgE^%h$plcE2# z@}NI${pC=DblD^HL;DU$QF=?fE{zAeM7Zup%O}_Vd)=+!$X(yiq?!jRCJv-OSewgM930HR_hp?ExoZV-5WH+k_rcqaamsFdl(ska!6hv;2OFa|x$^nj*AAcA0^pN7??@3=< ztzxgNP_frmxnePjHMU?Y5^0=)NjyP|X3{kqR1x}YAhKGgAlW7P;qiAGy;)q&u!eW*5v`y(4jO-k7Q|E~!OT zk<}O2o{nBwQ$0IVI=iE~e9aWmtba}4Ufup8QU>CKUf3R4eL1gOGI8^6BJ=K(;oD2o z@2bpx6!7K@hZbaG( zd2AjKarjYssC^{f=#!RSg052%c8&45&AZ%dx~Kgo@wYWUF&fz)uaUv2mI9XU)dV+# z7^_B_SgPVDg00&qQ(Q@JKss2T?b?SXE?Jt%V$4wj1_KMTWs=r7mDhXj0@K*@VLN)b z@!I_K+VG@%Mw}AwRJV*)@Qoih#)B#YX9s6z^fQKjCG?K9ZI}~lgrY%66D;8(S2=y->O(llHWiXYnnrPG8D!UpkW6J6CcueQZC|bp7G4MrfsF0=p<_BNxcXYO;HxHg zCaSn8P$7-@S*=F&i8HW)}{RHx3HrA+_NXd?RPS2u5)| zB>x9p1sM3q8G#NT?6Fh*VL6S6hUuUL4q;%D{YMTSTZfLjoy`FUrq?lXF;O0z;bki< zbY_02+Oqr+ia`3PiEc*3HDmDxc8~xTWge;3z?#@WIRzUw^V*1mMy>VM#fER&bxf$2 z*Y4nj_BU7uN34U#^L&K_)d{LiR)JY3$&u-?aSI3DA!G5ST!!(+!j)e!DRHvY1y)X3 zAvs29*%9iIe@DSPgJEXe$E}Fpz+ilx;F~j-v&I`=nONV0ekbE>cGj_3#!y$x+R;#t z><{5JV!E@E!y~#f9IKf1Oe1$xeP1RQe@4Lw>kz{nD;AW7mfwGyHF)_K-WY7yTJd|H z#{1)Ui07L}O#@&&e=*j-Gc(b>tc)3i@G>Y=9!i|v9Dc&=mEF)BdQnGb-etE*EFPF_ z6#YKEdA3XQ!63~UW78ndlibzrM|aOFU7)d6P}rQcBfJgE!+=f}L=d>_c>5hHfr$*g z#vR*xBrh}ix~LT~D3z$uT_z`4DlEBkiH?`K}j?_Bctfx`XNl z!!^|C-MZZG1qOm%xLj37;lGcz4e8=0#oj?LVC-rrJq7wRt8{uFtf?)h=K+rrD7SVAvS%owxu zq4Gd4se^w1u{s=k4-a8Hp@m^PTJhN`U8^6}PCIwm+00Us)D{2lTj9JhV+|Wx@x3_D zsY-Ea*#+6}gR3Xrb^_m1mveBVP`W0RosJz=oo3!v$%78<`lp)3~*fy9q{>>1Qz}z`%MJ3h|gS8IQmZ74e?HuE9Wb+M{juDP{?^0z}Hn;QB+z$d` z#74`HvV@rh3|S24NNO-uVV0@Qa(A+`W}{f@*RC6v(gv|n&XgGJE>s6lzpi;$ zVc!Wv>ZjV2^!=L=`(tBk4@Zn6g!uU4HUN=ioAvZz8-V1T-6M(Sz>Mz#(RwW`@ZTJu zaoEGj;BaC5bb0S6ZESfFMxE)M#XB0@`+xXvOet&@U~W`#(8(8n=s2p7gAZxn{eT*GgL4HNoaYPTE5@l1-0UT|7g*E=v>{&=-f~La&=NdkV=b+iq@Rp$xDv*5sjC6(B z?blql{oS&+zgE+$#%X%Gc*_xoV?6FLD0TGL&F`-02ZOL_& zDX_{6+At1|4x^j`FWkv;{stQ%v;M0Y9l|%g#tWf|A6kqdmi> z%~nU@%P)`z!8Cl_xRz&m5x?Ml+Q!=u>N^T+@`|K_jt1sov)8(7n$Rw?`ill^FciNO z3`SXmPDo&2bNoEX?QoD|=xnL29UTkz6lXE#d05-jt1MyCsvRXD#YR9nt`R5{5c*+4 zoYq58)Wg|cBq{4LtRz;KQxn(ZWp>oZAMSaH3-W5?d@Mws5>?zGOFE;(y26Nc#}!+P z`_>7(dCE$@RECxeK2ZX{Prj!s-feV;`););d7#FDvZm>k4rWX? zMpACICQgNNp(`z5P5oVkT-fznovlTT32{Vgt73@=5<9D2r>;B+Z&&#R^}UFLD*)88 zsG92VQ8Q$tr2GGgC!?=iK!KUlH3V~Qg9E>z^nziqF}QHdA&@R#`;vz*ec0H)al6#u zEk-?x8d5 zFBDQo%3JjMelCiy&Uhjndm`Cap5nXpiJ8l>1^ficHXqz>$~Kqt<8K+W7xBQ{4ylxW zC?E=0JOCziufL z)NX)OiHkGRFx`a~t)a~>>`(+~vx|g?tvlgf5AHb|=d;GpNblNH(KclB;*bYV`>JAF z{|2?;ETBII11k;O`RGsXx#{G*U?er>EC!()RTcwB9 z|H8NRQDJ2DKk(dA2vrsAr>s^`RoNIBNu1R-SDTL{Nw88OODhvUo@=V^RAiTRMZe3H z!%XbEu5vfNPw~15{5Hz_ZgS{UcAVVeFzCH4R&$(1K-mTD@mm6D*<0BmP$zV{FUhY1 zYXBAd{AkKWw$$`4PGDP)VGhTk7rnMP_m1wQ+`_c8hGL9a=oOnfhFOUAigcy6MMHnZ z=K(&O_|nFJ}14>)NV;7?3OWGw$YMU0Lys z2x-KP?|}wMhM1V*eGNk9&4+do{4YkDhCoP38v;kh?0HHe$vHM7xtBIG-7)=2{LEpH zvHdIpeO^f!28cy#%I+T($OJ4Gd)?w?e@QVnKQj}iEpzwQ z*}&DUIzVApuTUyMQ51J&Y2`|SB9AU8K=y_XEsv;W4v=v4*o3f#f{U95mY)f*$Wt9P z0HaDQHF769c??xiIuExK@K2bEN(JqwhU( zrfm37{-jR&lxg~Ds%ft}W3O?(h#QGU@iaIhn>u3-E zC~f`P=sifrTu0`5S>iqQxc)}FH(>C=iwVnQwsmQDaZJ4_^zpvTkRaJOH95E65tY`}k;4$Xf`GMJHYLI~-fu5E|0JR=Anr zuC{>KlxQC7Zw#X4X3i*(V817nYh~jjl(Pv;Gxm?mln0$P&M)z@uK^-1t>roHE7 zu8pK^;=;G+-keSRH-WU>?fpcmirGl|UOkI=+C$ru7DcO;Ri-W3nv6m^?k*YNC%e0= zUB5M%dwfXUubd@mOu3r%Vdq`*W>d3%C7Y8Lx8KA>T4B{6TTxQ;nYqX2LcZlnbc}XoConHVpc-P!0 z_N9hQj%xTYhp2zOd(Nm9D9_PvXatj~(L2Ls%Iik!D{buUVYC|~$*Z@Z>>gyKPjzx|mw`v_plZGtwZ=2&D-oJd7-_C%R zm%D-;Id^f%Ej6xSzZ#7$?}q{)p9YAPn(LWd`q7?Adbvi9*OsUjST6k^xaz+SMb4k} z%=hG6TgKuOjc*X;8zaiL_}w33U=tNBzxC$Cj7je=6R5Ioy|3jrqYAY zoZU1yd8cU$(fs#Ak4Pc&9nXH8&K?+3T0XA$_0!&aWaJ=gf@E(o>%H89Y~_djTRy`- z`MH<5oZi*p(A$_u(grP@76x{)%dxP#{0Pn zB}EvP6d|npbY_VpgkX!VYik{nRI#akfS?NM=gABK!&9(SrE7S?3exxp2{qA^&lf8Q z#%3pGW$bibM=*ZI@?6G(AY+Z65eXWj5accN^G>s#b7MrmEw?dJ2flf9jG$%lbFvFG zM(WYp>_yHNCB1mAYQms1yaJeglPX)LQB|qg61Gz$4~5*F z&7R}3Q;KD;^0QMPWzS+urwJRF*63+cxQGV@Fmy_xiT{TiF~%$4Pleup#M$(_HH-QR ztvYM`HOug=0v#5q+{Poxxi_K5!FaNjSh*Y{5aIbNkOzm~zjCt6rmf@zP|i`qJ`XB_ zDuJy!L2k#qKYN3FL^k=6yn+e`c?+${b0D~dtXt-~akuesLu=9-`d34W) z8dP|(epC;FuA(}4+TaL@IW69~qiJYO6sg`zUD21>Ne+Suq3o13F)YVmfa4_vX{Dt^ zGqK#*Qsfr6K}3>6jv?Kk=GJ?=uTgDkd_4?Z-3w<=;S8rBF(L9Os9MJNZzGRNmm-WT z;SE`^4xt8azOzK!j{vf0EAlpoqgISFLZMZkDp{P|-aGGco!_r0ZPNdIE9_jo+NLAxk+i`?KIK?J=6M zviicW994Y>{zU_Ugy4t!O{}B(W^iYVfJY1mgPJa0Q}6w=Er|$Dp=Hioks5#`>V*Q< zI?GE1{a)j%R8K{2A$oIRE zx;(kFcfn>GsjYan^;>>GEvM`IgOM7-$fOC#VFgY#<`C1QT<0~#M}&8uyTYF!12)#= zcbU(wXmbxK9{kfy$;{yFG~(j#irCDWLS=XH8oFJZ+1FuCa;-k{Lk>UPN&^o1XIgHA z*uB~a6}6r&)dd!)DY~^sr5p>zL2I$7^be0Td4M0#Pqk)LZOdAt^=`B^j<`KyH>q2M?cc~^pzgMyz^o?99DUx)1BabbZG)*Mj z+Koqt3ETxGb$T&;;{i)hxTTl|bjm~Y@JT*Ww((TU$G4&ziI9OGHx-|!(5 z#OY9ZQGEr-Lhp$FvMyNFiy9ON0CpoID-QwiiJ%hJ%MLWMsm(P2sD+>*HHJDv$R}(3 z`en2eZY#8E^6pgAK9VOtRX$H-4DtUy({6^BK9HIs-Rtt?9pyD(qBc|eq}}`nQbjy6 z5j%z$@VWU4Irk0j11z~(!NmdWp?gm^NW z5_B_j#!ZRAmU)?2KR(Iak^u5@qhFY~%2-}TM{KXS4IdFcN4YL)a`%gA+Y&g;R`#5bna+pkMx$i#NOZNU9?y|R!x%#qyF<6{fRN;?V9^~ za-nhIv(}G+|KoS%!(a5C9Q<2;H~2Q%x%w|Z1b%x%4u0v;!DkXUiMl4Jt^dPap_#0X z#zdg|SsJ=?K7`u*mLXM%@x;*rKwj+W9(K7HOlN zkWa1`WKnr$w@^^;WfrIxuxU~N>!!OEh>OCF-d7eWc>KFV$1v@3Np1WCdwRne!y#1a zc1CRsng=-90O6)!BR0Jk_QpK#QBO8`LrYT&!rpU+d{rAO&~=GCRrc?sPnDJG<>^Xg zPF0rk(p^%;_aN_^6-RG)=hwX+YUb)V_QC24zo_}Xifub8WFRYx;e@v52bh&xUSgB3 zeLGvspf05jWH-~$en`@QND?B8hVYU2!?At+yF4>K zTvqx!3Dve0kCD>`ux$LUR}1ib7VAYD0$nImUX_ohB^#<}6<&E*)zGh~TO7WPtrTy) zbqk8kIOcj%(S+ouN=E`umKlQln=nDI+iu2qWt9Y{wzzcpr4WFdpMg~Lrb`jMJ(z5L za0ETPrU$Wud7IAbqXHe}@Et1Nn_N+VXahLD-fQ;jh9orxZ(q88sIDP=oA&7G#qfb# zAO%3N05tU?UK!xTsA-pP3sHRbZre4``Mc}NrfYU&bms=^gItT4$$MRNSET(V+AfQU zkA99+_qMTaRV=e2! z0AgKi_eul@J${pHx$Qy6ihCBSFj$T9RrY)1fc!3f(f4D{?`7xoAqbsr9BsB{$B%2n z#}G0qjDDd2yg|Jd?VPrYAWWTgT9-U5;Rt8s_+p8@p9yR!mn)@(7d6Z=jjaB*+4a#N z`n?v7#%Pr>&RA3_oI9B?m-!Nl?X6`smmRIW6vJRKgBGxO^vi@ns%g6mm~e4)@3L9= zHiG8YHI&{40pE_#H*CNbT^_zTHq7aw0;an8YM8zcXj!YIjLRP~&T-#At1Pv-5z%lM z3TZ8|!Mzh>UBZJIbZcGHuF=6w+~x*1awq)zrihheIAZo;H>F~`M@O!yM`xi7SG1=t zs*#KJ_^4$XsEp{YRB5}7T$2YjXTKL9PMJfy&Vr3Xn8U~O4@Fx78uI7#YxJ(-+6^7> zu!s$OLB}Ya8Y4EE2pUOtF_@T`PD5&}R)1#FD!yCPi zSeb}QUb)z6R3xLoFwo=WQ6(+Yc|oSGv6-@WSvKZnP*imI4ci$ztT=}LE?stEu5V{I zc-5|^V>-OK!J8OVKiA<;Hp}YrA$|V+^Yi=MU0XV0pO-GXJ)BWIkhYK8w@1sZ@Fz+C-hEj5! z!Sup4voY76gB1ie*L!nDVO_!8fh&4a89s9#!&&d0KAL4P{e^XeHF}dqb1WnWdvatf zUs!K(zj}wOZVbdIfQ*WlOLs`L-rzms$2ARP78XLYUA_k`-=l}-YnF1^C_0rq!fU