From 6cc4fa582aa5a3395ef8a7ff19dc01dce77fd510 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 5 Jun 2017 12:53:26 +0200 Subject: [PATCH] [Friends] First version of working avatars --- src/Components/Modules/Colors.cpp | 2 +- src/Components/Modules/Friends.cpp | 60 ++-- src/Components/Modules/Friends.hpp | 2 + src/Components/Modules/Materials.cpp | 30 +- src/Components/Modules/Materials.hpp | 5 +- src/Components/Modules/Toast.cpp | 14 +- src/Components/Modules/Toast.hpp | 9 +- src/Game/Functions.cpp | 468 +++++++++++++-------------- src/Game/Functions.hpp | 2 +- 9 files changed, 325 insertions(+), 267 deletions(-) diff --git a/src/Components/Modules/Colors.cpp b/src/Components/Modules/Colors.cpp index b549c198..82695c9c 100644 --- a/src/Components/Modules/Colors.cpp +++ b/src/Components/Modules/Colors.cpp @@ -195,7 +195,7 @@ namespace Components __asm { push ebx - push[esp + 8h] // Index + push [esp + 8h] // Index push esi // Color ref call Colors::LookupColor add esp, 8h diff --git a/src/Components/Modules/Friends.cpp b/src/Components/Modules/Friends.cpp index 0d77918c..d19690ab 100644 --- a/src/Components/Modules/Friends.cpp +++ b/src/Components/Modules/Friends.cpp @@ -117,7 +117,11 @@ namespace Components int notify = Dvar::Var("cl_notifyFriendState").get(); if(gotOnline && (notify == -1 || (notify == 1 && !Game::CL_IsCgameInitialized())) && !Dvar::Var("ui_streamFriendly").get()) { - Toast::Show("cardicon_joystick", entry->name, "is playing IW4x", 3000); + Game::Material* material = Friends::CreateAvatar(user); + Toast::Show(material, entry->name, "is playing IW4x", 3000, [material]() + { + Materials::Delete(material, true); + }); } } @@ -530,6 +534,34 @@ namespace Components Utils::IO::WriteFile("players/friends.dat", list.SerializeAsString()); } + Game::Material* Friends::CreateAvatar(SteamID user) + { + if (!Steam::Proxy::SteamUtils || !Steam::Proxy::SteamFriends) return nullptr; + + int index = Steam::Proxy::SteamFriends->GetMediumFriendAvatar(user); + + unsigned int width, height; + Steam::Proxy::SteamUtils->GetImageSize(index, &width, &height); + + Game::GfxImage* image = Materials::CreateImage(Utils::String::VA("texture_%llX", user.bits), width, height, 1, 0x1000003, D3DFMT_A8R8G8B8); + + D3DLOCKED_RECT lockedRect; + image->map->LockRect(0, &lockedRect, nullptr, 0); + + unsigned char* buffer = static_cast(lockedRect.pBits); + Steam::Proxy::SteamUtils->GetImageRGBA(index, buffer, width * height * 4); + + // Swap red and blue channel + for (unsigned int i = 0; i < width * height * 4; i += 4) + { + std::swap(buffer[i + 0], buffer[i + 2]); + } + + image->map->UnlockRect(0); + + return Materials::Create(Utils::String::VA("avatar_%llX", user.bits), image); + } + Friends::Friends() { Friends::LoggedOn = false; @@ -554,13 +586,6 @@ namespace Components Command::Execute("openmenu popup_friends", true); }, HOOK_JUMP).install()->quick(); - // Avatar callback -// Steam::Proxy::RegisterCallback(333, [](void* data) -// { -// MessageBoxA(0, 0, 0, 0); -// -// }); - // Callback to update user information Steam::Proxy::RegisterCallback(336, [](void* data) { @@ -699,11 +724,10 @@ namespace Components { std::lock_guard _(Friends::Mutex); - for(auto user : Friends::FriendsList) + for (auto user : Friends::FriendsList) { Logger::Print("Fetching %s...\n", user.name.data()); - int index = Steam::Proxy::SteamFriends->GetSmallFriendAvatar(user.userId); - + int index = Steam::Proxy::SteamFriends->GetMediumFriendAvatar(user.userId); if (!Steam::Proxy::SteamUtils) return; @@ -715,25 +739,18 @@ namespace Components unsigned int width, height; Steam::Proxy::SteamUtils->GetImageSize(index, &width, &height); Game::Image_Setup(&image, static_cast(width), static_cast(height), 1, 0x1000003, D3DFMT_A8R8G8B8); + Logger::Print("%dx%d\n", width, height); D3DLOCKED_RECT lockedRect; image.map->LockRect(0, &lockedRect, nullptr, 0); unsigned char* buffer = static_cast(lockedRect.pBits); - Steam::Proxy::SteamUtils->GetImageRGBA(index, buffer, width * height * 4); + // Swap red and blue channel for (unsigned int i = 0; i < width * height * 4; i += 4) { - unsigned char r = buffer[i + 0]; - unsigned char g = buffer[i + 1]; - unsigned char b = buffer[i + 2]; - unsigned char a = buffer[i + 3]; - - buffer[i + 0] = a; - buffer[i + 1] = r; - buffer[i + 2] = g; - buffer[i + 3] = b; + std::swap(buffer[i + 0], buffer[i + 2]); } image.map->UnlockRect(0); @@ -760,7 +777,6 @@ namespace Components Friends::StoreFriendsList(); - //Steam::Proxy::UnregisterCallback(333); Steam::Proxy::UnregisterCallback(336); Steam::Proxy::UnregisterCallback(304); diff --git a/src/Components/Modules/Friends.hpp b/src/Components/Modules/Friends.hpp index 34ae5712..00f0c447 100644 --- a/src/Components/Modules/Friends.hpp +++ b/src/Components/Modules/Friends.hpp @@ -95,5 +95,7 @@ namespace Components static void SetRawPresence(const char* key, const char* value); static std::vector GetAppIdList(); + + static Game::Material* CreateAvatar(SteamID user); }; } diff --git a/src/Components/Modules/Materials.cpp b/src/Components/Modules/Materials.cpp index 07591916..f303ca65 100644 --- a/src/Components/Modules/Materials.cpp +++ b/src/Components/Modules/Materials.cpp @@ -47,7 +47,7 @@ namespace Components return material; } - void Materials::Delete(Game::Material* material) + void Materials::Delete(Game::Material* material, bool deleteImage) { if (!material) return; @@ -57,11 +57,39 @@ namespace Components Materials::MaterialTable.erase(mat); } + if (deleteImage) + { + for (char i = 0; i < material->textureCount; ++i) + { + Materials::DeleteImage(material->textureTable[i].info.image); + } + } + Utils::Memory::GetAllocator()->free(material->textureTable); Utils::Memory::GetAllocator()->free(material->name); Utils::Memory::GetAllocator()->free(material); } + Game::GfxImage* Materials::CreateImage(std::string name, unsigned int width, unsigned int height, unsigned int depth, unsigned int flags, _D3DFORMAT format) + { + Game::GfxImage* image = Utils::Memory::GetAllocator()->allocate(); + image->name = Utils::Memory::GetAllocator()->duplicateString(name); + + Game::Image_Setup(image, width, height, depth, flags, format); + + return image; + } + + void Materials::DeleteImage(Game::GfxImage* image) + { + if (!image) return; + + Game::Image_Release(image); + + Utils::Memory::GetAllocator()->free(image->name); + Utils::Memory::GetAllocator()->free(image); + } + void Materials::DeleteAll() { std::vector materials; diff --git a/src/Components/Modules/Materials.hpp b/src/Components/Modules/Materials.hpp index 0e6cd392..02d66ae2 100644 --- a/src/Components/Modules/Materials.hpp +++ b/src/Components/Modules/Materials.hpp @@ -11,7 +11,10 @@ namespace Components static int FormatImagePath(char* buffer, size_t size, int, int, const char* image); static Game::Material* Create(std::string name, Game::GfxImage* image); - static void Delete(Game::Material* material); + static void Delete(Game::Material* material, bool deleteImage = false); + + static Game::GfxImage* CreateImage(std::string name, unsigned int width, unsigned int height, unsigned int depth, unsigned int flags, _D3DFORMAT format); + static void DeleteImage(Game::GfxImage* image); private: static std::vector MaterialTable; diff --git a/src/Components/Modules/Toast.cpp b/src/Components/Modules/Toast.cpp index b544bcb0..12dbbc13 100644 --- a/src/Components/Modules/Toast.cpp +++ b/src/Components/Modules/Toast.cpp @@ -7,10 +7,16 @@ namespace Components Toast::WinToastHandler* Toast::ToastHandler = nullptr; - void Toast::Show(std::string image, std::string title, std::string description, int length) + void Toast::Show(std::string image, std::string title, std::string description, int length, Utils::Slot callback) + { + Game::Material* material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, image.data()).material; + return Show(material, title, description, length, callback); + } + + void Toast::Show(Game::Material* material, std::string title, std::string description, int length, Utils::Slot callback) { Toast::Mutex.lock(); - Toast::Queue.push({ image, Utils::String::ToUpper(title), description, length, 0 }); + Toast::Queue.push({ material, Utils::String::ToUpper(title), description, length, 0, callback }); Toast::Mutex.unlock(); } @@ -54,7 +60,6 @@ namespace Components float descSize = 0.9f; Game::Material* white = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "white").material; - Game::Material* image = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, toast->image.data()).material; Game::Font* font = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/objectiveFont").font; Game::Font* descfont = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FONT, "fonts/normalFont").font; Game::vec4_t wColor = { 1.0f, 1.0f, 1.0f, 1.0f }; @@ -111,7 +116,7 @@ namespace Components Game::CL_DrawStretchPicPhysical(static_cast(width / 2 - bWidth / 2), static_cast(height + bHeight / 2), bWidth * 1.0f, border * 1.0f, 0, 0, 1.0f, 1.0f, borderColor, white); // Bottom // Image - Game::CL_DrawStretchPicPhysical(static_cast(width / 2 - bWidth / 2 + iOffsetLeft), static_cast(height - bHeight / 2 + iOffset), imgDim * 1.0f, imgDim * 1.0f, 0, 0, 1.0f, 1.0f, wColor, image); + Game::CL_DrawStretchPicPhysical(static_cast(width / 2 - bWidth / 2 + iOffsetLeft), static_cast(height - bHeight / 2 + iOffset), imgDim * 1.0f, imgDim * 1.0f, 0, 0, 1.0f, 1.0f, wColor, toast->image); // Text float leftText = width / 2 - bWidth / 2 - cornerSize + iOffsetLeft * 2 + imgDim; @@ -136,6 +141,7 @@ namespace Components if ((toast->start + toast->length) < Game::Sys_Milliseconds()) { + if(toast->callback) toast->callback(); Toast::Queue.pop(); } else diff --git a/src/Components/Modules/Toast.hpp b/src/Components/Modules/Toast.hpp index dc59ec0f..03559435 100644 --- a/src/Components/Modules/Toast.hpp +++ b/src/Components/Modules/Toast.hpp @@ -11,7 +11,8 @@ namespace Components typedef WinToastLib::WinToastTemplate Template; - static void Show(std::string image, std::string title, std::string description, int length); + static void Show(std::string image, std::string title, std::string description, int length, Utils::Slot callback = Utils::Slot()); + static void Show(Game::Material* material, std::string title, std::string description, int length, Utils::Slot callback = Utils::Slot()); static bool ShowNative(const WinToastLib::WinToastTemplate& toast); static std::string GetIcon(); @@ -20,14 +21,16 @@ namespace Components class UIToast { public: - std::string image; + Game::Material* image; std::string title; std::string desc; int length; int start; + Utils::Slot callback; }; - class WinToastHandler: public WinToastLib::IWinToastHandler { + class WinToastHandler: public WinToastLib::IWinToastHandler + { public: void toastActivated() const override {}; void toastDismissed(WinToastLib::IWinToastHandler::WinToastDismissalReason /*state*/) const override {}; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 4d854e73..20ce5ed8 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -394,19 +394,6 @@ namespace Game return poolEntry; } - __declspec(naked) void Menu_FreeItemMemory(Game::itemDef_t* /*item*/) - { - __asm - { - pushad - mov edi, [esp + 24h] - mov eax, 63D880h - call eax - popad - retn - } - } - const char* TableLookup(StringTable* stringtable, int row, int column) { if (!stringtable || !stringtable->values || row >= stringtable->rowCount || column >= stringtable->columnCount) return ""; @@ -454,24 +441,6 @@ namespace Game return gameType; } - __declspec(naked) float UI_GetScoreboardLeft(void* /*a1*/) - { - __asm - { - push eax - pushad - - mov ecx, 590390h - mov eax, [esp + 28h] - call ecx - mov[esp + 20h], eax - popad - pop eax - - retn - } - } - const char *DB_GetXAssetName(XAsset *asset) { if (!asset) return ""; @@ -572,6 +541,219 @@ namespace Game if(lock) InterlockedDecrement(lockVar); } + // this cant be MessageBox because windows.h has a define that converts it to MessageBoxW. which is just stupid + void ShowMessageBox(std::string message, std::string title) + { + if (!Game::CL_IsCgameInitialized()) + { + Dvar_SetStringByName("com_errorMessage", message.data()); + Dvar_SetStringByName("com_errorTitle", title.data()); + Cbuf_AddText(0, "openmenu error_popmenu_lobby"); + } + } + + unsigned int R_HashString(const char* string) + { + unsigned int hash = 0; + + while (*string) + { + hash = (*string | 0x20) ^ (33 * hash); + ++string; + } + + return hash; + } + + void SV_KickClientError(client_t* client, std::string reason) + { + if (client->state < 5) + { + Components::Network::SendCommand(client->addr, "error", reason); + } + + SV_KickClient(client, reason.data()); + } + + void Scr_iPrintLn(int clientNum, std::string message) + { + Game::SV_GameSendServerCommand(clientNum, 0, Utils::String::VA("%c \"%s\"", 0x66, message.data())); + } + + void Scr_iPrintLnBold(int clientNum, std::string message) + { + Game::SV_GameSendServerCommand(clientNum, 0, Utils::String::VA("%c \"%s\"", 0x67, message.data())); + } + + int FS_FOpenFileReadCurrentThread(const char* file, int* fh) + { + if (GetCurrentThreadId() == *reinterpret_cast(0x1CDE7FC)) + { + return FS_FOpenFileRead(file, fh); + } + else if (GetCurrentThreadId() == *reinterpret_cast(0x1CDE814)) + { + return FS_FOpenFileReadDatabase(file, fh); + } + else + { + *fh = NULL; + return -1; + } + } + + void Load_IndexBuffer(void* data, IDirect3DIndexBuffer9** storeHere, int count) + { + if (Components::Dvar::Var("r_loadForRenderer").get()) + { + void* buffer = R_AllocStaticIndexBuffer(storeHere, 2 * count); + std::memcpy(buffer, data, 2 * count); + + if (storeHere && *storeHere) + { + (*storeHere)->Unlock(); + } + } + } + + char* Com_GetParseThreadInfo() + { + if (Game::Sys_IsMainThread()) + { + return reinterpret_cast(0x6466628); + } + else if (Game::Sys_IsRenderThread()) + { + return reinterpret_cast(0x646AC34); + } + else if (Game::Sys_IsServerThread()) + { + return reinterpret_cast(0x646F240); + } + else if(Game::Sys_IsDatabaseThread()) + { + return reinterpret_cast(0x647384C); + } + else + { + return nullptr; + } + } + + void Com_SetParseNegativeNumbers(int parse) + { + char* g_parse = Com_GetParseThreadInfo(); + + if (g_parse) + { + g_parse[1056 * *(reinterpret_cast(g_parse) + 4224) + 1032] = parse != 0; + } + } + + int CL_GetMaxXP() + { + StringTable* rankTable = DB_FindXAssetHeader(ASSET_TYPE_STRINGTABLE, "mp/rankTable.csv").stringTable; + const char* maxrank = StringTable_Lookup(rankTable, 0, "maxrank", 1); + return atoi(StringTable_Lookup(rankTable, 0, maxrank, 7)); + } + + void SortWorldSurfaces(GfxWorld* world) + { + DWORD* specular1 = reinterpret_cast(0x69F105C); + DWORD* specular2 = reinterpret_cast(0x69F92D4); + DWORD saveSpecular1 = *specular1; + DWORD saveSpecular2 = *specular2; + + GfxWorld** gameWorld = reinterpret_cast(0x66DEE94); + GfxWorld* saveWorld = *gameWorld; + + *specular1 = 1; + *specular2 = 1; + *gameWorld = world; + + R_SortWorldSurfaces(); + + *gameWorld = saveWorld; + *specular1 = saveSpecular1; + *specular2 = saveSpecular2; + } + + void R_AddDebugBounds(float* color, Bounds* b) + { + Game::vec3_t v1, v2, v3, v4, v5, v6, v7, v8; + float* center = b->midPoint; + float* halfSize = b->halfSize; + + v1[0] = center[0] - halfSize[0]; + v1[1] = center[1] - halfSize[1]; + v1[2] = center[2] - halfSize[2]; + + v2[0] = center[0] + halfSize[0]; + v2[1] = center[1] - halfSize[1]; + v2[2] = center[2] - halfSize[2]; + + v3[0] = center[0] - halfSize[0]; + v3[1] = center[1] + halfSize[1]; + v3[2] = center[2] - halfSize[2]; + + v4[0] = center[0] + halfSize[0]; + v4[1] = center[1] + halfSize[1]; + v4[2] = center[2] - halfSize[2]; + + v5[0] = center[0] - halfSize[0]; + v5[1] = center[1] - halfSize[1]; + v5[2] = center[2] + halfSize[2]; + + v6[0] = center[0] + halfSize[0]; + v6[1] = center[1] - halfSize[1]; + v6[2] = center[2] + halfSize[2]; + + v7[0] = center[0] - halfSize[0]; + v7[1] = center[1] + halfSize[1]; + v7[2] = center[2] + halfSize[2]; + + v8[0] = center[0] + halfSize[0]; + v8[1] = center[1] + halfSize[1]; + v8[2] = center[2] + halfSize[2]; + + // bottom + Game::R_AddDebugLine(color, v1, v2); + Game::R_AddDebugLine(color, v2, v4); + Game::R_AddDebugLine(color, v4, v3); + Game::R_AddDebugLine(color, v3, v1); + + // top + Game::R_AddDebugLine(color, v5, v6); + Game::R_AddDebugLine(color, v6, v8); + Game::R_AddDebugLine(color, v8, v7); + Game::R_AddDebugLine(color, v7, v5); + + // verticals + Game::R_AddDebugLine(color, v1, v5); + Game::R_AddDebugLine(color, v2, v6); + Game::R_AddDebugLine(color, v3, v7); + Game::R_AddDebugLine(color, v4, v8); + } + +#pragma optimize("", off) + __declspec(naked) float UI_GetScoreboardLeft(void* /*a1*/) + { + __asm + { + push eax + pushad + + mov ecx, 590390h + mov eax, [esp + 28h] + call ecx + mov[esp + 20h], eax + popad + pop eax + + retn + } + } + __declspec(naked) XAssetHeader DB_FindXAssetDefaultHeaderInternal(XAssetType /*type*/) { __asm @@ -583,7 +765,7 @@ namespace Game mov edi, [esp + 28h] call eax - mov [esp + 20h], eax + mov[esp + 20h], eax popad pop eax @@ -633,30 +815,6 @@ namespace Game } } - // this cant be MessageBox because windows.h has a define that converts it to MessageBoxW. which is just stupid - void ShowMessageBox(std::string message, std::string title) - { - if (!Game::CL_IsCgameInitialized()) - { - Dvar_SetStringByName("com_errorMessage", message.data()); - Dvar_SetStringByName("com_errorTitle", title.data()); - Cbuf_AddText(0, "openmenu error_popmenu_lobby"); - } - } - - unsigned int R_HashString(const char* string) - { - unsigned int hash = 0; - - while (*string) - { - hash = (*string | 0x20) ^ (33 * hash); - ++string; - } - - return hash; - } - __declspec(naked) void R_LoadSunThroughDvars(const char* /*mapname*/, sunflare_t* /*sun*/) { __asm @@ -697,7 +855,7 @@ namespace Game mov edi, 0 mov esi, [esp + 24h] - push[esp + 28h] + push [esp + 28h] push 0 push 0 @@ -711,26 +869,6 @@ namespace Game } } - void SV_KickClientError(client_t* client, std::string reason) - { - if (client->state < 5) - { - Components::Network::SendCommand(client->addr, "error", reason); - } - - SV_KickClient(client, reason.data()); - } - - void Scr_iPrintLn(int clientNum, std::string message) - { - Game::SV_GameSendServerCommand(clientNum, 0, Utils::String::VA("%c \"%s\"", 0x66, message.data())); - } - - void Scr_iPrintLnBold(int clientNum, std::string message) - { - Game::SV_GameSendServerCommand(clientNum, 0, Utils::String::VA("%c \"%s\"", 0x67, message.data())); - } - __declspec(naked) void Scr_NotifyId(unsigned int /*id*/, unsigned __int16 /*stringValue*/, unsigned int /*paramcount*/) { __asm @@ -778,37 +916,6 @@ namespace Game } } - int FS_FOpenFileReadCurrentThread(const char* file, int* fh) - { - if (GetCurrentThreadId() == *reinterpret_cast(0x1CDE7FC)) - { - return FS_FOpenFileRead(file, fh); - } - else if (GetCurrentThreadId() == *reinterpret_cast(0x1CDE814)) - { - return FS_FOpenFileReadDatabase(file, fh); - } - else - { - *fh = NULL; - return -1; - } - } - - void Load_IndexBuffer(void* data, IDirect3DIndexBuffer9** storeHere, int count) - { - if (Components::Dvar::Var("r_loadForRenderer").get()) - { - void* buffer = R_AllocStaticIndexBuffer(storeHere, 2 * count); - std::memcpy(buffer, data, 2 * count); - - if (storeHere && *storeHere) - { - (*storeHere)->Unlock(); - } - } - } - __declspec(naked) void Load_VertexBuffer(void* /*data*/, IDirect3DVertexBuffer9** /*where*/, int /*len*/) { __asm @@ -829,91 +936,40 @@ namespace Game } } - char* Com_GetParseThreadInfo() - { - if (Game::Sys_IsMainThread()) - { - return reinterpret_cast(0x6466628); - } - else if (Game::Sys_IsRenderThread()) - { - return reinterpret_cast(0x646AC34); - } - else if (Game::Sys_IsServerThread()) - { - return reinterpret_cast(0x646F240); - } - else if(Game::Sys_IsDatabaseThread()) - { - return reinterpret_cast(0x647384C); - } - else - { - return nullptr; - } - } - - void Com_SetParseNegativeNumbers(int parse) - { - char* g_parse = Com_GetParseThreadInfo(); - - if (g_parse) - { - g_parse[1056 * *(reinterpret_cast(g_parse) + 4224) + 1032] = parse != 0; - } - } - - int CL_GetMaxXP() - { - StringTable* rankTable = DB_FindXAssetHeader(ASSET_TYPE_STRINGTABLE, "mp/rankTable.csv").stringTable; - const char* maxrank = StringTable_Lookup(rankTable, 0, "maxrank", 1); - return atoi(StringTable_Lookup(rankTable, 0, maxrank, 7)); - } - - __declspec(naked) void Image_Setup(GfxImage* /*image*/, unsigned int /*width*/, unsigned int /*height*/, unsigned int /*depth*/, unsigned int /*flags*/, int /*format*/) + __declspec(naked) void Image_Setup(GfxImage* /*image*/, unsigned int /*width*/, unsigned int /*height*/, unsigned int /*depth*/, unsigned int /*flags*/, _D3DFORMAT /*format*/) { __asm { pushad - xor edi, edi - mov eax, [esp + 24h] // image - mov di, word ptr [esp + 28h] // width - push [esp + 38h] // format - push [esp + 38h] // flags - push 0 - push [esp + 3Ch] // depth - push [esp + 3Ch] // height + mov eax, [esp + 24h] // image + mov edi, [esp + 28h] // width + push [esp + 38h] // format + push [esp + 38h] // flags + push [esp + 38h] // depth + push [esp + 38h] // height mov ecx, 54AF50h call ecx - add esp, 14h + add esp, 10h popad retn } } - void SortWorldSurfaces(GfxWorld* world) + __declspec(naked) void Menu_FreeItemMemory(itemDef_t* /*item*/) { - DWORD* specular1 = reinterpret_cast(0x69F105C); - DWORD* specular2 = reinterpret_cast(0x69F92D4); - DWORD saveSpecular1 = *specular1; - DWORD saveSpecular2 = *specular2; - - GfxWorld** gameWorld = reinterpret_cast(0x66DEE94); - GfxWorld* saveWorld = *gameWorld; - - *specular1 = 1; - *specular2 = 1; - *gameWorld = world; - - R_SortWorldSurfaces(); - - *gameWorld = saveWorld; - *specular1 = saveSpecular1; - *specular2 = saveSpecular2; + __asm + { + pushad + mov edi, [esp + 24h] + mov eax, 63D880h + call eax + popad + retn + } } __declspec(naked) void R_AddDebugLine(float* /*color*/, float* /*v1*/, float* /*v2*/) @@ -975,61 +1031,5 @@ namespace Game retn } } - - void R_AddDebugBounds(float* color, Bounds* b) - { - Game::vec3_t v1, v2, v3, v4, v5, v6, v7, v8; - float* center = b->midPoint; - float* halfSize = b->halfSize; - - v1[0] = center[0] - halfSize[0]; - v1[1] = center[1] - halfSize[1]; - v1[2] = center[2] - halfSize[2]; - - v2[0] = center[0] + halfSize[0]; - v2[1] = center[1] - halfSize[1]; - v2[2] = center[2] - halfSize[2]; - - v3[0] = center[0] - halfSize[0]; - v3[1] = center[1] + halfSize[1]; - v3[2] = center[2] - halfSize[2]; - - v4[0] = center[0] + halfSize[0]; - v4[1] = center[1] + halfSize[1]; - v4[2] = center[2] - halfSize[2]; - - v5[0] = center[0] - halfSize[0]; - v5[1] = center[1] - halfSize[1]; - v5[2] = center[2] + halfSize[2]; - - v6[0] = center[0] + halfSize[0]; - v6[1] = center[1] - halfSize[1]; - v6[2] = center[2] + halfSize[2]; - - v7[0] = center[0] - halfSize[0]; - v7[1] = center[1] + halfSize[1]; - v7[2] = center[2] + halfSize[2]; - - v8[0] = center[0] + halfSize[0]; - v8[1] = center[1] + halfSize[1]; - v8[2] = center[2] + halfSize[2]; - - // bottom - Game::R_AddDebugLine(color, v1, v2); - Game::R_AddDebugLine(color, v2, v4); - Game::R_AddDebugLine(color, v4, v3); - Game::R_AddDebugLine(color, v3, v1); - - // top - Game::R_AddDebugLine(color, v5, v6); - Game::R_AddDebugLine(color, v6, v8); - Game::R_AddDebugLine(color, v8, v7); - Game::R_AddDebugLine(color, v7, v5); - - // verticals - Game::R_AddDebugLine(color, v1, v5); - Game::R_AddDebugLine(color, v2, v6); - Game::R_AddDebugLine(color, v3, v7); - Game::R_AddDebugLine(color, v4, v8); - } +#pragma optimize("", on) } diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index cb7f79f5..345664a3 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -845,7 +845,7 @@ namespace Game int CL_GetMaxXP(); - void Image_Setup(GfxImage* image, unsigned int width, unsigned int height, unsigned int depth, unsigned int flags, int format); + void Image_Setup(GfxImage* image, unsigned int width, unsigned int height, unsigned int depth, unsigned int flags, _D3DFORMAT format); void SortWorldSurfaces(GfxWorld* world); void R_AddDebugLine(float* color, float* v1, float* v2);