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

132 lines
3.0 KiB
C++
Raw Normal View History

2016-08-07 19:57:00 -04:00
#include "STDInclude.hpp"
namespace Components
{
2016-09-04 11:13:06 -04:00
int Materials::ImageNameLength;
2016-08-07 19:57:00 -04:00
Utils::Hook Materials::ImageVersionCheckHook;
__declspec(naked) void Materials::ImageVersionCheck()
{
__asm
{
cmp eax, 9
je returnSafely
jmp Materials::ImageVersionCheckHook.Original
returnSafely:
mov al, 1
add esp, 18h
retn
}
}
2016-09-04 11:13:06 -04:00
Game::Material* Materials::ResolveMaterial(const char* stringPtr)
2016-08-07 19:57:00 -04:00
{
2016-09-04 11:13:06 -04:00
const char* imagePtr = stringPtr + 4;
unsigned int length = static_cast<unsigned int>(stringPtr[3] & 0xFF);
2016-09-03 10:59:05 -04:00
2016-09-04 11:13:06 -04:00
if (strlen(imagePtr) >= length)
2016-09-03 10:59:05 -04:00
{
2016-09-04 11:13:06 -04:00
Materials::ImageNameLength = 4 + length;
std::string image(imagePtr, length);
return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, image.data()).material;
}
2016-09-03 10:59:05 -04:00
2016-09-04 11:13:06 -04:00
Materials::ImageNameLength = 4;
return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material;
}
2016-09-03 10:59:05 -04:00
2016-09-04 11:13:06 -04:00
__declspec(naked) void Materials::PostDrawMaterialStub()
{
__asm
2016-09-03 10:59:05 -04:00
{
2016-09-04 11:13:06 -04:00
mov eax, Materials::ImageNameLength
add [esp + 30h], eax
mov eax, 5358FFh
jmp eax
2016-09-03 10:59:05 -04:00
}
2016-08-07 19:57:00 -04:00
}
__declspec(naked) void Materials::DrawMaterialStub()
{
__asm
{
2016-09-04 11:13:06 -04:00
push ecx
call Materials::ResolveMaterial
2016-08-07 19:57:00 -04:00
add esp, 4h
mov edx, 5310F0h
jmp edx
}
}
2016-09-04 11:13:06 -04:00
int Materials::WriteDeathMessageIcon(char* string, int offset, Game::Material* material)
{
if (!material)
{
material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material;
}
int length = strlen(material->name);
string[offset++] = static_cast<char>(length);
strncpy_s(string + offset, 1024 - offset, material->name, length);
return offset + length;
}
__declspec(naked) void Materials::DeathMessageStub()
{
__asm
{
push edx // Material
push eax // offset
push ecx // String
call Materials::WriteDeathMessageIcon
add esp, 14h
retn
}
}
2016-08-07 19:57:00 -04:00
Materials::Materials()
{
2016-09-04 11:13:06 -04:00
Materials::ImageNameLength = 7;
2016-08-07 19:57:00 -04:00
// Allow codo images
Materials::ImageVersionCheckHook.Initialize(0x53A456, Materials::ImageVersionCheck, HOOK_CALL)->Install();
// Fix material pointer exploit
Utils::Hook(0x534E0C, Materials::DrawMaterialStub, HOOK_CALL).Install()->Quick();
2016-09-04 11:13:06 -04:00
// Increment string pointer accordingly
Utils::Hook(0x5358FA, Materials::PostDrawMaterialStub, HOOK_JUMP).Install()->Quick();
// Adapt death message to IW5 material format
Utils::Hook(0x5A30D9, Materials::DeathMessageStub, HOOK_JUMP).Install()->Quick();
#ifdef DEBUG
// Ignore missing images
Utils::Hook::Nop(0x51F5AC, 5);
Utils::Hook::Nop(0x51F4C4, 5);
#endif
2016-09-04 11:13:06 -04:00
// Renderer::OnFrame([] ()
// {
// Game::Font* font = Game::R_RegisterFont("fonts/normalFont");
// float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
//
// Game::R_AddCmdDrawText("test^==preview_mp_rustzob", 0x7FFFFFFF, font, 500.0f, 150.0f, 1.0f, 1.0f, 0.0f, color, Game::ITEM_TEXTSTYLE_SHADOWED);
// });
2016-08-07 19:57:00 -04:00
}
Materials::~Materials()
{
Materials::ImageVersionCheckHook.Uninstall();
}
}