diff --git a/.gitignore b/.gitignore index 8aa0c63..89e8cdb 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,15 @@ *.vscode *.project *.cproject +*.vcproj +*.vcxproj +*.vcxproj.filters +**/CMakeFiles/** +cmake_install.cmake +CMakeCache.txt +*.sln +*.rc +/*.dir # Build directories Release @@ -46,7 +55,12 @@ bin/ *.opendb *.wixpdb +**/RelWithDebInfo/ +**/Debug/ +/bin +/win32 /out /build +/_deps .idea \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e04a7d..f8227ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ endif() set(VERSION_MAJOR 1) set(VERSION_MINOR 5) -set(VERSION_PATCH 5) +set(VERSION_PATCH 6) set(VERSION_TWEAK 0) set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc") @@ -49,6 +49,7 @@ endif() list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") include(libzippp) +include(minhook) add_library(gMod SHARED) @@ -72,6 +73,7 @@ target_link_libraries(gMod PRIVATE ${DXGUID_LIB} libzippp psapi + minhook ) target_link_options(gMod PRIVATE "$<$:/NODEFAULTLIB:LIBCMT>" diff --git a/cmake/libzippp.cmake b/cmake/libzippp.cmake index 3ffbed9..3472d13 100644 --- a/cmake/libzippp.cmake +++ b/cmake/libzippp.cmake @@ -21,7 +21,7 @@ if (NOT libzippp_POPULATED) FetchContent_Populate(libzippp) endif() -add_library(libzippp) +add_library(libzippp STATIC) set(SOURCES "${libzippp_SOURCE_DIR}/src/libzippp.h" diff --git a/cmake/minhook.cmake b/cmake/minhook.cmake new file mode 100644 index 0000000..d1da7ca --- /dev/null +++ b/cmake/minhook.cmake @@ -0,0 +1,16 @@ +include_guard() +include(FetchContent) + +FetchContent_Declare( + minhook + GIT_REPOSITORY https://github.com/TsudaKageyu/minhook + GIT_TAG master) +FetchContent_GetProperties(minhook) + +if (NOT minhook_POPULATED) + FetchContent_Populate(minhook) +endif() + +add_subdirectory(${minhook_SOURCE_DIR} EXCLUDE_FROM_ALL) + +set_target_properties(minhook PROPERTIES FOLDER "Dependencies/") diff --git a/header/Defines.h b/header/Defines.h new file mode 100644 index 0000000..707b12b --- /dev/null +++ b/header/Defines.h @@ -0,0 +1,15 @@ +#pragma once + +//#define HashType DWORD64 +using HashType = DWORD32; + +#ifdef LOG_MESSAGE +#include + +#ifdef _DEBUG +#define Message(...) { printf(__VA_ARGS__); } +#else +#define Message(...) +#endif + +#endif diff --git a/header/uMod_Error.h b/header/Error.h similarity index 81% rename from header/uMod_Error.h rename to header/Error.h index 94240e0..6d43a21 100644 --- a/header/uMod_Error.h +++ b/header/Error.h @@ -42,3 +42,11 @@ #define uMod_ERROR_UPDATE 1u<<7 #define uMod_ERROR_SERVER 1u<<8 +__declspec(noreturn) void FatalAssert( + const char* expr, + const char* file, + unsigned int line, + const char* function); + +#define ASSERT(expr) ((void)(!!(expr) || (FatalAssert(#expr, __FILE__, (unsigned)__LINE__, __FUNCTION__), 0))) + diff --git a/header/gMod_FileLoader.h b/header/FileLoader.h similarity index 87% rename from header/gMod_FileLoader.h rename to header/FileLoader.h index cea84f7..4ddd746 100644 --- a/header/gMod_FileLoader.h +++ b/header/FileLoader.h @@ -9,11 +9,10 @@ struct TpfEntry { std::string name; std::string entry; uint32_t crc_hash; - void* data; - unsigned long long size; + std::vector data; }; -class gMod_FileLoader { +class FileLoader { std::string file_name; const std::string TPF_PASSWORD{ 0x73, 0x2A, 0x63, 0x7D, 0x5F, 0x0A, static_cast(0xA6), static_cast(0xBD), @@ -25,7 +24,7 @@ class gMod_FileLoader { }; public: - gMod_FileLoader(const std::string& fileName); + FileLoader(const std::string& fileName); std::vector GetContents(); diff --git a/header/uMod_Main.h b/header/Main.h similarity index 64% rename from header/uMod_Main.h rename to header/Main.h index ff492a3..27b60f8 100644 --- a/header/uMod_Main.h +++ b/header/Main.h @@ -4,15 +4,16 @@ #include #include +#include "Utils.h" #include #include -#include "uMod_GlobalDefines.h" -#include "uMod_Error.h" -#include "uMod_Defines.h" -#include "uMod_DX9_dll.h" -#include "uMod_TextureFunction.h" +#include "Defines.h" +#include "Error.h" +#include "Defines.h" +#include "dll_main.h" +#include "TextureFunction.h" #include "uMod_IDirect3D9.h" #include "uMod_IDirect3D9Ex.h" @@ -24,10 +25,9 @@ #include "uMod_IDirect3DTexture9.h" #include "uMod_IDirect3DVolumeTexture9.h" -#include "uMod_ArrayHandler.h" -#include "uMod_TextureServer.h" -#include "uMod_TextureClient.h" +#include "TextureClient.h" #pragma warning(disable : 4477) extern unsigned int gl_ErrorState; +extern HINSTANCE gl_hThisInstance; diff --git a/header/TextureClient.h b/header/TextureClient.h new file mode 100644 index 0000000..d5aaa2f --- /dev/null +++ b/header/TextureClient.h @@ -0,0 +1,251 @@ +#pragma once + +#include + +#include "FileLoader.h" +#include "uMod_IDirect3DTexture9.h" + +extern unsigned int gl_ErrorState; + +struct TextureFileStruct { + std::vector data{}; + HashType crc_hash = 0; // hash value +}; + +template +concept uModTexturePtr = requires(T a) +{ + std::same_as || + std::same_as || + std::same_as; +}; + +template +concept uModTexturePtrPtr = uModTexturePtr>; + +/* + * An object of this class is owned by each d3d9 device. + * functions called by the Server are called from the server thread instance. + * All other functions are called from the render thread instance of the game itself. + */ +class TextureClient { +public: + TextureClient(IDirect3DDevice9* device); + ~TextureClient(); + + int AddTexture(uModTexturePtr auto pTexture); + int RemoveTexture(uModTexturePtr auto pTexture); //called from uMod_IDirect3DTexture9::Release() + int LookUpToMod(uModTexturePtr auto pTexture); + // called at the end AddTexture(...) and from Device->UpdateTexture(...) + + int MergeUpdate(); //called from uMod_IDirect3DDevice9::BeginScene() + + // Add TpfEntry data, return size of data added. 0 on failure. + unsigned long AddFile(TpfEntry& entry); + + std::vector OriginalTextures; + // stores the pointer to the uMod_IDirect3DTexture9 objects created by the game + std::vector OriginalVolumeTextures; + // stores the pointer to the uMod_IDirect3DVolumeTexture9 objects created by the game + std::vector OriginalCubeTextures; + // stores the pointer to the uMod_IDirect3DCubeTexture9 objects created by the game + + D3DCOLOR FontColour; + D3DCOLOR TextureColour; + + void Initialize(); + +private: + IDirect3DDevice9* D3D9Device; + // Cached info about whether this id a dx9ex device or not; used for proxy functions + bool isDirectXExDevice = false; + + // DX9 proxy functions + uMod_IDirect3DTexture9* GetSingleTexture(); + uMod_IDirect3DVolumeTexture9* GetSingleVolumeTexture(); + uMod_IDirect3DCubeTexture9* GetSingleCubeTexture(); + int SetLastCreatedTexture(uMod_IDirect3DTexture9*); + int SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9*); + int SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9*); + + bool should_update = false; + + int LockMutex(); + int UnlockMutex(); + HANDLE Mutex; + + std::unordered_map modded_textures; + // array which stores the file in memory and the hash of each texture to be modded + + // called if a target texture is found + int LoadTexture(TextureFileStruct* file_in_memory, uModTexturePtrPtr auto ppTexture); + + void LoadModsFromFile(const char* source); +}; + +int TextureClient::AddTexture(uModTexturePtr auto pTexture) +{ + if constexpr (std::same_as) { + SetLastCreatedTexture(nullptr); + } + else if constexpr (std::same_as) { + SetLastCreatedVolumeTexture(nullptr); + } + else if constexpr (std::same_as) { + SetLastCreatedCubeTexture(nullptr); + } + + if (pTexture->FAKE) { + return RETURN_OK; // this is a fake texture + } + + if (gl_ErrorState & uMod_ERROR_FATAL) { + return RETURN_FATAL_ERROR; + } + + Message("TextureClient::AddTexture( Cube: %p): %p (thread: %u)\n", pTexture, this, GetCurrentThreadId()); + + pTexture->Hash = pTexture->GetHash(); + if (!pTexture->Hash) { + return RETURN_FATAL_ERROR; + } + + if constexpr (std::same_as) { + OriginalTextures.push_back(pTexture); + } + else if constexpr (std::same_as) { + OriginalVolumeTextures.push_back(pTexture); + } + else if constexpr (std::same_as) { + OriginalCubeTextures.push_back(pTexture); + } + + return LookUpToMod(pTexture); // check if this texture should be modded +} + +int TextureClient::RemoveTexture(uModTexturePtr auto pTexture) +{ + Message("TextureClient::RemoveTexture( %p, %#lX): %p\n", pTexture, pTexture->Hash, this); + + if (gl_ErrorState & uMod_ERROR_FATAL) { + return RETURN_FATAL_ERROR; + } + + if (!pTexture->FAKE) { + if constexpr (std::same_as) { + utils::erase_first(OriginalTextures, pTexture); + } + else if constexpr (std::same_as) { + utils::erase_first(OriginalVolumeTextures, pTexture); + } + else if constexpr (std::same_as) { + utils::erase_first(OriginalCubeTextures, pTexture); + } + } + if (!pTexture->Reference) + return RETURN_OK; // Should this ever happen? + return RETURN_OK; +} + +int TextureClient::LookUpToMod(uModTexturePtr auto pTexture) +{ + Message("TextureClient::LookUpToMod( %p): hash: %#lX, %p\n", pTexture, pTexture->Hash, this); + int ret = RETURN_OK; + + if (pTexture->CrossRef_D3Dtex != nullptr) + return ret; // bug, this texture is already switched + + const auto found = modded_textures.find(pTexture->Hash); + if (found == modded_textures.end()) + return ret; + + const auto textureFileStruct = found->second; + + decltype(pTexture) fake_Texture; + ret = LoadTexture(textureFileStruct, &fake_Texture); + if (ret != RETURN_OK) + return ret; + + ret = SwitchTextures(fake_Texture, pTexture); + if (ret != RETURN_OK) { + Message("TextureClient::LookUpToMod(): textures not switched %#lX\n", textureFileStruct->crc_hash); + fake_Texture->Release(); + return ret; + } + fake_Texture->Reference = textureFileStruct; + return ret; +} + +int TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uModTexturePtrPtr auto ppTexture) +{ + Message("LoadTexture( %p, %p, %#lX): %p\n", file_in_memory, ppTexture, file_in_memory->crc_hash, this); + if constexpr (std::same_as) { + if (D3D_OK != D3DXCreateTextureFromFileInMemoryEx( + D3D9Device, file_in_memory->data.data(), + file_in_memory->data.size(), D3DX_DEFAULT, D3DX_DEFAULT, + D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, + D3DX_DEFAULT, D3DX_DEFAULT, 0, nullptr, nullptr, + (IDirect3DTexture9**)ppTexture)) { + *ppTexture = nullptr; + return RETURN_TEXTURE_NOT_LOADED; + } + SetLastCreatedTexture(nullptr); + } + else if constexpr (std::same_as) { + if (D3D_OK != D3DXCreateVolumeTextureFromFileInMemoryEx( + D3D9Device, file_in_memory->data.data(), + file_in_memory->data.size(), D3DX_DEFAULT, D3DX_DEFAULT, + D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, + D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, + nullptr, + nullptr, + (IDirect3DVolumeTexture9**)ppTexture)) { + *ppTexture = nullptr; + return RETURN_TEXTURE_NOT_LOADED; + } + SetLastCreatedVolumeTexture(nullptr); + } + else if constexpr (std::same_as) { + if (D3D_OK != D3DXCreateCubeTextureFromFileInMemoryEx( + D3D9Device, file_in_memory->data.data(), file_in_memory->data.size(), D3DX_DEFAULT, D3DX_DEFAULT, 0, + D3DFMT_UNKNOWN, D3DPOOL_MANAGED, + D3DX_DEFAULT, D3DX_DEFAULT, 0, nullptr, nullptr, + (IDirect3DCubeTexture9**)ppTexture)) { + *ppTexture = nullptr; + return RETURN_TEXTURE_NOT_LOADED; + } + SetLastCreatedCubeTexture(nullptr); + } + (*ppTexture)->FAKE = true; + + Message("LoadTexture( %p, %#lX): DONE\n", *ppTexture, file_in_memory->crc_hash); + return RETURN_OK; +} + +template requires uModTexturePtr +void UnswitchTextures(T pTexture) +{ + decltype(pTexture) CrossRef = pTexture->CrossRef_D3Dtex; + if (CrossRef != nullptr) { + std::swap(pTexture->m_D3Dtex, CrossRef->m_D3Dtex); + + // cancel the link + CrossRef->CrossRef_D3Dtex = nullptr; + pTexture->CrossRef_D3Dtex = nullptr; + } +} + +template requires uModTexturePtr +inline int SwitchTextures(T pTexture1, T pTexture2) +{ + if (pTexture1->m_D3Ddev == pTexture2->m_D3Ddev && pTexture1->CrossRef_D3Dtex == nullptr && pTexture2->CrossRef_D3Dtex == nullptr) { + // make cross reference + pTexture1->CrossRef_D3Dtex = pTexture2; + pTexture2->CrossRef_D3Dtex = pTexture1; + + // switch textures + std::swap(pTexture1->m_D3Dtex, pTexture2->m_D3Dtex); + return RETURN_OK; + } + return RETURN_TEXTURE_NOT_SWITCHED; +} diff --git a/header/uMod_TextureFunction.h b/header/TextureFunction.h similarity index 93% rename from header/uMod_TextureFunction.h rename to header/TextureFunction.h index 56964e1..bdc4974 100644 --- a/header/uMod_TextureFunction.h +++ b/header/TextureFunction.h @@ -1,6 +1,20 @@ #pragma once -unsigned int GetCRC32(char* pcDatabuf, unsigned int ulDatalen); +constexpr auto crc32_poly = 0xEDB88320u; +constexpr auto ul_crc_in = 0xffffffff; + +inline unsigned int GetCRC32(char* pcDatabuf, unsigned int ulDatalen) +{ + unsigned int crc = ul_crc_in; + for (unsigned int idx = 0u; idx < ulDatalen; idx++) { + unsigned int data = *pcDatabuf++; + for (unsigned int bit = 0u; bit < 8u; bit++, data >>= 1) { + crc = crc >> 1 ^ ((crc ^ data) & 1 ? crc32_poly : 0); + } + } + return crc; +} + /* case D3DFMT_MULTI2_ARGB8: case D3DFMT_VERTEXDATA: diff --git a/header/XorStreamReader.h b/header/TpfReader.h similarity index 94% rename from header/XorStreamReader.h rename to header/TpfReader.h index 7d98013..d391b09 100644 --- a/header/XorStreamReader.h +++ b/header/TpfReader.h @@ -3,9 +3,9 @@ #include #include -class XorStreamReader { +class TpfReader { public: - XorStreamReader(const std::string& path) + TpfReader(const std::string& path) { file_stream = std::ifstream(path, std::ios::binary); if (!file_stream.seekg(0, std::ios::end).good() || !file_stream.seekg(0, std::ios::beg).good()) { @@ -13,7 +13,7 @@ public: } } - ~XorStreamReader() + ~TpfReader() { file_stream.close(); } diff --git a/header/Utils.h b/header/Utils.h new file mode 100644 index 0000000..d443968 --- /dev/null +++ b/header/Utils.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace utils +{ + template + void erase_first(std::vector& vec, const T& elem) + { + const auto found = std::ranges::find(vec, elem); + if (found != std::ranges::end(vec)) { + vec.erase(found); + } + } +} diff --git a/header/dll_main.h b/header/dll_main.h new file mode 100644 index 0000000..72fa87f --- /dev/null +++ b/header/dll_main.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +void InitInstance(HINSTANCE hModule); +void ExitInstance(); +HMODULE LoadOriginalDll(); + +IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion); +HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D); diff --git a/header/uMod_ArrayHandler.h b/header/uMod_ArrayHandler.h deleted file mode 100644 index 172c186..0000000 --- a/header/uMod_ArrayHandler.h +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include "uMod_GlobalDefines.h" -#include "uMod_IDirect3DTexture9.h" -extern unsigned int gl_ErrorState; - -struct TextureFileStruct { - bool ForceReload; // to force a reload of the texture (if it is already modded) - char* pData; // store texture file as file in memory - unsigned int Size; // size of file - int NumberOfTextures; - int Reference; // for a fast delete in the FileHandler - IDirect3DBaseTexture9** Textures; // pointer to the fake textures - MyTypeHash Hash; // hash value -}; - -class uMod_FileHandler // array to store TextureFileStruct -{ -public: - uMod_FileHandler(); - ~uMod_FileHandler(); - - int Add(TextureFileStruct* file); - int Remove(TextureFileStruct* file); - - int GetNumber() { return Number; } - - TextureFileStruct* operator [](int i) - { - if (i < 0 || i >= Number) { - return nullptr; - } - return Files[i / FieldLength][i % FieldLength]; - } - -protected: - static constexpr int FieldLength = 1024; - long Number = 0; - int FieldCounter = 0; - TextureFileStruct*** Files = nullptr; -}; - - -template -class uMod_TextureHandler // array to store uMod_IDirect3DTexture9, uMod_IDirect3DVolumeTexture9 or uMod_IDirect3DCubeTexture9 -{ -public: - uMod_TextureHandler(); - ~uMod_TextureHandler(); - - int Add(T* texture); - int Remove(T* texture); - - int GetNumber() { return Number; } - - T* operator [](int i) - { - if (i < 0 || i >= Number) { - return nullptr; - } - return Textures[i / FieldLength][i % FieldLength]; - } - -private: - static constexpr int FieldLength = 1024; - long Number; - int FieldCounter; - T*** Textures; -}; - -template -uMod_TextureHandler::uMod_TextureHandler() -{ - Message("uMod_TextureHandler(): %p\n", this); - Number = 0; - FieldCounter = 0; - - Textures = NULL; -} - -template -uMod_TextureHandler::~uMod_TextureHandler() -{ - Message("~uMod_TextureHandler(): %p\n", this); - if (Textures != nullptr) { - for (int i = 0; i < FieldCounter; i++) { - delete [] Textures[i]; - } - delete [] Textures; - } -} - -template -int uMod_TextureHandler::Add(T* pTexture) -{ - Message("uMod_TextureHandler::Add( %p): %p\n", pTexture, this); - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - - if (pTexture->Reference >= 0) { - return RETURN_TEXTURE_ALLREADY_ADDED; - } - - if (Number / FieldLength == FieldCounter) { - T*** temp = nullptr; - try { temp = new T**[FieldCounter + 10]; } - catch (...) { - gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_TEXTURE; - return RETURN_NO_MEMORY; - } - - for (int i = 0; i < FieldCounter; i++) { - temp[i] = Textures[i]; - } - - for (int i = FieldCounter; i < FieldCounter + 10; i++) { - temp[i] = NULL; - } - - FieldCounter += 10; - - delete [] Textures; - - Textures = temp; - } - if (Number % FieldLength == 0) { - try { - if (Textures[Number / FieldLength] == NULL) { - Textures[Number / FieldLength] = new T*[FieldLength]; - } - } - catch (...) { - Textures[Number / FieldLength] = NULL; - gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_TEXTURE; - return RETURN_NO_MEMORY; - } - } - - Textures[Number / FieldLength][Number % FieldLength] = pTexture; - pTexture->Reference = Number++; - - return RETURN_OK; -} - - -template -int uMod_TextureHandler::Remove(T* pTexture) //will be called, if a texture is completely released -{ - Message("uMod_TextureHandler::Remove(%p): %p\n", pTexture, this); - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - - int ref = pTexture->Reference; - if (ref < 0) { - return RETURN_OK; // returning if no TextureHandlerRef is set - } - - if (ref < (--Number)) { - Textures[ref / FieldLength][ref % FieldLength] = Textures[Number / FieldLength][Number % FieldLength]; - Textures[ref / FieldLength][ref % FieldLength]->Reference = ref; - } - return RETURN_OK; -} diff --git a/header/uMod_DX9_dll.h b/header/uMod_DX9_dll.h deleted file mode 100644 index f548b43..0000000 --- a/header/uMod_DX9_dll.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -void InitInstance(HINSTANCE hModule); -void ExitInstance(); -void LoadOriginalDll(); -bool FindLoadedDll(); -bool IsDesiredModule(HMODULE hModule, HANDLE hProcess); -bool HasDesiredMethods(HMODULE hModule, HANDLE hProcess); -bool HookThisProgram(char* ret); - -void* DetourFunc(BYTE* src, const BYTE* dst, int len); -bool RetourFunc(BYTE* src, BYTE* restore, int len); -IDirect3D9*APIENTRY uMod_Direct3DCreate9(UINT SDKVersion); -HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D); - - -#ifdef DIRECT_INJECTION -void Nothing(); -#endif diff --git a/header/uMod_Defines.h b/header/uMod_Defines.h deleted file mode 100644 index 7051c84..0000000 --- a/header/uMod_Defines.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include - -#ifdef LOG_MESSAGE -extern FILE* gl_File; - -#ifdef _DEBUG -#define Message(...) { printf(__VA_ARGS__); } -#else -#define Message(...) -#endif -#ifdef HOOK_INJECTION -#define OpenMessage(...) {if (fopen_s( &gl_File, "uMod_log.txt", "wt")) gl_File=NULL; else fprintf( gl_File, "HI R40: 0000000\n");} -#endif - -#ifdef DIRECT_INJECTION -#define OpenMessage(...) -#endif - -#ifdef NO_INJECTION -#define OpenMessage(...) {if (fopen_s( &gl_File, "uMod_log.txt", "wt")) gl_File=NULL; else fprintf( gl_File, "NI R40: 0000000\n");} -#endif - -#define CloseMessage(...) - - -#else -#define OpenMessage(...) -#define Message(...) -#define CloseMessage(...) -#endif - - -#ifdef __CDT_PARSER__ -typedef unsigned long DWORD64; -typedef unsigned long DWORD32; - -#define STDMETHOD(method) virtual HRESULT method -#define STDMETHOD_(ret, method) virtual ret method -#define sprintf_s(...) -#define fprintf(...) -#define fclose(...) -#define fseek(...) -#define ftell(...) 0 -#define fflush(...) -typedef LONG HRESULT; - -#define UNREFERENCED_PARAMETER(...) -#endif diff --git a/header/uMod_GlobalDefines.h b/header/uMod_GlobalDefines.h deleted file mode 100644 index 1668648..0000000 --- a/header/uMod_GlobalDefines.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -//#define MyTypeHash DWORD64 -#define MyTypeHash DWORD32 - -#define BIG_BUFSIZE 1<<24 -#define SMALL_BUFSIZE 1<<10 - -using MsgStruct = struct { - unsigned int Control; - unsigned int Value; - MyTypeHash Hash; -}; - -using PipeStruct = struct { - HANDLE In; - HANDLE Out; -}; - - -#define uMod_APP_DX9 L"uMod_DX9.txt" -#define uMod_APP_DIR L"uMod" -#define uMod_VERSION L"uMod V 1.0" - -#define PIPE_uMod2Game L"\\\\.\\pipe\\uMod2Game" -#define PIPE_Game2uMod L"\\\\.\\pipe\\Game2uMod" - -#define CONTROL_ADD_TEXTURE 1 -#define CONTROL_FORCE_RELOAD_TEXTURE 2 -#define CONTROL_REMOVE_TEXTURE 3 -#define CONTROL_FORCE_RELOAD_TEXTURE_DATA 4 -#define CONTROL_ADD_TEXTURE_DATA 5 -#define CONTROL_MORE_TEXTURES 6 - - -#define CONTROL_SAVE_ALL 10 -#define CONTROL_SAVE_SINGLE 11 -#define CONTROL_SET_DIR 12 - -#define CONTROL_KEY_BACK 20 -#define CONTROL_KEY_SAVE 21 -#define CONTROL_KEY_NEXT 22 - -#define CONTROL_FONT_COLOUR 30 -#define CONTROL_TEXTURE_COLOUR 31 diff --git a/header/uMod_IDirect3D9.h b/header/uMod_IDirect3D9.h index 5713d28..982a70e 100644 --- a/header/uMod_IDirect3D9.h +++ b/header/uMod_IDirect3D9.h @@ -1,11 +1,10 @@ #pragma once #include -#include "uMod_TextureServer.h" class uMod_IDirect3D9 : public IDirect3D9 { public: - uMod_IDirect3D9(IDirect3D9* pOriginal, uMod_TextureServer* server); + uMod_IDirect3D9(IDirect3D9* pOriginal); virtual ~uMod_IDirect3D9(); // The original DX9 function definitions @@ -29,5 +28,4 @@ public: private: IDirect3D9* m_pIDirect3D9; - uMod_TextureServer* uMod_Server; }; diff --git a/header/uMod_IDirect3D9Ex.h b/header/uMod_IDirect3D9Ex.h index 5a4b45b..6692458 100644 --- a/header/uMod_IDirect3D9Ex.h +++ b/header/uMod_IDirect3D9Ex.h @@ -1,11 +1,10 @@ #pragma once #include -#include "uMod_TextureServer.h" class uMod_IDirect3D9Ex : public IDirect3D9Ex { public: - uMod_IDirect3D9Ex(IDirect3D9Ex* pOriginal, uMod_TextureServer* server); + uMod_IDirect3D9Ex(IDirect3D9Ex* pOriginal); virtual ~uMod_IDirect3D9Ex(); // The original DX9 function definitions @@ -36,6 +35,5 @@ public: private: IDirect3D9Ex* m_pIDirect3D9Ex; - uMod_TextureServer* uMod_Server; }; diff --git a/header/uMod_IDirect3DCubeTexture9.h b/header/uMod_IDirect3DCubeTexture9.h index 73b2b3e..33fbe3d 100644 --- a/header/uMod_IDirect3DCubeTexture9.h +++ b/header/uMod_IDirect3DCubeTexture9.h @@ -11,18 +11,15 @@ interface uMod_IDirect3DCubeTexture9 : IDirect3DCubeTexture9 { // fake texture: store the pointer to the original uMod_IDirect3DCubeTexture9 object, needed if a fake texture is unselected // original texture: stores the pointer to the fake texture object, is needed if original texture is deleted, // thus the fake texture can also be deleted - Reference = -1; //need for fast deleting - Hash = 0u; - FAKE = false; } // callback interface - IDirect3DCubeTexture9* m_D3Dtex; - uMod_IDirect3DCubeTexture9* CrossRef_D3Dtex; - IDirect3DDevice9* m_D3Ddev; - int Reference; - MyTypeHash Hash; - bool FAKE; + IDirect3DCubeTexture9* m_D3Dtex = nullptr; + uMod_IDirect3DCubeTexture9* CrossRef_D3Dtex = nullptr; + IDirect3DDevice9* m_D3Ddev = nullptr; + TextureFileStruct* Reference = nullptr; + HashType Hash = 0u; + bool FAKE = false; // original interface STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override; @@ -50,38 +47,5 @@ interface uMod_IDirect3DCubeTexture9 : IDirect3DCubeTexture9 { STDMETHOD(UnlockRect)(D3DCUBEMAP_FACES FaceType, UINT Level) override; - int GetHash(MyTypeHash& hash); + [[nodiscard]] HashType GetHash() const; }; - - - -inline void UnswitchTextures(uMod_IDirect3DCubeTexture9* pTexture) -{ - uMod_IDirect3DCubeTexture9* CrossRef = pTexture->CrossRef_D3Dtex; - if (CrossRef != nullptr) { - // switch textures back - IDirect3DCubeTexture9* cpy = pTexture->m_D3Dtex; - pTexture->m_D3Dtex = CrossRef->m_D3Dtex; - CrossRef->m_D3Dtex = cpy; - - // cancel the link - CrossRef->CrossRef_D3Dtex = nullptr; - pTexture->CrossRef_D3Dtex = nullptr; - } -} - -inline int SwitchTextures(uMod_IDirect3DCubeTexture9* pTexture1, uMod_IDirect3DCubeTexture9* pTexture2) -{ - if (pTexture1->m_D3Ddev == pTexture2->m_D3Ddev && pTexture1->CrossRef_D3Dtex == nullptr && pTexture2->CrossRef_D3Dtex == nullptr) { - // make cross reference - pTexture1->CrossRef_D3Dtex = pTexture2; - pTexture2->CrossRef_D3Dtex = pTexture1; - - // switch textures - IDirect3DCubeTexture9* cpy = pTexture2->m_D3Dtex; - pTexture2->m_D3Dtex = pTexture1->m_D3Dtex; - pTexture1->m_D3Dtex = cpy; - return RETURN_OK; - } - return RETURN_TEXTURE_NOT_SWITCHED; -} diff --git a/header/uMod_IDirect3DDevice9.h b/header/uMod_IDirect3DDevice9.h index ea114aa..f0eeaa0 100644 --- a/header/uMod_IDirect3DDevice9.h +++ b/header/uMod_IDirect3DDevice9.h @@ -5,11 +5,12 @@ #include "uMod_IDirect3DTexture9.h" #include "uMod_IDirect3DVolumeTexture9.h" #include "uMod_IDirect3DCubeTexture9.h" +#include "TextureClient.h" class uMod_IDirect3DDevice9 : public IDirect3DDevice9 { public: - uMod_IDirect3DDevice9(IDirect3DDevice9* pOriginal, uMod_TextureServer* server, int back_buffer_count); + uMod_IDirect3DDevice9(IDirect3DDevice9* pOriginal, int back_buffer_count); virtual ~uMod_IDirect3DDevice9(); // START: The original DX9 function definitions @@ -135,9 +136,7 @@ public: HRESULT __stdcall CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) override; // END: The original DX9 function definitions - - - uMod_TextureClient* GetuMod_Client() { return uMod_Client; } + TextureClient* GetuMod_Client() { return uMod_Client; } uMod_IDirect3DTexture9* GetLastCreatedTexture() { return LastCreatedTexture; } @@ -170,12 +169,12 @@ public: private: int CreateSingleTexture(); - IDirect3DDevice9* m_pIDirect3DDevice9; + IDirect3DDevice9* m_pIDirect3DDevice9 = nullptr; int CounterSaveSingleTexture; - uMod_IDirect3DTexture9* SingleTexture; - uMod_IDirect3DVolumeTexture9* SingleVolumeTexture; - uMod_IDirect3DCubeTexture9* SingleCubeTexture; + uMod_IDirect3DTexture9* SingleTexture = nullptr; + uMod_IDirect3DVolumeTexture9* SingleVolumeTexture = nullptr; + uMod_IDirect3DCubeTexture9* SingleCubeTexture = nullptr; char SingleTextureMod; D3DCOLOR TextureColour; @@ -186,10 +185,9 @@ private: int uMod_Reference; - uMod_IDirect3DTexture9* LastCreatedTexture; - uMod_IDirect3DVolumeTexture9* LastCreatedVolumeTexture; - uMod_IDirect3DCubeTexture9* LastCreatedCubeTexture; + uMod_IDirect3DTexture9* LastCreatedTexture = nullptr; + uMod_IDirect3DVolumeTexture9* LastCreatedVolumeTexture = nullptr; + uMod_IDirect3DCubeTexture9* LastCreatedCubeTexture = nullptr; - uMod_TextureServer* uMod_Server; - uMod_TextureClient* uMod_Client; + TextureClient* uMod_Client; }; diff --git a/header/uMod_IDirect3DDevice9Ex.h b/header/uMod_IDirect3DDevice9Ex.h index 44d393f..98c72d4 100644 --- a/header/uMod_IDirect3DDevice9Ex.h +++ b/header/uMod_IDirect3DDevice9Ex.h @@ -5,11 +5,12 @@ #include "uMod_IDirect3DTexture9.h" #include "uMod_IDirect3DVolumeTexture9.h" #include "uMod_IDirect3DCubeTexture9.h" +#include "TextureClient.h" class uMod_IDirect3DDevice9Ex : public IDirect3DDevice9Ex { public: - uMod_IDirect3DDevice9Ex(IDirect3DDevice9Ex* pOriginal, uMod_TextureServer* server, int back_buffer_count); + uMod_IDirect3DDevice9Ex(IDirect3DDevice9Ex* pOriginal, int back_buffer_count); virtual ~uMod_IDirect3DDevice9Ex(); // START: The original DX9 function definitions @@ -157,8 +158,7 @@ public: // END: The original DX9 function definitions - - uMod_TextureClient* GetuMod_Client() { return uMod_Client; } + TextureClient* GetuMod_Client() { return uMod_Client; } uMod_IDirect3DTexture9* GetLastCreatedTexture() { return LastCreatedTexture; } @@ -211,6 +211,5 @@ private: uMod_IDirect3DVolumeTexture9* LastCreatedVolumeTexture; uMod_IDirect3DCubeTexture9* LastCreatedCubeTexture; - uMod_TextureServer* uMod_Server; - uMod_TextureClient* uMod_Client; + TextureClient* uMod_Client; }; diff --git a/header/uMod_IDirect3DTexture9.h b/header/uMod_IDirect3DTexture9.h index 7f29ea5..30739d8 100644 --- a/header/uMod_IDirect3DTexture9.h +++ b/header/uMod_IDirect3DTexture9.h @@ -1,7 +1,7 @@ #pragma once #include - +struct TextureFileStruct; interface uMod_IDirect3DTexture9 : public IDirect3DTexture9 { uMod_IDirect3DTexture9(IDirect3DTexture9** ppTex, IDirect3DDevice9* pIDirect3DDevice9) { @@ -11,18 +11,15 @@ interface uMod_IDirect3DTexture9 : public IDirect3DTexture9 { // fake texture: store the pointer to the original uMod_IDirect3DTexture9 object, needed if a fake texture is unselected // original texture: stores the pointer to the fake texture object, is needed if original texture is deleted, // thus the fake texture can also be deleted - Reference = -1; //need for fast deleting - Hash = 0u; - FAKE = false; } // callback interface - IDirect3DTexture9* m_D3Dtex; - uMod_IDirect3DTexture9* CrossRef_D3Dtex; - IDirect3DDevice9* m_D3Ddev; - int Reference; - MyTypeHash Hash; - bool FAKE; + IDirect3DTexture9* m_D3Dtex = nullptr; + uMod_IDirect3DTexture9* CrossRef_D3Dtex = nullptr; + IDirect3DDevice9* m_D3Ddev = nullptr; + TextureFileStruct* Reference = nullptr; + HashType Hash = 0u; + bool FAKE = false; // original interface STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override; @@ -48,40 +45,5 @@ interface uMod_IDirect3DTexture9 : public IDirect3DTexture9 { STDMETHOD(UnlockRect)(UINT Level) override; STDMETHOD(AddDirtyRect)(CONST RECT* pDirtyRect) override; - int GetHash(MyTypeHash& hash); + [[nodiscard]] HashType GetHash() const; }; - - - -inline void UnswitchTextures(uMod_IDirect3DTexture9* pTexture) -{ - uMod_IDirect3DTexture9* CrossRef = pTexture->CrossRef_D3Dtex; - if (CrossRef != nullptr) { - // switch textures back - IDirect3DTexture9* cpy = pTexture->m_D3Dtex; - pTexture->m_D3Dtex = CrossRef->m_D3Dtex; - CrossRef->m_D3Dtex = cpy; - - // cancel the link - CrossRef->CrossRef_D3Dtex = nullptr; - pTexture->CrossRef_D3Dtex = nullptr; - } -} - -inline int SwitchTextures(uMod_IDirect3DTexture9* pTexture1, uMod_IDirect3DTexture9* pTexture2) -{ - if (pTexture1->m_D3Ddev == pTexture2->m_D3Ddev && pTexture1->CrossRef_D3Dtex == nullptr && pTexture2->CrossRef_D3Dtex == nullptr) { - // make cross reference - pTexture1->CrossRef_D3Dtex = pTexture2; - pTexture2->CrossRef_D3Dtex = pTexture1; - - // switch textures - IDirect3DTexture9* cpy = pTexture2->m_D3Dtex; - pTexture2->m_D3Dtex = pTexture1->m_D3Dtex; - pTexture1->m_D3Dtex = cpy; - return RETURN_OK; - } - return RETURN_TEXTURE_NOT_SWITCHED; -} - - diff --git a/header/uMod_IDirect3DVolumeTexture9.h b/header/uMod_IDirect3DVolumeTexture9.h index deb8f88..fcc0029 100644 --- a/header/uMod_IDirect3DVolumeTexture9.h +++ b/header/uMod_IDirect3DVolumeTexture9.h @@ -11,18 +11,15 @@ interface uMod_IDirect3DVolumeTexture9 : IDirect3DVolumeTexture9 { // fake texture: store the pointer to the original uMod_IDirect3DVolumeTexture9 object, needed if a fake texture is unselected // original texture: stores the pointer to the fake texture object, is needed if original texture is deleted, // thus the fake texture can also be deleted - Reference = -1; //need for fast deleting - Hash = 0u; - FAKE = false; } // callback interface - IDirect3DVolumeTexture9* m_D3Dtex; - uMod_IDirect3DVolumeTexture9* CrossRef_D3Dtex; - IDirect3DDevice9* m_D3Ddev; - int Reference; - MyTypeHash Hash; - bool FAKE; + IDirect3DVolumeTexture9* m_D3Dtex = nullptr; + uMod_IDirect3DVolumeTexture9* CrossRef_D3Dtex = nullptr; + IDirect3DDevice9* m_D3Ddev = nullptr; + TextureFileStruct* Reference = nullptr; + HashType Hash = 0u; + bool FAKE = false; // original interface STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj) override; @@ -49,39 +46,5 @@ interface uMod_IDirect3DVolumeTexture9 : IDirect3DVolumeTexture9 { STDMETHOD(UnlockBox)(UINT Level) override; - int GetHash(MyTypeHash& hash); + [[nodiscard]] HashType GetHash() const; }; - - - -inline void UnswitchTextures(uMod_IDirect3DVolumeTexture9* pTexture) -{ - uMod_IDirect3DVolumeTexture9* CrossRef = pTexture->CrossRef_D3Dtex; - if (CrossRef != nullptr) { - // switch textures back - IDirect3DVolumeTexture9* cpy = pTexture->m_D3Dtex; - pTexture->m_D3Dtex = CrossRef->m_D3Dtex; - CrossRef->m_D3Dtex = cpy; - - // cancel the link - CrossRef->CrossRef_D3Dtex = nullptr; - pTexture->CrossRef_D3Dtex = nullptr; - } -} - -inline int SwitchTextures(uMod_IDirect3DVolumeTexture9* pTexture1, uMod_IDirect3DVolumeTexture9* pTexture2) -{ - if (pTexture1->m_D3Ddev == pTexture2->m_D3Ddev && pTexture1->CrossRef_D3Dtex == nullptr && pTexture2->CrossRef_D3Dtex == nullptr) { - // make cross reference - pTexture1->CrossRef_D3Dtex = pTexture2; - pTexture2->CrossRef_D3Dtex = pTexture1; - - // switch textures - IDirect3DVolumeTexture9* cpy = pTexture2->m_D3Dtex; - pTexture2->m_D3Dtex = pTexture1->m_D3Dtex; - pTexture1->m_D3Dtex = cpy; - return RETURN_OK; - } - return RETURN_TEXTURE_NOT_SWITCHED; -} - diff --git a/header/uMod_Texture.h b/header/uMod_Texture.h deleted file mode 100644 index 464b416..0000000 --- a/header/uMod_Texture.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include -#include -#include - -struct UModTexture { - std::vector data; - std::string name; - DWORD64 hash; -}; diff --git a/header/uMod_TextureClient.h b/header/uMod_TextureClient.h deleted file mode 100644 index ecf11e9..0000000 --- a/header/uMod_TextureClient.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include "uMod_IDirect3DTexture9.h" -#include "uMod_IDirect3DDevice9.h" -#include "uMod_Error.h" -#include "uMod_ArrayHandler.h" - - -class uMod_TextureServer; - -/* - * An object of this class is owned by each d3d9 device. - * functions called by the Server are called from the server thread instance. - * All other functions are called from the render thread instance of the game itself. - */ - -class uMod_TextureClient { -public: - uMod_TextureClient(uMod_TextureServer* server, IDirect3DDevice9* device); - ~uMod_TextureClient(); - - int AddTexture(uMod_IDirect3DTexture9* tex); //called from uMod_IDirect3DDevice9::CreateTexture(...) or uMod_IDirect3DDevice9::BeginScene() - int AddTexture(uMod_IDirect3DVolumeTexture9* tex); //called from uMod_IDirect3DVolumeTexture9::CreateTexture(...) or uMod_IDirect3DDevice9::BeginScene() - int AddTexture(uMod_IDirect3DCubeTexture9* tex); //called from uMod_IDirect3DCubeTexture9::CreateTexture(...) or uMod_IDirect3DDevice9::BeginScene() - - int RemoveTexture(uMod_IDirect3DTexture9* tex); //called from uMod_IDirect3DTexture9::Release() - int RemoveTexture(uMod_IDirect3DVolumeTexture9* tex); //called from uMod_IDirect3DVolumeTexture9::Release() - int RemoveTexture(uMod_IDirect3DCubeTexture9* tex); //called from uMod_IDirect3DCubeTexture9::Release() - - int AddUpdate(TextureFileStruct* update, int number); //called from the Server, client object must delete update array - int MergeUpdate(); //called from uMod_IDirect3DDevice9::BeginScene() - - int LookUpToMod(uMod_IDirect3DTexture9* pTexture, int num_index_list = 0, int* index_list = nullptr); // called at the end AddTexture(...) and from Device->UpdateTexture(...) - int LookUpToMod(uMod_IDirect3DVolumeTexture9* pTexture, int num_index_list = 0, int* index_list = nullptr); // called at the end AddTexture(...) and from Device->UpdateTexture(...) - int LookUpToMod(uMod_IDirect3DCubeTexture9* pTexture, int num_index_list = 0, int* index_list = nullptr); // called at the end AddTexture(...) and from Device->UpdateTexture(...) - - uMod_TextureHandler OriginalTextures; // stores the pointer to the uMod_IDirect3DTexture9 objects created by the game - uMod_TextureHandler OriginalVolumeTextures; // stores the pointer to the uMod_IDirect3DVolumeTexture9 objects created by the game - uMod_TextureHandler OriginalCubeTextures; // stores the pointer to the uMod_IDirect3DCubeTexture9 objects created by the game - - D3DCOLOR FontColour; - D3DCOLOR TextureColour; - -private: - uMod_TextureServer* Server; - IDirect3DDevice9* D3D9Device; - - TextureFileStruct* Update; - int NumberOfUpdate; - - int LockMutex(); - int UnlockMutex(); - HANDLE Mutex; - - int NumberToMod; // number of texture to be modded - TextureFileStruct* FileToMod; // array which stores the file in memory and the hash of each texture to be modded - - - int LookUpToMod(MyTypeHash hash, int num_index_list, int* index_list); // called from LookUpToMod(...); - int LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DTexture9** ppTexture); // called if a target texture is found - int LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DVolumeTexture9** ppTexture); // called if a target texture is found - int LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DCubeTexture9** ppTexture); // called if a target texture is found - - // and the corresponding fake texture should be loaded - - //MyTypeHash GetHash(unsigned char *str, int len); - //unsigned int GetCRC32(char *pcDatabuf, unsigned int ulDatalen); -}; - diff --git a/header/uMod_TextureServer.h b/header/uMod_TextureServer.h deleted file mode 100644 index 0ce571a..0000000 --- a/header/uMod_TextureServer.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "uMod_GlobalDefines.h" -#include "uMod_ArrayHandler.h" - - -/* - * An object of this class is created only once. - * The Mainloop functions is executed by a server thread, - * which listen on a pipe. - * - * Functions called by the Client are called from the a thread instance of the game itself. - * Nearly all other functions are called from the server thread instance. - */ - - -class uMod_TextureClient; - -class uMod_TextureServer { -public: - uMod_TextureServer(char* name, char* uModName); - ~uMod_TextureServer(); - - int AddClient(uMod_TextureClient* client, TextureFileStruct** update, int* number); // called from a Client - int Initialize(); // is executed in a server thread - - - // following functions are only public for testing purpose !! - // they should be private and only be called from the Mainloop - - int AddFile(char* buffer, unsigned int size, MyTypeHash hash, bool force); // called from Mainloop(), if the content of the texture is sent - -private: - wchar_t GameName[MAX_PATH]; - char UModName[MAX_PATH]; - - void LoadModsFromFile(const char* source); - int PropagateUpdate(uMod_TextureClient* client = nullptr); // called from Mainloop() if texture are loaded or removed - int PrepareUpdate(TextureFileStruct** update, int* number); // called from PropagateUpdate() and AddClient() - // generate a copy of the current texture to be modded - // the file content of the textures are not copied, the clients get the pointer to the file content - // but the arrays allocate by this function, must be deleted by the client - - uMod_TextureClient* Client; - uMod_FileHandler CurrentMod; // hold the file content of texture - uMod_FileHandler OldMod; // hold the file content of texture which were added previously but are not needed any more - // this is needed, because a texture clients might not have merged the last update and thus hold pointers to the file content of old textures -}; diff --git a/header/utils.h b/header/utils.h deleted file mode 100644 index 85b86b9..0000000 --- a/header/utils.h +++ /dev/null @@ -1,157 +0,0 @@ -#pragma once - -#include -#include - -void ReplaceAll(std::wstring& str, const std::wstring& from, const std::wstring& to) -{ - if (from.empty()) { - return; - } - size_t startPos = 0; - while ((startPos = str.find(from, startPos)) != std::wstring::npos) { - str.replace(startPos, from.length(), to); - startPos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' - } -} - -void ReplaceAll(std::string& str, const std::string& from, const std::string& to) -{ - if (from.empty()) { - return; - } - size_t startPos = 0; - while ((startPos = str.find(from, startPos)) != std::string::npos) { - str.replace(startPos, from.length(), to); - startPos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' - } -} - -std::wstring AfterFirst(const std::wstring& str, wchar_t delimiter) -{ - const size_t pos = str.find(delimiter); - if (pos != std::wstring::npos) { - // Return the substring after the delimiter - return str.substr(pos + 1); - } - // If the delimiter is not found, return an empty string - return L""; -} - -std::string AfterFirst(const std::string& str, char delimiter) -{ - const size_t pos = str.find(delimiter); - if (pos != std::string::npos) { - // Return the substring after the delimiter - return str.substr(pos + 1); - } - // If the delimiter is not found, return an empty string - return ""; -} - -std::wstring BeforeFirst(const std::wstring& str, wchar_t delimiter) -{ - const size_t pos = str.find(delimiter); - return pos != std::wstring::npos ? str.substr(0, pos) : str; -} - -std::string BeforeFirst(const std::string& str, char delimiter) -{ - const size_t pos = str.find(delimiter); - return pos != std::string::npos ? str.substr(0, pos) : str; -} - -std::string BeforeLast(const std::string& file_path, char separator) -{ - // Find the last occurrence of '.' - const std::size_t last_dot_pos = file_path.find_last_of(separator); - - // If there is a dot, and it is not at the beginning of the filename - if (last_dot_pos != std::string::npos && last_dot_pos != 0) { - // Extract the substring from the dot to the end of the string - return file_path.substr(0, last_dot_pos); - } - // If the dot is not found, or is the first character, return an empty string - return ""; -} - -std::wstring BeforeLast(const std::wstring& file_path, wchar_t separator) -{ - // Find the last occurrence of '.' - const std::size_t last_dot_pos = file_path.find_last_of(separator); - - // If there is a dot, and it is not at the beginning of the filename - if (last_dot_pos != std::wstring::npos && last_dot_pos != 0) { - // Extract the substring from the dot to the end of the string - return file_path.substr(0, last_dot_pos); - } - // If the dot is not found, or is the first character, return an empty string - return L""; -} - -std::string AfterLast(const std::string& file_path, char separator) -{ - // Find the last occurrence of '.' - const std::size_t last_dot_pos = file_path.find_last_of(separator); - - // If there is a dot, and it is not at the beginning of the filename - if (last_dot_pos != std::string::npos && last_dot_pos != 0) { - // Extract the substring from the dot to the end of the string - return file_path.substr(last_dot_pos + 1); - } - // If the dot is not found, or is the first character, return an empty string - return ""; -} - -std::wstring AfterLast(const std::wstring& file_path, wchar_t separator) -{ - // Find the last occurrence of '.' - const std::size_t last_dot_pos = file_path.find_last_of(separator); - - // If there is a dot, and it is not at the beginning of the filename - if (last_dot_pos != std::wstring::npos && last_dot_pos != 0) { - // Extract the substring from the dot to the end of the string - return file_path.substr(last_dot_pos + 1); - } - // If the dot is not found, or is the first character, return an empty string - return L""; -} - -std::string GetFileExtension(const std::string& file_path) -{ - // Find the last occurrence of '.' - const std::size_t last_dot_pos = file_path.find_last_of("."); - - // If there is a dot, and it is not at the beginning of the filename - if (last_dot_pos != std::string::npos && last_dot_pos != 0) { - // Extract the substring from the dot to the end of the string - return file_path.substr(last_dot_pos + 1); - } - // If the dot is not found, or is the first character, return an empty string - return ""; -} - -std::string WideStringToString(const std::wstring& wstr) -{ - if (wstr.empty()) { - return std::string(); - } - - const int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast(wstr.size()), nullptr, 0, nullptr, nullptr); - std::string strTo(size_needed, 0); - WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast(wstr.size()), &strTo[0], size_needed, nullptr, nullptr); - return strTo; -} - - -std::wstring StringToWString(const std::string& str) -{ - if (str.empty()) { - return std::wstring(); - } - - const int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast(str.size()), nullptr, 0); - std::wstring wstrTo(size_needed, 0); - MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast(str.size()), &wstrTo[0], size_needed); - return wstrTo; -} diff --git a/source/Error.cpp b/source/Error.cpp new file mode 100644 index 0000000..4b62bb2 --- /dev/null +++ b/source/Error.cpp @@ -0,0 +1,23 @@ +#include "Error.h" + +#include +#include +#include + +__declspec(noreturn) void FatalAssert( +const char *expr, +const char *file, +unsigned int line, +const char *function) +{ + const char* fmt = "%s\n%s\n%s line %d"; + int len = snprintf(NULL, 0, fmt, expr, file, function, line); + + char* buf = new char[len + 1]; + snprintf(buf,len + 1, fmt, expr, file, function, line); + + MessageBox(0, "uMod Assertion", buf, MB_OK | MB_ICONERROR); + + delete[] buf; + abort(); +} diff --git a/source/gMod_FileLoader.cpp b/source/FileLoader.cpp similarity index 77% rename from source/gMod_FileLoader.cpp rename to source/FileLoader.cpp index 93e58c4..cba6b66 100644 --- a/source/gMod_FileLoader.cpp +++ b/source/FileLoader.cpp @@ -1,14 +1,14 @@ -#include +#include <..\header\Main.h> #include -#include "gMod_FileLoader.h" -#include "XorStreamReader.h" +#include "FileLoader.h" +#include "TpfReader.h" -gMod_FileLoader::gMod_FileLoader(const std::string& fileName) +FileLoader::FileLoader(const std::string& fileName) { file_name = std::filesystem::absolute(fileName).string(); } -std::vector gMod_FileLoader::GetContents() +std::vector FileLoader::GetContents() { try { return file_name.ends_with(".tpf") ? GetTpfContents() : GetFileContents(); @@ -19,11 +19,11 @@ std::vector gMod_FileLoader::GetContents() return {}; } -std::vector gMod_FileLoader::GetTpfContents() +std::vector FileLoader::GetTpfContents() { std::vector entries; - auto xorreader = XorStreamReader(file_name); - const auto buffer = xorreader.ReadToEnd(); + auto tpf_reader = TpfReader(file_name); + const auto buffer = tpf_reader.ReadToEnd(); const auto zip_archive = libzippp::ZipArchive::fromBuffer(buffer.data(), buffer.size(), false, TPF_PASSWORD); if (!zip_archive) { Message("Failed to open tpf file: %s - %u bytes!", file_name.c_str(), buffer.size()); @@ -41,7 +41,7 @@ std::vector gMod_FileLoader::GetTpfContents() return entries; } -std::vector gMod_FileLoader::GetFileContents() +std::vector FileLoader::GetFileContents() { std::vector entries; @@ -58,8 +58,6 @@ void ParseSimpleArchive(const libzippp::ZipArchive& archive, std::vector(entry.readAsBinary()); + const auto size = entry.getSize(); + std::vector vec; + vec.assign(data_ptr, data_ptr + size); + entries.emplace_back(name, entry.getName(), crc_hash, std::move(vec)); } } } @@ -124,9 +126,8 @@ void ParseTexmodArchive(std::vector& lines, libzippp::ZipArchive& a } // Remove trailing newline and carriage return characters - const size_t endpos = path.find_last_not_of("\r\n"); - if (endpos != std::string::npos) { - path.erase(endpos + 1); + if (const auto end_pos = path.find_last_not_of("\r\n"); end_pos != std::string::npos) { + path.erase(end_pos + 1); } else if (!path.empty()) { path.clear(); @@ -141,11 +142,9 @@ void ParseTexmodArchive(std::vector& lines, libzippp::ZipArchive& a continue; } - const auto data_ptr = entry.readAsBinary(); - const auto size = entry.getSize(); - uint32_t crcHash; + uint32_t crc_hash{}; try { - crcHash = std::stoul(addrstr, nullptr, 16); + crc_hash = std::stoul(addrstr, nullptr, 16); } catch (const std::invalid_argument& e) { Message("Failed to parse %s as a hash", addrstr.c_str()); @@ -156,11 +155,15 @@ void ParseTexmodArchive(std::vector& lines, libzippp::ZipArchive& a continue; } - entries.push_back({addrstr, entry.getName(), crcHash, data_ptr, size}); + const auto data_ptr = static_cast(entry.readAsBinary()); + const auto size = static_cast(entry.getSize()); + std::vector vec(data_ptr, data_ptr + size); + entries.emplace_back(addrstr, entry.getName(), crc_hash, std::move(vec)); + delete[] data_ptr; } } -void gMod_FileLoader::LoadEntries(libzippp::ZipArchive& archive, std::vector& entries) +void FileLoader::LoadEntries(libzippp::ZipArchive& archive, std::vector& entries) { // Iterate over the files in the zip archive const auto def_file = archive.getEntry("texmod.def"); diff --git a/source/TextureClient.cpp b/source/TextureClient.cpp new file mode 100644 index 0000000..07ebdbb --- /dev/null +++ b/source/TextureClient.cpp @@ -0,0 +1,208 @@ +#include +#include + +#include "Main.h" + +TextureClient::TextureClient(IDirect3DDevice9* device) +{ + Message("TextureClient::TextureClient(): %p\n", this); + D3D9Device = device; + + void* cpy; + isDirectXExDevice = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy) == 0x01000001L; + + Mutex = CreateMutex(nullptr, false, nullptr); + + FontColour = D3DCOLOR_ARGB(255, 255, 0, 0); + TextureColour = D3DCOLOR_ARGB(255, 0, 255, 0); +} + +TextureClient::~TextureClient() +{ + Message("TextureClient::~TextureClient(): %p\n", this); + if (Mutex != nullptr) { + CloseHandle(Mutex); + } + for (const auto& it : modded_textures) { + delete it.second; + } + modded_textures.clear(); +} + +int TextureClient::MergeUpdate() +{ + if (!should_update) return RETURN_OK; + should_update = false; + if (const int ret = LockMutex()) { + gl_ErrorState |= uMod_ERROR_TEXTURE; + return ret; + } + + Message("MergeUpdate(): %p\n", this); + + const auto single_texture = GetSingleTexture(); + for (const auto pTexture : OriginalTextures) { + if (pTexture->CrossRef_D3Dtex == nullptr || pTexture->CrossRef_D3Dtex == single_texture) { + UnswitchTextures(pTexture); //this we can do always, so we unswitch the single texture + LookUpToMod(pTexture); + } + } + const auto single_volume_texture = GetSingleVolumeTexture(); + for (const auto pTexture : OriginalVolumeTextures) { + if (pTexture->CrossRef_D3Dtex == nullptr || pTexture->CrossRef_D3Dtex == single_volume_texture) { + UnswitchTextures(pTexture); //this we can do always, so we unswitch the single texture + LookUpToMod(pTexture); + } + } + const auto single_cube_texture = GetSingleCubeTexture(); + for (const auto pTexture : OriginalCubeTextures) { + if (pTexture->CrossRef_D3Dtex == nullptr || pTexture->CrossRef_D3Dtex == single_cube_texture) { + UnswitchTextures(pTexture); //this we can do always, so we unswitch the single texture + LookUpToMod(pTexture); + } + } + + return UnlockMutex(); +} + +uMod_IDirect3DTexture9* TextureClient::GetSingleTexture() +{ + if (isDirectXExDevice) + return static_cast(D3D9Device)->GetSingleTexture(); + //this texture must no be added twice + return static_cast(D3D9Device)->GetSingleTexture(); +} + +uMod_IDirect3DVolumeTexture9* TextureClient::GetSingleVolumeTexture() +{ + if (isDirectXExDevice) + return static_cast(D3D9Device)->GetSingleVolumeTexture(); + //this texture must no be added twice + return static_cast(D3D9Device)->GetSingleVolumeTexture(); +} + +uMod_IDirect3DCubeTexture9* TextureClient::GetSingleCubeTexture() +{ + if (isDirectXExDevice) + return static_cast(D3D9Device)->GetSingleCubeTexture(); + //this texture must no be added twice + return static_cast(D3D9Device)->GetSingleCubeTexture(); +} + +int TextureClient::SetLastCreatedTexture(uMod_IDirect3DTexture9* texture) +{ + if (isDirectXExDevice) + return static_cast(D3D9Device)->SetLastCreatedTexture(texture); + //this texture must no be added twice + return static_cast(D3D9Device)->SetLastCreatedTexture(texture); +} + +int TextureClient::SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* texture) +{ + if (isDirectXExDevice) + return static_cast(D3D9Device)->SetLastCreatedVolumeTexture(texture); + //this texture must no be added twice + return static_cast(D3D9Device)->SetLastCreatedVolumeTexture(texture); +} + +int TextureClient::SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* texture) +{ + if (isDirectXExDevice) + return static_cast(D3D9Device)->SetLastCreatedCubeTexture(texture); + //this texture must no be added twice + return static_cast(D3D9Device)->SetLastCreatedCubeTexture(texture); +} + + +int TextureClient::LockMutex() +{ + if ((gl_ErrorState & (uMod_ERROR_FATAL | uMod_ERROR_MUTEX))) { + return RETURN_NO_MUTEX; + } + if (WAIT_OBJECT_0 != WaitForSingleObject(Mutex, 100)) { + return RETURN_MUTEX_LOCK; //waiting 100ms, to wait infinite pass INFINITE + } + return RETURN_OK; +} + +int TextureClient::UnlockMutex() +{ + if (ReleaseMutex(Mutex) == 0) { + return RETURN_MUTEX_UNLOCK; + } + return RETURN_OK; +} + +unsigned long TextureClient::AddFile(TpfEntry& entry) +{ + if (modded_textures.contains(entry.crc_hash)) { + return 0; + } + TextureFileStruct* texture_file_struct = new TextureFileStruct(); + texture_file_struct->data = std::move(entry.data); + texture_file_struct->crc_hash = entry.crc_hash; + modded_textures.emplace(entry.crc_hash, texture_file_struct); + should_update = true; + return texture_file_struct->data.size(); +} + +void TextureClient::LoadModsFromFile(const char* source) +{ + static unsigned long loaded_size = 0; + Message("Initialize: searching in %s\n", source); + + std::ifstream file(source); + if (!file.is_open()) { + Message("LoadModsFromFile: failed to open modlist.txt for reading; aborting!!!"); + return; + } + Message("Initialize: found modlist.txt. Reading\n"); + std::string line; + while (std::getline(file, line)) { + Message("Initialize: loading file %s... ", line.c_str()); + + // Remove newline character + line.erase(std::ranges::remove(line, '\n').begin(), line.end()); + + auto file_loader = FileLoader(line); + auto entries = file_loader.GetContents(); + if (loaded_size > 1'500'000'000) { + Message("LoadModsFromFile: Loaded %d bytes, aborting!!!\n", loaded_size); + return; + } + if (entries.empty()) { + Message("No entries found.\n"); + continue; + } + Message("%zu textures... ", entries.size()); + unsigned long file_bytes_loaded = 0; + for (auto& tpf_entry : entries) { + file_bytes_loaded += AddFile(tpf_entry); + } + entries.clear(); + Message("%d bytes loaded.\n", file_bytes_loaded); + loaded_size += file_bytes_loaded; + } + Message("Finished loading mods from %s: Loaded %u bytes (%u mb)", source, loaded_size, loaded_size / 1024 / 1024); +} + +void TextureClient::Initialize() +{ + Message("Initialize: begin\n"); + Message("Initialize: searching for modlist.txt\n"); + char gwpath[MAX_PATH]{}; + GetModuleFileName(GetModuleHandle(nullptr), gwpath, MAX_PATH); //ask for name and path of this executable + char dllpath[MAX_PATH]{}; + GetModuleFileName(gl_hThisInstance, dllpath, MAX_PATH); //ask for name and path of this dll + const auto exe = std::filesystem::path(gwpath).parent_path(); + const auto dll = std::filesystem::path(dllpath).parent_path(); + for (const auto& path : {exe, dll}) { + const auto modlist = path / "modlist.txt"; + if (std::filesystem::exists(modlist)) { + Message("Initialize: found %s\n", modlist.string().c_str()); + LoadModsFromFile(modlist.string().c_str()); + } + } + + Message("Initialize: end\n"); +} diff --git a/source/dll_main.cpp b/source/dll_main.cpp new file mode 100644 index 0000000..527fab0 --- /dev/null +++ b/source/dll_main.cpp @@ -0,0 +1,203 @@ +#include "dll_main.h" + +#include +#include +#include "Main.h" +#include + +#include "MinHook.h" + +namespace { + + using Direct3DCreate9_type = IDirect3D9* (APIENTRY*)(UINT); + using Direct3DCreate9Ex_type = HRESULT(APIENTRY*)(UINT SDKVersion, IDirect3D9Ex** ppD3D); + + // Pointer to original address of Direct3DCreate9 + Direct3DCreate9_type Direct3DCreate9_fn = nullptr; + Direct3DCreate9_type Direct3DCreate9_ret = nullptr; + + // Pointer to original address of Direct3DCreate9 + Direct3DCreate9Ex_type Direct3DCreate9Ex_fn = nullptr; + Direct3DCreate9Ex_type Direct3DCreate9Ex_ret = nullptr; + + static FILE* stdout_proxy; + static FILE* stderr_proxy; + + /* + * global variable which are linked external + */ + unsigned int gl_ErrorState = 0u; + + // If not nullptr, we're responsible for freeing this library on termination + HMODULE gl_hOriginalDll = nullptr; + + // If this hModule called d3d9.dll? + bool IsD3d9Module(HMODULE hModule, HANDLE hProcess) + { + TCHAR szModuleName[MAX_PATH]; + GetModuleBaseName(hProcess, hModule, szModuleName, sizeof(szModuleName) / sizeof(TCHAR)); + return strcmp(szModuleName, TEXT("d3d9.dll")) == 0; + } + // Does this module contain exported function calls for creating a d3d9 device? + bool HasD3d9Methods(HMODULE hModule, HANDLE hProcess) + { + return GetProcAddress(hModule, "Direct3DCreate9") + && GetProcAddress(hModule, "Direct3DCreate9Ex"); + } + + + HMODULE FindLoadedDll() + { + HMODULE hModules[1024]; + HANDLE hProcess; + DWORD cbNeeded; + unsigned int i; + + // Get a handle to the current process. + hProcess = GetCurrentProcess(); + if (!EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) + return nullptr; + for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { + if (IsD3d9Module(hModules[i], hProcess) + || HasD3d9Methods(hModules[i], hProcess)) { + return hModules[i]; + } + } + return nullptr; + } +} + +unsigned int gl_ErrorState = 0; +HINSTANCE gl_hThisInstance = nullptr; + +/* + * dll entry routine, here we initialize or clean up + */ +BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + UNREFERENCED_PARAMETER(lpReserved); + + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: { +#ifdef _DEBUG + AllocConsole(); + SetConsoleTitleA("gMod Console"); + freopen_s(&stdout_proxy, "CONOUT$", "w", stdout); + freopen_s(&stderr_proxy, "CONOUT$", "w", stderr); +#endif + InitInstance(hModule); + break; + } + case DLL_PROCESS_DETACH: { + ExitInstance(); + break; + } + default: break; + } + + return true; +} + +void InitInstance(HINSTANCE hModule) +{ + DisableThreadLibraryCalls(hModule); //reduce overhead + gl_hThisInstance = hModule; + Message("InitInstance: %p\n", hModule); + + const auto d3d9_dll = LoadOriginalDll(); + ASSERT(d3d9_dll); + + Direct3DCreate9_fn = reinterpret_cast(GetProcAddress(d3d9_dll, "Direct3DCreate9")); + ASSERT(Direct3DCreate9_fn); + + Direct3DCreate9Ex_fn = reinterpret_cast(GetProcAddress(d3d9_dll, "Direct3DCreate9Ex")); + ASSERT(Direct3DCreate9Ex_fn); + + MH_Initialize(); + + if (Direct3DCreate9_fn) { + MH_CreateHook(Direct3DCreate9_fn, uMod_Direct3DCreate9, (void**)&Direct3DCreate9_ret); + MH_EnableHook(Direct3DCreate9_fn); + } + + if (Direct3DCreate9Ex_fn) { + MH_CreateHook(Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex, (void**)&Direct3DCreate9Ex_ret); + MH_EnableHook(Direct3DCreate9Ex_fn); + } + +} +void ExitInstance() +{ + if(Direct3DCreate9_fn) + MH_DisableHook(Direct3DCreate9_fn); + if(Direct3DCreate9Ex_fn) + MH_DisableHook(Direct3DCreate9Ex_fn); + + MH_Uninitialize(); + + // Release the system's d3d9.dll + if (gl_hOriginalDll != nullptr) { + FreeLibrary(gl_hOriginalDll); + gl_hOriginalDll = nullptr; + } + +#ifdef _DEBUG + if (stdout_proxy) + fclose(stdout_proxy); + if (stderr_proxy) + fclose(stderr_proxy); + FreeConsole(); +#endif +} + +HMODULE LoadOriginalDll() +{ + HMODULE found = FindLoadedDll(); + if (found) + return found; + + char buffer[MAX_PATH]; + GetSystemDirectory(buffer, MAX_PATH); //get the system directory, we need to open the original d3d9.dll + + // Append dll name + strcat_s(buffer, MAX_PATH, "\\d3d9.dll"); + gl_hOriginalDll = LoadLibrary(buffer); + found = FindLoadedDll(); + ASSERT(found && found == gl_hOriginalDll); + + return found; +} + +/* + * We inject the dll into the game, thus we retour the original Direct3DCreate9 function to our MyDirect3DCreate9 function + */ + +IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion) +{ + Message("uMod_Direct3DCreate9: original %p, uMod %p\n", Direct3DCreate9_fn, uMod_Direct3DCreate9); + + ASSERT(Direct3DCreate9_ret); + + IDirect3D9* pIDirect3D9_orig = Direct3DCreate9_ret(SDKVersion); //creating the original IDirect3D9 object + ASSERT(pIDirect3D9_orig); + + return new uMod_IDirect3D9(pIDirect3D9_orig); //return our object instead of the "real one" +} + +HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D) +{ + Message("uMod_Direct3DCreate9Ex: original %p, uMod %p\n", Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex); + + ASSERT(Direct3DCreate9Ex_ret); + + IDirect3D9Ex* pIDirect3D9Ex_orig = nullptr; + HRESULT ret = Direct3DCreate9Ex_ret(SDKVersion, &pIDirect3D9Ex_orig); //creating the original IDirect3D9 object + + if (ret != S_OK) + return ret; + + // @Cleanup: should be we freeing pIDirect3D9Ex at the end of our own lifecycle? + uMod_IDirect3D9Ex* pIDirect3D9Ex = new uMod_IDirect3D9Ex(pIDirect3D9Ex_orig); + ppD3D = (IDirect3D9Ex**)&pIDirect3D9Ex; + return ret; +} diff --git a/source/uMod_ArrayHandler.cpp b/source/uMod_ArrayHandler.cpp deleted file mode 100644 index 430ac41..0000000 --- a/source/uMod_ArrayHandler.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "uMod_Main.h" - -uMod_FileHandler::uMod_FileHandler() -{ - Message("uMod_FileHandler(): %p\n", this); -} - -uMod_FileHandler::~uMod_FileHandler() -{ - Message("~uMod_FileHandler(): %p\n", this); - if (Files != nullptr) { - for (int i = 0; i < FieldCounter; i++) { - delete [] Files[i]; - } - delete [] Files; - } -} - -int uMod_FileHandler::Add(TextureFileStruct* file) -{ - Message("uMod_FileHandler::Add(%p): %p\n", file, this); - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - - if (file->Reference >= 0) { - return RETURN_UPDATE_ALLREADY_ADDED; - } - - if (Number / FieldLength == FieldCounter) // get more memory - { - TextureFileStruct*** temp = nullptr; - try { temp = new TextureFileStruct**[FieldCounter + 10]; } - catch (...) { - gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_TEXTURE; - return RETURN_NO_MEMORY; - } - - for (int i = 0; i < FieldCounter; i++) { - temp[i] = Files[i]; //copy to new allocated memory - } - - for (int i = FieldCounter; i < FieldCounter + 10; i++) { - temp[i] = nullptr; // initialize unused parts to zero - } - - FieldCounter += 10; - - delete [] Files; - - Files = temp; - } - if (Number % FieldLength == 0) // maybe we need to get more memory - { - try { - if (Files[Number / FieldLength] == nullptr) { - Files[Number / FieldLength] = new TextureFileStruct*[FieldLength]; - } - } - catch (...) { - Files[Number / FieldLength] = nullptr; - gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_TEXTURE; - return RETURN_NO_MEMORY; - } - } - - Files[Number / FieldLength][Number % FieldLength] = file; - file->Reference = Number++; //set the reference for a fast deleting - - return RETURN_OK; -} - - -int uMod_FileHandler::Remove(TextureFileStruct* file) -{ - Message("uMod_FileHandler::Remove(%p): %p\n", file, this); - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - const int ref = file->Reference; - - if (ref < 0) { - return RETURN_OK; // returning if no Reference is set - } - file->Reference = -1; //set reference outside of bound - if (ref < (--Number)) //if reference is unequal to Number-1 we copy the last entry to the index "ref" - { - Files[ref / FieldLength][ref % FieldLength] = Files[Number / FieldLength][Number % FieldLength]; - Files[ref / FieldLength][ref % FieldLength]->Reference = ref; //set the new reference entry - } - return RETURN_OK; -} diff --git a/source/uMod_DX9_dll.cpp b/source/uMod_DX9_dll.cpp deleted file mode 100644 index e40cb1f..0000000 --- a/source/uMod_DX9_dll.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include "uMod_DX9_dll.h" - -#include -#include -#include "uMod_Main.h" -#include - -HINSTANCE gl_hOriginalDll = nullptr; -HINSTANCE gl_hThisInstance = nullptr; -std::unique_ptr gl_TextureServer = nullptr; - -using Direct3DCreate9_type = IDirect3D9* (APIENTRY*)(UINT); -using Direct3DCreate9Ex_type = HRESULT(APIENTRY*)(UINT SDKVersion, IDirect3D9Ex** ppD3D); - -Direct3DCreate9_type Direct3DCreate9_fn; // we need to store the pointer to the original Direct3DCreate9 function after we have done a detour -Direct3DCreate9Ex_type Direct3DCreate9Ex_fn; // we need to store the pointer to the original Direct3DCreate9 function after we have done a detour -HHOOK gl_hHook = nullptr; - -static FILE* stdout_proxy; -static FILE* stderr_proxy; - -/* - * global variable which are linked external - */ -unsigned int gl_ErrorState = 0u; - -#ifdef LOG_MESSAGE -FILE* gl_File = nullptr; -#endif - - -#ifdef DIRECT_INJECTION -void Nothing() { (void)NULL; } -#endif -/* - * dll entry routine, here we initialize or clean up - */ -BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - UNREFERENCED_PARAMETER(lpReserved); - - switch (ul_reason_for_call) { - case DLL_PROCESS_ATTACH: { -#ifdef _DEBUG - AllocConsole(); - SetConsoleTitleA("gMod Console"); - freopen_s(&stdout_proxy, "CONOUT$", "w", stdout); - freopen_s(&stderr_proxy, "CONOUT$", "w", stderr); -#endif - InitInstance(hModule); - break; - } - case DLL_PROCESS_DETACH: { - ExitInstance(); - break; - } - default: break; - } - - return true; -} - -void InitInstance(HINSTANCE hModule) -{ - DisableThreadLibraryCalls(hModule); //reduce overhead - gl_hThisInstance = hModule; - - char game[MAX_PATH]; - if (HookThisProgram(game)) //ask if we need to hook this program - { - OpenMessage(); - Message("InitInstance: %p\n", hModule); - std::array uMod{}; - - GetModuleFileNameA(hModule, uMod.data(), MAX_PATH); - Message("InitInstance: %s\n", uMod.data()); - gl_TextureServer = std::make_unique(game, uMod.data()); //create the server which listen on the pipe and prepare the update for the texture clients - LoadOriginalDll(); - if (gl_hOriginalDll) { - Direct3DCreate9_fn = reinterpret_cast(GetProcAddress(gl_hOriginalDll, "Direct3DCreate9")); - if (Direct3DCreate9_fn != nullptr) { - Message("Detour: Direct3DCreate9\n"); - Direct3DCreate9_fn = static_cast(DetourFunc((BYTE*)Direct3DCreate9_fn, (BYTE*)uMod_Direct3DCreate9, 5)); - } - - Direct3DCreate9Ex_fn = reinterpret_cast(GetProcAddress(gl_hOriginalDll, "Direct3DCreate9Ex")); - if (Direct3DCreate9Ex_fn != nullptr) { - Message("Detour: Direct3DCreate9Ex\n"); - Direct3DCreate9Ex_fn = static_cast(DetourFunc((BYTE*)Direct3DCreate9Ex_fn, (BYTE*)uMod_Direct3DCreate9Ex, 7)); - } - } - gl_TextureServer->Initialize(); - } -} - -bool HasDesiredMethods(HMODULE hModule, HANDLE hProcess) -{ - const auto d3dcreate9Addr = GetProcAddress(hModule, "Direct3DCreate9"); - if (!d3dcreate9Addr) { - return false; - } - - const auto d3dcreate9ExAddr = GetProcAddress(hModule, "Direct3DCreate9Ex"); - if (!d3dcreate9ExAddr) { - return false; - } - - return true; -} - -bool IsDesiredModule(HMODULE hModule, HANDLE hProcess) -{ - TCHAR szModuleName[MAX_PATH]; - GetModuleBaseName(hProcess, hModule, szModuleName, sizeof(szModuleName) / sizeof(TCHAR)); - return strcmp(szModuleName, TEXT("d3d9.dll")) == 0; -} - -bool FindLoadedDll() -{ - HMODULE hModules[1024]; - HANDLE hProcess; - DWORD cbNeeded; - unsigned int i; - - // Get a handle to the current process. - hProcess = GetCurrentProcess(); - if (EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) { - for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { - if (IsDesiredModule(hModules[i], hProcess)) { - // If the module is d3d9.dll, store the handle or do your hooking here. - gl_hOriginalDll = hModules[i]; - break; - } - if (HasDesiredMethods(hModules[i], hProcess)) { - // If the module has the two specific methods, store the handle or do your hooking here. - gl_hOriginalDll = hModules[i]; - break; - } - } - } - - if (gl_hOriginalDll) { - return true; - } - - return false; -} - -void LoadOriginalDll() -{ - if (FindLoadedDll()) { - return; - } - - char buffer[MAX_PATH]; - GetSystemDirectory(buffer, MAX_PATH); //get the system directory, we need to open the original d3d9.dll - - // Append dll name - strcat_s(buffer, MAX_PATH, "\\d3d9.dll"); - - // try to load the system's d3d9.dll, if pointer empty - if (!gl_hOriginalDll) { - gl_hOriginalDll = LoadLibrary(buffer); - } - - if (!gl_hOriginalDll) { - ExitProcess(0); // exit the hard way - } -} - -void ExitInstance() -{ - // Release the system's d3d9.dll - if (gl_hOriginalDll != nullptr) { - FreeLibrary(gl_hOriginalDll); - gl_hOriginalDll = nullptr; - } - -#ifdef _DEBUG - if (stdout_proxy) - fclose(stdout_proxy); - if (stderr_proxy) - fclose(stderr_proxy); - FreeConsole(); -#endif - CloseMessage(); -} - -/* - * We inject the dll into the game, thus we retour the original Direct3DCreate9 function to our MyDirect3DCreate9 function - */ - -IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion) -{ - Message("uMod_Direct3DCreate9: original %p, uMod %p\n", Direct3DCreate9_fn, uMod_Direct3DCreate9); - - // in the Internet are many tutorials for detouring functions and all of them will work without the following 5 marked lines - // but somehow, for me it only works, if I retour the function and calling afterward the original function - - // BEGIN - - LoadOriginalDll(); - - RetourFunc((BYTE*)GetProcAddress(gl_hOriginalDll, "Direct3DCreate9"), (BYTE*)Direct3DCreate9_fn, 5); - Direct3DCreate9_fn = (Direct3DCreate9_type)GetProcAddress(gl_hOriginalDll, "Direct3DCreate9"); - - /* - if (Direct3DCreate9Ex_fn!=NULL) - { - RetourFunc((BYTE*) GetProcAddress( gl_hOriginalDll, "Direct3DCreate9Ex"), (BYTE*)Direct3DCreate9Ex_fn, 7); - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type) GetProcAddress( gl_hOriginalDll, "Direct3DCreate9Ex"); - } - */ - // END - - IDirect3D9* pIDirect3D9_orig = nullptr; - if (Direct3DCreate9_fn) { - pIDirect3D9_orig = Direct3DCreate9_fn(SDKVersion); //creating the original IDirect3D9 object - } - else { - return nullptr; - } - uMod_IDirect3D9* pIDirect3D9; - if (pIDirect3D9_orig) { - pIDirect3D9 = new uMod_IDirect3D9(pIDirect3D9_orig, gl_TextureServer.get()); //creating our uMod_IDirect3D9 object - } - - // we detour again - Direct3DCreate9_fn = static_cast(DetourFunc((BYTE*)Direct3DCreate9_fn, (BYTE*)uMod_Direct3DCreate9, 5)); - /* - if (Direct3DCreate9Ex_fn!=NULL) - { - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type)DetourFunc( (BYTE*) Direct3DCreate9Ex_fn, (BYTE*)uMod_Direct3DCreate9Ex,7); - } - */ - return pIDirect3D9; //return our object instead of the "real one" -} - -HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D) -{ - Message("uMod_Direct3DCreate9Ex: original %p, uMod %p\n", Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex); - - // in the Internet are many tutorials for detouring functions and all of them will work without the following 5 marked lines - // but somehow, for me it only works, if I retour the function and calling afterward the original function - - // BEGIN - - LoadOriginalDll(); - /* - if (Direct3DCreate9_fn!=NULL) - { - RetourFunc((BYTE*) GetProcAddress( gl_hOriginalDll, "Direct3DCreate9"), (BYTE*)Direct3DCreate9_fn, 5); - Direct3DCreate9_fn = (Direct3DCreate9_type) GetProcAddress( gl_hOriginalDll, "Direct3DCreate9"); - } - */ - RetourFunc((BYTE*)GetProcAddress(gl_hOriginalDll, "Direct3DCreate9Ex"), (BYTE*)Direct3DCreate9Ex_fn, 7); - Direct3DCreate9Ex_fn = (Direct3DCreate9Ex_type)GetProcAddress(gl_hOriginalDll, "Direct3DCreate9Ex"); - // END - - IDirect3D9Ex* pIDirect3D9Ex_orig = nullptr; - HRESULT ret; - if (Direct3DCreate9Ex_fn) { - ret = Direct3DCreate9Ex_fn(SDKVersion, &pIDirect3D9Ex_orig); //creating the original IDirect3D9 object - } - else { - return D3DERR_NOTAVAILABLE; - } - - if (ret != S_OK) { - return ret; - } - - uMod_IDirect3D9Ex* pIDirect3D9Ex; - if (pIDirect3D9Ex_orig) { - pIDirect3D9Ex = new uMod_IDirect3D9Ex(pIDirect3D9Ex_orig, gl_TextureServer.get()); //creating our uMod_IDirect3D9 object - } - - // we detour again - /* - if (Direct3DCreate9_fn!=NULL) - { - Direct3DCreate9_fn = (Direct3DCreate9_type)DetourFunc( (BYTE*) Direct3DCreate9_fn, (BYTE*)uMod_Direct3DCreate9,5); - } - */ - Direct3DCreate9Ex_fn = static_cast(DetourFunc((BYTE*)Direct3DCreate9Ex_fn, (BYTE*)uMod_Direct3DCreate9Ex, 7)); - ppD3D = (IDirect3D9Ex**)&pIDirect3D9Ex; //return our object instead of the "real one" - return ret; -} - -bool HookThisProgram(char* ret) -{ - char Game[MAX_PATH]; - GetModuleFileName(GetModuleHandle(nullptr), Game, MAX_PATH); //ask for name and path of this executable - - // we inject directly - strcpy(ret, Game); - return true; -} - -void* DetourFunc(BYTE* src, const BYTE* dst, const int len) -{ - auto jmp = static_cast(malloc(len + 5)); - DWORD dwback = 0; - VirtualProtect(jmp, len + 5, PAGE_EXECUTE_READWRITE, &dwback); //This is the addition needed for Windows 7 RC - VirtualProtect(src, len, PAGE_READWRITE, &dwback); - memcpy(jmp, src, len); - jmp += len; - jmp[0] = 0xE9; - *(DWORD*)(jmp + 1) = static_cast(src + len - jmp) - 5; - memset(src, 0x90, len); - src[0] = 0xE9; - *(DWORD*)(src + 1) = static_cast(dst - src) - 5; - VirtualProtect(src, len, dwback, &dwback); - return jmp - len; -} - -bool RetourFunc(BYTE* src, BYTE* restore, const int len) -{ - DWORD dwback; - if (!VirtualProtect(src, len, PAGE_READWRITE, &dwback)) { return false; } - if (!memcpy(src, restore, len)) { return false; } - restore[0] = 0xE9; - *(DWORD*)(restore + 1) = static_cast(src - restore) - 5; - if (!VirtualProtect(src, len, dwback, &dwback)) { return false; } - return true; -} diff --git a/source/uMod_IDirect3D9.cpp b/source/uMod_IDirect3D9.cpp index cf8bced..5e85215 100644 --- a/source/uMod_IDirect3D9.cpp +++ b/source/uMod_IDirect3D9.cpp @@ -1,14 +1,13 @@ -#include "uMod_Main.h" +#include "Main.h" #ifndef PRE_MESSAGE #define PRE_MESSAGE "uMod_IDirect3D9" #endif -uMod_IDirect3D9::uMod_IDirect3D9(IDirect3D9* pOriginal, uMod_TextureServer* server) +uMod_IDirect3D9::uMod_IDirect3D9(IDirect3D9* pOriginal) { - Message(PRE_MESSAGE "::" PRE_MESSAGE "( %p, %p): %p\n", pOriginal, server, this); + Message(PRE_MESSAGE "::" PRE_MESSAGE " (%p): %p\n", pOriginal, this); m_pIDirect3D9 = pOriginal; - uMod_Server = server; } uMod_IDirect3D9::~uMod_IDirect3D9() @@ -126,7 +125,7 @@ HRESULT __stdcall uMod_IDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceT if (pPresentationParameters != nullptr) { count = pPresentationParameters->BackBufferCount; } - const auto pIDirect3DDevice9 = new uMod_IDirect3DDevice9(*ppReturnedDeviceInterface, uMod_Server, count); + const auto pIDirect3DDevice9 = new uMod_IDirect3DDevice9(*ppReturnedDeviceInterface, count); // store our pointer (the fake one) for returning it to the calling program *ppReturnedDeviceInterface = pIDirect3DDevice9; diff --git a/source/uMod_IDirect3D9Ex.cpp b/source/uMod_IDirect3D9Ex.cpp index 12aa157..f5c23b2 100644 --- a/source/uMod_IDirect3D9Ex.cpp +++ b/source/uMod_IDirect3D9Ex.cpp @@ -1,4 +1,4 @@ -#include "uMod_Main.h" +#include "Main.h" #define IDirect3D9 IDirect3D9Ex #define uMod_IDirect3D9 uMod_IDirect3D9Ex @@ -19,7 +19,7 @@ HRESULT __stdcall uMod_IDirect3D9Ex::CreateDeviceEx(UINT Adapter, D3DDEVTYPE Dev if (pPresentationParameters != nullptr) { count = pPresentationParameters->BackBufferCount; } - const auto pIDirect3DDevice9Ex = new uMod_IDirect3DDevice9Ex(*ppReturnedDeviceInterface, uMod_Server, count); + const auto pIDirect3DDevice9Ex = new uMod_IDirect3DDevice9Ex(*ppReturnedDeviceInterface, count); // store our pointer (the fake one) for returning it to the calling program *ppReturnedDeviceInterface = pIDirect3DDevice9Ex; diff --git a/source/uMod_IDirect3DCubeTexture9.cpp b/source/uMod_IDirect3DCubeTexture9.cpp index a85fe55..3f9639f 100644 --- a/source/uMod_IDirect3DCubeTexture9.cpp +++ b/source/uMod_IDirect3DCubeTexture9.cpp @@ -1,4 +1,4 @@ -#include "uMod_Main.h" +#include "Main.h" //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DCubeTexture9::QueryInterface(REFIID riid, void** ppvObj) @@ -100,7 +100,7 @@ ULONG APIENTRY uMod_IDirect3DCubeTexture9::Release() } } - delete(this); + delete this; } return count; } @@ -235,19 +235,16 @@ HRESULT APIENTRY uMod_IDirect3DCubeTexture9::UnlockRect(D3DCUBEMAP_FACES FaceTyp -int uMod_IDirect3DCubeTexture9::GetHash(MyTypeHash& hash) +HashType uMod_IDirect3DCubeTexture9::GetHash() const { - hash = 0u; if (FAKE) { - return RETURN_BAD_ARGUMENT; + return 0; } IDirect3DCubeTexture9* pTexture = m_D3Dtex; if (CrossRef_D3Dtex != nullptr) { pTexture = CrossRef_D3Dtex->m_D3Dtex; } - //IDirect3DSurface9 *pOffscreenSurface = NULL; - //IDirect3DCubeTexture9 *pOffscreenTexture = NULL; IDirect3DSurface9* pResolvedSurface = nullptr; D3DLOCKED_RECT d3dlr; D3DSURFACE_DESC desc; @@ -255,98 +252,29 @@ int uMod_IDirect3DCubeTexture9::GetHash(MyTypeHash& hash) if (pTexture->GetLevelDesc(0, &desc) != D3D_OK) //get the format and the size of the texture { Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetLevelDesc \n"); - return RETURN_GetLevelDesc_FAILED; + return 0; } Message("uMod_IDirect3DCubeTexture9::GetHash() (%d %d) %d\n", desc.Width, desc.Height, desc.Format); -/* - if (desc.Pool==D3DPOOL_DEFAULT) //get the raw data of the texture - { - //Message("uMod_IDirect3DCubeTexture9::GetHash() (D3DPOOL_DEFAULT)\n"); - - IDirect3DSurface9 *pSurfaceLevel_orig = NULL; - if (pTexture->GetSurfaceLevel( 0, &pSurfaceLevel_orig)!=D3D_OK) + if (pTexture->LockRect(D3DCUBEMAP_FACE_POSITIVE_X, 0, &d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) { - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetSurfaceLevel 1 (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - - if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) - { - //Message("uMod_IDirect3DCubeTexture9::GetHash() MultiSampleType\n"); - if (D3D_OK!=m_D3Ddev->CreateRenderTarget( desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pResolvedSurface, NULL )) - { - pSurfaceLevel_orig->Release(); - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - if (D3D_OK!=m_D3Ddev->StretchRect( pSurfaceLevel_orig, NULL, pResolvedSurface, NULL, D3DTEXF_NONE )) - { - pSurfaceLevel_orig->Release(); - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: StretchRect (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - - pSurfaceLevel_orig = pResolvedSurface; - } - - - if (D3D_OK!=m_D3Ddev->CreateOffscreenPlainSurface( desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pOffscreenSurface, NULL)) - { - pSurfaceLevel_orig->Release(); - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: CreateOffscreenPlainSurface (D3DPOOL_DEFAULT)\n"); - return RETURN_TEXTURE_NOT_LOADED); - } - - if (D3D_OK!=m_D3Ddev->GetRenderTargetData( pSurfaceLevel_orig, pOffscreenSurface)) - { - pSurfaceLevel_orig->Release(); - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - pOffscreenSurface->Release(); - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - pSurfaceLevel_orig->Release(); - - if (pOffscreenSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK) - { - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - pOffscreenSurface->Release(); - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - } - else - */ - if (pTexture->LockRect(D3DCUBEMAP_FACE_POSITIVE_X, 0, &d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) { Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: LockRect 1\n"); if (pTexture->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &pResolvedSurface) != D3D_OK) { Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetSurfaceLevel\n"); - return RETURN_LockRect_FAILED; + return 0; } if (pResolvedSurface->LockRect(&d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) { pResolvedSurface->Release(); Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: LockRect 2\n"); - return RETURN_LockRect_FAILED; + return 0; } } - const int size = (GetBitsFromFormat(desc.Format) * desc.Width * desc.Height) / 8; + const auto hash = GetCRC32(static_cast(d3dlr.pBits), size); //calculate the crc32 of the texture - hash = GetCRC32(static_cast(d3dlr.pBits), size); //calculate the crc32 of the texture -/* - if (pOffscreenSurface!=NULL) - { - pOffscreenSurface->UnlockRect(); - pOffscreenSurface->Release(); - //pOffscreenTexture->Release(); - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - } - else - */ + // Only release surfaces after we're finished with d3dlr if (pResolvedSurface != nullptr) { pResolvedSurface->UnlockRect(); pResolvedSurface->Release(); @@ -356,5 +284,5 @@ int uMod_IDirect3DCubeTexture9::GetHash(MyTypeHash& hash) } Message("uMod_IDirect3DCubeTexture9::GetHash() %#lX (%d %d) %d = %d\n", hash, desc.Width, desc.Height, desc.Format, size); - return RETURN_OK; + return hash; } diff --git a/source/uMod_IDirect3DDevice9.cpp b/source/uMod_IDirect3DDevice9.cpp index 7a31b8d..5c537c4 100644 --- a/source/uMod_IDirect3DDevice9.cpp +++ b/source/uMod_IDirect3DDevice9.cpp @@ -1,4 +1,4 @@ -#include "uMod_Main.h" +#include "Main.h" #ifndef RETURN_QueryInterface #define RETURN_QueryInterface 0x01000000L @@ -24,7 +24,6 @@ int uMod_IDirect3DDevice9::CreateSingleTexture() } LastCreatedTexture = nullptr; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture SingleTexture->FAKE = true; //this is no texture created from by game - SingleTexture->Reference = -2; } { @@ -54,7 +53,6 @@ int uMod_IDirect3DDevice9::CreateSingleTexture() } LastCreatedVolumeTexture = nullptr; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture SingleVolumeTexture->FAKE = true; //this is no texture created from by game - SingleVolumeTexture->Reference = -2; } { @@ -83,7 +81,6 @@ int uMod_IDirect3DDevice9::CreateSingleTexture() } LastCreatedCubeTexture = nullptr; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture SingleCubeTexture->FAKE = true; //this is no texture created from by game - SingleCubeTexture->Reference = -2; } { @@ -109,15 +106,15 @@ int uMod_IDirect3DDevice9::CreateSingleTexture() return RETURN_OK; } -uMod_IDirect3DDevice9::uMod_IDirect3DDevice9(IDirect3DDevice9* pOriginal, uMod_TextureServer* server, int back_buffer_count) +uMod_IDirect3DDevice9::uMod_IDirect3DDevice9(IDirect3DDevice9* pOriginal, int back_buffer_count) { - Message(PRE_MESSAGE "::" PRE_MESSAGE "( %p, %p): %p\n", pOriginal, server, this); + Message(PRE_MESSAGE "::" PRE_MESSAGE " (%p): %p\n", pOriginal, this); BackBufferCount = back_buffer_count; NormalRendering = true; - uMod_Server = server; - uMod_Client = new uMod_TextureClient(uMod_Server, this); //get a new texture client for this device + uMod_Client = new TextureClient(this); //get a new texture client for this device + uMod_Client->Initialize(); LastCreatedTexture = nullptr; LastCreatedVolumeTexture = nullptr; @@ -422,12 +419,10 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu uMod_IDirect3DCubeTexture9* pSourceCube = nullptr; IDirect3DBaseTexture9* cpy; if (pSourceTexture != nullptr) { - long int ret = pSourceTexture->QueryInterface(IID_IDirect3D9, (void**)&cpy); - switch (ret) { + switch (pSourceTexture->QueryInterface(IID_IDirect3D9, (void**)&cpy)) { case 0x01000000L: { - MyTypeHash hash; pSource = static_cast(pSourceTexture); - if (pSource->GetHash(hash) == RETURN_OK) { + if (const auto hash = pSource->GetHash()) { if (hash != pSource->Hash) // this hash has changed !! { pSource->Hash = hash; @@ -451,9 +446,8 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu break; } case 0x01000001L: { - MyTypeHash hash; pSourceVolume = static_cast(pSourceTexture); - if (pSourceVolume->GetHash(hash) == RETURN_OK) { + if (const auto hash = pSource->GetHash()) { if (hash != pSourceVolume->Hash) // this hash has changed !! { pSourceVolume->Hash = hash; @@ -477,9 +471,8 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu break; } case 0x01000002L: { - MyTypeHash hash; pSourceCube = static_cast(pSourceTexture); - if (pSourceCube->GetHash(hash) == RETURN_OK) { + if (const auto hash = pSourceCube->GetHash()) { if (hash != pSourceCube->Hash) // this hash has changed !! { pSourceCube->Hash = hash; @@ -509,10 +502,9 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu if (pDestinationTexture != nullptr) { - long int ret = pSourceTexture->QueryInterface(IID_IDirect3D9, (void**)&cpy); - switch (ret) { + switch (pSourceTexture->QueryInterface(IID_IDirect3D9, (void**)&cpy)) { case 0x01000000L: { - auto pDest = static_cast(pDestinationTexture); + const auto pDest = static_cast(pDestinationTexture); if (pSource != nullptr && pDest->Hash != pSource->Hash) { pDest->Hash = pSource->Hash; // take over the hash @@ -532,7 +524,7 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu break; } case 0x01000001L: { - auto pDest = static_cast(pDestinationTexture); + const auto pDest = static_cast(pDestinationTexture); if (pSourceVolume != nullptr && pDest->Hash != pSourceVolume->Hash) { pDest->Hash = pSourceVolume->Hash; // take over the hash diff --git a/source/uMod_IDirect3DDevice9Ex.cpp b/source/uMod_IDirect3DDevice9Ex.cpp index e828e3d..efe4429 100644 --- a/source/uMod_IDirect3DDevice9Ex.cpp +++ b/source/uMod_IDirect3DDevice9Ex.cpp @@ -1,4 +1,4 @@ -#include "uMod_Main.h" +#include "Main.h" #define uMod_IDirect3DDevice9 uMod_IDirect3DDevice9Ex #define IDirect3DDevice9 IDirect3DDevice9Ex diff --git a/source/uMod_IDirect3DTexture9.cpp b/source/uMod_IDirect3DTexture9.cpp index 566b514..1cdbd9d 100644 --- a/source/uMod_IDirect3DTexture9.cpp +++ b/source/uMod_IDirect3DTexture9.cpp @@ -1,4 +1,4 @@ -#include "uMod_Main.h" +#include "Main.h" //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DTexture9::QueryInterface(REFIID riid, void** ppvObj) @@ -100,7 +100,7 @@ ULONG APIENTRY uMod_IDirect3DTexture9::Release() } } - delete(this); + delete this; } Message("uMod_IDirect3DTexture9::Release() end: %p\n", this); @@ -236,12 +236,9 @@ HRESULT APIENTRY uMod_IDirect3DTexture9::AddDirtyRect(CONST RECT* pDirtyRect) } -int uMod_IDirect3DTexture9::GetHash(MyTypeHash& hash) +HashType uMod_IDirect3DTexture9::GetHash() const { - hash = 0u; - if (FAKE) { - return RETURN_BAD_ARGUMENT; - } + ASSERT(!FAKE); IDirect3DTexture9* pTexture = m_D3Dtex; if (CrossRef_D3Dtex != nullptr) { pTexture = CrossRef_D3Dtex->m_D3Dtex; @@ -256,7 +253,7 @@ int uMod_IDirect3DTexture9::GetHash(MyTypeHash& hash) if (pTexture->GetLevelDesc(0, &desc) != D3D_OK) //get the format and the size of the texture { Message("uMod_IDirect3DTexture9::GetHash() Failed: GetLevelDesc \n"); - return RETURN_GetLevelDesc_FAILED; + return 0; } Message("uMod_IDirect3DTexture9::GetHash() (%d %d) %d\n", desc.Width, desc.Height, desc.Format); @@ -269,7 +266,7 @@ int uMod_IDirect3DTexture9::GetHash(MyTypeHash& hash) IDirect3DSurface9* pSurfaceLevel_orig = nullptr; if (pTexture->GetSurfaceLevel(0, &pSurfaceLevel_orig) != D3D_OK) { Message("uMod_IDirect3DTexture9::GetHash() Failed: GetSurfaceLevel 1 (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED; + return 0; } if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) { @@ -277,12 +274,12 @@ int uMod_IDirect3DTexture9::GetHash(MyTypeHash& hash) if (D3D_OK != m_D3Ddev->CreateRenderTarget(desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pResolvedSurface, nullptr)) { pSurfaceLevel_orig->Release(); Message("uMod_IDirect3DTexture9::GetHash() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED; + return 0; } if (D3D_OK != m_D3Ddev->StretchRect(pSurfaceLevel_orig, nullptr, pResolvedSurface, nullptr, D3DTEXF_NONE)) { pSurfaceLevel_orig->Release(); Message("uMod_IDirect3DTexture9::GetHash() Failed: StretchRect (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED; + return 0; } pSurfaceLevel_orig = pResolvedSurface; @@ -294,7 +291,7 @@ int uMod_IDirect3DTexture9::GetHash(MyTypeHash& hash) pResolvedSurface->Release(); } Message("uMod_IDirect3DTexture9::GetHash() Failed: CreateOffscreenPlainSurface (D3DPOOL_DEFAULT)\n"); - return RETURN_TEXTURE_NOT_LOADED; + return 0; } if (D3D_OK != m_D3Ddev->GetRenderTargetData(pSurfaceLevel_orig, pOffscreenSurface)) { @@ -304,7 +301,7 @@ int uMod_IDirect3DTexture9::GetHash(MyTypeHash& hash) } pOffscreenSurface->Release(); Message("uMod_IDirect3DTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED; + return 0; } pSurfaceLevel_orig->Release(); @@ -314,26 +311,26 @@ int uMod_IDirect3DTexture9::GetHash(MyTypeHash& hash) } pOffscreenSurface->Release(); Message("uMod_IDirect3DTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED; + return 0; } } else if (pTexture->LockRect(0, &d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) { Message("uMod_IDirect3DTexture9::GetHash() Failed: LockRect 1\n"); if (pTexture->GetSurfaceLevel(0, &pResolvedSurface) != D3D_OK) { Message("uMod_IDirect3DTexture9::GetHash() Failed: GetSurfaceLevel\n"); - return RETURN_LockRect_FAILED; + return 0; } if (pResolvedSurface->LockRect(&d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) { pResolvedSurface->Release(); Message("uMod_IDirect3DTexture9::GetHash() Failed: LockRect 2\n"); - return RETURN_LockRect_FAILED; + return 0; } } const int size = (GetBitsFromFormat(desc.Format) * desc.Width * desc.Height) / 8; + const auto hash = GetCRC32(static_cast(d3dlr.pBits), size); //calculate the crc32 of the texture - hash = GetCRC32(static_cast(d3dlr.pBits), size); //calculate the crc32 of the texture - + // Only release surfaces after we're finished with d3dlr if (pOffscreenSurface != nullptr) { pOffscreenSurface->UnlockRect(); pOffscreenSurface->Release(); @@ -348,7 +345,6 @@ int uMod_IDirect3DTexture9::GetHash(MyTypeHash& hash) else { pTexture->UnlockRect(0); } - Message("uMod_IDirect3DTexture9::GetHash() %#lX (%d %d) %d = %d\n", hash, desc.Width, desc.Height, desc.Format, size); - return RETURN_OK; + return hash; } diff --git a/source/uMod_IDirect3DVolumeTexture9.cpp b/source/uMod_IDirect3DVolumeTexture9.cpp index 0cb9b22..d7cb6eb 100644 --- a/source/uMod_IDirect3DVolumeTexture9.cpp +++ b/source/uMod_IDirect3DVolumeTexture9.cpp @@ -1,4 +1,4 @@ -#include "uMod_Main.h" +#include "Main.h" HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::QueryInterface(REFIID riid, void** ppvObj) { @@ -99,7 +99,7 @@ ULONG APIENTRY uMod_IDirect3DVolumeTexture9::Release() } } - delete(this); + delete this; } return count; } @@ -235,19 +235,16 @@ HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::UnlockBox(UINT Level) } -int uMod_IDirect3DVolumeTexture9::GetHash(MyTypeHash& hash) +HashType uMod_IDirect3DVolumeTexture9::GetHash() const { - hash = 0u; if (FAKE) { - return RETURN_BAD_ARGUMENT; + return 0; } IDirect3DVolumeTexture9* pTexture = m_D3Dtex; if (CrossRef_D3Dtex != nullptr) { pTexture = CrossRef_D3Dtex->m_D3Dtex; } - //IDirect3DVolume9 *pOffscreenSurface = NULL; - //IDirect3DVolumeTexture9 *pOffscreenTexture = NULL; IDirect3DVolume9* pResolvedSurface = nullptr; D3DLOCKED_BOX d3dlr; D3DVOLUME_DESC desc; @@ -255,124 +252,29 @@ int uMod_IDirect3DVolumeTexture9::GetHash(MyTypeHash& hash) if (pTexture->GetLevelDesc(0, &desc) != D3D_OK) //get the format and the size of the texture { Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetLevelDesc \n"); - return RETURN_GetLevelDesc_FAILED; + return 0; } Message("uMod_IDirect3DVolumeTexture9::GetHash() (%d %d %d) %d\n", desc.Width, desc.Height, desc.Depth, desc.Format); - -/* - if (desc.Pool==D3DPOOL_DEFAULT) //get the raw data of the texture - { - //Message("uMod_IDirect3DVolumeTexture9::GetHash() (D3DPOOL_DEFAULT)\n"); - - IDirect3DSurface9 *pSurfaceLevel_orig = NULL; - if (pTexture->GetSurfaceLevel( 0, &pSurfaceLevel_orig)!=D3D_OK) - { - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel 1 (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } -/* - if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) - { - //Message("uMod_IDirect3DVolumeTexture9::GetHash() MultiSampleType\n"); - if (D3D_OK!=m_D3Ddev->CreateRenderTarget( desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pResolvedSurface, NULL )) - { - pSurfaceLevel_orig->Release(); - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - if (D3D_OK!=m_D3Ddev->StretchRect( pSurfaceLevel_orig, NULL, pResolvedSurface, NULL, D3DTEXF_NONE )) - { - pSurfaceLevel_orig->Release(); - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: StretchRect (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - - pSurfaceLevel_orig = pResolvedSurface; - } - */ -//CreateTexture(8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DVolumeTexture9**) &SingleTexture, NULL) - /* - if (D3D_OK!=m_D3Ddev->CreateTexture( desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &pOffscreenTexture, NULL)) - { - pSurfaceLevel_orig->Release(); - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: CreateTexture (D3DPOOL_DEFAULT)\n"); - return RETURN_TEXTURE_NOT_LOADED); - } - if (pOffscreenTexture->GetSurfaceLevel( 0, &pOffscreenSurface)!=D3D_OK) - { - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel 2 (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - - if (D3D_OK!=m_D3Ddev->GetRenderTargetData( pSurfaceLevel_orig, pOffscreenSurface)) - { - pSurfaceLevel_orig->Release(); - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - pOffscreenSurface->Release(); - pOffscreenTexture->Release(); - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - pSurfaceLevel_orig->Release(); - - if (pOffscreenSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK) - { - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - pOffscreenSurface->Release(); - pOffscreenTexture->Release(); - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - */ -/* - if (D3D_OK!=m_D3Ddev->CreateOffscreenPlainSurface( desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pOffscreenSurface, NULL)) - { - pSurfaceLevel_orig->Release(); - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: CreateOffscreenPlainSurface (D3DPOOL_DEFAULT)\n"); - return RETURN_TEXTURE_NOT_LOADED); - } - - if (D3D_OK!=m_D3Ddev->GetRenderTargetData( pSurfaceLevel_orig, pOffscreenSurface)) - { - pSurfaceLevel_orig->Release(); - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - pOffscreenSurface->Release(); - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - pSurfaceLevel_orig->Release(); - - if (pOffscreenSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK) - { - if (pResolvedSurface!=NULL) pResolvedSurface->Release(); - pOffscreenSurface->Release(); - Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n"); - return RETURN_LockRect_FAILED); - } - } - else - */ if (pTexture->LockBox(0, &d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) { Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 1\n"); if (pTexture->GetVolumeLevel(0, &pResolvedSurface) != D3D_OK) { Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel\n"); - return RETURN_LockRect_FAILED; + return 0; } if (pResolvedSurface->LockBox(&d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) { pResolvedSurface->Release(); Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 2\n"); - return RETURN_LockRect_FAILED; + return 0; } } + + const int size = (GetBitsFromFormat(desc.Format) * desc.Width * desc.Height * desc.Depth) / 8; + const auto hash = GetCRC32(static_cast(d3dlr.pBits), size); //calculate the crc32 of the texture - hash = GetCRC32(static_cast(d3dlr.pBits), size); //calculate the crc32 of the texture - - + // Only release surfaces after we're finished with d3dlr if (pResolvedSurface != nullptr) { pResolvedSurface->UnlockBox(); pResolvedSurface->Release(); @@ -382,5 +284,5 @@ int uMod_IDirect3DVolumeTexture9::GetHash(MyTypeHash& hash) } Message("uMod_IDirect3DVolumeTexture9::GetHash() %#lX (%d %d) %d = %d\n", hash, desc.Width, desc.Height, desc.Format, size); - return RETURN_OK; + return hash; } diff --git a/source/uMod_TextureClient.cpp b/source/uMod_TextureClient.cpp deleted file mode 100644 index cb5222e..0000000 --- a/source/uMod_TextureClient.cpp +++ /dev/null @@ -1,829 +0,0 @@ -#include "uMod_Main.h" - -uMod_TextureClient::uMod_TextureClient(uMod_TextureServer* server, IDirect3DDevice9* device) -{ - Message("uMod_TextureClient::uMod_TextureClient(): %p\n", this); - Server = server; - D3D9Device = device; - NumberToMod = 0; - FileToMod = nullptr; - - if (Server != nullptr) { - if (Server->AddClient(this, &FileToMod, &NumberToMod)) { - Server = nullptr; - NumberToMod = 0; - FileToMod = nullptr; - } - else { - for (int i = 0; i < NumberToMod; i++) { - FileToMod[i].NumberOfTextures = 0; - FileToMod[i].Textures = nullptr; - } - } - } - Mutex = CreateMutex(nullptr, false, nullptr); - - Update = nullptr; - NumberOfUpdate = -1; - FontColour = D3DCOLOR_ARGB(255, 255, 0, 0); - TextureColour = D3DCOLOR_ARGB(255, 0, 255, 0); -} - -uMod_TextureClient::~uMod_TextureClient() -{ - Message("uMod_TextureClient::~uMod_TextureClient(): %p\n", this); - if (Mutex != nullptr) { - CloseHandle(Mutex); - } - - delete [] Update; - - if (FileToMod != nullptr) { - for (int i = 0; i < NumberToMod; i++) { - - delete [] FileToMod[i].Textures; - - } - delete [] FileToMod; - } -} - - -int uMod_TextureClient::AddTexture(uMod_IDirect3DTexture9* pTexture) -{ - void* cpy; - const long ret = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) { - static_cast(D3D9Device)->SetLastCreatedTexture(nullptr); //this texture must no be added twice - } - else { - static_cast(D3D9Device)->SetLastCreatedTexture(nullptr); //this texture must no be added twice - } - - if (pTexture->FAKE) { - return RETURN_OK; // this is a fake texture - } - - Message("uMod_TextureClient::AddTexture( %p): %p (thread: %p)\n", pTexture, this, GetCurrentThreadId()); - - MyTypeHash hash; - if (const int ret = pTexture->GetHash(hash)) { - return ret; - } - - pTexture->Hash = hash; - - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - - OriginalTextures.Add(pTexture); // add the texture to the list of original texture - - return LookUpToMod(pTexture); // check if this texture should be modded -} - -int uMod_TextureClient::AddTexture(uMod_IDirect3DVolumeTexture9* pTexture) -{ - void* cpy; - const long ret = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) { - static_cast(D3D9Device)->SetLastCreatedVolumeTexture(nullptr); //this texture must no be added twice - } - else { - static_cast(D3D9Device)->SetLastCreatedVolumeTexture(nullptr); //this texture must no be added twice - } - - if (pTexture->FAKE) { - return RETURN_OK; // this is a fake texture - } - - Message("uMod_TextureClient::AddTexture( Volume: %p): %p (thread: %p)\n", pTexture, this, GetCurrentThreadId()); - - MyTypeHash hash; - if (const int ret = pTexture->GetHash(hash)) { - return ret; - } - - pTexture->Hash = hash; - - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - - OriginalVolumeTextures.Add(pTexture); // add the texture to the list of original texture - - return LookUpToMod(pTexture); // check if this texture should be modded -} - -int uMod_TextureClient::AddTexture(uMod_IDirect3DCubeTexture9* pTexture) -{ - void* cpy; - const long ret = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) { - static_cast(D3D9Device)->SetLastCreatedCubeTexture(nullptr); //this texture must no be added twice - } - else { - static_cast(D3D9Device)->SetLastCreatedCubeTexture(nullptr); //this texture must no be added twice - } - - if (pTexture->FAKE) { - return RETURN_OK; // this is a fake texture - } - - Message("uMod_TextureClient::AddTexture( Cube: %p): %p (thread: %p)\n", pTexture, this, GetCurrentThreadId()); - - MyTypeHash hash; - if (const int ret = pTexture->GetHash(hash)) { - return ret; - } - - pTexture->Hash = hash; - - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - - OriginalCubeTextures.Add(pTexture); // add the texture to the list of original texture - - return LookUpToMod(pTexture); // check if this texture should be modded -} - - - -int uMod_TextureClient::RemoveTexture(uMod_IDirect3DTexture9* pTexture) // is called from a texture, if it is finally released -{ - Message("uMod_TextureClient::RemoveTexture( %p, %#lX): %p\n", pTexture, pTexture->Hash, this); - - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - if (pTexture->FAKE) { - // we need to set the corresponding FileToMod[X].pTexture to NULL, to avoid a link to a non existing texture object - const int ref = pTexture->Reference; - if (ref >= 0 && ref < NumberToMod) { - for (int i = 0; i < FileToMod[ref].NumberOfTextures; i++) { - if (FileToMod[ref].Textures[i] == pTexture) { - FileToMod[ref].NumberOfTextures--; - for (int j = i; j < FileToMod[ref].NumberOfTextures; j++) { - FileToMod[ref].Textures[j] = FileToMod[ref].Textures[j + 1]; - } - FileToMod[ref].Textures[FileToMod[ref].NumberOfTextures] = nullptr; - break; - } - } - } - } - else { - return OriginalTextures.Remove(pTexture); //remove this texture form the list - } - return RETURN_OK; -} - -int uMod_TextureClient::RemoveTexture(uMod_IDirect3DVolumeTexture9* pTexture) // is called from a texture, if it is finally released -{ - Message("uMod_TextureClient::RemoveTexture( Volume %p, %#lX): %p\n", pTexture, pTexture->Hash, this); - - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - if (pTexture->FAKE) { - // we need to set the corresponding FileToMod[X].pTexture to NULL, to avoid a link to a non existing texture object - const int ref = pTexture->Reference; - if (ref >= 0 && ref < NumberToMod) { - for (int i = 0; i < FileToMod[ref].NumberOfTextures; i++) { - if (FileToMod[ref].Textures[i] == pTexture) { - FileToMod[ref].NumberOfTextures--; - for (int j = i; j < FileToMod[ref].NumberOfTextures; j++) { - FileToMod[ref].Textures[j] = FileToMod[ref].Textures[j + 1]; - } - FileToMod[ref].Textures[FileToMod[ref].NumberOfTextures] = nullptr; - break; - } - } - } - } - else { - return OriginalVolumeTextures.Remove(pTexture); //remove this texture form the list - } - return RETURN_OK; -} - -int uMod_TextureClient::RemoveTexture(uMod_IDirect3DCubeTexture9* pTexture) // is called from a texture, if it is finally released -{ - Message("uMod_TextureClient::RemoveTexture( Cube %p, %#lX): %p\n", pTexture, pTexture->Hash, this); - - if (gl_ErrorState & uMod_ERROR_FATAL) { - return RETURN_FATAL_ERROR; - } - if (pTexture->FAKE) { - // we need to set the corresponding FileToMod[X].pTexture to NULL, to avoid a link to a non existing texture object - const int ref = pTexture->Reference; - if (ref >= 0 && ref < NumberToMod) { - for (int i = 0; i < FileToMod[ref].NumberOfTextures; i++) { - if (FileToMod[ref].Textures[i] == pTexture) { - FileToMod[ref].NumberOfTextures--; - for (int j = i; j < FileToMod[ref].NumberOfTextures; j++) { - FileToMod[ref].Textures[j] = FileToMod[ref].Textures[j + 1]; - } - FileToMod[ref].Textures[FileToMod[ref].NumberOfTextures] = nullptr; - break; - } - } - } - } - else { - return OriginalCubeTextures.Remove(pTexture); //remove this texture form the list - } - return RETURN_OK; -} - - -int uMod_TextureClient::AddUpdate(TextureFileStruct* update, int number) //client must delete the update array -{ - Message("AddUpdate( %p, %d): %p\n", update, number, this); - if (const int ret = LockMutex()) { - gl_ErrorState |= uMod_ERROR_TEXTURE; - return ret; - } - - delete [] Update; - - Update = update; - NumberOfUpdate = number; - return UnlockMutex(); -} - - -int uMod_TextureClient::MergeUpdate() -{ - if (NumberOfUpdate < 0) { return RETURN_OK; } - if (const int ret = LockMutex()) { - gl_ErrorState |= uMod_ERROR_TEXTURE; - return ret; - } - - Message("MergeUpdate(): %p\n", this); - - for (int i = 0; i < NumberOfUpdate; i++) { - Update[i].NumberOfTextures = 0; - Update[i].Textures = nullptr; - } // this is already done, but safety comes first ^^ - - int pos_old = 0; - int pos_new = 0; - int* to_lookup = nullptr; - if (NumberOfUpdate > 0) { - to_lookup = new int[NumberOfUpdate]; - } - int num_to_lookup = 0; - - /* - * FileToMod contains the old files (textures) which should replace the target textures (if they are loaded by the game) - * Update contains the new files (textures) which should replace the target textures (if they are loaded by the game) - * - * Both arrays (FileToMod and Update) are sorted according to their hash values. - * - * First we go through both arrays linearly and - * 1) take over the old entry if the hash is the same, - * 2) release old fake texture (if target texture exist and is not in the Update) - * 3) or mark newly added fake texture (if they are not in FileToMod) - */ - - while (pos_old < NumberToMod && pos_new < NumberOfUpdate) { - if (FileToMod[pos_old].Hash > Update[pos_new].Hash) // this fake texture is new - { - to_lookup[num_to_lookup++] = pos_new++; // keep this fake texture in mind, we must search later for it through all original textures - // we increase only the new counter by one - } - else if (FileToMod[pos_old].Hash < Update[pos_new].Hash) // this fake texture is not in the update - { - for (int i = FileToMod[pos_old].NumberOfTextures - 1; i >= 0; i--) { - FileToMod[pos_old].Textures[i]->Release(); // we release the fake textures - } - - delete [] FileToMod[pos_old].Textures; // we delete the memory - - FileToMod[pos_old].NumberOfTextures = 0; - FileToMod[pos_old].Textures = nullptr; - - pos_old++; // we increase only the old counter by one - } - else // the hash value is the same, thus this texture is in the array FileToMod as well as in the array Update - { - if (Update[pos_new].ForceReload) { - if (FileToMod[pos_old].NumberOfTextures > 0) { - Update[pos_new].Textures = new IDirect3DBaseTexture9*[FileToMod[pos_old].NumberOfTextures]; - } - for (int i = 0; i < FileToMod[pos_old].NumberOfTextures; i++) { - IDirect3DBaseTexture9* base_texture; - int ret = FileToMod[pos_old].Textures[i]->QueryInterface(IID_IDirect3D9, (void**)&base_texture); - switch (ret) { - case 0x01000000L: { - auto pTexture = static_cast(FileToMod[pos_old].Textures[i]);// - uMod_IDirect3DTexture9* pRefTexture = pTexture->CrossRef_D3Dtex; - pTexture->Release(); - i--; //after the Release of the old fake texture FileToMod[pos_old].Textures[i] is overwritten by entries with index greater than i - - uMod_IDirect3DTexture9* fake_Texture; - if (int ret = LoadTexture(&(Update[pos_new]), &fake_Texture)) { - return ret; - } - if (SwitchTextures(fake_Texture, pRefTexture)) { - Message("MergeUpdate(): textures not switched %#lX\n", pRefTexture->Hash); - fake_Texture->Release(); - } - else { - Update[pos_new].Textures[Update[pos_new].NumberOfTextures++] = fake_Texture; - fake_Texture->Reference = pos_new; - } - break; - } - case 0x01000001L: { - auto pTexture = static_cast(FileToMod[pos_old].Textures[i]);// - uMod_IDirect3DVolumeTexture9* pRefTexture = pTexture->CrossRef_D3Dtex; - pTexture->Release(); - i--; //after the Release of the old fake texture FileToMod[pos_old].Textures[i] is overwritten by entries with index greater than i - - uMod_IDirect3DVolumeTexture9* fake_Texture; - if (int ret = LoadTexture(&(Update[pos_new]), &fake_Texture)) { - return ret; - } - if (SwitchTextures(fake_Texture, pRefTexture)) { - Message("MergeUpdate(): textures not switched %#lX\n", pRefTexture->Hash); - fake_Texture->Release(); - } - else { - Update[pos_new].Textures[Update[pos_new].NumberOfTextures++] = fake_Texture; - fake_Texture->Reference = pos_new; - } - break; - } - case 0x01000002L: { - auto pTexture = static_cast(FileToMod[pos_old].Textures[i]);// - uMod_IDirect3DCubeTexture9* pRefTexture = pTexture->CrossRef_D3Dtex; - pTexture->Release(); - i--; //after the Release of the old fake texture FileToMod[pos_old].Textures[i] is overwritten by entries with index greater than i - - uMod_IDirect3DCubeTexture9* fake_Texture; - if (int ret = LoadTexture(&Update[pos_new], &fake_Texture)) { - return ret; - } - if (SwitchTextures(fake_Texture, pRefTexture)) { - Message("MergeUpdate(): textures not switched %#lX\n", pRefTexture->Hash); - fake_Texture->Release(); - } - else { - Update[pos_new].Textures[Update[pos_new].NumberOfTextures++] = fake_Texture; - fake_Texture->Reference = pos_new; - } - break; - } - default: - break; // this is no fake texture and QueryInterface failed, because IDirect3DBaseTexture9 object cannot be a IDirect3D9 object ;) - } - } - } - else // the texture might be loaded or not - { - Update[pos_new].NumberOfTextures = FileToMod[pos_old].NumberOfTextures; - Update[pos_new].Textures = FileToMod[pos_old].Textures; - FileToMod[pos_old].NumberOfTextures = 0; - FileToMod[pos_old].Textures = nullptr; - } - // we increase both counters by one - pos_old++; - pos_new++; - } - } - - while (pos_old < NumberToMod) //this fake textures are not in the Update - { - for (int i = FileToMod[pos_old].NumberOfTextures - 1; i >= 0; i--) { - FileToMod[pos_old].Textures[i]->Release(); // we release the fake textures - } - //for (int i=0; iRelease(); // we release the fake textures - - delete [] FileToMod[pos_old].Textures; // we delete the memory - - FileToMod[pos_old].Textures = nullptr; - pos_old++; - } - while (pos_new < NumberOfUpdate) //this fake textures are newly added - { - to_lookup[num_to_lookup++] = pos_new++; //keep this fake texture in mind, we must search later for it through all original textures - } - - - /* - * if (num_to_lookup>0) we need to look through all original textures - * because there were newly added textures and we don't know - * if the corresponding target textures are loaded by the game or not. - * - * Note: to_lookup[num_to_lookup++] = pos_new++; is in ascending order, - * thus Update[to_lookup[pos]].Hash is also sorted ascending! - */ -/* - uMod_IDirect3DTexture9 *single_texture = ((uMod_IDirect3DDevice9*)D3D9Device)->GetSingleTexture(); - if (num_to_lookup>0) - { - int num = OriginalTextures.GetNumber(); - for (int i=0; iCrossRef_D3Dtex==NULL || OriginalTextures[i]->CrossRef_D3Dtex==single_texture) - // We need look only for textures, that are not switched or switched with the single_texture. - // The single_texture is a special texture, which you can toggle through all original texture, if save single texture is turned on. - { - MyTypeHash hash = OriginalTextures[i]->Hash; - - if (hashUpdate[to_lookup[num_to_lookup-1]].Hash) continue; - - int index = -1; - int pos = num_to_lookup/2; - int begin = 0; - int end = num_to_lookup-1; - - // We look in the middle of the interval and each step we halve the interval, - // unless we find the texture or the size of the interval is less than 3. - // Note: contradicting to normal C-code here the interval includes the index "begin" and "end"! - while (begin+1 Update[to_lookup[pos]].Hash) // the new interval is the right half of the actual interval - { - begin = pos+1; // the new interval does not contain the index "pos" - pos = (begin + end)/2; // set "pos" somewhere inside the new intervall - } - else if (hash < Update[to_lookup[pos]].Hash) // the new interval is the left half of the actual interval - { - end = pos-1; // the new interval does not contain the index "pos" - pos = (begin + end)/2; // set "pos" somewhere inside the new intervall - } - else {index = to_lookup[pos]; break;} // we hit the correct hash - } - if (index<0) // if we did not find the hash, it might be in the last interval - { - for (int i=begin; i<=end; i++) if (Update[to_lookup[i]].Hash==hash) index = to_lookup[i]; - } - - if (index>=0) // target texture is loaded by the game - { - if (OriginalTextures[i]->CrossRef_D3Dtex!=NULL) UnswitchTextures(OriginalTextures[i]); // this texture was switched with the single texture - - uMod_IDirect3DTexture9 *fake_Texture; - if (int ret = LoadTexture( & (Update[index]), &fake_Texture)) return ret; - if (SwitchTextures( fake_Texture, OriginalTextures[i])) - { - Message("uMod_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash); - fake_Texture->Release(); - } - else - { - IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[Update[index].NumberOfTextures+1]; - for (int j=0; jReference = index; - } - } - } - } -*/ - - - //for (int i=0; i 0) { - uMod_IDirect3DTexture9* single_texture; - void* cpy; - const long ret = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) { - single_texture = static_cast(D3D9Device)->GetSingleTexture(); //this texture must no be added twice - } - else { - single_texture = static_cast(D3D9Device)->GetSingleTexture(); //this texture must no be added twice - } - - int num = OriginalTextures.GetNumber(); - for (int i = 0; i < num; i++) { - if (OriginalTextures[i]->CrossRef_D3Dtex == nullptr || OriginalTextures[i]->CrossRef_D3Dtex == single_texture) { - UnswitchTextures(OriginalTextures[i]); //this we can do always, so we unswitch the single texture - LookUpToMod(OriginalTextures[i], num_to_lookup, to_lookup); - } - } - - uMod_IDirect3DVolumeTexture9* single_volume_texture; - if (ret == 0x01000000L) { - single_volume_texture = static_cast(D3D9Device)->GetSingleVolumeTexture(); //this texture must no be added twice - } - else { - single_volume_texture = static_cast(D3D9Device)->GetSingleVolumeTexture(); //this texture must no be added twice - } - num = OriginalVolumeTextures.GetNumber(); - for (int i = 0; i < num; i++) { - if (OriginalVolumeTextures[i]->CrossRef_D3Dtex == nullptr || OriginalVolumeTextures[i]->CrossRef_D3Dtex == single_volume_texture) { - UnswitchTextures(OriginalVolumeTextures[i]); //this we can do always, so we unswitch the single texture - LookUpToMod(OriginalVolumeTextures[i], num_to_lookup, to_lookup); - } - } - - uMod_IDirect3DCubeTexture9* single_cube_texture; - if (ret == 0x01000000L) { - single_cube_texture = static_cast(D3D9Device)->GetSingleCubeTexture(); //this texture must no be added twice - } - else { - single_cube_texture = static_cast(D3D9Device)->GetSingleCubeTexture(); //this texture must no be added twice - } - num = OriginalCubeTextures.GetNumber(); - for (int i = 0; i < num; i++) { - if (OriginalCubeTextures[i]->CrossRef_D3Dtex == nullptr || OriginalCubeTextures[i]->CrossRef_D3Dtex == single_cube_texture) { - UnswitchTextures(OriginalCubeTextures[i]); //this we can do always, so we unswitch the single texture - LookUpToMod(OriginalCubeTextures[i], num_to_lookup, to_lookup); - } - } - } - - delete [] to_lookup; - - return UnlockMutex(); -} - - - -int uMod_TextureClient::LockMutex() -{ - if ((gl_ErrorState & (uMod_ERROR_FATAL | uMod_ERROR_MUTEX))) { - return RETURN_NO_MUTEX; - } - if (WAIT_OBJECT_0 != WaitForSingleObject(Mutex, 100)) { - return RETURN_MUTEX_LOCK; //waiting 100ms, to wait infinite pass INFINITE - } - return RETURN_OK; -} - -int uMod_TextureClient::UnlockMutex() -{ - if (ReleaseMutex(Mutex) == 0) { - return RETURN_MUTEX_UNLOCK; - } - return RETURN_OK; -} - - -int uMod_TextureClient::LookUpToMod(MyTypeHash hash, int num_index_list, int* index_list) -{ - if (NumberToMod > 0) { - if (index_list == nullptr || num_index_list == 0) { - if (hash < FileToMod[0].Hash || hash > FileToMod[NumberToMod - 1].Hash) { - return -1; - } - int pos = NumberToMod / 2; - int begin = 0; - int end = NumberToMod - 1; - - // We look in the middle of the interval and each step we halve the interval, - // unless we find the texture or the size of the interval is less than 3. - // Note: contradicting to normal C-code here the interval includes the index "begin" and "end"! - while (begin + 1 < end) // as long as the interval is longer than two - { - if (hash > FileToMod[pos].Hash) // the new interval is the right half of the actual interval - { - begin = pos + 1; // the new interval does not contain the index "pos" - pos = (begin + end) / 2; // set "pos" somewhere inside the new interval - } - else if (hash < FileToMod[pos].Hash) // the new interval is the left half of the actual interval - { - end = pos - 1; // the new interval does not contain the index "pos" - pos = (begin + end) / 2; // set "pos" somewhere inside the new interval - } - else { - return pos; - break; - } // we hit the correct hash - } - for (pos = begin; pos <= end; pos++) { - if (FileToMod[pos].Hash == hash) { - return pos; - } - } - } - else { - if (hash < FileToMod[index_list[0]].Hash || hash > FileToMod[index_list[num_index_list - 1]].Hash) { - return -1; - } - int pos = num_index_list / 2; - int begin = 0; - int end = num_index_list - 1; - - // We look in the middle of the interval and each step we halve the interval, - // unless we find the texture or the size of the interval is less than 3. - // Note: contradicting to normal C-code here the interval includes the index "begin" and "end"! - while (begin + 1 < end) // as long as the interval is longer than two - { - if (hash > FileToMod[index_list[pos]].Hash) // the new interval is the right half of the actual interval - { - begin = pos + 1; // the new interval does not contain the index "pos" - pos = (begin + end) / 2; // set "pos" somewhere inside the new interval - } - else if (hash < FileToMod[index_list[pos]].Hash) // the new interval is the left half of the actual interval - { - end = pos - 1; // the new interval does not contain the index "pos" - pos = (begin + end) / 2; // set "pos" somewhere inside the new interval - } - else { - return index_list[pos]; - break; - } // we hit the correct hash - } - for (pos = begin; pos <= end; pos++) { - if (FileToMod[index_list[pos]].Hash == hash) { - return index_list[pos]; - } - } - } - } - return -1; -} - -int uMod_TextureClient::LookUpToMod(uMod_IDirect3DTexture9* pTexture, int num_index_list, int* index_list) // should only be called for original textures -{ - Message("uMod_TextureClient::LookUpToMod( %p): hash: %#lX, %p\n", pTexture, pTexture->Hash, this); - if (pTexture->CrossRef_D3Dtex != nullptr) { - return RETURN_OK; // bug, this texture is already switched - } - const int index = LookUpToMod(pTexture->Hash, num_index_list, index_list); - if (index >= 0) { - uMod_IDirect3DTexture9* fake_Texture; - if (const int ret = LoadTexture(&(FileToMod[index]), &fake_Texture)) { - return ret; - } - if (SwitchTextures(fake_Texture, pTexture)) { - Message("uMod_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash); - fake_Texture->Release(); - } - else { - const auto temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures + 1]; - for (int j = 0; j < FileToMod[index].NumberOfTextures; j++) { - temp[j] = FileToMod[index].Textures[j]; - } - - delete [] FileToMod[index].Textures; - - FileToMod[index].Textures = temp; - - FileToMod[index].Textures[FileToMod[index].NumberOfTextures++] = fake_Texture; - fake_Texture->Reference = index; - } - } - return RETURN_OK; -} - -int uMod_TextureClient::LookUpToMod(uMod_IDirect3DVolumeTexture9* pTexture, int num_index_list, int* index_list) // should only be called for original textures -{ - Message("uMod_TextureClient::LookUpToMod( Volume %p): hash: %#lX, %p\n", pTexture, pTexture->Hash, this); - if (pTexture->CrossRef_D3Dtex != nullptr) { - return RETURN_OK; // bug, this texture is already switched - } - const int index = LookUpToMod(pTexture->Hash, num_index_list, index_list); - if (index >= 0) { - uMod_IDirect3DVolumeTexture9* fake_Texture; - if (const int ret = LoadTexture(&(FileToMod[index]), &fake_Texture)) { - return ret; - } - if (SwitchTextures(fake_Texture, pTexture)) { - Message("uMod_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash); - fake_Texture->Release(); - } - else { - const auto temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures + 1]; - for (int j = 0; j < FileToMod[index].NumberOfTextures; j++) { - temp[j] = FileToMod[index].Textures[j]; - } - - delete [] FileToMod[index].Textures; - - FileToMod[index].Textures = temp; - - FileToMod[index].Textures[FileToMod[index].NumberOfTextures++] = fake_Texture; - fake_Texture->Reference = index; - } - } - return RETURN_OK; -} - -int uMod_TextureClient::LookUpToMod(uMod_IDirect3DCubeTexture9* pTexture, int num_index_list, int* index_list) // should only be called for original textures -{ - Message("uMod_TextureClient::LookUpToMod( Cube %p): hash: %#lX, %p\n", pTexture, pTexture->Hash, this); - if (pTexture->CrossRef_D3Dtex != nullptr) { - return RETURN_OK; // bug, this texture is already switched - } - const int index = LookUpToMod(pTexture->Hash, num_index_list, index_list); - if (index >= 0) { - uMod_IDirect3DCubeTexture9* fake_Texture; - if (const int ret = LoadTexture(&(FileToMod[index]), &fake_Texture)) { - return ret; - } - if (SwitchTextures(fake_Texture, pTexture)) { - Message("uMod_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash); - fake_Texture->Release(); - } - else { - const auto temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures + 1]; - for (int j = 0; j < FileToMod[index].NumberOfTextures; j++) { - temp[j] = FileToMod[index].Textures[j]; - } - - delete [] FileToMod[index].Textures; - FileToMod[index].Textures = temp; - - FileToMod[index].Textures[FileToMod[index].NumberOfTextures++] = fake_Texture; - fake_Texture->Reference = index; - } - } - return RETURN_OK; -} - -int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DTexture9** ppTexture) // to load fake texture from a file in memory -{ - Message("LoadTexture( %p, %p, %#lX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this); - if (D3D_OK != D3DXCreateTextureFromFileInMemoryEx(D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, nullptr, nullptr, - (IDirect3DTexture9**)ppTexture)) - //if (D3D_OK != D3DXCreateTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DTexture9 **) ppTexture)) - { - *ppTexture = nullptr; - return RETURN_TEXTURE_NOT_LOADED; - } - (*ppTexture)->FAKE = true; - - void* cpy; - const long ret = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) { - static_cast(D3D9Device)->SetLastCreatedTexture(nullptr); //this texture must no be added twice - } - else { - static_cast(D3D9Device)->SetLastCreatedTexture(nullptr); //this texture must no be added twice - } - - Message("LoadTexture( %p, %#lX): DONE\n", *ppTexture, file_in_memory->Hash); - return RETURN_OK; -} - -int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DVolumeTexture9** ppTexture) // to load fake texture from a file in memory -{ - Message("LoadTexture( Volume %p, %p, %#lX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this); - if (D3D_OK != D3DXCreateVolumeTextureFromFileInMemoryEx(D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, nullptr, - nullptr, - (IDirect3DVolumeTexture9**)ppTexture)) - //if (D3D_OK != D3DXCreateVolumeTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DVolumeTexture9 **) ppTexture)) - { - *ppTexture = nullptr; - return RETURN_TEXTURE_NOT_LOADED; - } - (*ppTexture)->FAKE = true; - - void* cpy; - const long ret = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) { - static_cast(D3D9Device)->SetLastCreatedVolumeTexture(nullptr); //this texture must no be added twice - } - else { - static_cast(D3D9Device)->SetLastCreatedVolumeTexture(nullptr); //this texture must no be added twice - } - - Message("LoadTexture( Volume %p, %#lX): DONE\n", *ppTexture, file_in_memory->Hash); - return RETURN_OK; -} - -int uMod_TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uMod_IDirect3DCubeTexture9** ppTexture) // to load fake texture from a file in memory -{ - Message("LoadTexture( Cube %p, %p, %#lX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this); - if (D3D_OK != D3DXCreateCubeTextureFromFileInMemoryEx(D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, nullptr, nullptr, - (IDirect3DCubeTexture9**)ppTexture)) - //if (D3D_OK != D3DXCreateCubeTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DCubeTexture9 **) ppTexture)) - { - *ppTexture = nullptr; - return RETURN_TEXTURE_NOT_LOADED; - } - (*ppTexture)->FAKE = true; - - void* cpy; - const long ret = D3D9Device->QueryInterface(IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) { - static_cast(D3D9Device)->SetLastCreatedCubeTexture(nullptr); //this texture must no be added twice - } - else { - static_cast(D3D9Device)->SetLastCreatedCubeTexture(nullptr); //this texture must no be added twice - } - - Message("LoadTexture( Cube %p, %#lX): DONE\n", *ppTexture, file_in_memory->Hash); - return RETURN_OK; -} diff --git a/source/uMod_TextureFunction.cpp b/source/uMod_TextureFunction.cpp deleted file mode 100644 index 30726bd..0000000 --- a/source/uMod_TextureFunction.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "uMod_Main.h" - -/* -MyTypeHash GetHash(unsigned char *str, int len) // estimate the hash -{ - MyTypeHash hash = 0; - for (int i=0; i>= 1) { - crc = crc >> 1 ^ ((crc ^ data) & 1 ? CRC32POLY : 0); - } - } - return crc; -} diff --git a/source/uMod_TextureServer.cpp b/source/uMod_TextureServer.cpp deleted file mode 100644 index 037b51a..0000000 --- a/source/uMod_TextureServer.cpp +++ /dev/null @@ -1,271 +0,0 @@ -#include -#include -#include - -#include "uMod_Main.h" -#include "gMod_FileLoader.h" - -unsigned long loadedSize = 0; - -uMod_TextureServer::uMod_TextureServer(char* game, char* uModName) -{ - Message("uMod_TextureServer(): %p\n", this); - - Client = nullptr; - - int len = 0; - int path_pos = 0; - int dot_pos = 0; - for (len = 0; len < MAX_PATH && (game[len]); len++) { - if (game[len] == '\\' || game[len] == '/') { - path_pos = len + 1; - } - else if (game[len] == '.') { - dot_pos = len; - } - } - - if (dot_pos > path_pos) { - len = dot_pos - path_pos; - } - else { - len -= path_pos; - } - - for (int i = 0; i < len; i++) { - GameName[i] = game[i + path_pos]; - } - - if (len < MAX_PATH) { - GameName[len] = 0; - } - else { - GameName[0] = 0; - } - - strcpy(UModName, uModName); -} - -uMod_TextureServer::~uMod_TextureServer() -{ - Message("~uMod_TextureServer(): %p\n", this); - //delete the files in memory - int num = CurrentMod.GetNumber(); - for (int i = 0; i < num; i++) { - delete[] CurrentMod[i]->pData; //delete the file content of the texture - } - - num = OldMod.GetNumber(); - for (int i = 0; i < num; i++) { - delete[] OldMod[i]->pData; //delete the file content of the texture - } -} - -int uMod_TextureServer::AddClient(uMod_TextureClient* client, TextureFileStruct** update, int* number) // called from a client -{ - Message("AddClient(%p): %p\n", client, this); - // the following functions must not change the original uMod_IDirect3DDevice9 object - // somehow on game start some uMod_IDirect3DDevice9 object are created, which must rest unchanged!! - // these objects are released and are not used for rendering - - if (const int ret = PrepareUpdate(update, number)) { - return ret; // get a copy of all texture to be modded - } - - Client = client; - - return RETURN_OK; -} - -int uMod_TextureServer::AddFile(char* dataPtr, unsigned int size, MyTypeHash hash, bool force) // called from Mainloop() -{ - Message("uMod_TextureServer::AddFile( %p %p, %#lX, %d): %p\n", dataPtr, size, hash, force, this); - - TextureFileStruct* temp = nullptr; - - int num = CurrentMod.GetNumber(); - for (int i = 0; i < num; i++) { - if (CurrentMod[i]->Hash == hash) //look through all current textures - { - if (force) { - temp = CurrentMod[i]; - break; - } // we need to reload it - - - return RETURN_EXISTS; // we still have added this texture - } - } - if (temp == nullptr) // if not found, look through all old textures - { - num = OldMod.GetNumber(); - for (int i = 0; i < num; i++) { - if (OldMod[i]->Hash == hash) { - temp = OldMod[i]; - OldMod.Remove(temp); - CurrentMod.Add(temp); - if (force) { - break; // we must reload it - } - - return RETURN_EXISTS; // we should not reload it - } - } - } - - bool new_file = true; - if (temp != nullptr) //if it was found, we delete the old file content - { - new_file = false; - - delete[] temp->pData; // todo: this tries deleting memory out of a vector of tpfentries, which won't do anything - // todo: therefore we don't get out memory back here - - temp->pData = nullptr; - } - else //if it was not found, we need to create a new object - { - new_file = true; - temp = new TextureFileStruct; - temp->Reference = -1; - } - - temp->pData = dataPtr; - temp->Size = size; - temp->NumberOfTextures = 0; - temp->Textures = nullptr; - temp->Hash = hash; - - //if (new_file) temp->ForceReload = false; // no need to force a load of the texture - //else - temp->ForceReload = force; - - Message("End AddFile(%#lX)\n", hash); - if (new_file) { - return CurrentMod.Add(temp); // new files must be added to the list of the CurrentMod - } - return RETURN_OK; -} - -int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called from Mainloop(), send the update to all clients -{ - Message("PropagateUpdate(%p): %p\n", client, this); - if (client != nullptr) { - TextureFileStruct* update; - int number; - if (const int ret = PrepareUpdate(&update, &number)) { - return ret; - } - client->AddUpdate(update, number); - } - return RETURN_OK; -} - -void cpy_file_struct(TextureFileStruct& a,TextureFileStruct& b) -{ - a.ForceReload = b.ForceReload; - a.pData = b.pData; - a.Size = b.Size; - a.NumberOfTextures = b.NumberOfTextures; - a.Reference = b.Reference; - a.Textures = b.Textures; - a.Hash = b.Hash; -} - -int TextureFileStruct_Compare(const void* elem1, const void* elem2) -{ - const auto tex1 = (TextureFileStruct*)elem1; - const auto tex2 = (TextureFileStruct*)elem2; - if (tex1->Hash < tex2->Hash) { - return -1; - } - if (tex1->Hash > tex2->Hash) { - return +1; - } - return 0; -} - -int uMod_TextureServer::PrepareUpdate(TextureFileStruct** update, int* number) // called from the PropagateUpdate() and AddClient. -// Prepare an update for one client. The allocated memory must deleted by the client. -{ - Message("PrepareUpdate(%p, %d): %p\n", update, number, this); - - TextureFileStruct* temp = nullptr; - const int num = CurrentMod.GetNumber(); - if (num > 0) { - try { temp = new TextureFileStruct[num]; } - catch (...) { - gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER; - return RETURN_NO_MEMORY; - } - - for (int i = 0; i < num; i++) cpy_file_struct(temp[i], *CurrentMod[i]); - qsort(temp, num, sizeof(TextureFileStruct), TextureFileStruct_Compare); - } - - *update = temp; - *number = num; - return RETURN_OK; -} - -void uMod_TextureServer::LoadModsFromFile(const char* source) -{ - Message("Initialize: searching in %s\n", source); - - std::ifstream file(source); - if (file.is_open()) { - Message("Initialize: found modlist.txt. Reading\n"); - std::string line; - while (std::getline(file, line)) { - Message("Initialize: loading file %s\n", line.c_str()); - - // Remove newline character - line.erase(std::ranges::remove(line, '\n').begin(), line.end()); - - auto file_loader = gMod_FileLoader(line); - const auto entries = file_loader.GetContents(); - if (loadedSize > 1'500'000'000) { - Message("LoadModsFromFile: Loaded %d bytes, aborting!!!", loadedSize); - return; - } - if (!entries.empty()) { - Message("Initialize: Texture count %zu %s\n", entries.size(), line.c_str()); - for (const auto& tpf_entry : entries) { - loadedSize += tpf_entry.size; - if (AddFile(static_cast(tpf_entry.data), static_cast(tpf_entry.size), tpf_entry.crc_hash, false) == RETURN_EXISTS) { - //Texture is already loaded, so we need to clear our data - loadedSize -= tpf_entry.size; - } - - Message("LoadModsFromFile: Loaded %d bytes", loadedSize); - } - - PropagateUpdate(Client); - } - else { - Message("Initialize: Failed to load any textures for %s\n", line.c_str()); - } - } - Message("Finished loading mods: Loaded %u bytes (%u mb)", loadedSize, loadedSize / 1024 / 1024); - } -} - -int uMod_TextureServer::Initialize() -{ - Message("Initialize: begin\n"); - Message("Initialize: searching for modlist.txt\n"); - char gwpath[MAX_PATH]; - GetModuleFileName(GetModuleHandle(nullptr), gwpath, MAX_PATH); //ask for name and path of this executable - const auto exe = std::filesystem::path(gwpath).parent_path(); - const auto dll = std::filesystem::path(UModName).parent_path(); - for (const auto& path : {exe, dll}) { - const auto modlist = path / "modlist.txt"; - if (std::filesystem::exists(modlist)) { - LoadModsFromFile(modlist.string().c_str()); - } - } - - Message("Initialize: end\n"); - - return RETURN_OK; -}