From f96973f439adf799b17100b27cae28ea534a8176 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 7 Oct 2016 17:50:30 +0200 Subject: [PATCH] Some zone stuff --- deps/fmt | 2 +- deps/json11 | 2 +- deps/mongoose | 2 +- src/Components/Modules/AssetHandler.cpp | 55 ++++++++++++++++++++++++- src/Components/Modules/AssetHandler.hpp | 19 +++++---- src/Components/Modules/Zones.cpp | 14 +++++-- src/Game/Functions.cpp | 1 + src/Game/Functions.hpp | 3 ++ src/Game/Structs.hpp | 37 +++++++++++++++++ 9 files changed, 120 insertions(+), 15 deletions(-) diff --git a/deps/fmt b/deps/fmt index cee50b75..4809e295 160000 --- a/deps/fmt +++ b/deps/fmt @@ -1 +1 @@ -Subproject commit cee50b7572e4416f5aa7a2a6068543c1e5cd04a9 +Subproject commit 4809e2956a9ec04e97f026c5df224349f61179b0 diff --git a/deps/json11 b/deps/json11 index 78780917..bb0e389f 160000 --- a/deps/json11 +++ b/deps/json11 @@ -1 +1 @@ -Subproject commit 787809178ddb3d739e6f408af5233930c9077929 +Subproject commit bb0e389ffd1e994df9580bf9801a1e78b8c83862 diff --git a/deps/mongoose b/deps/mongoose index 786f46c6..f9a6403b 160000 --- a/deps/mongoose +++ b/deps/mongoose @@ -1 +1 @@ -Subproject commit 786f46c6551af34bb720913c13a5d7fb37c02822 +Subproject commit f9a6403b115f2b62ead2664e57f0dd906d3f51d0 diff --git a/src/Components/Modules/AssetHandler.cpp b/src/Components/Modules/AssetHandler.cpp index 882b7303..4170255d 100644 --- a/src/Components/Modules/AssetHandler.cpp +++ b/src/Components/Modules/AssetHandler.cpp @@ -9,6 +9,8 @@ namespace Components std::map AssetHandler::Relocations; + std::vector> AssetHandler::EmptyAssets; + std::map AssetHandler::TemporaryAssets[Game::XAssetType::ASSET_TYPE_COUNT]; void AssetHandler::RegisterInterface(IAsset* iAsset) @@ -118,6 +120,18 @@ namespace Components const char* name = Game::DB_GetXAssetNameHandlers[type](asset); if (!name) return false; + for (auto i = AssetHandler::EmptyAssets.begin(); i != AssetHandler::EmptyAssets.end();) + { + if (i->first == type && i->second == name) + { + i = AssetHandler::EmptyAssets.erase(i); + } + else + { + ++i; + } + } + if (Flags::HasFlag("entries")) { OutputDebugStringA(Utils::String::VA("%s: %d: %s\n", FastFiles::Current().data(), type, name)); @@ -172,7 +186,6 @@ namespace Components { for (DWORD i = 0; i < size; i += 4) { - // Reinterpret cast is fine here, as we are working with low-level pointers (due to the relocation hook) AssetHandler::Relocations[reinterpret_cast(start) + i] = reinterpret_cast(to) + i; } } @@ -260,6 +273,30 @@ namespace Components return header; } + void AssetHandler::StoreEmptyAsset(Game::XAssetType type, const char* name) + { + AssetHandler::EmptyAssets.push_back({ type,name }); + } + + __declspec(naked) void AssetHandler::StoreEmptyAssetStub() + { + __asm + { + pushad + push ebx + push eax + + call AssetHandler::StoreEmptyAsset + + pop eax + pop ebx + popad + + push 5BB290h + retn + } + } + AssetHandler::AssetHandler() { AssetHandler::ClearTemporaryAssets(); @@ -273,6 +310,22 @@ namespace Components // DB_AddXAsset Utils::Hook(0x5BB650, AssetHandler::AddAssetStub, HOOK_JUMP).Install()->Quick(); + // Store empty assets + Utils::Hook(0x5BB6EC, AssetHandler::StoreEmptyAssetStub, HOOK_CALL).Install()->Quick(); + + QuickPatch::OnFrame([] () + { + if (Game::Sys_IsDatabaseReady() && Game::Sys_IsDatabaseReady2() && !AssetHandler::EmptyAssets.empty()) + { + for (auto& asset : AssetHandler::EmptyAssets) + { + Game::Sys_Error(25, reinterpret_cast(0x724428), Game::DB_GetXAssetTypeName(asset.first), asset.second.data()); + } + + AssetHandler::EmptyAssets.clear(); + } + }); + // Register asset interfaces if (ZoneBuilder::IsEnabled()) { diff --git a/src/Components/Modules/AssetHandler.hpp b/src/Components/Modules/AssetHandler.hpp index b04e0b7c..8a6f12c7 100644 --- a/src/Components/Modules/AssetHandler.hpp +++ b/src/Components/Modules/AssetHandler.hpp @@ -46,6 +46,16 @@ namespace Components private: static bool BypassState; + static std::map TemporaryAssets[Game::XAssetType::ASSET_TYPE_COUNT]; + + static std::map AssetInterfaces; + static std::map> TypeCallbacks; + static wink::signal> RestrictSignal; + + static std::map Relocations; + + static std::vector> EmptyAssets; + static void RegisterInterface(IAsset* iAsset); static Game::XAssetHeader FindAsset(Game::XAssetType type, const char* filename); @@ -55,13 +65,8 @@ namespace Components static void OffsetToAlias(Utils::Stream::Offset* offset); - static std::map TemporaryAssets[Game::XAssetType::ASSET_TYPE_COUNT]; - - static std::map AssetInterfaces; - static std::map> TypeCallbacks; - static wink::signal> RestrictSignal; - - static std::map Relocations; + static void StoreEmptyAsset(Game::XAssetType type, const char* name); + static void StoreEmptyAssetStub(); }; } diff --git a/src/Components/Modules/Zones.cpp b/src/Components/Modules/Zones.cpp index f53e97d9..87bbdf72 100644 --- a/src/Components/Modules/Zones.cpp +++ b/src/Components/Modules/Zones.cpp @@ -1123,8 +1123,9 @@ namespace Components { bool result = Game::Load_Stream(atStreamStart, buffer, size + 4); - std::memmove(buffer + 8, buffer + 12, 196); - AssetHandler::Relocate(buffer + 12, buffer + 8, 196); + int shiftTest = 4; + std::memmove(buffer + 8 + shiftTest, buffer + 12 + shiftTest, 196 - shiftTest); + AssetHandler::Relocate(buffer + 12 + shiftTest, buffer + 8 + shiftTest, 196 - shiftTest); return result; } @@ -1150,6 +1151,8 @@ namespace Components static_assert(offsetof(material339_s, sortKey) == 20, ""); static_assert(offsetof(material339_s, textureAtlasColumnCount) == 22, ""); + static_assert(offsetof(Game::Material, stateBitsEntry) == 24, ""); + Game::Material* material = (Game::Material*)buffer; memcpy(&material359, material, sizeof(material359)); @@ -1158,9 +1161,12 @@ namespace Components material->textureAtlasRowCount = material359.textureAtlasRowCount; material->textureAtlasColumnCount = material359.textureAtlasColumnCount; material->gameFlags = material359.gameFlags; + + // Probably wrong material->surfaceTypeBits = material359.surfaceTypeBits; - - memcpy(material->drawSurf, material359.drawSurfBegin, 4); // Probably wrong + + // Pretty sure that's wrong + memcpy(material->drawSurf, material359.drawSurfBegin, 4); material->drawSurf[4] = 0; material->drawSurf[5] = 0; diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index c93f361e..c267b963 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -203,6 +203,7 @@ namespace Game SV_Cmd_EndTokenizedString_t SV_Cmd_EndTokenizedString = (SV_Cmd_EndTokenizedString_t)0x464750; SV_DirectConnect_t SV_DirectConnect = (SV_DirectConnect_t)0x460480; + Sys_Error_t Sys_Error = (Sys_Error_t)0x4E0200; Sys_FreeFileList_t Sys_FreeFileList = (Sys_FreeFileList_t)0x4D8580; Sys_IsDatabaseReady_t Sys_IsDatabaseReady = (Sys_IsDatabaseReady_t)0x4CA4A0; Sys_IsDatabaseReady2_t Sys_IsDatabaseReady2 = (Sys_IsDatabaseReady2_t)0x441280; diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index 66d90559..f6735aec 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -473,6 +473,9 @@ namespace Game typedef void(__cdecl * SV_DirectConnect_t)(netadr_t adr); extern SV_DirectConnect_t SV_DirectConnect; + typedef int(__cdecl * Sys_Error_t)(int, char *, ...); + extern Sys_Error_t Sys_Error; + typedef void(__cdecl * Sys_FreeFileList_t)(char** list); extern Sys_FreeFileList_t Sys_FreeFileList; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index ef3f467f..e1680cb7 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -340,6 +340,15 @@ namespace Game MaterialTechnique* techniques[48]; }; + struct MaterialTechniqueSet_new + { + const char* name; + char pad[4]; + MaterialTechniqueSet* remappedTechniques; + int pad2; + MaterialTechnique* techniques[48]; + }; + struct MaterialConstantDef { int nameHash; @@ -368,6 +377,30 @@ namespace Game void *stateBitTable; }; + struct Material_new + { + char drawSurfBegin[4]; // Probably wrong + int surfaceTypeBits; + const char *name; + char drawSurf[6]; + char gameFlags; + char pad; + char sortKey; + char textureAtlasRowCount; + char textureAtlasColumnCount; + char pad2; + char stateBitsEntry[48]; + char textureCount; + char constantCount; + char stateBitsCount; + char stateFlags; + char cameraRegion; + MaterialTechniqueSet_new *techniqueSet; + MaterialTextureDef *textureTable; + MaterialConstantDef *constantTable; + void *stateBitTable; + }; + struct TracerDef { const char * name; @@ -2776,6 +2809,10 @@ namespace Game }; #pragma pack(pop) +#ifdef __cplusplus + static_assert(offsetof(GfxWorld, worldDraw) == 80, ""); +#endif + union XAssetHeader { void *data;