mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-21 01:49:31 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b49428bafd | |||
| ae2c93fc32 | |||
| a1cadde802 | |||
| 69b06d94a2 | |||
| 514aefa371 |
+5
-3
@@ -17,7 +17,7 @@ endif()
|
||||
|
||||
set(VERSION_MAJOR 1)
|
||||
set(VERSION_MINOR 5)
|
||||
set(VERSION_PATCH 6)
|
||||
set(VERSION_PATCH 8)
|
||||
set(VERSION_TWEAK 0)
|
||||
|
||||
set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc")
|
||||
@@ -50,6 +50,7 @@ endif()
|
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
include(libzippp)
|
||||
include(minhook)
|
||||
include(dxtk)
|
||||
|
||||
add_library(gMod SHARED)
|
||||
|
||||
@@ -59,10 +60,10 @@ file(GLOB SOURCES
|
||||
${VERSION_RC}
|
||||
)
|
||||
|
||||
target_include_directories(gMod PRIVATE $ENV{DXSDK_DIR}/Include)
|
||||
target_include_directories(gMod PUBLIC
|
||||
target_include_directories(gMod PRIVATE
|
||||
"header"
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
$ENV{DXSDK_DIR}/Include
|
||||
)
|
||||
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
|
||||
target_sources(gMod PRIVATE ${SOURCES})
|
||||
@@ -74,6 +75,7 @@ target_link_libraries(gMod PRIVATE
|
||||
libzippp
|
||||
psapi
|
||||
minhook
|
||||
directxtex
|
||||
)
|
||||
target_link_options(gMod PRIVATE
|
||||
"$<$<CONFIG:DEBUG>:/NODEFAULTLIB:LIBCMT>"
|
||||
|
||||
+11
-6
@@ -1,9 +1,14 @@
|
||||
Requirements:
|
||||
- The DirectX SDK (I use June 2010)
|
||||
- Visual Studio (2010+)
|
||||
(- Maybe CMake if you don't want to use Visual Studio)
|
||||
- DirectX SDK (June 2010)
|
||||
- Visual Studio 2022
|
||||
- CMake 3.16+, integrated into the Developer Powershell for VS 2022
|
||||
|
||||
Compile:
|
||||
- cmake -B build
|
||||
- cmake --open build
|
||||
- compile
|
||||
|
||||
Usage:
|
||||
Create a file in the root GuildWars folder (where gw.exe is located) called modlist.txt
|
||||
Each line in the modlist.txt is the full path to a mod you want to load (eg. D:Games\uMod\Mods\Borderless Cartography Made Easy 2015 1.3.tpf)
|
||||
uMod will load all these files on startup
|
||||
- Create a file called modlist.txt in either the Guild Wars (Gw.exe) folder, or the gMod.dll folder.
|
||||
Each line in the modlist.txt is the full path to a mod you want to load (eg. D:\uMod\Mods\Borderless Cartography Made Easy 2015 1.3.tpf)
|
||||
gMod will load all these files on startup
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
include_guard()
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
DirectXTex
|
||||
GIT_REPOSITORY https://github.com/microsoft/DirectXTex
|
||||
GIT_TAG oct2023)
|
||||
FetchContent_GetProperties(directxtex)
|
||||
if (directxtex_POPULATED)
|
||||
return()
|
||||
endif()
|
||||
|
||||
FetchContent_Populate(directxtex)
|
||||
|
||||
file(READ "${directxtex_SOURCE_DIR}/WICTextureLoader/WICTextureLoader9.cpp" FILE_CONTENT)
|
||||
string(REPLACE
|
||||
"hr = frame->GetPixelFormat(&pixelFormat);\n"
|
||||
"hr = frame->GetPixelFormat(&pixelFormat); if (pixelFormat == GUID_WICPixelFormat32bppBGR) pixelFormat = GUID_WICPixelFormat32bppBGRA;\n"
|
||||
FILE_CONTENT "${FILE_CONTENT}" )
|
||||
file(WRITE "${directxtex_SOURCE_DIR}/WICTextureLoader/WICTextureLoader9.cpp" "${FILE_CONTENT}")
|
||||
|
||||
add_library(directxtex)
|
||||
file(GLOB SOURCES
|
||||
"${directxtex_SOURCE_DIR}/DDSTextureLoader/DDSTextureLoader9.h"
|
||||
"${directxtex_SOURCE_DIR}/DDSTextureLoader/DDSTextureLoader9.cpp"
|
||||
"${directxtex_SOURCE_DIR}/WICTextureLoader/WICTextureLoader9.h"
|
||||
"${directxtex_SOURCE_DIR}/WICTextureLoader/WICTextureLoader9.cpp"
|
||||
"${directxtex_SOURCE_DIR}/DirectXTex/*.h"
|
||||
"${directxtex_SOURCE_DIR}/DirectXTex/*.cpp"
|
||||
)
|
||||
list(REMOVE_ITEM SOURCES
|
||||
"${directxtex_SOURCE_DIR}/DirectXTex/BCDirectCompute.cpp"
|
||||
)
|
||||
source_group(TREE ${directxtex_SOURCE_DIR} FILES ${SOURCES})
|
||||
target_sources(directxtex PRIVATE ${SOURCES})
|
||||
target_include_directories(directxtex PUBLIC "${directxtex_SOURCE_DIR}")
|
||||
|
||||
set_target_properties(directxtex PROPERTIES FOLDER "Dependencies/")
|
||||
@@ -7,9 +7,23 @@ using HashType = DWORD32;
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
#if 1
|
||||
#define Message(...) { printf(__VA_ARGS__); }
|
||||
#else
|
||||
#define Message(...)
|
||||
#endif
|
||||
#define Warning(...) { fprintf(stderr, __VA_ARGS__); }
|
||||
|
||||
#else
|
||||
|
||||
#define Message(...)
|
||||
#define Warning(...)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _countof
|
||||
#define _countof(arr) sizeof(arr) / sizeof(*arr)
|
||||
#endif
|
||||
|
||||
+4
-12
@@ -2,16 +2,8 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <ranges>
|
||||
#include <libzippp.h>
|
||||
|
||||
struct TpfEntry {
|
||||
std::string name;
|
||||
std::string entry;
|
||||
uint32_t crc_hash;
|
||||
std::vector<char> data;
|
||||
};
|
||||
|
||||
class FileLoader {
|
||||
std::string file_name;
|
||||
const std::string TPF_PASSWORD{
|
||||
@@ -26,13 +18,13 @@ class FileLoader {
|
||||
public:
|
||||
FileLoader(const std::string& fileName);
|
||||
|
||||
std::vector<TpfEntry> GetContents();
|
||||
std::vector<TextureFileStruct> GetContents();
|
||||
|
||||
private:
|
||||
|
||||
std::vector<TpfEntry> GetTpfContents();
|
||||
std::vector<TextureFileStruct> GetTpfContents();
|
||||
|
||||
std::vector<TpfEntry> GetFileContents();
|
||||
std::vector<TextureFileStruct> GetFileContents();
|
||||
|
||||
void LoadEntries(libzippp::ZipArchive& archive, std::vector<TpfEntry>& entries);
|
||||
void LoadEntries(libzippp::ZipArchive& archive, std::vector<TextureFileStruct>& entries);
|
||||
};
|
||||
|
||||
+2
-1
@@ -4,10 +4,11 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include "Utils.h"
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
|
||||
#include "Defines.h"
|
||||
#include "Error.h"
|
||||
|
||||
+54
-41
@@ -1,15 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "FileLoader.h"
|
||||
#include "uMod_IDirect3DTexture9.h"
|
||||
#include <DDSTextureLoader/DDSTextureLoader9.h>
|
||||
#include <WICTextureLoader/WICTextureLoader9.h>
|
||||
#include <d3dx9.h>
|
||||
|
||||
extern unsigned int gl_ErrorState;
|
||||
|
||||
struct TextureFileStruct {
|
||||
std::vector<char> data{};
|
||||
std::vector<BYTE> data{};
|
||||
HashType crc_hash = 0; // hash value
|
||||
bool is_wic_texture = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -25,7 +27,6 @@ concept uModTexturePtrPtr = uModTexturePtr<std::remove_pointer_t<T>>;
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
@@ -39,9 +40,10 @@ public:
|
||||
// called at the end AddTexture(...) and from Device->UpdateTexture(...)
|
||||
|
||||
int MergeUpdate(); //called from uMod_IDirect3DDevice9::BeginScene()
|
||||
void Initialize();
|
||||
|
||||
// Add TpfEntry data, return size of data added. 0 on failure.
|
||||
unsigned long AddFile(TpfEntry& entry);
|
||||
// Add TextureFileStruct data, return size of data added. 0 on failure.
|
||||
unsigned long AddFile(TextureFileStruct& entry);
|
||||
|
||||
std::vector<uMod_IDirect3DTexture9*> OriginalTextures;
|
||||
// stores the pointer to the uMod_IDirect3DTexture9 objects created by the game
|
||||
@@ -50,10 +52,6 @@ public:
|
||||
std::vector<uMod_IDirect3DCubeTexture9*> OriginalCubeTextures;
|
||||
// stores the pointer to the uMod_IDirect3DCubeTexture9 objects created by the game
|
||||
|
||||
D3DCOLOR FontColour;
|
||||
D3DCOLOR TextureColour;
|
||||
|
||||
void Initialize();
|
||||
|
||||
private:
|
||||
IDirect3DDevice9* D3D9Device;
|
||||
@@ -61,18 +59,15 @@ private:
|
||||
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*);
|
||||
void SetLastCreatedTexture(uMod_IDirect3DTexture9*);
|
||||
void SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9*);
|
||||
void SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9*);
|
||||
|
||||
bool should_update = false;
|
||||
|
||||
int LockMutex();
|
||||
int UnlockMutex();
|
||||
HANDLE Mutex;
|
||||
HANDLE mutex;
|
||||
|
||||
std::unordered_map<HashType, TextureFileStruct*> modded_textures;
|
||||
// array which stores the file in memory and the hash of each texture to be modded
|
||||
@@ -176,44 +171,62 @@ int TextureClient::LookUpToMod(uModTexturePtr auto pTexture)
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern HINSTANCE gl_hThisInstance;
|
||||
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<decltype(ppTexture), uMod_IDirect3DTexture9**>) {
|
||||
if (file_in_memory->is_wic_texture) {
|
||||
Warning("(%#lX)\n", file_in_memory->crc_hash);
|
||||
#if 0
|
||||
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)) {
|
||||
reinterpret_cast<IDirect3DTexture9**>(ppTexture))) {
|
||||
*ppTexture = nullptr;
|
||||
Warning("LoadWICTexture(%p, %#lX): FAILED\n", *ppTexture, file_in_memory->crc_hash);
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
D3DXIMAGE_INFO info;
|
||||
D3DXGetImageInfoFromFileInMemory(file_in_memory->data.data(), file_in_memory->data.size(), &info);
|
||||
char dllpath[MAX_PATH]{};
|
||||
GetModuleFileName(gl_hThisInstance, dllpath, MAX_PATH); //ask for name and path of this dll
|
||||
const auto dds_export_path = std::filesystem::path(dllpath).parent_path() / "d3dxout" / std::format("GW.EXE_{:X}.dds", file_in_memory->crc_hash);
|
||||
if (!std::filesystem::exists(dds_export_path)) {
|
||||
D3DXSaveTextureToFile(dds_export_path.string().c_str(), D3DXIFF_DDS, *ppTexture, nullptr);
|
||||
}
|
||||
#else
|
||||
if (D3D_OK != DirectX::CreateWICTextureFromMemoryEx(
|
||||
D3D9Device,
|
||||
file_in_memory->data.data(),
|
||||
file_in_memory->data.size(),
|
||||
0, 0, D3DPOOL_MANAGED, DirectX::WIC_LOADER_MIP_AUTOGEN,
|
||||
reinterpret_cast<IDirect3DTexture9**>(ppTexture))) {
|
||||
*ppTexture = nullptr;
|
||||
Warning("LoadWICTexture(%p, %#lX): FAILED\n", *ppTexture, file_in_memory->crc_hash);
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (D3D_OK != DirectX::CreateDDSTextureFromMemoryEx(
|
||||
D3D9Device,
|
||||
file_in_memory->data.data(),
|
||||
file_in_memory->data.size(),
|
||||
0, D3DPOOL_MANAGED, false,
|
||||
reinterpret_cast<LPDIRECT3DTEXTURE9*>(ppTexture))) {
|
||||
*ppTexture = nullptr;
|
||||
Warning("LoadDDSTexture Normal(%p, %#lX): FAILED\n", *ppTexture, file_in_memory->crc_hash);
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
if constexpr (std::same_as<decltype(ppTexture), uMod_IDirect3DTexture9**>) {
|
||||
|
||||
SetLastCreatedTexture(nullptr);
|
||||
}
|
||||
else if constexpr (std::same_as<decltype(ppTexture), uMod_IDirect3DVolumeTexture9**>) {
|
||||
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<decltype(ppTexture), uMod_IDirect3DCubeTexture9**>) {
|
||||
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;
|
||||
@@ -222,7 +235,7 @@ int TextureClient::LoadTexture(TextureFileStruct* file_in_memory, uModTexturePtr
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
template<typename T> requires uModTexturePtr<T>
|
||||
template <typename T> requires uModTexturePtr<T>
|
||||
void UnswitchTextures(T pTexture)
|
||||
{
|
||||
decltype(pTexture) CrossRef = pTexture->CrossRef_D3Dtex;
|
||||
@@ -235,8 +248,8 @@ void UnswitchTextures(T pTexture)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> requires uModTexturePtr<T>
|
||||
inline int SwitchTextures(T pTexture1, T pTexture2)
|
||||
template <typename T> requires uModTexturePtr<T>
|
||||
int SwitchTextures(T pTexture1, T pTexture2)
|
||||
{
|
||||
if (pTexture1->m_D3Ddev == pTexture2->m_D3Ddev && pTexture1->CrossRef_D3Dtex == nullptr && pTexture2->CrossRef_D3Dtex == nullptr) {
|
||||
// make cross reference
|
||||
|
||||
@@ -6,5 +6,3 @@ void InitInstance(HINSTANCE hModule);
|
||||
void ExitInstance();
|
||||
HMODULE LoadOriginalDll();
|
||||
|
||||
IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion);
|
||||
HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
#include "uMod_IDirect3DTexture9.h"
|
||||
#include "uMod_IDirect3DVolumeTexture9.h"
|
||||
#include "uMod_IDirect3DCubeTexture9.h"
|
||||
@@ -140,50 +139,31 @@ public:
|
||||
|
||||
uMod_IDirect3DTexture9* GetLastCreatedTexture() { return LastCreatedTexture; }
|
||||
|
||||
int SetLastCreatedTexture(uMod_IDirect3DTexture9* pTexture)
|
||||
void SetLastCreatedTexture(uMod_IDirect3DTexture9* pTexture)
|
||||
{
|
||||
LastCreatedTexture = pTexture;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uMod_IDirect3DVolumeTexture9* GetLastCreatedVolumeTexture() { return LastCreatedVolumeTexture; }
|
||||
|
||||
int SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* pTexture)
|
||||
void SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* pTexture)
|
||||
{
|
||||
LastCreatedVolumeTexture = pTexture;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uMod_IDirect3DCubeTexture9* GetLastCreatedCubeTexture() { return LastCreatedCubeTexture; }
|
||||
|
||||
int SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* pTexture)
|
||||
void SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* pTexture)
|
||||
{
|
||||
LastCreatedCubeTexture = pTexture;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
uMod_IDirect3DTexture9* GetSingleTexture() { return SingleTexture; }
|
||||
uMod_IDirect3DVolumeTexture9* GetSingleVolumeTexture() { return SingleVolumeTexture; }
|
||||
uMod_IDirect3DCubeTexture9* GetSingleCubeTexture() { return SingleCubeTexture; }
|
||||
|
||||
private:
|
||||
int CreateSingleTexture();
|
||||
IDirect3DDevice9* m_pIDirect3DDevice9 = nullptr;
|
||||
|
||||
int CounterSaveSingleTexture;
|
||||
uMod_IDirect3DTexture9* SingleTexture = nullptr;
|
||||
uMod_IDirect3DVolumeTexture9* SingleVolumeTexture = nullptr;
|
||||
uMod_IDirect3DCubeTexture9* SingleCubeTexture = nullptr;
|
||||
char SingleTextureMod;
|
||||
|
||||
D3DCOLOR TextureColour;
|
||||
ID3DXFont* OSD_Font;
|
||||
//D3DCOLOR FontColour;
|
||||
int BackBufferCount;
|
||||
bool NormalRendering;
|
||||
|
||||
int uMod_Reference;
|
||||
bool NormalRendering = true;
|
||||
int uMod_Reference = 1;
|
||||
|
||||
uMod_IDirect3DTexture9* LastCreatedTexture = nullptr;
|
||||
uMod_IDirect3DVolumeTexture9* LastCreatedVolumeTexture = nullptr;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
|
||||
#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, int back_buffer_count);
|
||||
@@ -162,54 +161,36 @@ public:
|
||||
|
||||
uMod_IDirect3DTexture9* GetLastCreatedTexture() { return LastCreatedTexture; }
|
||||
|
||||
int SetLastCreatedTexture(uMod_IDirect3DTexture9* pTexture)
|
||||
void SetLastCreatedTexture(uMod_IDirect3DTexture9* pTexture)
|
||||
{
|
||||
LastCreatedTexture = pTexture;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uMod_IDirect3DVolumeTexture9* GetLastCreatedVolumeTexture() { return LastCreatedVolumeTexture; }
|
||||
|
||||
int SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* pTexture)
|
||||
void SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* pTexture)
|
||||
{
|
||||
LastCreatedVolumeTexture = pTexture;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uMod_IDirect3DCubeTexture9* GetLastCreatedCubeTexture() { return LastCreatedCubeTexture; }
|
||||
|
||||
int SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* pTexture)
|
||||
void SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* pTexture)
|
||||
{
|
||||
LastCreatedCubeTexture = pTexture;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
uMod_IDirect3DTexture9* GetSingleTexture() { return SingleTexture; }
|
||||
uMod_IDirect3DVolumeTexture9* GetSingleVolumeTexture() { return SingleVolumeTexture; }
|
||||
uMod_IDirect3DCubeTexture9* GetSingleCubeTexture() { return SingleCubeTexture; }
|
||||
|
||||
private:
|
||||
int CreateSingleTexture();
|
||||
IDirect3DDevice9Ex* m_pIDirect3DDevice9Ex;
|
||||
|
||||
int CounterSaveSingleTexture;
|
||||
uMod_IDirect3DTexture9* SingleTexture;
|
||||
uMod_IDirect3DVolumeTexture9* SingleVolumeTexture;
|
||||
uMod_IDirect3DCubeTexture9* SingleCubeTexture;
|
||||
char SingleTextureMod;
|
||||
|
||||
D3DCOLOR TextureColour;
|
||||
ID3DXFont* OSD_Font;
|
||||
//D3DCOLOR FontColour;
|
||||
int BackBufferCount;
|
||||
bool NormalRendering;
|
||||
bool NormalRendering = true;
|
||||
|
||||
int uMod_Reference;
|
||||
int uMod_Reference = 1;
|
||||
|
||||
uMod_IDirect3DTexture9* LastCreatedTexture;
|
||||
uMod_IDirect3DVolumeTexture9* LastCreatedVolumeTexture;
|
||||
uMod_IDirect3DCubeTexture9* LastCreatedCubeTexture;
|
||||
uMod_IDirect3DTexture9* LastCreatedTexture = nullptr;
|
||||
uMod_IDirect3DVolumeTexture9* LastCreatedVolumeTexture = nullptr;
|
||||
uMod_IDirect3DCubeTexture9* LastCreatedCubeTexture = nullptr;
|
||||
|
||||
TextureClient* uMod_Client;
|
||||
TextureClient* uMod_Client = nullptr;
|
||||
};
|
||||
|
||||
@@ -7,11 +7,14 @@ interface uMod_IDirect3DTexture9 : public IDirect3DTexture9 {
|
||||
{
|
||||
m_D3Dtex = *ppTex; //Texture which will be displayed and will be passed to the game
|
||||
m_D3Ddev = pIDirect3DDevice9; //device pointer
|
||||
CrossRef_D3Dtex = nullptr; //cross reference
|
||||
// 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
|
||||
}
|
||||
virtual ~uMod_IDirect3DTexture9()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// callback interface
|
||||
IDirect3DTexture9* m_D3Dtex = nullptr;
|
||||
|
||||
+14
-6
@@ -1,8 +1,9 @@
|
||||
#include "Error.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <process.h>
|
||||
#include <Main.h>
|
||||
|
||||
__declspec(noreturn) void FatalAssert(
|
||||
const char *expr,
|
||||
@@ -10,13 +11,20 @@ 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 module_path[MAX_PATH]{};
|
||||
if (gl_hThisInstance) {
|
||||
GetModuleFileName(gl_hThisInstance, module_path, _countof(module_path));
|
||||
}
|
||||
if (!*module_path) {
|
||||
strcpy(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);
|
||||
char* buf = new char[len + 1];
|
||||
snprintf(buf,len + 1, fmt, expr, file, function, line);
|
||||
snprintf(buf,len + 1, fmt, module_path, expr, file, function, line);
|
||||
|
||||
MessageBox(0, "uMod Assertion", buf, MB_OK | MB_ICONERROR);
|
||||
|
||||
MessageBox(0, buf, "uMod Assertion Failure", MB_OK | MB_ICONERROR);
|
||||
|
||||
delete[] buf;
|
||||
abort();
|
||||
|
||||
+21
-20
@@ -8,25 +8,25 @@ FileLoader::FileLoader(const std::string& fileName)
|
||||
file_name = std::filesystem::absolute(fileName).string();
|
||||
}
|
||||
|
||||
std::vector<TpfEntry> FileLoader::GetContents()
|
||||
std::vector<TextureFileStruct> FileLoader::GetContents()
|
||||
{
|
||||
try {
|
||||
return file_name.ends_with(".tpf") ? GetTpfContents() : GetFileContents();
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
Message("Failed to open mod file: %s\n", file_name.c_str());
|
||||
Warning("Failed to open mod file: %s\n", file_name.c_str());
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<TpfEntry> FileLoader::GetTpfContents()
|
||||
std::vector<TextureFileStruct> FileLoader::GetTpfContents()
|
||||
{
|
||||
std::vector<TpfEntry> entries;
|
||||
std::vector<TextureFileStruct> entries;
|
||||
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());
|
||||
Warning("Failed to open tpf file: %s - %u bytes!", file_name.c_str(), buffer.size());
|
||||
return {};
|
||||
}
|
||||
zip_archive->setErrorHandlerCallback(
|
||||
@@ -41,9 +41,9 @@ std::vector<TpfEntry> FileLoader::GetTpfContents()
|
||||
return entries;
|
||||
}
|
||||
|
||||
std::vector<TpfEntry> FileLoader::GetFileContents()
|
||||
std::vector<TextureFileStruct> FileLoader::GetFileContents()
|
||||
{
|
||||
std::vector<TpfEntry> entries;
|
||||
std::vector<TextureFileStruct> entries;
|
||||
|
||||
libzippp::ZipArchive zip_archive(file_name);
|
||||
zip_archive.open();
|
||||
@@ -53,7 +53,7 @@ std::vector<TpfEntry> FileLoader::GetFileContents()
|
||||
return entries;
|
||||
}
|
||||
|
||||
void ParseSimpleArchive(const libzippp::ZipArchive& archive, std::vector<TpfEntry>& entries)
|
||||
void ParseSimpleArchive(const libzippp::ZipArchive& archive, std::vector<TextureFileStruct>& entries)
|
||||
{
|
||||
for (const auto& entry : archive.getEntries()) {
|
||||
if (entry.isFile()) {
|
||||
@@ -84,7 +84,7 @@ void ParseSimpleArchive(const libzippp::ZipArchive& archive, std::vector<TpfEntr
|
||||
crc_hash = std::stoul(name, nullptr, 16);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
Message("Failed to parse %s as a hash", name.c_str());
|
||||
Warning("Failed to parse %s as a hash", name.c_str());
|
||||
continue;
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
@@ -92,16 +92,17 @@ void ParseSimpleArchive(const libzippp::ZipArchive& archive, std::vector<TpfEntr
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto data_ptr = static_cast<char*>(entry.readAsBinary());
|
||||
const auto data_ptr = static_cast<BYTE*>(entry.readAsBinary());
|
||||
const auto size = entry.getSize();
|
||||
std::vector<char> vec;
|
||||
vec.assign(data_ptr, data_ptr + size);
|
||||
entries.emplace_back(name, entry.getName(), crc_hash, std::move(vec));
|
||||
std::vector vec(data_ptr, data_ptr + size);
|
||||
std::filesystem::path tex_name(entry.getName());
|
||||
entries.emplace_back(std::move(vec), crc_hash, tex_name.extension() != ".dds");
|
||||
delete[] data_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParseTexmodArchive(std::vector<std::string>& lines, libzippp::ZipArchive& archive, std::vector<TpfEntry>& entries)
|
||||
void ParseTexmodArchive(std::vector<std::string>& lines, libzippp::ZipArchive& archive, std::vector<TextureFileStruct>& entries)
|
||||
{
|
||||
for (const auto& line : lines) {
|
||||
std::istringstream iss(line);
|
||||
@@ -147,25 +148,25 @@ void ParseTexmodArchive(std::vector<std::string>& lines, libzippp::ZipArchive& a
|
||||
crc_hash = std::stoul(addrstr, nullptr, 16);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
Message("Failed to parse %s as a hash", addrstr.c_str());
|
||||
Warning("Failed to parse %s as a hash", addrstr.c_str());
|
||||
continue;
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
Message("Out of range while parsing %s as a hash", addrstr.c_str());
|
||||
Warning("Out of range while parsing %s as a hash", addrstr.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto data_ptr = static_cast<char*>(entry.readAsBinary());
|
||||
const auto data_ptr = static_cast<BYTE*>(entry.readAsBinary());
|
||||
const auto size = static_cast<size_t>(entry.getSize());
|
||||
std::vector vec(data_ptr, data_ptr + size);
|
||||
entries.emplace_back(addrstr, entry.getName(), crc_hash, std::move(vec));
|
||||
const auto tex_name = std::filesystem::path(entry.getName());
|
||||
entries.emplace_back(std::move(vec), crc_hash, tex_name.extension() != ".dds");
|
||||
delete[] data_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void FileLoader::LoadEntries(libzippp::ZipArchive& archive, std::vector<TpfEntry>& entries)
|
||||
void FileLoader::LoadEntries(libzippp::ZipArchive& archive, std::vector<TextureFileStruct>& entries)
|
||||
{
|
||||
// Iterate over the files in the zip archive
|
||||
const auto def_file = archive.getEntry("texmod.def");
|
||||
if (def_file.isNull() || !def_file.isFile()) {
|
||||
ParseSimpleArchive(archive, entries);
|
||||
|
||||
+14
-50
@@ -11,17 +11,14 @@ TextureClient::TextureClient(IDirect3DDevice9* 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);
|
||||
mutex = CreateMutex(nullptr, false, nullptr);
|
||||
}
|
||||
|
||||
TextureClient::~TextureClient()
|
||||
{
|
||||
Message("TextureClient::~TextureClient(): %p\n", this);
|
||||
if (Mutex != nullptr) {
|
||||
CloseHandle(Mutex);
|
||||
if (mutex != nullptr) {
|
||||
CloseHandle(mutex);
|
||||
}
|
||||
for (const auto& it : modded_textures) {
|
||||
delete it.second;
|
||||
@@ -40,24 +37,18 @@ int TextureClient::MergeUpdate()
|
||||
|
||||
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
|
||||
if (pTexture->CrossRef_D3Dtex == nullptr) {
|
||||
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
|
||||
if (pTexture->CrossRef_D3Dtex == nullptr) {
|
||||
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
|
||||
if (pTexture->CrossRef_D3Dtex == nullptr) {
|
||||
LookUpToMod(pTexture);
|
||||
}
|
||||
}
|
||||
@@ -65,61 +56,33 @@ int TextureClient::MergeUpdate()
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
uMod_IDirect3DTexture9* TextureClient::GetSingleTexture()
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->GetSingleTexture();
|
||||
//this texture must no be added twice
|
||||
return static_cast<uMod_IDirect3DDevice9*>(D3D9Device)->GetSingleTexture();
|
||||
}
|
||||
|
||||
uMod_IDirect3DVolumeTexture9* TextureClient::GetSingleVolumeTexture()
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->GetSingleVolumeTexture();
|
||||
//this texture must no be added twice
|
||||
return static_cast<uMod_IDirect3DDevice9*>(D3D9Device)->GetSingleVolumeTexture();
|
||||
}
|
||||
|
||||
uMod_IDirect3DCubeTexture9* TextureClient::GetSingleCubeTexture()
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->GetSingleCubeTexture();
|
||||
//this texture must no be added twice
|
||||
return static_cast<uMod_IDirect3DDevice9*>(D3D9Device)->GetSingleCubeTexture();
|
||||
}
|
||||
|
||||
int TextureClient::SetLastCreatedTexture(uMod_IDirect3DTexture9* texture)
|
||||
void TextureClient::SetLastCreatedTexture(uMod_IDirect3DTexture9* texture)
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedTexture(texture);
|
||||
//this texture must no be added twice
|
||||
return static_cast<uMod_IDirect3DDevice9*>(D3D9Device)->SetLastCreatedTexture(texture);
|
||||
}
|
||||
|
||||
int TextureClient::SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* texture)
|
||||
void TextureClient::SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* texture)
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedVolumeTexture(texture);
|
||||
//this texture must no be added twice
|
||||
return static_cast<uMod_IDirect3DDevice9*>(D3D9Device)->SetLastCreatedVolumeTexture(texture);
|
||||
}
|
||||
|
||||
int TextureClient::SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* texture)
|
||||
void TextureClient::SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* texture)
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedCubeTexture(texture);
|
||||
//this texture must no be added twice
|
||||
return static_cast<uMod_IDirect3DDevice9*>(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)) {
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject(mutex, 100)) {
|
||||
return RETURN_MUTEX_LOCK; //waiting 100ms, to wait infinite pass INFINITE
|
||||
}
|
||||
return RETURN_OK;
|
||||
@@ -127,13 +90,13 @@ int TextureClient::LockMutex()
|
||||
|
||||
int TextureClient::UnlockMutex()
|
||||
{
|
||||
if (ReleaseMutex(Mutex) == 0) {
|
||||
if (ReleaseMutex(mutex) == 0) {
|
||||
return RETURN_MUTEX_UNLOCK;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
unsigned long TextureClient::AddFile(TpfEntry& entry)
|
||||
unsigned long TextureClient::AddFile(TextureFileStruct& entry)
|
||||
{
|
||||
if (modded_textures.contains(entry.crc_hash)) {
|
||||
return 0;
|
||||
@@ -141,6 +104,7 @@ unsigned long TextureClient::AddFile(TpfEntry& entry)
|
||||
TextureFileStruct* texture_file_struct = new TextureFileStruct();
|
||||
texture_file_struct->data = std::move(entry.data);
|
||||
texture_file_struct->crc_hash = entry.crc_hash;
|
||||
texture_file_struct->is_wic_texture = entry.is_wic_texture;
|
||||
modded_textures.emplace(entry.crc_hash, texture_file_struct);
|
||||
should_update = true;
|
||||
return texture_file_struct->data.size();
|
||||
@@ -153,7 +117,7 @@ void TextureClient::LoadModsFromFile(const char* source)
|
||||
|
||||
std::ifstream file(source);
|
||||
if (!file.is_open()) {
|
||||
Message("LoadModsFromFile: failed to open modlist.txt for reading; aborting!!!");
|
||||
Warning("LoadModsFromFile: failed to open modlist.txt for reading; aborting!!!");
|
||||
return;
|
||||
}
|
||||
Message("Initialize: found modlist.txt. Reading\n");
|
||||
|
||||
+160
-113
@@ -1,53 +1,37 @@
|
||||
#include "dll_main.h"
|
||||
|
||||
#include <array>
|
||||
#include <Windows.h>
|
||||
#include "Main.h"
|
||||
#include <Psapi.h>
|
||||
|
||||
#include "MinHook.h"
|
||||
#include <filesystem>
|
||||
|
||||
namespace {
|
||||
|
||||
#define DISABLE_HOOK(var) if(var) { MH_DisableHook(var);}
|
||||
|
||||
using Direct3DCreate9_type = IDirect3D9* (APIENTRY*)(UINT);
|
||||
using Direct3DCreate9Ex_type = HRESULT(APIENTRY*)(UINT SDKVersion, IDirect3D9Ex** ppD3D);
|
||||
using GetProcAddress_type = FARPROC(APIENTRY*)(HMODULE, LPCSTR);
|
||||
|
||||
// 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;
|
||||
GetProcAddress_type GetProcAddress_fn = nullptr;
|
||||
GetProcAddress_type GetProcAddress_ret = nullptr;
|
||||
|
||||
/*
|
||||
* global variable which are linked external
|
||||
*/
|
||||
unsigned int gl_ErrorState = 0u;
|
||||
FILE* stdout_proxy;
|
||||
FILE* stderr_proxy;
|
||||
|
||||
// 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 gMod_Loaded_d3d9_Module_Handle = nullptr;
|
||||
|
||||
|
||||
HMODULE FindLoadedDll()
|
||||
{
|
||||
|
||||
HMODULE FindLoadedModuleByName(const char* name, bool include_this_module = false) {
|
||||
HMODULE hModules[1024];
|
||||
HANDLE hProcess;
|
||||
DWORD cbNeeded;
|
||||
@@ -58,18 +42,140 @@ namespace {
|
||||
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)) {
|
||||
if (hModules[i] == gl_hThisInstance && !include_this_module)
|
||||
continue;
|
||||
TCHAR szModuleName[MAX_PATH];
|
||||
ASSERT(GetModuleFileName(hModules[i], szModuleName, _countof(szModuleName)) > 0);
|
||||
const auto basename = strrchr(szModuleName, '\\');
|
||||
if (basename && stricmp(basename + 1, name) == 0)
|
||||
return hModules[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HMODULE LoadD3d9Dll()
|
||||
{
|
||||
HMODULE found = FindLoadedModuleByName("d3d9.dll");
|
||||
if (!found) {
|
||||
char executable_path[MAX_PATH]{};
|
||||
ASSERT(GetModuleFileName(GetModuleHandle(nullptr), executable_path, _countof(executable_path)) > 0);
|
||||
|
||||
char dll_path[MAX_PATH]{};
|
||||
ASSERT(GetModuleFileName(gl_hThisInstance, dll_path, _countof(dll_path)) > 0);
|
||||
|
||||
const auto exe_path = std::filesystem::path(executable_path);
|
||||
const auto gmod_path = std::filesystem::path(dll_path);
|
||||
|
||||
bool successful_load = false;
|
||||
|
||||
if (exe_path.parent_path() != gmod_path.parent_path()
|
||||
|| gmod_path.filename() != "d3d9.dll") {
|
||||
// Call basic LoadLibrary function; we're not in the same directory as the exe.
|
||||
gMod_Loaded_d3d9_Module_Handle = LoadLibrary("d3d9.dll");
|
||||
}
|
||||
if (!gMod_Loaded_d3d9_Module_Handle) {
|
||||
// Tried resolving d3d9.dll locally, didn't work. Try system directory
|
||||
char buffer[MAX_PATH] ;
|
||||
ASSERT(GetSystemDirectory(buffer, _countof(buffer)) > 0); //get the system directory, we need to open the original d3d9.dll
|
||||
|
||||
// Append dll name
|
||||
strcat_s(buffer, _countof(buffer), "\\d3d9.dll");
|
||||
gMod_Loaded_d3d9_Module_Handle = LoadLibrary(buffer);
|
||||
}
|
||||
|
||||
ASSERT(gMod_Loaded_d3d9_Module_Handle);
|
||||
|
||||
found = FindLoadedModuleByName("d3d9.dll");
|
||||
ASSERT(found && found == gMod_Loaded_d3d9_Module_Handle);
|
||||
}
|
||||
|
||||
DISABLE_HOOK(GetProcAddress_fn);
|
||||
// GetProcAddress, hooked via OnGetProcAddress
|
||||
Direct3DCreate9_ret = (Direct3DCreate9_type)GetProcAddress(found, "Direct3DCreate9");
|
||||
Direct3DCreate9Ex_ret = (Direct3DCreate9Ex_type)GetProcAddress(found, "Direct3DCreate9Ex");
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
FARPROC APIENTRY OnGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
|
||||
ASSERT(GetProcAddress_ret);
|
||||
if ((int)lpProcName < 0xffff)
|
||||
return GetProcAddress_ret(hModule, lpProcName); // lpProcName is ordinal offset, not string
|
||||
|
||||
if (strcmp(lpProcName, "Direct3DCreate9") == 0) {
|
||||
Direct3DCreate9_ret = (Direct3DCreate9_type)GetProcAddress_ret(hModule, lpProcName);
|
||||
return (FARPROC)Direct3DCreate9;
|
||||
}
|
||||
if (strcmp(lpProcName, "Direct3DCreate9Ex") == 0) {
|
||||
Direct3DCreate9Ex_ret = (Direct3DCreate9Ex_type)GetProcAddress_ret(hModule, lpProcName);
|
||||
return (FARPROC)Direct3DCreate9Ex;
|
||||
}
|
||||
return GetProcAddress_ret(hModule, lpProcName);
|
||||
}
|
||||
|
||||
// If the original d3d9 function is nullptr or points to gMod, load the actual d3d9 dll and redirect the addresses
|
||||
void CheckLoadD3d9Dll() {
|
||||
if (!(Direct3DCreate9_ret && Direct3DCreate9_ret != Direct3DCreate9)) {
|
||||
ASSERT(LoadD3d9Dll());
|
||||
ASSERT(Direct3DCreate9_ret && Direct3DCreate9_ret != Direct3DCreate9);
|
||||
}
|
||||
if (!(Direct3DCreate9Ex_ret && Direct3DCreate9Ex_ret != Direct3DCreate9Ex)) {
|
||||
ASSERT(LoadD3d9Dll());
|
||||
ASSERT(Direct3DCreate9Ex_ret && Direct3DCreate9Ex_ret != Direct3DCreate9Ex);
|
||||
}
|
||||
}
|
||||
|
||||
// There may be a sitation where more than 1 gmod is loaded; avoid recursions!
|
||||
bool creating_d3d9 = false;
|
||||
}
|
||||
|
||||
unsigned int gl_ErrorState = 0;
|
||||
HINSTANCE gl_hThisInstance = nullptr;
|
||||
|
||||
extern "C" IDirect3D9* APIENTRY Direct3DCreate9(UINT SDKVersion)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9: uMod %p\n", Direct3DCreate9);
|
||||
|
||||
ASSERT(!creating_d3d9);
|
||||
creating_d3d9 = true;
|
||||
|
||||
DISABLE_HOOK(GetProcAddress_fn);
|
||||
CheckLoadD3d9Dll();
|
||||
|
||||
IDirect3D9* pIDirect3D9_orig = Direct3DCreate9_ret(SDKVersion); //creating the original IDirect3D9 object
|
||||
ASSERT(pIDirect3D9_orig);
|
||||
|
||||
creating_d3d9 = false;
|
||||
|
||||
return new uMod_IDirect3D9(pIDirect3D9_orig); //return our object instead of the "real one"
|
||||
}
|
||||
|
||||
extern "C" HRESULT APIENTRY Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9Ex: uMod %p\n", Direct3DCreate9Ex);
|
||||
|
||||
ASSERT(!creating_d3d9);
|
||||
creating_d3d9 = true;
|
||||
|
||||
|
||||
DISABLE_HOOK(GetProcAddress_fn);
|
||||
CheckLoadD3d9Dll();
|
||||
|
||||
IDirect3D9Ex* pIDirect3D9Ex_orig = nullptr;
|
||||
HRESULT ret = Direct3DCreate9Ex_ret(SDKVersion, &pIDirect3D9Ex_orig); //creating the original IDirect3D9 object
|
||||
|
||||
creating_d3d9 = false;
|
||||
|
||||
if (ret != S_OK)
|
||||
return ret;
|
||||
|
||||
// @Cleanup: should be we freeing pIDirect3D9Ex at the end of our own lifecycle?
|
||||
const auto pIDirect3D9Ex = new uMod_IDirect3D9Ex(pIDirect3D9Ex_orig);
|
||||
// original umod does not do this for some reason
|
||||
*ppD3D = static_cast<IDirect3D9Ex*>(pIDirect3D9Ex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* dll entry routine, here we initialize or clean up
|
||||
*/
|
||||
@@ -80,10 +186,10 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
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);
|
||||
AllocConsole();
|
||||
SetConsoleTitleA("gMod Console");
|
||||
freopen_s(&stdout_proxy, "CONOUT$", "w", stdout);
|
||||
freopen_s(&stderr_proxy, "CONOUT$", "w", stderr);
|
||||
#endif
|
||||
InitInstance(hModule);
|
||||
break;
|
||||
@@ -100,104 +206,45 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
|
||||
void InitInstance(HINSTANCE hModule)
|
||||
{
|
||||
DisableThreadLibraryCalls(hModule); //reduce overhead
|
||||
gl_hThisInstance = hModule;
|
||||
Message("InitInstance: %p\n", hModule);
|
||||
DisableThreadLibraryCalls(hModule); //reduce overhead
|
||||
|
||||
const auto d3d9_dll = LoadOriginalDll();
|
||||
ASSERT(d3d9_dll);
|
||||
// Store the handle to this module
|
||||
gl_hThisInstance = hModule;
|
||||
|
||||
Direct3DCreate9_fn = reinterpret_cast<Direct3DCreate9_type>(GetProcAddress(d3d9_dll, "Direct3DCreate9"));
|
||||
ASSERT(Direct3DCreate9_fn);
|
||||
|
||||
Direct3DCreate9Ex_fn = reinterpret_cast<Direct3DCreate9Ex_type>(GetProcAddress(d3d9_dll, "Direct3DCreate9Ex"));
|
||||
ASSERT(Direct3DCreate9Ex_fn);
|
||||
// d3d9.dll shouldn't be loaded at this point.
|
||||
const auto d3d9_loaded = FindLoadedModuleByName("d3d9.dll");
|
||||
ASSERT(!d3d9_loaded);
|
||||
|
||||
MH_Initialize();
|
||||
|
||||
if (Direct3DCreate9_fn) {
|
||||
MH_CreateHook(Direct3DCreate9_fn, uMod_Direct3DCreate9, (void**)&Direct3DCreate9_ret);
|
||||
MH_EnableHook(Direct3DCreate9_fn);
|
||||
// Hook into LoadLibraryA - we'll do our hooks on the flip side
|
||||
GetProcAddress_fn = reinterpret_cast<GetProcAddress_type>(GetProcAddress);
|
||||
ASSERT(GetProcAddress_fn);
|
||||
if (GetProcAddress_fn) {
|
||||
MH_CreateHook(GetProcAddress_fn, OnGetProcAddress, (void**)&GetProcAddress_ret);
|
||||
MH_EnableHook(GetProcAddress_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);
|
||||
DISABLE_HOOK(GetProcAddress_fn);
|
||||
|
||||
MH_Uninitialize();
|
||||
|
||||
// Release the system's d3d9.dll
|
||||
if (gl_hOriginalDll != nullptr) {
|
||||
FreeLibrary(gl_hOriginalDll);
|
||||
gl_hOriginalDll = nullptr;
|
||||
}
|
||||
if (gMod_Loaded_d3d9_Module_Handle)
|
||||
FreeLibrary(gMod_Loaded_d3d9_Module_Handle);
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (stdout_proxy)
|
||||
fclose(stdout_proxy);
|
||||
if (stderr_proxy)
|
||||
fclose(stderr_proxy);
|
||||
FreeConsole();
|
||||
__try {
|
||||
FreeConsole();
|
||||
}
|
||||
__except (EXCEPTION_CONTINUE_EXECUTION) { }
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -62,16 +62,7 @@ ULONG APIENTRY uMod_IDirect3DCubeTexture9::Release()
|
||||
if (count == 0) //if texture is released we switch the textures back
|
||||
{
|
||||
UnswitchTextures(this);
|
||||
if (ret == 0x01000000L) {
|
||||
if (static_cast<uMod_IDirect3DDevice9*>(m_D3Ddev)->GetSingleCubeTexture() != fake_texture) {
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (static_cast<uMod_IDirect3DDevice9Ex*>(m_D3Ddev)->GetSingleCubeTexture() != fake_texture) {
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -233,8 +224,6 @@ HRESULT APIENTRY uMod_IDirect3DCubeTexture9::UnlockRect(D3DCUBEMAP_FACES FaceTyp
|
||||
return m_D3Dtex->UnlockRect(FaceType, Level);
|
||||
}
|
||||
|
||||
|
||||
|
||||
HashType uMod_IDirect3DCubeTexture9::GetHash() const
|
||||
{
|
||||
if (FAKE) {
|
||||
@@ -251,7 +240,7 @@ HashType uMod_IDirect3DCubeTexture9::GetHash() const
|
||||
|
||||
if (pTexture->GetLevelDesc(0, &desc) != D3D_OK) //get the format and the size of the texture
|
||||
{
|
||||
Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetLevelDesc \n");
|
||||
Warning("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetLevelDesc \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -259,14 +248,14 @@ HashType uMod_IDirect3DCubeTexture9::GetHash() const
|
||||
|
||||
if (pTexture->LockRect(D3DCUBEMAP_FACE_POSITIVE_X, 0, &d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK)
|
||||
{
|
||||
Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: LockRect 1\n");
|
||||
Warning("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");
|
||||
Warning("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetSurfaceLevel\n");
|
||||
return 0;
|
||||
}
|
||||
if (pResolvedSurface->LockRect(&d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) {
|
||||
pResolvedSurface->Release();
|
||||
Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: LockRect 2\n");
|
||||
Warning("uMod_IDirect3DCubeTexture9::GetHash() Failed: LockRect 2\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,128 +8,15 @@
|
||||
#define PRE_MESSAGE "uMod_IDirect3DDevice9"
|
||||
#endif
|
||||
|
||||
|
||||
int uMod_IDirect3DDevice9::CreateSingleTexture()
|
||||
{
|
||||
if (SingleTexture != nullptr && SingleVolumeTexture != nullptr && SingleCubeTexture != nullptr && TextureColour == uMod_Client->TextureColour) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
TextureColour = uMod_Client->TextureColour;
|
||||
if (SingleTexture == nullptr) //create texture
|
||||
{
|
||||
if (D3D_OK != CreateTexture(8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DTexture9**)&SingleTexture, nullptr)) {
|
||||
Message(PRE_MESSAGE "::CreateSingleTexture(): CreateTexture Failed\n");
|
||||
SingleTexture = nullptr;
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
LastCreatedTexture = nullptr; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture
|
||||
SingleTexture->FAKE = true; //this is no texture created from by game
|
||||
}
|
||||
|
||||
{
|
||||
D3DLOCKED_RECT d3dlr;
|
||||
IDirect3DTexture9* pD3Dtex = SingleTexture->m_D3Dtex;
|
||||
|
||||
if (D3D_OK != pD3Dtex->LockRect(0, &d3dlr, nullptr, 0)) {
|
||||
Message(PRE_MESSAGE "::CreateSingleTexture(): LockRect Failed\n");
|
||||
SingleTexture->Release();
|
||||
SingleTexture = nullptr;
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
const auto pDst = static_cast<DWORD*>(d3dlr.pBits);
|
||||
|
||||
for (int i = 0; i < 8 * 8; i++) {
|
||||
pDst[i] = TextureColour;
|
||||
}
|
||||
pD3Dtex->UnlockRect(0);
|
||||
}
|
||||
|
||||
if (SingleVolumeTexture == nullptr) //create texture
|
||||
{
|
||||
if (D3D_OK != CreateVolumeTexture(8, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DVolumeTexture9**)&SingleVolumeTexture, nullptr)) {
|
||||
Message(PRE_MESSAGE "::CreateSingleTexture(): CreateVolumeTexture Failed\n");
|
||||
SingleVolumeTexture = nullptr;
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
LastCreatedVolumeTexture = nullptr; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture
|
||||
SingleVolumeTexture->FAKE = true; //this is no texture created from by game
|
||||
}
|
||||
|
||||
{
|
||||
D3DLOCKED_BOX d3dlr;
|
||||
IDirect3DVolumeTexture9* pD3Dtex = SingleVolumeTexture->m_D3Dtex;
|
||||
//LockBox)(UINT Level, D3DLOCKED_BOX *pLockedVolume, CONST D3DBOX *pBox,
|
||||
if (D3D_OK != pD3Dtex->LockBox(0, &d3dlr, nullptr, 0)) {
|
||||
Message(PRE_MESSAGE "::CreateSingleTexture(): LockBox Failed\n");
|
||||
SingleVolumeTexture->Release();
|
||||
SingleVolumeTexture = nullptr;
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
const auto pDst = static_cast<DWORD*>(d3dlr.pBits);
|
||||
|
||||
for (int i = 0; i < 8 * 8 * 8; i++) {
|
||||
pDst[i] = TextureColour;
|
||||
}
|
||||
pD3Dtex->UnlockBox(0);
|
||||
}
|
||||
if (SingleCubeTexture == nullptr) //create texture
|
||||
{
|
||||
if (D3D_OK != CreateCubeTexture(8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DCubeTexture9**)&SingleCubeTexture, nullptr)) {
|
||||
Message(PRE_MESSAGE "::CreateSingleTexture(): CreateCubeTexture Failed\n");
|
||||
SingleCubeTexture = nullptr;
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
LastCreatedCubeTexture = nullptr; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture
|
||||
SingleCubeTexture->FAKE = true; //this is no texture created from by game
|
||||
}
|
||||
|
||||
{
|
||||
D3DLOCKED_RECT d3dlr;
|
||||
IDirect3DCubeTexture9* pD3Dtex = SingleCubeTexture->m_D3Dtex;
|
||||
|
||||
for (int c = 0; c < 6; c++) {
|
||||
if (D3D_OK != pD3Dtex->LockRect(static_cast<D3DCUBEMAP_FACES>(c), 0, &d3dlr, nullptr, 0)) {
|
||||
Message(PRE_MESSAGE "::CreateSingleTexture(): LockRect (Cube) Failed\n");
|
||||
SingleCubeTexture->Release();
|
||||
SingleCubeTexture = nullptr;
|
||||
return RETURN_TEXTURE_NOT_LOADED;
|
||||
}
|
||||
const auto pDst = static_cast<DWORD*>(d3dlr.pBits);
|
||||
|
||||
for (int i = 0; i < 8 * 8; i++) {
|
||||
pDst[i] = TextureColour;
|
||||
}
|
||||
pD3Dtex->UnlockRect(static_cast<D3DCUBEMAP_FACES>(c), 0);
|
||||
}
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uMod_IDirect3DDevice9::uMod_IDirect3DDevice9(IDirect3DDevice9* pOriginal, int back_buffer_count)
|
||||
{
|
||||
Message(PRE_MESSAGE "::" PRE_MESSAGE " (%p): %p\n", pOriginal, this);
|
||||
|
||||
BackBufferCount = back_buffer_count;
|
||||
NormalRendering = true;
|
||||
|
||||
uMod_Client = new TextureClient(this); //get a new texture client for this device
|
||||
uMod_Client->Initialize();
|
||||
|
||||
LastCreatedTexture = nullptr;
|
||||
LastCreatedVolumeTexture = nullptr;
|
||||
LastCreatedCubeTexture = nullptr;
|
||||
m_pIDirect3DDevice9 = pOriginal; // store the pointer to original object
|
||||
TextureColour = D3DCOLOR_ARGB(255, 0, 255, 0);
|
||||
|
||||
CounterSaveSingleTexture = -20;
|
||||
|
||||
SingleTextureMod = 0;
|
||||
SingleTexture = nullptr;
|
||||
SingleVolumeTexture = nullptr;
|
||||
SingleCubeTexture = nullptr;
|
||||
OSD_Font = nullptr;
|
||||
uMod_Reference = 1;
|
||||
}
|
||||
|
||||
uMod_IDirect3DDevice9::~uMod_IDirect3DDevice9()
|
||||
@@ -172,23 +59,8 @@ ULONG uMod_IDirect3DDevice9::Release()
|
||||
// we must not release the fake textures, cause they are released if the target textures are released
|
||||
// and the target textures are released by the game.
|
||||
|
||||
if (SingleTexture != nullptr) {
|
||||
SingleTexture->Release(); //this is the only texture we must release by ourself
|
||||
}
|
||||
if (SingleVolumeTexture != nullptr) {
|
||||
SingleVolumeTexture->Release(); //this is the only texture we must release by ourself
|
||||
}
|
||||
if (SingleCubeTexture != nullptr) {
|
||||
SingleCubeTexture->Release(); //this is the only texture we must release by ourself
|
||||
}
|
||||
if (OSD_Font != nullptr) {
|
||||
OSD_Font->Release();
|
||||
}
|
||||
|
||||
delete uMod_Client; //must be deleted at the end, because other releases might call a function of this object
|
||||
uMod_Client = nullptr;
|
||||
SingleTexture = nullptr;
|
||||
OSD_Font = nullptr;
|
||||
}
|
||||
|
||||
const ULONG count = m_pIDirect3DDevice9->Release();
|
||||
@@ -271,10 +143,6 @@ UINT uMod_IDirect3DDevice9::GetNumberOfSwapChains()
|
||||
|
||||
HRESULT uMod_IDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters)
|
||||
{
|
||||
if (OSD_Font != nullptr) {
|
||||
OSD_Font->Release();
|
||||
OSD_Font = nullptr;
|
||||
} //the game will crashes if the font is not released before the game is minimized!
|
||||
return m_pIDirect3DDevice9->Reset(pPresentationParameters);
|
||||
}
|
||||
|
||||
@@ -311,23 +179,18 @@ void uMod_IDirect3DDevice9::GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP* pRamp)
|
||||
HRESULT uMod_IDirect3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle)
|
||||
{
|
||||
//create real texture
|
||||
//Message("uMod_IDirect3DDevice9::CreateTexture()\n");
|
||||
Message("uMod_IDirect3DDevice9::CreateTexture()\n");
|
||||
const HRESULT ret = m_pIDirect3DDevice9->CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle);
|
||||
if (ret != D3D_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
//create fake texture
|
||||
const auto texture = new uMod_IDirect3DTexture9(ppTexture, this);
|
||||
if (texture) {
|
||||
*ppTexture = texture;
|
||||
}
|
||||
*ppTexture = texture;
|
||||
|
||||
if (LastCreatedTexture != nullptr) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
|
||||
if (LastCreatedTexture != nullptr && uMod_Client != nullptr) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
|
||||
{
|
||||
if (uMod_Client != nullptr) {
|
||||
uMod_Client->AddTexture(LastCreatedTexture);
|
||||
}
|
||||
uMod_Client->AddTexture(LastCreatedTexture);
|
||||
}
|
||||
LastCreatedTexture = texture;
|
||||
return ret;
|
||||
@@ -336,7 +199,7 @@ HRESULT uMod_IDirect3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Level
|
||||
HRESULT uMod_IDirect3DDevice9::CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle)
|
||||
{
|
||||
//create real texture
|
||||
//Message("uMod_IDirect3DDevice9::CreateVolumeTexture()\n");
|
||||
Message("uMod_IDirect3DDevice9::CreateVolumeTexture()\n");
|
||||
const HRESULT ret = m_pIDirect3DDevice9->CreateVolumeTexture(Width, Height, Depth, Levels, Usage, Format, Pool, ppVolumeTexture, pSharedHandle);
|
||||
if (ret != D3D_OK) {
|
||||
return ret;
|
||||
@@ -344,15 +207,11 @@ HRESULT uMod_IDirect3DDevice9::CreateVolumeTexture(UINT Width, UINT Height, UINT
|
||||
|
||||
//create fake texture
|
||||
const auto texture = new uMod_IDirect3DVolumeTexture9(ppVolumeTexture, this);
|
||||
if (texture) {
|
||||
*ppVolumeTexture = texture;
|
||||
}
|
||||
*ppVolumeTexture = texture;
|
||||
|
||||
if (LastCreatedVolumeTexture != nullptr) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
|
||||
if (LastCreatedVolumeTexture != nullptr && uMod_Client != nullptr) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
|
||||
{
|
||||
if (uMod_Client != nullptr) {
|
||||
uMod_Client->AddTexture(LastCreatedVolumeTexture);
|
||||
}
|
||||
uMod_Client->AddTexture(LastCreatedVolumeTexture);
|
||||
}
|
||||
LastCreatedVolumeTexture = texture;
|
||||
return ret;
|
||||
@@ -361,7 +220,7 @@ HRESULT uMod_IDirect3DDevice9::CreateVolumeTexture(UINT Width, UINT Height, UINT
|
||||
HRESULT uMod_IDirect3DDevice9::CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle)
|
||||
{
|
||||
//create real texture
|
||||
//Message("uMod_IDirect3DDevice9::CreateCubeTexture()\n");
|
||||
Message("uMod_IDirect3DDevice9::CreateCubeTexture()\n");
|
||||
const HRESULT ret = m_pIDirect3DDevice9->CreateCubeTexture(EdgeLength, Levels, Usage, Format, Pool, ppCubeTexture, pSharedHandle);
|
||||
if (ret != D3D_OK) {
|
||||
return ret;
|
||||
@@ -369,15 +228,11 @@ HRESULT uMod_IDirect3DDevice9::CreateCubeTexture(UINT EdgeLength, UINT Levels, D
|
||||
|
||||
//create fake texture
|
||||
const auto texture = new uMod_IDirect3DCubeTexture9(ppCubeTexture, this);
|
||||
if (texture) {
|
||||
*ppCubeTexture = texture;
|
||||
}
|
||||
*ppCubeTexture = texture;
|
||||
|
||||
if (LastCreatedCubeTexture != nullptr) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
|
||||
if (LastCreatedCubeTexture != nullptr && uMod_Client != nullptr) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
|
||||
{
|
||||
if (uMod_Client != nullptr) {
|
||||
uMod_Client->AddTexture(LastCreatedCubeTexture);
|
||||
}
|
||||
uMod_Client->AddTexture(LastCreatedCubeTexture);
|
||||
}
|
||||
LastCreatedCubeTexture = texture;
|
||||
return ret;
|
||||
|
||||
@@ -62,16 +62,7 @@ ULONG APIENTRY uMod_IDirect3DTexture9::Release()
|
||||
if (count == 0) //if texture is released we switch the textures back
|
||||
{
|
||||
UnswitchTextures(this);
|
||||
if (ret == 0x01000000L) {
|
||||
if (static_cast<uMod_IDirect3DDevice9*>(m_D3Ddev)->GetSingleTexture() != fake_texture) {
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (static_cast<uMod_IDirect3DDevice9Ex*>(m_D3Ddev)->GetSingleTexture() != fake_texture) {
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -252,7 +243,7 @@ HashType uMod_IDirect3DTexture9::GetHash() const
|
||||
|
||||
if (pTexture->GetLevelDesc(0, &desc) != D3D_OK) //get the format and the size of the texture
|
||||
{
|
||||
Message("uMod_IDirect3DTexture9::GetHash() Failed: GetLevelDesc \n");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: GetLevelDesc \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -265,7 +256,7 @@ HashType uMod_IDirect3DTexture9::GetHash() const
|
||||
|
||||
IDirect3DSurface9* pSurfaceLevel_orig = nullptr;
|
||||
if (pTexture->GetSurfaceLevel(0, &pSurfaceLevel_orig) != D3D_OK) {
|
||||
Message("uMod_IDirect3DTexture9::GetHash() Failed: GetSurfaceLevel 1 (D3DPOOL_DEFAULT)\n");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: GetSurfaceLevel 1 (D3DPOOL_DEFAULT)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -273,12 +264,12 @@ HashType uMod_IDirect3DTexture9::GetHash() const
|
||||
//Message("uMod_IDirect3DTexture9::GetHash() MultiSampleType\n");
|
||||
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");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n");
|
||||
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");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: StretchRect (D3DPOOL_DEFAULT)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -290,7 +281,7 @@ HashType uMod_IDirect3DTexture9::GetHash() const
|
||||
if (pResolvedSurface != nullptr) {
|
||||
pResolvedSurface->Release();
|
||||
}
|
||||
Message("uMod_IDirect3DTexture9::GetHash() Failed: CreateOffscreenPlainSurface (D3DPOOL_DEFAULT)\n");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: CreateOffscreenPlainSurface (D3DPOOL_DEFAULT)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -300,7 +291,7 @@ HashType uMod_IDirect3DTexture9::GetHash() const
|
||||
pResolvedSurface->Release();
|
||||
}
|
||||
pOffscreenSurface->Release();
|
||||
Message("uMod_IDirect3DTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n");
|
||||
return 0;
|
||||
}
|
||||
pSurfaceLevel_orig->Release();
|
||||
@@ -310,19 +301,19 @@ HashType uMod_IDirect3DTexture9::GetHash() const
|
||||
pResolvedSurface->Release();
|
||||
}
|
||||
pOffscreenSurface->Release();
|
||||
Message("uMod_IDirect3DTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (pTexture->LockRect(0, &d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) {
|
||||
Message("uMod_IDirect3DTexture9::GetHash() Failed: LockRect 1\n");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: LockRect 1\n");
|
||||
if (pTexture->GetSurfaceLevel(0, &pResolvedSurface) != D3D_OK) {
|
||||
Message("uMod_IDirect3DTexture9::GetHash() Failed: GetSurfaceLevel\n");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: GetSurfaceLevel\n");
|
||||
return 0;
|
||||
}
|
||||
if (pResolvedSurface->LockRect(&d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) {
|
||||
pResolvedSurface->Release();
|
||||
Message("uMod_IDirect3DTexture9::GetHash() Failed: LockRect 2\n");
|
||||
Warning("uMod_IDirect3DTexture9::GetHash() Failed: LockRect 2\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,16 +61,7 @@ ULONG APIENTRY uMod_IDirect3DVolumeTexture9::Release()
|
||||
if (count == 0) //if texture is released we switch the textures back
|
||||
{
|
||||
UnswitchTextures(this);
|
||||
if (ret == 0x01000000L) {
|
||||
if (static_cast<uMod_IDirect3DDevice9*>(m_D3Ddev)->GetSingleVolumeTexture() != fake_texture) {
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (static_cast<uMod_IDirect3DDevice9Ex*>(m_D3Ddev)->GetSingleVolumeTexture() != fake_texture) {
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
fake_texture->Release(); // we release the fake texture
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -187,8 +178,6 @@ void APIENTRY uMod_IDirect3DVolumeTexture9::GenerateMipSubLevels()
|
||||
m_D3Dtex->GenerateMipSubLevels();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//this function yields for the non switched texture object
|
||||
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::AddDirtyBox(CONST D3DBOX* pDirtyBox)
|
||||
{
|
||||
@@ -234,7 +223,6 @@ HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::UnlockBox(UINT Level)
|
||||
return m_D3Dtex->UnlockBox(Level);
|
||||
}
|
||||
|
||||
|
||||
HashType uMod_IDirect3DVolumeTexture9::GetHash() const
|
||||
{
|
||||
if (FAKE) {
|
||||
@@ -251,26 +239,24 @@ HashType uMod_IDirect3DVolumeTexture9::GetHash() const
|
||||
|
||||
if (pTexture->GetLevelDesc(0, &desc) != D3D_OK) //get the format and the size of the texture
|
||||
{
|
||||
Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetLevelDesc \n");
|
||||
Warning("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetLevelDesc \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Message("uMod_IDirect3DVolumeTexture9::GetHash() (%d %d %d) %d\n", desc.Width, desc.Height, desc.Depth, desc.Format);
|
||||
if (pTexture->LockBox(0, &d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) {
|
||||
Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 1\n");
|
||||
Warning("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 1\n");
|
||||
if (pTexture->GetVolumeLevel(0, &pResolvedSurface) != D3D_OK) {
|
||||
Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel\n");
|
||||
Warning("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel\n");
|
||||
return 0;
|
||||
}
|
||||
if (pResolvedSurface->LockBox(&d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) {
|
||||
pResolvedSurface->Release();
|
||||
Message("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 2\n");
|
||||
Warning("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 2\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const int size = (GetBitsFromFormat(desc.Format) * desc.Width * desc.Height * desc.Depth) / 8;
|
||||
const auto hash = GetCRC32(static_cast<char*>(d3dlr.pBits), size); //calculate the crc32 of the texture
|
||||
|
||||
|
||||
Reference in New Issue
Block a user