More stuff
This commit is contained in:
parent
49beaf5566
commit
3ff854f0dd
@ -149,6 +149,11 @@ namespace Components
|
||||
Maps::DependencyList[expression] = zone;
|
||||
}
|
||||
|
||||
bool Maps::IgnoreEntityStub(const char* entity)
|
||||
{
|
||||
return (Utils::String::StartsWith(entity, "dyn_") || Utils::String::StartsWith(entity, "node_") || Utils::String::StartsWith(entity, "actor_"));
|
||||
}
|
||||
|
||||
void Maps::ReallocateEntryPool()
|
||||
{
|
||||
Assert_Size(Game::XAssetEntry, 16);
|
||||
@ -208,6 +213,9 @@ namespace Components
|
||||
// Intercept map zone loading
|
||||
Utils::Hook(0x42C2AF, Maps::LoadMapZones, HOOK_CALL).Install()->Quick();
|
||||
|
||||
// Ignore SP entities
|
||||
Utils::Hook(0x5FBD6E, Maps::IgnoreEntityStub, HOOK_CALL).Install()->Quick();
|
||||
|
||||
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_GAME_MAP_SP, 1);
|
||||
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMAGE, 7168);
|
||||
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, 2700);
|
||||
|
@ -24,6 +24,8 @@ namespace Components
|
||||
|
||||
static void OverrideMapEnts(Game::MapEnts* ents);
|
||||
|
||||
static bool IgnoreEntityStub(const char* entity);
|
||||
|
||||
void ReallocateEntryPool();
|
||||
};
|
||||
}
|
||||
|
@ -114,6 +114,239 @@ namespace Components
|
||||
return modelSurfs;
|
||||
}
|
||||
|
||||
Game::FS_FOpenFileRead_t FS_FOpenFileReadDatabase = (Game::FS_FOpenFileRead_t)0x42ECA0;
|
||||
|
||||
void FS_FOpenFileReadCurrentThread(char* filename, int* handle)
|
||||
{
|
||||
if (GetCurrentThreadId() == *(DWORD*)0x1CDE7FC)
|
||||
{
|
||||
Game::FS_FOpenFileRead(filename, handle, 0);
|
||||
}
|
||||
else if (GetCurrentThreadId() == *(DWORD*)0x1CDE814)
|
||||
{
|
||||
FS_FOpenFileReadDatabase(filename, handle, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
*handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct CModelSectionHeader
|
||||
{
|
||||
int size;
|
||||
int offset;
|
||||
int fixupStart;
|
||||
int fixupCount;
|
||||
char* buffer;
|
||||
};
|
||||
|
||||
struct CModelHeader
|
||||
{
|
||||
int version;
|
||||
unsigned int signature;
|
||||
CModelSectionHeader main;
|
||||
CModelSectionHeader index;
|
||||
CModelSectionHeader vertex;
|
||||
CModelSectionHeader fixup;
|
||||
};
|
||||
|
||||
void ReadCModelSection(int handle, CModelSectionHeader& header)
|
||||
{
|
||||
Game::FS_Seek(handle, header.offset, FS_SEEK_SET);
|
||||
Game::FS_Read(header.buffer, header.size, handle);
|
||||
}
|
||||
|
||||
void FixupCModelSection(CModelHeader& header, CModelSectionHeader& section, DWORD* fixups)
|
||||
{
|
||||
for (int i = section.fixupStart; i < section.fixupStart + section.fixupCount; i++)
|
||||
{
|
||||
DWORD fixup = fixups[i];
|
||||
int targetSectionNum = fixup & 3;
|
||||
CModelSectionHeader* targetSection;
|
||||
|
||||
if (targetSectionNum == 0)
|
||||
{
|
||||
targetSection = &header.main;
|
||||
}
|
||||
else if (targetSectionNum == 1)
|
||||
{
|
||||
targetSection = &header.index;
|
||||
}
|
||||
else if (targetSectionNum == 2)
|
||||
{
|
||||
targetSection = &header.vertex;
|
||||
}
|
||||
|
||||
*(DWORD*)(section.buffer + (fixup >> 3)) += (DWORD)targetSection->buffer;
|
||||
}
|
||||
}
|
||||
|
||||
void Load_VertexBuffer(void* data, void** where, int len)
|
||||
{
|
||||
DWORD func = 0x5112C0;
|
||||
|
||||
__asm
|
||||
{
|
||||
push edi
|
||||
|
||||
mov eax, len
|
||||
mov edi, where
|
||||
push data
|
||||
|
||||
call func
|
||||
|
||||
add esp, 4
|
||||
pop edi
|
||||
}
|
||||
}
|
||||
|
||||
typedef void* (__cdecl * R_AllocStaticIndexBuffer_t)(void** store, int length);
|
||||
R_AllocStaticIndexBuffer_t R_AllocStaticIndexBuffer = (R_AllocStaticIndexBuffer_t)0x51E7A0;
|
||||
|
||||
void Load_IndexBuffer(void* data, void** storeHere, int count)
|
||||
{
|
||||
static Game::dvar_t* r_loadForRenderer = *(Game::dvar_t**)0x69F0ED4;
|
||||
|
||||
if (r_loadForRenderer->current.boolean)
|
||||
{
|
||||
void* buffer = R_AllocStaticIndexBuffer(storeHere, 2 * count);
|
||||
memcpy(buffer, data, 2 * count);
|
||||
|
||||
if (IsBadReadPtr(storeHere, 4) || IsBadReadPtr(*storeHere, 4))
|
||||
{
|
||||
Game::Com_Error(0, "Static index buffer allocation failed.");
|
||||
}
|
||||
|
||||
__asm
|
||||
{
|
||||
push ecx
|
||||
mov ecx, storeHere
|
||||
mov ecx, [ecx]
|
||||
|
||||
mov eax, [ecx]
|
||||
add eax, 30h
|
||||
mov eax, [eax]
|
||||
|
||||
push ecx
|
||||
call eax
|
||||
|
||||
pop ecx
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateCModelBuffers(void* surfs)
|
||||
{
|
||||
Game::XModelSurfs* model = (Game::XModelSurfs*)surfs;
|
||||
|
||||
for (int i = 0; i < model->numSurfaces; i++)
|
||||
{
|
||||
Game::XSurface* surface = &model->surfaces[i];
|
||||
|
||||
void* vertexBuffer;
|
||||
void* indexBuffer;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
char* LoadCModel(const char* name)
|
||||
{
|
||||
char filename[512];
|
||||
sprintf_s(filename, sizeof(filename), "models/%s", name);
|
||||
|
||||
int handle;
|
||||
FS_FOpenFileReadCurrentThread(filename, &handle);
|
||||
|
||||
if (handle <= 0)
|
||||
{
|
||||
Game::Com_Error(1, "Error opening %s", filename);
|
||||
}
|
||||
|
||||
CModelHeader header;
|
||||
|
||||
if (Game::FS_Read(&header, sizeof(header), handle) != sizeof(header))
|
||||
{
|
||||
Game::FS_FCloseFile(handle);
|
||||
Game::Com_Error(1, "%s: header could not be read", filename);
|
||||
}
|
||||
|
||||
if (header.version != 1)
|
||||
{
|
||||
Game::FS_FCloseFile(handle);
|
||||
Game::Com_Error(1, "%s: header version is not '1'", filename);
|
||||
}
|
||||
|
||||
static DWORD fixups[4096];
|
||||
|
||||
if (header.fixup.size >= sizeof(fixups))
|
||||
{
|
||||
Game::FS_FCloseFile(handle);
|
||||
Game::Com_Error(1, "%s: fixup size too big", filename);
|
||||
}
|
||||
|
||||
header.main.buffer = (char*)malloc(header.main.size);
|
||||
header.index.buffer = (char*)_aligned_malloc(header.index.size, 16);
|
||||
header.vertex.buffer = (char*)_aligned_malloc(header.vertex.size, 16);
|
||||
header.fixup.buffer = (char*)fixups;
|
||||
|
||||
ReadCModelSection(handle, header.main);
|
||||
ReadCModelSection(handle, header.index);
|
||||
ReadCModelSection(handle, header.vertex);
|
||||
ReadCModelSection(handle, header.fixup);
|
||||
|
||||
Game::FS_FCloseFile(handle);
|
||||
|
||||
FixupCModelSection(header, header.main, fixups);
|
||||
FixupCModelSection(header, header.index, fixups);
|
||||
FixupCModelSection(header, header.vertex, fixups);
|
||||
|
||||
Game::CModelAllocData* allocationData = (Game::CModelAllocData*)malloc(sizeof(Game::CModelAllocData));
|
||||
allocationData->mainArray = header.main.buffer;
|
||||
allocationData->indexBuffer = header.index.buffer;
|
||||
allocationData->vertexBuffer = header.vertex.buffer;
|
||||
|
||||
*(void**)(header.main.buffer + 44) = allocationData;
|
||||
|
||||
// maybe the +36/48 = 0 stuff here?
|
||||
|
||||
// move buffers to work with iw4
|
||||
int numSurfaces = *(short*)(header.main.buffer + 8);
|
||||
|
||||
char* tempSurface = new char[84 * numSurfaces];
|
||||
char* surface = *(char**)(header.main.buffer + 4);
|
||||
|
||||
for (int i = 0; i < numSurfaces; i++)
|
||||
{
|
||||
char* source = &surface[84 * i];
|
||||
char* dest = &tempSurface[64 * i];
|
||||
|
||||
memcpy(dest, source, 12);
|
||||
memcpy(dest + 12, source + 16, 20);
|
||||
memcpy(dest + 32, source + 40, 8);
|
||||
memcpy(dest + 40, source + 52, 24);
|
||||
|
||||
dest[6] = 0xFF; // fake stream handle for the vertex/index buffer get code to use
|
||||
}
|
||||
|
||||
memcpy(surface, tempSurface, 84 * numSurfaces);
|
||||
|
||||
delete[] tempSurface;
|
||||
|
||||
// create vertex/index buffers
|
||||
CreateCModelBuffers(header.main.buffer);
|
||||
|
||||
// store the buffer bit
|
||||
ModelSurfs::AllocMap[header.vertex.buffer] = allocationData;
|
||||
|
||||
return header.main.buffer;
|
||||
}
|
||||
|
||||
bool ModelSurfs::LoadSurfaces(Game::XModel* model)
|
||||
{
|
||||
if (!model) return false;
|
||||
@ -121,6 +354,9 @@ namespace Components
|
||||
|
||||
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;
|
||||
@ -139,12 +375,46 @@ namespace Components
|
||||
model->lods[i].someCount = numSurfs;
|
||||
model->lods[i].someTotalCount = surfCount;
|
||||
surfCount += numSurfs;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool Load_XModelAssetHookFunc(char* xmodel)
|
||||
{
|
||||
bool didStuff = false;
|
||||
short totalv = 0;
|
||||
|
||||
for (int i = 0; i < xmodel[241]; i++)
|
||||
{
|
||||
Game::XModelSurfs* surfs = *(Game::XModelSurfs**)(xmodel + 72 + (44 * i));
|
||||
|
||||
if (!surfs->surfaces)
|
||||
{
|
||||
char* newSurfs = LoadCModel(surfs->name);
|
||||
|
||||
memcpy(xmodel + 76 + (44 * i), &newSurfs[12], 24);
|
||||
memcpy(xmodel + 100 + (44 * i), &newSurfs[4], 4);
|
||||
|
||||
short v = *(short*)(newSurfs + 8);
|
||||
*(short*)(xmodel + 68 + (44 * i)) = v;
|
||||
*(short*)(xmodel + 70 + (44 * i)) = totalv;
|
||||
|
||||
totalv += v;
|
||||
|
||||
surfs->numSurfaces = ((Game::XModelSurfs*)newSurfs)->numSurfaces;
|
||||
surfs->surfaces = ((Game::XModelSurfs*)newSurfs)->surfaces;
|
||||
|
||||
didStuff = true;
|
||||
}
|
||||
}
|
||||
|
||||
return didStuff;
|
||||
}
|
||||
|
||||
void ModelSurfs::ReleaseModelSurf(Game::XAssetHeader header)
|
||||
{
|
||||
for (int i = 0; i < header.surfaces->numSurfaces && header.surfaces->surfaces; ++i)
|
||||
@ -200,7 +470,8 @@ namespace Components
|
||||
|
||||
void ModelSurfs::XModelSurfsFixup(Game::XModel* model)
|
||||
{
|
||||
if (!ModelSurfs::LoadSurfaces(model))
|
||||
//if (!ModelSurfs::LoadSurfaces(model))
|
||||
if(!Load_XModelAssetHookFunc((char*)model))
|
||||
{
|
||||
Game::DB_XModelSurfsFixup(model);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace Components
|
||||
const char* GetName() { return "ModelSurfs"; };
|
||||
#endif
|
||||
|
||||
private:
|
||||
//private:
|
||||
static std::map<void*, IUnknown*> BufferMap;
|
||||
static std::map<void*, Game::CModelAllocData*> AllocMap;
|
||||
|
||||
|
@ -1036,7 +1036,7 @@ namespace Components
|
||||
*(BYTE*)0x463D65 = (iw5) ? 0x90 : 0x40;
|
||||
*(DWORD*)0x463D66 = (iw5) ? 0x9004E0C1 : 0xC003C003; // shl eax, 4 instead of add eax, eax * 2
|
||||
|
||||
// addon_map_ents asset type (we reuse it for weaponattach)
|
||||
// addon_map_ents asset type (we reuse it for weaponattach)
|
||||
*(BYTE*)0x418B30 = (iw5) ? 43 : Game::ASSET_TYPE_ADDON_MAP_ENTS;
|
||||
|
||||
// hooks
|
||||
@ -1103,7 +1103,7 @@ namespace Components
|
||||
loadTechniquePassHook.Uninstall();
|
||||
loadStructuredDataChildArrayHook.Uninstall();
|
||||
|
||||
//xmodelDefaultHook.Uninstall();
|
||||
xmodelDefaultHook.Uninstall();
|
||||
fxDefaultHook.Uninstall();
|
||||
}
|
||||
}
|
||||
@ -1114,19 +1114,12 @@ namespace Components
|
||||
PatchMW2_FifthInfinityApply(version, version >= 316);
|
||||
}
|
||||
|
||||
bool IgnoreEntityHookFunc(const char* entity)
|
||||
{
|
||||
return (!strncmp(entity, "dyn_", 4) || !strncmp(entity, "node_", 5) || !strncmp(entity, "actor_", 6)/* || !strncmp(entity, "weapon_", 7)*/);
|
||||
}
|
||||
|
||||
Zones::Zones()
|
||||
{
|
||||
// Ignore missing soundaliases for now
|
||||
// TODO: Include them in the dependency zone!
|
||||
Utils::Hook::Nop(0x644207, 5);
|
||||
|
||||
Utils::Hook(0x5FBD6E, IgnoreEntityHookFunc).Install()->Quick();
|
||||
|
||||
fxEffectTailHook.Initialize(fxEffectTailHookLoc, FxEffectTailHookStub, HOOK_CALL);
|
||||
fxEffectModifyHook.Initialize(fxEffectModifyHookLoc, FxEffectModifyHookFunc, HOOK_CALL);
|
||||
xLodTailHook.Initialize(xLodTailHookLoc, XModelLODTailHookStub, HOOK_CALL);
|
||||
|
Loading…
Reference in New Issue
Block a user