From 23570ee64d4fa532a519f6953c5fa6abbcb531a8 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 19 Sep 2016 00:08:37 +0200 Subject: [PATCH] Pure mess, but maps load! A lot of cleanup and fixes need to be done! --- src/Components/Modules/AssetHandler.cpp | 14 +- src/Components/Modules/AssetHandler.hpp | 1 + src/Components/Modules/ModelSurfs.cpp | 278 ++++++++++++++++++++---- src/Components/Modules/Zones.cpp | 10 +- 4 files changed, 255 insertions(+), 48 deletions(-) diff --git a/src/Components/Modules/AssetHandler.cpp b/src/Components/Modules/AssetHandler.cpp index 95cf3e8e..3430ef08 100644 --- a/src/Components/Modules/AssetHandler.cpp +++ b/src/Components/Modules/AssetHandler.cpp @@ -155,6 +155,11 @@ namespace Components AssetHandler::RestrictSignal.connect(callback); } + void AssetHandler::ClearRelocations() + { + AssetHandler::Relocations.clear(); + } + void AssetHandler::Relocate(void* start, void* to, DWORD size) { for (DWORD i = 0; i < size; i += 4) @@ -167,12 +172,14 @@ namespace Components void AssetHandler::OffsetToAlias(Utils::Stream::Offset* offset) { // Same here, reinterpret the value, as we're operating inside the game's environment - offset->pointer = *reinterpret_cast((*Game::g_streamBlocks)[offset->GetUnpackedBlock()].data + offset->GetUnpackedOffset()); + void* pointer = (*Game::g_streamBlocks)[offset->GetUnpackedBlock()].data + offset->GetUnpackedOffset(); - if (AssetHandler::Relocations.find(offset->pointer) != AssetHandler::Relocations.end()) + if (AssetHandler::Relocations.find(pointer) != AssetHandler::Relocations.end()) { - offset->pointer = AssetHandler::Relocations[offset->pointer]; + pointer = AssetHandler::Relocations[pointer]; } + + offset->pointer = *reinterpret_cast(pointer); } void AssetHandler::ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder) @@ -285,6 +292,7 @@ namespace Components delete i->second; } + AssetHandler::Relocations.clear(); AssetHandler::AssetInterfaces.clear(); AssetHandler::RestrictSignal.clear(); AssetHandler::TypeCallbacks.clear(); diff --git a/src/Components/Modules/AssetHandler.hpp b/src/Components/Modules/AssetHandler.hpp index b1ee949c..b04e0b7c 100644 --- a/src/Components/Modules/AssetHandler.hpp +++ b/src/Components/Modules/AssetHandler.hpp @@ -27,6 +27,7 @@ namespace Components static void OnFind(Game::XAssetType type, Callback* callback); static void OnLoad(RestrictCallback* callback); + static void ClearRelocations(); static void Relocate(void* start, void* to, DWORD size = 4); static void Relocate(DWORD start, DWORD size, DWORD to) { diff --git a/src/Components/Modules/ModelSurfs.cpp b/src/Components/Modules/ModelSurfs.cpp index 208aec30..d4b48729 100644 --- a/src/Components/Modules/ModelSurfs.cpp +++ b/src/Components/Modules/ModelSurfs.cpp @@ -114,6 +114,9 @@ namespace Components return modelSurfs; } + + static std::map bufferMap; + Game::FS_FOpenFileRead_t FS_FOpenFileReadDatabase = (Game::FS_FOpenFileRead_t)0x42ECA0; void FS_FOpenFileReadCurrentThread(char* filename, int* handle) @@ -250,11 +253,20 @@ namespace Components Load_VertexBuffer(surface->vertexBuffer, &vertexBuffer, surface->numVertices * 32); Load_IndexBuffer(surface->indexBuffer, &indexBuffer, surface->numPrimitives * 3); - ModelSurfs::BufferMap[surface->vertexBuffer] = (IUnknown*)vertexBuffer; - ModelSurfs::BufferMap[surface->indexBuffer] = (IUnknown*)indexBuffer; + bufferMap[(DWORD)surface->vertexBuffer] = vertexBuffer; + bufferMap[(DWORD)surface->indexBuffer] = indexBuffer; } } + struct CModelAllocData + { + void* mainArray; + void* vertexBuffer; + void* indexBuffer; + }; + + static std::map allocData; + char* LoadCModel(const char* name) { char filename[512]; @@ -306,7 +318,7 @@ namespace Components FixupCModelSection(header, header.index, fixups); FixupCModelSection(header, header.vertex, fixups); - Game::CModelAllocData* allocationData = (Game::CModelAllocData*)malloc(sizeof(Game::CModelAllocData)); + CModelAllocData* allocationData = (CModelAllocData*)malloc(sizeof(CModelAllocData)); allocationData->mainArray = header.main.buffer; allocationData->indexBuffer = header.index.buffer; allocationData->vertexBuffer = header.vertex.buffer; @@ -342,46 +354,13 @@ namespace Components CreateCModelBuffers(header.main.buffer); // store the buffer bit - ModelSurfs::AllocMap[header.vertex.buffer] = allocationData; + allocData[(DWORD)header.vertex.buffer] = allocationData; return header.main.buffer; } - bool ModelSurfs::LoadSurfaces(Game::XModel* model) - { - if (!model) return false; - bool changed = false; - - short surfCount = 0; - - static_assert(offsetof(Game::XModel, lods) == 64, ""); - static_assert(offsetof(Game::XModelLodInfo, surfs) == 36, ""); - - for (char i = 0; i < model->numLods; ++i) - { - Game::XModelSurfs* surfs = model->lods[i].surfaces; - - if (!surfs->surfaces) - { - Game::XModelSurfs* newSurfs = ModelSurfs::LoadXModelSurfaces(surfs->name); - - surfs->surfaces = newSurfs->surfaces; - surfs->numSurfaces = newSurfs->numSurfaces; - - model->lods[i].surfaces = newSurfs; - memcpy(model->lods[i].pad3, newSurfs->pad, 24); - - short numSurfs = static_cast(newSurfs->numSurfaces); - model->lods[i].someCount = numSurfs; - model->lods[i].someTotalCount = surfCount; - surfCount += numSurfs; - - changed = true; - } - } - - return changed; - } + Utils::Hook loadXModelAssetHook; + DWORD loadXModelAssetHookLoc = 0x47A6BD; bool Load_XModelAssetHookFunc(char* xmodel) { @@ -415,6 +394,221 @@ namespace Components return didStuff; } +#pragma optimize("", off) + void __declspec(naked) Load_XModelAssetHookStub() + { + __asm + { + mov eax, [esp + 4] + push eax + call Load_XModelAssetHookFunc + add esp, 4h + + cmp al, al + jnz justReturn + + retn + + justReturn : + jmp loadXModelAssetHook.Original + } + } +#pragma optimize("", on) + + Utils::Hook getIndexBufferHook; + DWORD getIndexBufferHookLoc = 0x4B4DE0; + DWORD getIndexBufferHookRet = 0x4B4DE5; + + void GetIndexBufferHookFunc(char streamHandle, void* buffer, void** bufferOut, int* offsetOut) + { + *offsetOut = 0; + *bufferOut = bufferMap[(DWORD)buffer];//buffer; + } + +#pragma optimize("", off) + void __declspec(naked) GetIndexBufferHookStub() + { + __asm + { + mov eax, [esp + 4h] + cmp al, 0FFh + + je handleOwn + movzx eax, [esp + 4h] + jmp getIndexBufferHookRet + + handleOwn : + jmp GetIndexBufferHookFunc + } + } +#pragma optimize("", on) + + Utils::Hook getVertexBufferHook; + DWORD getVertexBufferHookLoc = 0x5BC050; + DWORD getVertexBufferHookRet = 0x5BC055; + + void GetVertexBufferHookFunc(char streamHandle, void* buffer, void** bufferOut, int* offsetOut) + { + *offsetOut = 0; + *bufferOut = bufferMap[(DWORD)buffer];//buffer; + } + +#pragma optimize("", off) + void __declspec(naked) GetVertexBufferHookStub() + { + __asm + { + mov eax, [esp + 4h] + cmp al, 0FFh + + je handleOwnVertex + movzx eax, [esp + 4h] + jmp getVertexBufferHookRet + + handleOwnVertex : + jmp GetVertexBufferHookFunc + } + } + + /*CallHook getIndexBuffer2Hook; + DWORD getIndexBuffer2HookLoc = 0x558F12; + + void* GetIndexBuffer2HookFunc(char streamHandle, void* buffer) + { + return buffer; + } + + void __declspec(naked) GetIndexBuffer2HookStub() + { + __asm + { + mov eax, [esp + 4h] + cmp al, 0FFh + + je handleOwn + movzx eax, [esp + 4h] + jmp getIndexBuffer2Hook.pOriginal + + handleOwn: + jmp GetIndexBuffer2HookFunc + } + }*/ + + Utils::Hook getIndexBuffer3Hook; + DWORD getIndexBuffer3HookLoc = 0x558E70; + + void* GetIndexBuffer3HookFunc(DWORD buffer) + { + return bufferMap[buffer]; + } + + void __declspec(naked) GetIndexBuffer3HookStub() + { + __asm + { + mov eax, [esp + 4h] + cmp al, 0FFh + + je handleOwn + movzx eax, [esp + 4h] + jmp getIndexBuffer3Hook.Original + + handleOwn : + mov eax, [edi + 0Ch] + push eax + call GetIndexBuffer3HookFunc + add esp, 4h + retn + } + } + + Utils::Hook getIndexBaseHook; + DWORD getIndexBaseHookLoc = 0x558F12; + + void __declspec(naked) GetIndexBaseHookStub() + { + __asm + { + mov eax, [esp + 4h] + cmp al, 0FFh + + je handleOwn + jmp getIndexBaseHook.Original + + handleOwn : + xor eax, eax + retn + } + } +#pragma optimize("", on) + + void PatchMW2_CModels() + { + loadXModelAssetHook.Initialize(loadXModelAssetHookLoc, Load_XModelAssetHookStub, HOOK_CALL); + loadXModelAssetHook.Install(); + + getIndexBufferHook.Initialize(getIndexBufferHookLoc, GetIndexBufferHookStub, HOOK_JUMP); + getIndexBufferHook.Install(); + + //getIndexBuffer2Hook.initialize(getIndexBuffer2HookLoc, GetIndexBuffer2HookStub); + //getIndexBuffer2Hook.installHook(); + + getIndexBuffer3Hook.Initialize(getIndexBuffer3HookLoc, GetIndexBuffer3HookStub, HOOK_CALL); + getIndexBuffer3Hook.Install(); + + getIndexBaseHook.Initialize(getIndexBaseHookLoc, GetIndexBaseHookStub, HOOK_CALL); + getIndexBaseHook.Install(); + + getVertexBufferHook.Initialize(getVertexBufferHookLoc, GetVertexBufferHookStub, HOOK_JUMP); + getVertexBufferHook.Install(); + + //*(DWORD*)0x799AC4 = (DWORD)DB_RemoveXModelSurfs; + + //getBoneIndexHook1.initialize(getBoneIndexHook1Loc, GetBoneIndexHookStub); + //getBoneIndexHook1.installHook(); + + //*(void**)0x4E3409 = CL_DObjCreateHookFunc; + + //updateDObjSetBitsHook.initialize(updateDObjSetBitsHookLoc, UpdateDObjSetBitsHookStub); + //updateDObjSetBitsHook.installHook(); + + //getBoneIndexHook2.initialize(getBoneIndexHook2Loc, GetBoneIndexHookStub); + //getBoneIndexHook2.installHook(); + } + + bool ModelSurfs::LoadSurfaces(Game::XModel* model) + { + if (!model) return false; + bool changed = false; + + short surfCount = 0; + + for (char i = 0; i < model->numLods; ++i) + { + Game::XModelSurfs* surfs = model->lods[i].surfaces; + + if (!surfs->surfaces) + { + Game::XModelSurfs* newSurfs = ModelSurfs::LoadXModelSurfaces(surfs->name); + + surfs->surfaces = newSurfs->surfaces; + surfs->numSurfaces = newSurfs->numSurfaces; + + model->lods[i].surfs = newSurfs->surfaces; + memcpy(model->lods[i].pad3, newSurfs->pad, 24); + + short numSurfs = static_cast(newSurfs->numSurfaces); + model->lods[i].someCount = numSurfs; + model->lods[i].someTotalCount = surfCount; + surfCount += numSurfs; + + changed = true; + } + } + + return changed; + } + void ModelSurfs::ReleaseModelSurf(Game::XAssetHeader header) { for (int i = 0; i < header.surfaces->numSurfaces && header.surfaces->surfaces; ++i) @@ -470,8 +664,8 @@ namespace Components void ModelSurfs::XModelSurfsFixup(Game::XModel* model) { - //if (!ModelSurfs::LoadSurfaces(model)) - if(!Load_XModelAssetHookFunc((char*)model)) + if (!ModelSurfs::LoadSurfaces(model)) + //if(!Load_XModelAssetHookFunc((char*)model)) { Game::DB_XModelSurfsFixup(model); } @@ -554,6 +748,8 @@ namespace Components ModelSurfs::ModelSurfs() { + PatchMW2_CModels(); + return; ModelSurfs::BufferMap.clear(); // Install release handler diff --git a/src/Components/Modules/Zones.cpp b/src/Components/Modules/Zones.cpp index 0863558f..742727ed 100644 --- a/src/Components/Modules/Zones.cpp +++ b/src/Components/Modules/Zones.cpp @@ -1071,7 +1071,7 @@ namespace Components loadStructuredDataChildArrayHook.Install(); //xmodelDefaultHook.Install(); - fxDefaultHook.Install(); + //fxDefaultHook.Install(); } else { @@ -1102,15 +1102,14 @@ namespace Components loadTechniquePassHook.Uninstall(); loadStructuredDataChildArrayHook.Uninstall(); - - xmodelDefaultHook.Uninstall(); - fxDefaultHook.Uninstall(); } } void Zones::InstallPatches(int version) { Zones::ZoneVersion = version; + AssetHandler::ClearRelocations(); + PatchMW2_FifthInfinityApply(version, version >= 316); } @@ -1141,6 +1140,9 @@ namespace Components loadStructuredDataChildArrayHook.Initialize(loadStructuredDataChildArrayHookLoc, Load_StructuredDataChildArrayHookFunc, HOOK_CALL); pathDataTailHook.Initialize(pathDataTailHookLoc, PathDataTailHookFunc, HOOK_JUMP); + + // path_node_constant_t marking function; has some terrible string references + *(BYTE*)0x4F74B0 = 0xC3; } Zones::~Zones()