iw4x-client/src/Components/Modules/Zones.cpp

878 lines
23 KiB
C++
Raw Normal View History

2016-09-18 09:10:23 -04:00
#include "STDInclude.hpp"
namespace Components
{
2016-09-19 16:52:00 -04:00
int Zones::ZoneVersion;
2016-09-18 12:08:30 -04:00
Utils::Hook Zones::LoadFxElemDefHook;
Utils::Hook Zones::LoadFxElemDefArrayHook;
Utils::Hook Zones::LoadXModelLodInfoHook;
2016-09-18 12:08:30 -04:00
Utils::Hook fxEffectLoadHook;
static char* fxEffectStringValue[64];
2016-09-18 12:08:30 -04:00
static int fxEffectIndex = 0;
void FxEffectLoadHookFunc(int a1, char* buffer, int len)
{
len /= 252;
int count = len;
len *= 260;
__asm
{
push len
push buffer
push a1
call fxEffectLoadHook.Original
add esp, 0Ch
}
fxEffectIndex = 0;
char* tempVar = new char[len];
for (int i = 0; i < count; i++)
{
AssetHandler::Relocate((DWORD)buffer + (260 * i), 252, (DWORD)buffer + (252 * i));
memcpy(tempVar + (252 * i), buffer + (260 * i), 252);
fxEffectStringValue[i] = *(char**)(buffer + (260 * i) + 256);
2016-09-18 12:08:30 -04:00
}
memcpy(buffer, tempVar, len);
delete[] tempVar;
}
bool Zones::LoadFxElemDefStub(bool atStreamStart, Game::FxElemDef* fxElem, int size)
2016-09-18 12:08:30 -04:00
{
if (fxElem->elemType == 3)
2016-09-18 12:08:30 -04:00
{
fxElem->elemType = 2;
2016-09-18 12:08:30 -04:00
}
else if (fxElem->elemType >= 5)
2016-09-18 12:08:30 -04:00
{
fxElem->elemType -= 2;
2016-09-18 12:08:30 -04:00
}
return Game::Load_Stream(atStreamStart, fxElem, size);
2016-09-18 12:08:30 -04:00
}
void Zones::LoadFxElemDefArrayStub(bool atStreamStart)
2016-09-18 12:08:30 -04:00
{
Game::Load_FxElemDef(atStreamStart);
*Game::varXString = &fxEffectStringValue[fxEffectIndex++];
Game::Load_XString(0);
2016-09-18 12:08:30 -04:00
}
Utils::Hook xModelModifyHook;
void XModelModifyHookFunc(int a1, char* buffer, size_t len)
{
__asm
{
push len
push buffer
push a1
call xModelModifyHook.Original
add esp, 0Ch
}
2016-09-19 16:52:00 -04:00
int elSize = (Zones::ZoneVersion == VERSION_ALPHA2) ? 364 : 360;
2016-09-18 12:08:30 -04:00
static unsigned char tempVar[364];
memcpy(&tempVar[0], &buffer[0], 36);
memcpy(&tempVar[36], &buffer[44], 28);
//DB_AddRelocation((DWORD)buffer + 44, 28, (DWORD)buffer + 36);
for (int i = 0; i < 4; i++)
{
//DB_AddRelocation((DWORD)buffer + 72 + (i * 56), 12, (DWORD)buffer + 64 + (i * 44));
//DB_AddRelocation((DWORD)buffer + 72 + (i * 56) + 12, 32, (DWORD)buffer + 64 + (i * 44) + 16);
memcpy(&tempVar[64 + (i * 44)], &buffer[72 + (i * 56)], 12);
memcpy(&tempVar[64 + (i * 44) + 12], &buffer[72 + (i * 56) + 16], 32);
memcpy(&tempVar[(elSize - 4) - (i * 4)], &buffer[72 + (i * 56) + 12], 4);
}
//DB_AddRelocation((DWORD)buffer + 292, (elSize - 292 - 4), (DWORD)buffer + 236);
//DB_AddRelocation((DWORD)buffer + (elSize - 8), 8, (DWORD)buffer + 296);
memcpy(&tempVar[236], &buffer[292], (elSize - 292 - 4)/*68*/);
memcpy(&tempVar[296], &buffer[(elSize - 8)], 8);
tempVar[304] = 0xDE;
tempVar[305] = 0xAD;
tempVar[306] = 0xC0;
tempVar[307] = 0xDE;
memcpy(buffer, tempVar, elSize);
}
void Zones::LoadXModelLodInfo(int i)
2016-09-18 12:08:30 -04:00
{
2016-09-19 16:52:00 -04:00
int elSize = (Zones::ZoneVersion == VERSION_ALPHA2) ? 364 : 360;
*Game::varXString = reinterpret_cast<char**>(reinterpret_cast<char*>(*Game::varXModel) + (elSize - 4) - (4 * (4 - i)));
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
}
void __declspec(naked) Zones::LoadXModelLodInfoStub()
2016-09-18 12:08:30 -04:00
{
__asm
{
push edi
call Zones::LoadXModelLodInfo
pop edi
2016-09-18 12:08:30 -04:00
jmp Game::Load_XModelSurfsFixup
2016-09-18 12:08:30 -04:00
}
}
Utils::Hook xsurfaceIntLoadHook;
void XSurfaceIntLoadHookFunc(int a1, char* buffer, size_t len)
{
len >>= 6;
int count = len;
len *= 84;
__asm
{
push len
push buffer
push a1
call xsurfaceIntLoadHook.Original
add esp, 0Ch
}
char* tempVar = new char[len];
for (int i = 0; i < count; i++)
{
char* source = &buffer[i * 84];
char* dest = &tempVar[i * 64];
//memcpy(dest, source, 12);
//memcpy(dest + 12, source + 16, 72);
memcpy(dest, source, 12);
memcpy(dest + 12, source + 16, 20);
memcpy(dest + 32, source + 40, 8);
memcpy(dest + 40, source + 52, 24);
}
memcpy(buffer, tempVar, len);
delete[] tempVar;
}
Utils::Hook loadWeaponDefHook;
2016-09-19 14:55:31 -04:00
void Load_WeaponDef_CodC(int /*doLoad*/)
2016-09-18 12:08:30 -04:00
{
// setup structures we use
DWORD varWeaponDef = *(DWORD*)0x112A9F4;//*(DWORD*)0x112AE14;
// and do the stuff
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)varWeaponDef, (Zones::ZoneVersion >= 318) ? 3156 : 3112);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
Game::DB_PushStreamPos(3);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 0);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 4);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 8);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 12);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varXModelPtr = (Game::XModel*)(varWeaponDef + 16);
Game::Load_XModelPtr(false);
2016-09-18 12:08:30 -04:00
for (int i = 0, offset = 20; i < 32; i++, offset += 4)
{
2016-09-20 16:00:02 -04:00
*Game::varXModelPtr = (Game::XModel*)(varWeaponDef + offset);
Game::Load_XModelPtr(false);
2016-09-18 12:08:30 -04:00
}
// 148
for (int offset = 148; offset <= 168; offset += 4)
{
2016-09-20 16:00:02 -04:00
*Game::varXModelPtr = (Game::XModel*)(varWeaponDef + offset);
Game::Load_XModelPtr(false);
2016-09-18 12:08:30 -04:00
}
// 172
// 32 scriptstrings, should not need to be loaded
// 236
*Game::varXString = (char**)(varWeaponDef + 236);
2016-09-20 16:00:02 -04:00
Game::Load_XStringArray(false, 48);
2016-09-18 12:08:30 -04:00
// 428
*Game::varXString = (char**)(varWeaponDef + 428);
2016-09-20 16:00:02 -04:00
Game::Load_XStringArray(false, 48);
2016-09-18 12:08:30 -04:00
// 620
*Game::varXString = (char**)(varWeaponDef + 620);
2016-09-20 16:00:02 -04:00
Game::Load_XStringArray(false, 48);
2016-09-18 12:08:30 -04:00
// 812
// 16 * 4 scriptstrings
// 972
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + 972);;
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + 976);
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
// 980
// 50 soundalias name references; up to and including 1180
for (int i = 0, offset = 980; i < 50; i++, offset += 4)
{
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + offset);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
}
2016-09-19 16:52:00 -04:00
if (Zones::ZoneVersion >= 318)
2016-09-18 12:08:30 -04:00
{
for (int i = 0, offset = 1184; i < 2; i++, offset += 4)
{
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + offset);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
}
varWeaponDef += 8; // to compensate for the 2 in between here
}
if (*(DWORD*)(varWeaponDef + 1184))
{
if (*(DWORD*)(varWeaponDef + 1184) == -1)
{
2016-09-20 16:00:02 -04:00
*(DWORD*)(varWeaponDef + 1184) = (DWORD)Game::DB_AllocStreamPos(3);
*Game::varsnd_alias_list_name = *(Game::snd_alias_list_t***)(varWeaponDef + 1184);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
Game::Load_snd_alias_list_nameArray(true, 31);
2016-09-18 12:08:30 -04:00
}
else
{
// full usability requires ConvertOffsetToPointer here
}
}
if (*(DWORD*)(varWeaponDef + 1188))
{
if (*(DWORD*)(varWeaponDef + 1188) == -1)
{
2016-09-20 16:00:02 -04:00
*(DWORD*)(varWeaponDef + 1188) = (DWORD)Game::DB_AllocStreamPos(3);
*Game::varsnd_alias_list_name = *(Game::snd_alias_list_t***)(varWeaponDef + 1188);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
Game::Load_snd_alias_list_nameArray(true, 31);
2016-09-18 12:08:30 -04:00
}
else
{
// full usability requires ConvertOffsetToPointer here
}
}
// 1192
for (int offset = 1192; offset <= 1204; offset += 4)
{
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + offset);
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
}
// 1208
2016-09-20 16:00:02 -04:00
static int matOffsets1[] = { 1208, 1212, 1428, 1432, 1436, 1440, 1444, 1448, 1456, 1464 };
2016-09-18 12:08:30 -04:00
for (int i = 0; i < sizeof(matOffsets1) / sizeof(int); i++)
{
2016-09-20 16:00:02 -04:00
*Game::varMaterialHandle = (Game::Material*)(varWeaponDef + matOffsets1[i]);
Game::Load_MaterialHandle(false);
2016-09-18 12:08:30 -04:00
}
*Game::varXString = (char**)(varWeaponDef + 1484);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 1492);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 1508);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
for (int offset = 1764; offset <= 1776; offset += 4)
{
2016-09-20 16:00:02 -04:00
*Game::varMaterialHandle = (Game::Material*)(varWeaponDef + offset);
Game::Load_MaterialHandle(false);
2016-09-18 12:08:30 -04:00
}
2016-09-20 16:00:02 -04:00
*Game::varPhysCollmapPtr = (Game::PhysCollmap*)(varWeaponDef + 1964);
Game::Load_PhysCollmapPtr(0);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varXModelPtr = (Game::XModel*)(varWeaponDef + 2052);
Game::Load_XModelPtr(0);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + 2060);
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + 2064);
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2068);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2072);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + 2336);
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + 2340);
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + 2368); // 2376
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2372); // 2380
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 2548); // 2556
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
if (*(DWORD*)(varWeaponDef + 2556) == -1) // 2564
{
2016-09-20 16:00:02 -04:00
DWORD vec2 = (DWORD)Game::DB_AllocStreamPos(3);
2016-09-18 12:08:30 -04:00
*(DWORD*)(varWeaponDef + 2556) = vec2;
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)vec2, 8 * *(short*)(varWeaponDef + ((Zones::ZoneVersion >= 318) ? 3076 : 3040)));
2016-09-18 12:08:30 -04:00
}
*Game::varXString = (char**)(varWeaponDef + 2552);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
if (*(DWORD*)(varWeaponDef + 2560) == -1)
{
2016-09-20 16:00:02 -04:00
DWORD vec2 = (DWORD)Game::DB_AllocStreamPos(3);
2016-09-18 12:08:30 -04:00
*(DWORD*)(varWeaponDef + 2560) = vec2;
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)vec2, 8 * *(short*)(varWeaponDef + ((Zones::ZoneVersion >= 318) ? 3078 : 3042)));
2016-09-18 12:08:30 -04:00
}
*Game::varXString = (char**)(varWeaponDef + 2640);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 2644);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 2676);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 2680);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 2804);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 2808);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varTracerDefPtr = (Game::TracerDef*)(varWeaponDef + 2812);
Game::Load_TracerDefPtr(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2840);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); // 2848
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varFxEffectDefHandle = (Game::FxEffectDef*)(varWeaponDef + 2844);
Game::Load_FxEffectDefHandle(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 2848);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2864);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2868);
Game::Load_snd_alias_list_nameArray(false, 4);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2884);
Game::Load_snd_alias_list_nameArray(false, 4);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2900);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + 2904); // 2912
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
2016-09-19 16:52:00 -04:00
if (Zones::ZoneVersion >= 318)
2016-09-18 12:08:30 -04:00
{
for (int i = 0, offset = 2972; i < 6; i++, offset += 4)
{
2016-09-20 16:00:02 -04:00
*Game::varsnd_alias_list_name = (Game::snd_alias_list_t**)(varWeaponDef + offset);
Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name);
2016-09-18 12:08:30 -04:00
}
varWeaponDef += (6 * 4);
varWeaponDef += 12;
}
else
{
}
*Game::varXString = (char**)(varWeaponDef + 2984);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 2996);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
*Game::varXString = (char**)(varWeaponDef + 3000);
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varMaterialHandle = (Game::Material*)(varWeaponDef + 3008);
Game::Load_MaterialHandle(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varMaterialHandle = (Game::Material*)(varWeaponDef + 3012);
Game::Load_MaterialHandle(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*Game::varMaterialHandle = (Game::Material*)(varWeaponDef + 3016);
Game::Load_MaterialHandle(false);
2016-09-18 12:08:30 -04:00
if (*(DWORD*)(varWeaponDef + 3044) == -1)
{
2016-09-20 16:00:02 -04:00
DWORD vec2 = (DWORD)Game::DB_AllocStreamPos(3);
2016-09-18 12:08:30 -04:00
*(DWORD*)(varWeaponDef + 3044) = vec2;
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)vec2, 8 * *(short*)(varWeaponDef + 3040));
2016-09-18 12:08:30 -04:00
}
if (*(DWORD*)(varWeaponDef + 3048) == -1)
{
2016-09-20 16:00:02 -04:00
DWORD vec2 = (DWORD)Game::DB_AllocStreamPos(3);
2016-09-18 12:08:30 -04:00
*(DWORD*)(varWeaponDef + 3048) = vec2;
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)vec2, 8 * *(short*)(varWeaponDef + 3042));
2016-09-18 12:08:30 -04:00
}
2016-09-20 16:00:02 -04:00
Game::DB_PopStreamPos();
2016-09-18 12:08:30 -04:00
}
Utils::Hook gameWorldSpLoadHook;
void GameWorldSpLoadHookFunc(int a1, char* buffer, size_t len)
{
len = 84;
__asm
{
push len
push buffer
push a1
call gameWorldSpLoadHook.Original
add esp, 0Ch
}
static char tempVar[84];
memcpy(&tempVar[0], &buffer[0], 44);
memcpy(&tempVar[56], &buffer[44], 28);
memcpy(&tempVar[44], &buffer[72], 12);
memcpy(buffer, tempVar, sizeof(tempVar));
}
Utils::Hook pathDataTailHook;
void PathDataTailHookFunc()
{
DWORD varStuff = *(DWORD*)0x112AD7C;
DWORD varThing;
if (*(DWORD*)(varStuff + 56))
{
2016-09-20 16:00:02 -04:00
*(DWORD*)(varStuff + 56) = (DWORD)Game::DB_AllocStreamPos(0);
2016-09-18 12:08:30 -04:00
varThing = *(DWORD*)(varStuff + 56);
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)varThing, *(DWORD*)(varStuff + 52));
2016-09-18 12:08:30 -04:00
}
if (*(DWORD*)(varStuff + 64))
{
2016-09-20 16:00:02 -04:00
*(DWORD*)(varStuff + 64) = (DWORD)Game::DB_AllocStreamPos(0);
2016-09-18 12:08:30 -04:00
varThing = *(DWORD*)(varStuff + 64);
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)varThing, *(DWORD*)(varStuff + 60));
2016-09-18 12:08:30 -04:00
}
if (*(DWORD*)(varStuff + 76))
{
2016-09-20 16:00:02 -04:00
*(DWORD*)(varStuff + 76) = (DWORD)Game::DB_AllocStreamPos(0);
2016-09-18 12:08:30 -04:00
varThing = *(DWORD*)(varStuff + 76);
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)varThing, *(DWORD*)(varStuff + 72));
2016-09-18 12:08:30 -04:00
}
}
Utils::Hook sndAliasLoadHook;
void SndAliasLoadHookFunc(int a1, char* buffer, size_t len)
{
len /= 100;
int count = len;
len *= 108;
__asm
{
push len
push buffer
push a1
call gameWorldSpLoadHook.Original
add esp, 0Ch
}
char* tempVar = new char[len];
for (int i = 0; i < count; i++)
{
char* src = &buffer[i * 108];
char* dest = &tempVar[i * 100];
memcpy(dest + 0, src + 0, 60);
memcpy(dest + 60, src + 68, 20);
memcpy(dest + 80, src + 88, 20);
AssetHandler::Relocate((DWORD)src + 0, 60, (DWORD)(buffer + (i * 100)) + 0);
AssetHandler::Relocate((DWORD)src + 68, 20, (DWORD)(buffer + (i * 100)) + 60);
AssetHandler::Relocate((DWORD)src + 88, 20, (DWORD)(buffer + (i * 100)) + 80);
}
memcpy(buffer, tempVar, len);
delete[] tempVar;
}
Utils::Hook mssSoundLoadHook;
void MssSoundLoadHookFunc(int a1, char* buffer, size_t len)
{
len = 48;
__asm
{
push len
push buffer
push a1
call gameWorldSpLoadHook.Original
add esp, 0Ch
}
memcpy(buffer + 28, buffer + 32, 16);
AssetHandler::Relocate((DWORD)buffer + 32, 16, (DWORD)buffer + 28);
}
Utils::Hook vehicleLoadHook;
void VehicleLoadHookFunc(int a1, char* buffer, int len)
{
len = 788;
__asm
{
push len
push buffer
push a1
call vehicleLoadHook.Original
add esp, 0Ch
}
static char tempVar[788];
memcpy(&tempVar[0], &buffer[0], 400);
memcpy(&tempVar[408], &buffer[400], 388);
AssetHandler::Relocate((DWORD)buffer + 400, 388, (DWORD)buffer + 408);
memcpy(buffer, tempVar, sizeof(tempVar));
}
Utils::Hook loadWeaponAttachHook;
DWORD varWeaponAttachStuff;
void Load_WeaponAttachStuff(int count)
{
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)varWeaponAttachStuff, 12 * count);
2016-09-18 12:08:30 -04:00
DWORD* varStuff = (DWORD*)varWeaponAttachStuff;
for (int i = 0; i < count; i++)
{
2016-09-19 14:55:31 -04:00
//DWORD* varXString = (DWORD*)0x112B340;
2016-09-18 12:08:30 -04:00
if (varStuff[1] < 16 || varStuff[1] == 39)
{
if (varStuff[2] == -1)
{
2016-09-20 16:00:02 -04:00
varStuff[2] = (DWORD)Game::DB_AllocStreamPos(0);
*Game::varConstChar = (const char*)varStuff[2];
Game::Load_XStringCustom(Game::varConstChar);
2016-09-18 12:08:30 -04:00
//if (*useEntryNames)
{
//DBG(("wA: %s\n", *varXStringData));
}
}
else if (varStuff[2])
{
// meh, no convertin' here
}
}
varStuff += 3;
}
}
Utils::Hook menuDefLoadHook;
void MenuDefLoadHookFunc(int doLoad, char* buffer, int len)
{
len += 4;
__asm
{
push len
push buffer
push doLoad
call menuDefLoadHook.Original
add esp, 0Ch
}
memcpy(buffer + 168, buffer + 172, 232);
AssetHandler::Relocate((DWORD)buffer + 172, 232, (DWORD)buffer + 168);
}
2016-09-19 14:55:31 -04:00
void Load_WeaponAttach(int /*doLoad*/)
2016-09-18 12:08:30 -04:00
{
// setup structures we use
DWORD varWeaponAttach = *(DWORD*)0x112ADE0;//*(DWORD*)0x112AE14;
DWORD* varXString = (DWORD*)0x112B340;
// and do the stuff
2016-09-20 16:00:02 -04:00
Game::Load_Stream(1, (void*)varWeaponAttach, 12);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
Game::DB_PushStreamPos(3);
2016-09-18 12:08:30 -04:00
*varXString = varWeaponAttach + 0;
2016-09-20 16:00:02 -04:00
Game::Load_XString(false);
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
*(void**)(varWeaponAttach + 8) = Game::DB_AllocStreamPos(3);
2016-09-18 12:08:30 -04:00
varWeaponAttachStuff = *(DWORD*)(varWeaponAttach + 8);
Load_WeaponAttachStuff(*(int*)(varWeaponAttach + 4));
2016-09-20 16:00:02 -04:00
Game::DB_PopStreamPos();
2016-09-18 12:08:30 -04:00
}
Utils::Hook gameWorldSpIntHook;
2016-09-19 14:55:31 -04:00
void GameWorldSpIntHookFunc(int /*doLoad*/)
2016-09-18 12:08:30 -04:00
{
memset(*(void**)0x112AD7C, 0, 40);
}
Utils::Hook loadTechniquePassHook;
2016-09-20 16:00:02 -04:00
void Load_TechniquePassHookFunc(bool atStreamStart, Game::ShaderArgumentDef* pass, size_t size)
2016-09-18 12:08:30 -04:00
{
int count = size / 8;
Game::MaterialPass* curPass = *(Game::MaterialPass**)0x112A960;
count = curPass->argCount1 + curPass->argCount2 + curPass->argCount3;
2016-09-20 16:00:02 -04:00
Game::Load_Stream(atStreamStart, pass, size);
2016-09-18 12:08:30 -04:00
for (int i = 0; i < count; i++)
{
2016-09-20 16:00:02 -04:00
Game::ShaderArgumentDef* arg = &pass[i];
2016-09-18 12:08:30 -04:00
2016-09-20 16:00:02 -04:00
if (arg->type != 3 && arg->type != 5)
2016-09-18 12:08:30 -04:00
{
continue;
}
// should be min 68 currently
// >= 58 fixes foliage without bad side effects
// >= 53 still has broken shadow mapping
// >= 23 is still broken somehow
if (arg->paramID >= 58 && arg->paramID <= 135) // >= 34 would be 31 in iw4 terms
{
arg->paramID -= 3;
}
// >= 21 works fine for specular, but breaks trees
// >= 4 is too low, breaks specular
else if (arg->paramID >= 11 && arg->paramID < 58)
{
arg->paramID -= 2;
}
}
}
Utils::Hook loadStructuredDataChildArrayHook;
2016-09-20 16:00:02 -04:00
void Load_StructuredDataChildArrayHookFunc(bool atStreamStart, char* data, size_t size)
2016-09-18 12:08:30 -04:00
{
int count = size / 16;
size = count * 24;
2016-09-20 16:00:02 -04:00
Game::Load_Stream(atStreamStart, data, size);
2016-09-18 12:08:30 -04:00
for (int i = 0; i < count; i++)
{
memcpy(data + (i * 16), data + (i * 24), 16);
AssetHandler::Relocate((DWORD)data + (i * 24), 16, (DWORD)data + (i * 16));
}
}
2016-09-20 16:00:02 -04:00
void Zones::InstallPatches(int version)
{
AssetHandler::ClearRelocations();
2016-09-20 16:55:40 -04:00
if (Zones::ZoneVersion == version) return;
Zones::ZoneVersion = version;
bool patch = (version >= VERSION_ALPHA2);
2016-09-20 16:00:02 -04:00
if (Zones::ZoneVersion == VERSION_ALPHA2 || Zones::ZoneVersion == VERSION_ALPHA3 || Zones::ZoneVersion == XFILE_VERSION)
{
Utils::Hook::Set<DWORD>(0x4158F4, version);
Utils::Hook::Set<DWORD>(0x4158FB, version);
}
2016-09-18 12:08:30 -04:00
// physpreset size
2016-09-20 16:00:02 -04:00
Utils::Hook::Set<BYTE>(0x49CE0A, (patch) ? 68 : 44);
2016-09-18 12:08:30 -04:00
// XModel size
2016-09-20 16:00:02 -04:00
Utils::Hook::Set<DWORD>(0x410D8A, (patch) ? ((Zones::ZoneVersion == VERSION_ALPHA2) ? 0x16C : 0x168) : 0x130);
2016-09-18 12:08:30 -04:00
// XSurface size
2016-09-20 16:00:02 -04:00
Utils::Hook::Set<BYTE>(0x48E84A, (patch) ? 48 : 36);
2016-09-18 12:08:30 -04:00
// impactfx internal size/count
2016-09-20 16:00:02 -04:00
Utils::Hook::Set<DWORD>(0x4447B6, (patch) ? 0x8C0 : 0x834);
Utils::Hook::Set<DWORD>(0x4447D1, (patch) ? 16 : 15);
2016-09-18 12:08:30 -04:00
// GameWorldSp asset type
2016-09-20 16:00:02 -04:00
Utils::Hook::Set<BYTE>(0x41899A, (patch) ? 18 : 17);
2016-09-18 12:08:30 -04:00
// PathData internal struct size
2016-09-20 16:00:02 -04:00
Utils::Hook::Set<DWORD>(0x4D6A04, (patch) ? 148 : 136);
Utils::Hook::Set<DWORD>(0x4D6A49, (patch) ? 148 : 136);
2016-09-18 12:08:30 -04:00
// PathData internal struct data size
2016-09-20 16:00:02 -04:00
Utils::Hook::Set<WORD>(0x463D63, (patch) ? 0x9090 : 0x048D);
Utils::Hook::Set<BYTE>(0x463D65, (patch) ? 0x90 : 0x40);
Utils::Hook::Set<DWORD>(0x463D66, (patch) ? 0x9004E0C1 : 0xC003C003); // shl eax, 4 instead of add eax, eax * 2
2016-09-18 12:08:30 -04:00
2016-09-18 14:52:32 -04:00
// addon_map_ents asset type (we reuse it for weaponattach)
2016-09-20 16:00:02 -04:00
Utils::Hook::Set<BYTE>(0x418B30, (patch) ? 43 : Game::ASSET_TYPE_ADDON_MAP_ENTS);
if (patch)
{
Zones::LoadFxElemDefArrayHook.Install();
Zones::LoadFxElemDefHook.Install();
2016-09-18 12:08:30 -04:00
Zones::LoadXModelLodInfoHook.Install();
2016-09-18 12:08:30 -04:00
xModelModifyHook.Install();
xsurfaceIntLoadHook.Install();
gameWorldSpLoadHook.Install();
pathDataTailHook.Install();
loadWeaponDefHook.Install();
vehicleLoadHook.Install();
sndAliasLoadHook.Install();
mssSoundLoadHook.Install();
menuDefLoadHook.Install();
fxEffectLoadHook.Install();
loadWeaponAttachHook.Install();
2016-09-19 16:52:00 -04:00
if (Zones::ZoneVersion >= VERSION_ALPHA3)
2016-09-18 12:08:30 -04:00
{
gameWorldSpIntHook.Install();
}
loadTechniquePassHook.Install();
2016-09-20 16:00:02 -04:00
loadStructuredDataChildArrayHook.Install();
}
else
{
Zones::LoadFxElemDefArrayHook.Uninstall();
Zones::LoadFxElemDefHook.Uninstall();
2016-09-18 12:08:30 -04:00
Zones::LoadXModelLodInfoHook.Uninstall();
2016-09-18 12:08:30 -04:00
xModelModifyHook.Uninstall();
xsurfaceIntLoadHook.Uninstall();
gameWorldSpLoadHook.Uninstall();
pathDataTailHook.Uninstall();
loadWeaponDefHook.Uninstall();
vehicleLoadHook.Uninstall();
sndAliasLoadHook.Uninstall();
mssSoundLoadHook.Uninstall();
menuDefLoadHook.Uninstall();
fxEffectLoadHook.Uninstall();
loadWeaponAttachHook.Uninstall();
gameWorldSpIntHook.Uninstall();
loadTechniquePassHook.Uninstall();
2016-09-20 16:00:02 -04:00
loadStructuredDataChildArrayHook.Uninstall();
2016-09-19 15:16:26 -04:00
}
AntiCheat::EmptyHash();
2016-09-18 12:08:30 -04:00
}
2016-09-18 09:10:23 -04:00
Zones::Zones()
{
2016-09-20 16:55:40 -04:00
Zones::ZoneVersion = 0;
2016-09-18 12:08:30 -04:00
// Ignore missing soundaliases for now
// TODO: Include them in the dependency zone!
Utils::Hook::Nop(0x644207, 5);
// Block Mark_pathnode_constant_t
Utils::Hook::Set<BYTE>(0x4F74B0, 0xC3);
Zones::LoadFxElemDefArrayHook.Initialize(0x495938, Zones::LoadFxElemDefArrayStub, HOOK_CALL);
Zones::LoadFxElemDefHook.Initialize(0x45ADA0, Zones::LoadFxElemDefStub, HOOK_CALL);
Zones::LoadXModelLodInfoHook.Initialize(0x4EA6FE, Zones::LoadXModelLodInfoStub, HOOK_CALL);
xModelModifyHook.Initialize(0x410D90, XModelModifyHookFunc, HOOK_CALL);
xsurfaceIntLoadHook.Initialize(0x4925C8, XSurfaceIntLoadHookFunc, HOOK_CALL);
gameWorldSpLoadHook.Initialize(0x4F4D0D, GameWorldSpLoadHookFunc, HOOK_CALL);
loadWeaponDefHook.Initialize(0x47CCD2, Load_WeaponDef_CodC, HOOK_CALL);
vehicleLoadHook.Initialize(0x483DA0, VehicleLoadHookFunc, HOOK_CALL);
sndAliasLoadHook.Initialize(0x4F0AC8, SndAliasLoadHookFunc, HOOK_CALL);
mssSoundLoadHook.Initialize(0x403A5D, MssSoundLoadHookFunc, HOOK_CALL);
loadWeaponAttachHook.Initialize(0x463022, Load_WeaponAttach, HOOK_CALL);
menuDefLoadHook.Initialize(0x41A570, MenuDefLoadHookFunc, HOOK_CALL);
fxEffectLoadHook.Initialize(0x49591B, FxEffectLoadHookFunc, HOOK_CALL);
gameWorldSpIntHook.Initialize(0x4F4D3B, GameWorldSpIntHookFunc, HOOK_CALL);
loadTechniquePassHook.Initialize(0x428F0A, Load_TechniquePassHookFunc, HOOK_CALL);
loadStructuredDataChildArrayHook.Initialize(0x4B1EB8, Load_StructuredDataChildArrayHookFunc, HOOK_CALL);
pathDataTailHook.Initialize(0x427A1B, PathDataTailHookFunc, HOOK_JUMP);
2016-09-18 09:10:23 -04:00
}
Zones::~Zones()
{
}
}