Pure mess, but maps load!

A lot of cleanup and fixes need to be done!
This commit is contained in:
momo5502 2016-09-19 00:08:37 +02:00
parent 3ff854f0dd
commit 23570ee64d
4 changed files with 255 additions and 48 deletions

View File

@ -155,6 +155,11 @@ namespace Components
AssetHandler::RestrictSignal.connect(callback); AssetHandler::RestrictSignal.connect(callback);
} }
void AssetHandler::ClearRelocations()
{
AssetHandler::Relocations.clear();
}
void AssetHandler::Relocate(void* start, void* to, DWORD size) void AssetHandler::Relocate(void* start, void* to, DWORD size)
{ {
for (DWORD i = 0; i < size; i += 4) for (DWORD i = 0; i < size; i += 4)
@ -167,12 +172,14 @@ namespace Components
void AssetHandler::OffsetToAlias(Utils::Stream::Offset* offset) void AssetHandler::OffsetToAlias(Utils::Stream::Offset* offset)
{ {
// Same here, reinterpret the value, as we're operating inside the game's environment // Same here, reinterpret the value, as we're operating inside the game's environment
offset->pointer = *reinterpret_cast<void**>((*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<void**>(pointer);
} }
void AssetHandler::ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder) void AssetHandler::ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder)
@ -285,6 +292,7 @@ namespace Components
delete i->second; delete i->second;
} }
AssetHandler::Relocations.clear();
AssetHandler::AssetInterfaces.clear(); AssetHandler::AssetInterfaces.clear();
AssetHandler::RestrictSignal.clear(); AssetHandler::RestrictSignal.clear();
AssetHandler::TypeCallbacks.clear(); AssetHandler::TypeCallbacks.clear();

View File

@ -27,6 +27,7 @@ namespace Components
static void OnFind(Game::XAssetType type, Callback* callback); static void OnFind(Game::XAssetType type, Callback* callback);
static void OnLoad(RestrictCallback* callback); static void OnLoad(RestrictCallback* callback);
static void ClearRelocations();
static void Relocate(void* start, void* to, DWORD size = 4); static void Relocate(void* start, void* to, DWORD size = 4);
static void Relocate(DWORD start, DWORD size, DWORD to) { static void Relocate(DWORD start, DWORD size, DWORD to) {

View File

@ -114,6 +114,9 @@ namespace Components
return modelSurfs; return modelSurfs;
} }
static std::map<DWORD, void*> bufferMap;
Game::FS_FOpenFileRead_t FS_FOpenFileReadDatabase = (Game::FS_FOpenFileRead_t)0x42ECA0; Game::FS_FOpenFileRead_t FS_FOpenFileReadDatabase = (Game::FS_FOpenFileRead_t)0x42ECA0;
void FS_FOpenFileReadCurrentThread(char* filename, int* handle) void FS_FOpenFileReadCurrentThread(char* filename, int* handle)
@ -250,11 +253,20 @@ namespace Components
Load_VertexBuffer(surface->vertexBuffer, &vertexBuffer, surface->numVertices * 32); Load_VertexBuffer(surface->vertexBuffer, &vertexBuffer, surface->numVertices * 32);
Load_IndexBuffer(surface->indexBuffer, &indexBuffer, surface->numPrimitives * 3); Load_IndexBuffer(surface->indexBuffer, &indexBuffer, surface->numPrimitives * 3);
ModelSurfs::BufferMap[surface->vertexBuffer] = (IUnknown*)vertexBuffer; bufferMap[(DWORD)surface->vertexBuffer] = vertexBuffer;
ModelSurfs::BufferMap[surface->indexBuffer] = (IUnknown*)indexBuffer; bufferMap[(DWORD)surface->indexBuffer] = indexBuffer;
} }
} }
struct CModelAllocData
{
void* mainArray;
void* vertexBuffer;
void* indexBuffer;
};
static std::map<DWORD, CModelAllocData*> allocData;
char* LoadCModel(const char* name) char* LoadCModel(const char* name)
{ {
char filename[512]; char filename[512];
@ -306,7 +318,7 @@ namespace Components
FixupCModelSection(header, header.index, fixups); FixupCModelSection(header, header.index, fixups);
FixupCModelSection(header, header.vertex, 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->mainArray = header.main.buffer;
allocationData->indexBuffer = header.index.buffer; allocationData->indexBuffer = header.index.buffer;
allocationData->vertexBuffer = header.vertex.buffer; allocationData->vertexBuffer = header.vertex.buffer;
@ -342,46 +354,13 @@ namespace Components
CreateCModelBuffers(header.main.buffer); CreateCModelBuffers(header.main.buffer);
// store the buffer bit // store the buffer bit
ModelSurfs::AllocMap[header.vertex.buffer] = allocationData; allocData[(DWORD)header.vertex.buffer] = allocationData;
return header.main.buffer; return header.main.buffer;
} }
bool ModelSurfs::LoadSurfaces(Game::XModel* model) Utils::Hook loadXModelAssetHook;
{ DWORD loadXModelAssetHookLoc = 0x47A6BD;
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<short>(newSurfs->numSurfaces);
model->lods[i].someCount = numSurfs;
model->lods[i].someTotalCount = surfCount;
surfCount += numSurfs;
changed = true;
}
}
return changed;
}
bool Load_XModelAssetHookFunc(char* xmodel) bool Load_XModelAssetHookFunc(char* xmodel)
{ {
@ -415,6 +394,221 @@ namespace Components
return didStuff; 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<short>(newSurfs->numSurfaces);
model->lods[i].someCount = numSurfs;
model->lods[i].someTotalCount = surfCount;
surfCount += numSurfs;
changed = true;
}
}
return changed;
}
void ModelSurfs::ReleaseModelSurf(Game::XAssetHeader header) void ModelSurfs::ReleaseModelSurf(Game::XAssetHeader header)
{ {
for (int i = 0; i < header.surfaces->numSurfaces && header.surfaces->surfaces; ++i) for (int i = 0; i < header.surfaces->numSurfaces && header.surfaces->surfaces; ++i)
@ -470,8 +664,8 @@ namespace Components
void ModelSurfs::XModelSurfsFixup(Game::XModel* model) void ModelSurfs::XModelSurfsFixup(Game::XModel* model)
{ {
//if (!ModelSurfs::LoadSurfaces(model)) if (!ModelSurfs::LoadSurfaces(model))
if(!Load_XModelAssetHookFunc((char*)model)) //if(!Load_XModelAssetHookFunc((char*)model))
{ {
Game::DB_XModelSurfsFixup(model); Game::DB_XModelSurfsFixup(model);
} }
@ -554,6 +748,8 @@ namespace Components
ModelSurfs::ModelSurfs() ModelSurfs::ModelSurfs()
{ {
PatchMW2_CModels();
return;
ModelSurfs::BufferMap.clear(); ModelSurfs::BufferMap.clear();
// Install release handler // Install release handler

View File

@ -1071,7 +1071,7 @@ namespace Components
loadStructuredDataChildArrayHook.Install(); loadStructuredDataChildArrayHook.Install();
//xmodelDefaultHook.Install(); //xmodelDefaultHook.Install();
fxDefaultHook.Install(); //fxDefaultHook.Install();
} }
else else
{ {
@ -1102,15 +1102,14 @@ namespace Components
loadTechniquePassHook.Uninstall(); loadTechniquePassHook.Uninstall();
loadStructuredDataChildArrayHook.Uninstall(); loadStructuredDataChildArrayHook.Uninstall();
xmodelDefaultHook.Uninstall();
fxDefaultHook.Uninstall();
} }
} }
void Zones::InstallPatches(int version) void Zones::InstallPatches(int version)
{ {
Zones::ZoneVersion = version; Zones::ZoneVersion = version;
AssetHandler::ClearRelocations();
PatchMW2_FifthInfinityApply(version, version >= 316); PatchMW2_FifthInfinityApply(version, version >= 316);
} }
@ -1141,6 +1140,9 @@ namespace Components
loadStructuredDataChildArrayHook.Initialize(loadStructuredDataChildArrayHookLoc, Load_StructuredDataChildArrayHookFunc, HOOK_CALL); loadStructuredDataChildArrayHook.Initialize(loadStructuredDataChildArrayHookLoc, Load_StructuredDataChildArrayHookFunc, HOOK_CALL);
pathDataTailHook.Initialize(pathDataTailHookLoc, PathDataTailHookFunc, HOOK_JUMP); pathDataTailHook.Initialize(pathDataTailHookLoc, PathDataTailHookFunc, HOOK_JUMP);
// path_node_constant_t marking function; has some terrible string references
*(BYTE*)0x4F74B0 = 0xC3;
} }
Zones::~Zones() Zones::~Zones()