* read modlist.txt files immediately on launch, textures still loaded on d3d creation
This commit is contained in:
DubbleClick
2024-11-10 23:06:49 +07:00
committed by GitHub
parent 93032262c3
commit 175002a9e4
10 changed files with 55 additions and 46 deletions
+2 -1
View File
@@ -18,7 +18,7 @@ endif()
set(VERSION_MAJOR 1)
set(VERSION_MINOR 7)
set(VERSION_PATCH 0)
set(VERSION_TWEAK 0)
set(VERSION_TWEAK 1)
set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in" "${VERSION_RC}" @ONLY)
@@ -52,6 +52,7 @@ target_include_directories(gMod PRIVATE
)
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
target_sources(gMod PRIVATE ${SOURCES})
target_compile_options(gMod PRIVATE /W4 /WX)
target_link_libraries(gMod PRIVATE
dxguid
+2 -2
View File
@@ -28,7 +28,7 @@ If you would like to use Reshade in combination with gMod, we recommend running
Requirements:
- Visual Studio 2022
- CMake 3.16+, integrated into the Developer Powershell for VS 2022
- CMake 3.29+, integrated into the Developer Powershell for VS 2022
- vcpkg, integrated into the Developer Powershell for VS 2022
Compile:
@@ -42,4 +42,4 @@ Usage:
- put TpfConvert.exe and d3dx9.dll anywhere
- create a folder "plugins" in that folder and put your .tpf/.zip files with invalid images there
- run TpfConvert.exe, My_Texmod.tpf is fixed and copied into My_Texmod_.zip
- copy My_Texmod_.zip into your GW Launcher plugins folder, delete My_Texmod.tpf from it, if it still exists
- copy My_Texmod_.zip into your GW Launcher plugins folder, delete My_Texmod.tpf from it, if it still exists
+1 -1
View File
@@ -34,7 +34,7 @@ struct TextureFileStruct {
HashType crc_hash = 0; // hash value
};
inline void Message(const char* format, ...)
inline void Message([[maybe_unused]] const char* format, ...)
{
#ifdef _DEBUG
#if 0
+4 -4
View File
@@ -23,13 +23,13 @@ public:
line_length = file_stream.tellg();
file_stream.seekg(0, std::ios::beg); // Go to the beginning of the stream
std::vector<char> data(line_length);
std::vector<char> data(static_cast<long>(line_length));
file_stream.read(data.data(), line_length);
for (auto i = 0; i < data.size(); i++) {
for (auto i = 0u; i < data.size(); i++) {
data[i] = XOR(data[i], i);
}
for (int i = data.size() - 1; i > 0 && data[i] != 0; i--) {
for (auto i = data.size() - 1; i > 0 && data[i] != 0; i--) {
data[i] = 0;
}
@@ -42,7 +42,7 @@ public:
private:
std::ifstream file_stream;
long line_length = 0;
std::streamoff line_length = 0;
[[nodiscard]] char XOR(const char b, const long position) const
{
+8 -25
View File
@@ -10,6 +10,7 @@ export module TextureClient;
import TextureFunction;
import ModfileLoader;
export std::vector<std::pair<std::string, std::string>> modlists_contents;
/*
* An object of this class is owned by each d3d9 device.
* All other functions are called from the render thread instance of the game itself.
@@ -56,8 +57,7 @@ private:
// called if a target texture is found
int LoadTexture(TextureFileStruct* file_in_memory, uModTexturePtrPtr auto ppTexture);
void LoadModsFromFile(const char* source);
std::filesystem::path exe_path; // path to gw.exe
void LoadModsFromModlist(std::pair<std::string, std::string> modfile_tuple);
std::filesystem::path dll_path; // path to gmod dll
};
@@ -189,18 +189,12 @@ std::vector<gsl::owner<TextureFileStruct*>> ProcessModfile(const std::filesystem
return texture_file_structs;
}
void TextureClient::LoadModsFromFile(const char* source)
void TextureClient::LoadModsFromModlist(std::pair<std::string, std::string> modfile_tuple)
{
static std::vector<std::filesystem::path> loaded_modfiles{};
Message("Initialize: searching in %s\n", source);
std::locale::global(std::locale(""));
std::ifstream file(source, std::ios::binary);
if (!file.is_open()) {
Warning("LoadModsFromFile: failed to open modlist.txt for reading; aborting!!!");
return;
}
Message("Initialize: found modlist.txt. Reading\n");
std::istringstream file(modfile_tuple.second);
std::string line;
std::vector<std::filesystem::path> modfiles;
while (std::getline(file, line)) {
@@ -216,7 +210,7 @@ void TextureClient::LoadModsFromFile(const char* source)
loaded_modfiles.push_back(fsline);
}
}
auto files_size = 0u;
auto files_size = 0ull;
for (const auto modfile : modfiles) {
if (std::filesystem::exists(modfile)) {
files_size += std::filesystem::file_size(modfile);
@@ -241,26 +235,15 @@ void TextureClient::LoadModsFromFile(const char* source)
}
should_update = true;
}
Message("Finished loading mods from %s: Loaded %u bytes (%u mb)", source, loaded_size, loaded_size / 1024 / 1024);
Message("Finished loading mods from %s: Loaded %u bytes (%u mb)", modfile_tuple.first.c_str(), loaded_size, loaded_size / 1024 / 1024);
}
void TextureClient::Initialize()
{
const auto t1 = std::chrono::high_resolution_clock::now();
Info("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
exe_path = std::filesystem::path(gwpath).parent_path();
dll_path = std::filesystem::path(dllpath).parent_path();
for (const auto& path : {exe_path, dll_path}) {
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());
}
for (const auto& modlists_content : modlists_contents) {
LoadModsFromModlist(modlists_content);
}
const auto t2 = std::chrono::high_resolution_clock::now();
const auto ms = duration_cast<std::chrono::milliseconds>(t2 - t1);
+1 -1
View File
@@ -146,7 +146,7 @@ export namespace TextureFunction {
return crc;
}
uint32_t get_crc32(const char* data_ptr, const int length)
uint32_t get_crc32(const char* data_ptr, const unsigned int length)
{
constexpr static auto crc32_poly = 0xEDB88320u;
constexpr static auto ul_crc_in = 0xffffffff;
+1 -1
View File
@@ -16,7 +16,7 @@ const char *function)
GetModuleFileName(gl_hThisInstance, module_path, _countof(module_path));
}
if (!*module_path) {
strcpy(module_path, "Unknown");
strcpy_s(module_path, "Unknown");
}
const char* fmt = "Module: %s\n\nExpr: %s\n\nFile: %s\n\nFunction: %s, line %d";
int len = snprintf(NULL, 0, fmt, module_path, expr, file, function, line);
+28 -3
View File
@@ -2,6 +2,8 @@
#include <Psapi.h>
#include "MinHook.h"
import TextureClient;
void ExitInstance();
void InitInstance(HINSTANCE hModule);
@@ -44,7 +46,7 @@ namespace {
TCHAR szModuleName[MAX_PATH];
ASSERT(GetModuleFileName(hModules[i], szModuleName, _countof(szModuleName)) > 0);
const auto basename = strrchr(szModuleName, '\\');
if (basename && stricmp(basename + 1, name) == 0)
if (basename && _stricmp(basename + 1, name) == 0)
return hModules[i];
}
return nullptr;
@@ -201,16 +203,39 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
return true;
}
void LoadModlists()
{
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_path = std::filesystem::path(gwpath).parent_path();
const auto dll_path = std::filesystem::path(dllpath).parent_path();
for (const auto& path : {exe_path, dll_path}) {
const auto modlist = path / "modlist.txt";
if (std::filesystem::exists(modlist)) {
Message("Initialize: found %s\n", modlist.string().c_str());
std::ifstream t(modlist, std::ios::binary);
std::stringstream buffer;
buffer << t.rdbuf();
modlists_contents.emplace_back(modlist.string(), buffer.str());
}
}
}
void InitInstance(HINSTANCE hModule)
{
Message("InitInstance: %p\n", hModule);
DisableThreadLibraryCalls(hModule); //reduce overhead
// Store the handle to this module
gl_hThisInstance = hModule;
LoadModlists();
DisableThreadLibraryCalls(hModule); //reduce overhead
// d3d9.dll shouldn't be loaded at this point.
const auto d3d9_loaded = FindLoadedModuleByName("d3d9.dll");
[[maybe_unused]] const auto d3d9_loaded = FindLoadedModuleByName("d3d9.dll");
//ASSERT(!d3d9_loaded);
MH_Initialize();
+1 -1
View File
@@ -264,7 +264,7 @@ HashTuple uMod_IDirect3DCubeTexture9::GetHash() const
}
}
const int size = (TextureFunction::GetBitsFromFormat(desc.Format) * desc.Width * desc.Height) / 8;
const auto size = (TextureFunction::GetBitsFromFormat(desc.Format) * desc.Width * desc.Height) / 8;
const auto crc32 = TextureFunction::get_crc32(static_cast<char*>(d3dlr.pBits), size);
const auto crc64 = HashCheck::Use64BitCrc() ? TextureFunction::get_crc64(static_cast<char*>(d3dlr.pBits), size) : 0;
+7 -7
View File
@@ -66,7 +66,7 @@ ULONG uMod_IDirect3DDevice9::Release()
const ULONG count = m_pIDirect3DDevice9->Release();
Message("%p = " PRE_MESSAGE "::Release(): %p\n", count, this);
if (uMod_Reference != count) //bug
if (uMod_Reference != static_cast<int>(count)) //bug
{
Message("Error in " PRE_MESSAGE "::Release(): %p!=%p\n", uMod_Reference, count);
}
@@ -367,9 +367,9 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu
pDest->Hash = pSource->Hash; // take over the hash
UnswitchTextures(pDest);
if (pSource->CrossRef_D3Dtex != nullptr) {
uMod_IDirect3DTexture9* cpy = pSource->CrossRef_D3Dtex;
uMod_IDirect3DTexture9* cpy2 = pSource->CrossRef_D3Dtex;
UnswitchTextures(pSource);
SwitchTextures(cpy, pDest);
SwitchTextures(cpy2, pDest);
}
}
if (pDest->CrossRef_D3Dtex != nullptr) {
@@ -387,9 +387,9 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu
pDest->Hash = pSourceVolume->Hash; // take over the hash
UnswitchTextures(pDest);
if (pSourceVolume->CrossRef_D3Dtex != nullptr) {
uMod_IDirect3DVolumeTexture9* cpy = pSourceVolume->CrossRef_D3Dtex;
uMod_IDirect3DVolumeTexture9* cpy2 = pSourceVolume->CrossRef_D3Dtex;
UnswitchTextures(pSourceVolume);
SwitchTextures(cpy, pDest);
SwitchTextures(cpy2, pDest);
}
}
if (pDest->CrossRef_D3Dtex != nullptr) {
@@ -407,9 +407,9 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu
pDest->Hash = pSourceCube->Hash; // take over the hash
UnswitchTextures(pDest);
if (pSourceCube->CrossRef_D3Dtex != nullptr) {
uMod_IDirect3DCubeTexture9* cpy = pSourceCube->CrossRef_D3Dtex;
uMod_IDirect3DCubeTexture9* cpy2 = pSourceCube->CrossRef_D3Dtex;
UnswitchTextures(pSourceCube);
SwitchTextures(cpy, pDest);
SwitchTextures(cpy2, pDest);
}
}
if (pDest->CrossRef_D3Dtex != nullptr) {