mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-15 15:09:30 +00:00
remove d3dx dependency, severely improve memory usage if necessary (#19)
* basic tga/hdr image loading * bgr tga tex * convert to dds during loading doesn't work yet, fails to create textures from dds memory * remove ext member from TextureFileStruct * do not convert images, leads to weird loading problems... * use regex matching for tpf loading * convert non-RGBA images to RGBA * remove d3dx (mostly) * fix moving wrong image * move TextureFunction to module * move FileLoader to ModfileLoader module * move TextureClient to module * spaces * ifdef debug * 1.6.0 * compress images to dxt5 (bc3_unorm) to use less memory * remove unnecessary directxtex source code patch * don't move unnecessarily * only compress if mods in filesystem use up more than 400mb * use std::future to prepare to multithread image loading fails when using std::launch::async though, maybe something in the directxtex library is not thread safe * remove d3dx sdk from workflows * remove extern "C" * catch exception when saving texture * make loading async (call CoInitializeEx) * support DXGI_FORMAT_BC1_UNORM (DXT1) compressed textures without warning * don't warn for BC2 BC4 or BC5 either * update README.md
This commit is contained in:
@@ -1,186 +0,0 @@
|
||||
#include <..\header\Main.h>
|
||||
#include <filesystem>
|
||||
#include "FileLoader.h"
|
||||
#include "TpfReader.h"
|
||||
|
||||
FileLoader::FileLoader(const std::string& fileName)
|
||||
{
|
||||
file_name = std::filesystem::absolute(fileName).string();
|
||||
}
|
||||
|
||||
std::vector<TextureFileStruct> FileLoader::GetContents()
|
||||
{
|
||||
try {
|
||||
return file_name.ends_with(".tpf") ? GetTpfContents() : GetFileContents();
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
Warning("Failed to open mod file: %s\n", file_name.c_str());
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<TextureFileStruct> FileLoader::GetTpfContents()
|
||||
{
|
||||
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) {
|
||||
Warning("Failed to open tpf file: %s - %u bytes!", file_name.c_str(), buffer.size());
|
||||
return {};
|
||||
}
|
||||
zip_archive->setErrorHandlerCallback(
|
||||
[](const std::string& message, const std::string& strerror, int zip_error_code, int system_error_code) -> void {
|
||||
Message("GetTpfContents: %s %s %d %d\n", message.c_str(), strerror.c_str(), zip_error_code, system_error_code);
|
||||
});
|
||||
zip_archive->open();
|
||||
LoadEntries(*zip_archive, entries);
|
||||
zip_archive->close();
|
||||
libzippp::ZipArchive::free(zip_archive);
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
std::vector<TextureFileStruct> FileLoader::GetFileContents()
|
||||
{
|
||||
std::vector<TextureFileStruct> entries;
|
||||
|
||||
libzippp::ZipArchive zip_archive(file_name);
|
||||
zip_archive.open();
|
||||
LoadEntries(zip_archive, entries);
|
||||
zip_archive.close();
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
void ParseSimpleArchive(const libzippp::ZipArchive& archive, std::vector<TextureFileStruct>& entries)
|
||||
{
|
||||
for (const auto& entry : archive.getEntries()) {
|
||||
if (entry.isFile()) {
|
||||
//TODO: #6 - Implement regex search
|
||||
auto name = entry.getName();
|
||||
|
||||
// Remove the part before the last underscore (if any)
|
||||
size_t firstIndex = name.find_last_of('_');
|
||||
while (firstIndex != std::string::npos) {
|
||||
if (firstIndex >= entry.getName().length() - 1) {
|
||||
name = entry.getName();
|
||||
}
|
||||
else {
|
||||
name = entry.getName().substr(firstIndex + 1);
|
||||
}
|
||||
|
||||
firstIndex = name.find_last_of('_');
|
||||
}
|
||||
|
||||
// Remove the file extension (if any)
|
||||
size_t lastIndex = name.find_last_of('.');
|
||||
if (lastIndex != std::string::npos) {
|
||||
name = name.substr(0, lastIndex);
|
||||
}
|
||||
|
||||
uint32_t crc_hash;
|
||||
try {
|
||||
crc_hash = std::stoul(name, nullptr, 16);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
Warning("Failed to parse %s as a hash", name.c_str());
|
||||
continue;
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
Message("Out of range while parsing %s as a hash", name.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto data_ptr = static_cast<BYTE*>(entry.readAsBinary());
|
||||
const auto size = entry.getSize();
|
||||
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<TextureFileStruct>& entries)
|
||||
{
|
||||
for (const auto& line : lines) {
|
||||
std::istringstream iss(line);
|
||||
std::string part;
|
||||
std::vector<std::string> splits;
|
||||
|
||||
// Split the line by '|'
|
||||
while (std::getline(iss, part, '|')) {
|
||||
splits.push_back(part);
|
||||
}
|
||||
|
||||
if (splits.size() != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string addrstr = splits[0];
|
||||
std::string path = splits[1];
|
||||
|
||||
// Remove unwanted characters from the beginning of the path
|
||||
while (!path.empty() && (path[0] == '.' && (path[1] == '/' || path[1] == '\\')) || path[0] == '/' || path[0] == '\\') {
|
||||
path.erase(0, 1);
|
||||
}
|
||||
|
||||
// Remove trailing newline and carriage return characters
|
||||
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();
|
||||
}
|
||||
|
||||
const auto entry = archive.getEntry(path);
|
||||
if (entry.isNull()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry.isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t crc_hash{};
|
||||
try {
|
||||
crc_hash = std::stoul(addrstr, nullptr, 16);
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
Warning("Failed to parse %s as a hash", addrstr.c_str());
|
||||
continue;
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
Warning("Out of range while parsing %s as a hash", addrstr.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
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<TextureFileStruct>& entries)
|
||||
{
|
||||
const auto def_file = archive.getEntry("texmod.def");
|
||||
if (def_file.isNull() || !def_file.isFile()) {
|
||||
ParseSimpleArchive(archive, entries);
|
||||
}
|
||||
else {
|
||||
const auto def = def_file.readAsText();
|
||||
std::istringstream iss(def);
|
||||
std::vector<std::string> lines;
|
||||
std::string line;
|
||||
|
||||
while (std::getline(iss, line)) {
|
||||
lines.push_back(line);
|
||||
}
|
||||
|
||||
ParseTexmodArchive(lines, archive, entries);
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
for (const auto pTexture : OriginalTextures) {
|
||||
if (pTexture->CrossRef_D3Dtex == nullptr) {
|
||||
LookUpToMod(pTexture);
|
||||
}
|
||||
}
|
||||
for (const auto pTexture : OriginalVolumeTextures) {
|
||||
if (pTexture->CrossRef_D3Dtex == nullptr) {
|
||||
LookUpToMod(pTexture);
|
||||
}
|
||||
}
|
||||
for (const auto pTexture : OriginalCubeTextures) {
|
||||
if (pTexture->CrossRef_D3Dtex == nullptr) {
|
||||
LookUpToMod(pTexture);
|
||||
}
|
||||
}
|
||||
|
||||
return UnlockMutex();
|
||||
}
|
||||
|
||||
void TextureClient::SetLastCreatedTexture(uMod_IDirect3DTexture9* texture)
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedTexture(texture);
|
||||
return static_cast<uMod_IDirect3DDevice9*>(D3D9Device)->SetLastCreatedTexture(texture);
|
||||
}
|
||||
|
||||
void TextureClient::SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* texture)
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedVolumeTexture(texture);
|
||||
return static_cast<uMod_IDirect3DDevice9*>(D3D9Device)->SetLastCreatedVolumeTexture(texture);
|
||||
}
|
||||
|
||||
void TextureClient::SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* texture)
|
||||
{
|
||||
if (isDirectXExDevice)
|
||||
return static_cast<uMod_IDirect3DDevice9Ex*>(D3D9Device)->SetLastCreatedCubeTexture(texture);
|
||||
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)) {
|
||||
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(TextureFileStruct& 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;
|
||||
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();
|
||||
}
|
||||
|
||||
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()) {
|
||||
Warning("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");
|
||||
}
|
||||
+24
-28
@@ -1,15 +1,13 @@
|
||||
#include "dll_main.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include "Main.h"
|
||||
#include <Psapi.h>
|
||||
|
||||
#include "MinHook.h"
|
||||
#include <filesystem>
|
||||
|
||||
void ExitInstance();
|
||||
void InitInstance(HINSTANCE hModule);
|
||||
|
||||
namespace {
|
||||
|
||||
#define DISABLE_HOOK(var) if(var) { MH_DisableHook(var);}
|
||||
#define DISABLE_HOOK(var) if(var) { MH_DisableHook(var);}
|
||||
|
||||
using Direct3DCreate9_type = IDirect3D9* (APIENTRY*)(UINT);
|
||||
using Direct3DCreate9Ex_type = HRESULT(APIENTRY*)(UINT SDKVersion, IDirect3D9Ex** ppD3D);
|
||||
@@ -29,9 +27,8 @@ namespace {
|
||||
|
||||
HMODULE gMod_Loaded_d3d9_Module_Handle = nullptr;
|
||||
|
||||
|
||||
|
||||
HMODULE FindLoadedModuleByName(const char* name, bool include_this_module = false) {
|
||||
HMODULE FindLoadedModuleByName(const char* name, bool include_this_module = false)
|
||||
{
|
||||
HMODULE hModules[1024];
|
||||
HANDLE hProcess;
|
||||
DWORD cbNeeded;
|
||||
@@ -66,8 +63,6 @@ namespace {
|
||||
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.
|
||||
@@ -75,7 +70,7 @@ namespace {
|
||||
}
|
||||
if (!gMod_Loaded_d3d9_Module_Handle) {
|
||||
// Tried resolving d3d9.dll locally, didn't work. Try system directory
|
||||
char buffer[MAX_PATH] ;
|
||||
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
|
||||
@@ -91,30 +86,32 @@ namespace {
|
||||
|
||||
DISABLE_HOOK(GetProcAddress_fn);
|
||||
// GetProcAddress, hooked via OnGetProcAddress
|
||||
Direct3DCreate9_ret = (Direct3DCreate9_type)GetProcAddress(found, "Direct3DCreate9");
|
||||
Direct3DCreate9Ex_ret = (Direct3DCreate9Ex_type)GetProcAddress(found, "Direct3DCreate9Ex");
|
||||
Direct3DCreate9_ret = reinterpret_cast<Direct3DCreate9_type>(GetProcAddress(found, "Direct3DCreate9"));
|
||||
Direct3DCreate9Ex_ret = reinterpret_cast<Direct3DCreate9Ex_type>(GetProcAddress(found, "Direct3DCreate9Ex"));
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
FARPROC APIENTRY OnGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
|
||||
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 (strcmp(lpProcName, "Direct3DCreate9") == 0) {
|
||||
Direct3DCreate9_ret = reinterpret_cast<Direct3DCreate9_type>(GetProcAddress_ret(hModule, lpProcName));
|
||||
return reinterpret_cast<FARPROC>(Direct3DCreate9);
|
||||
}
|
||||
if (strcmp(lpProcName, "Direct3DCreate9Ex") == 0) {
|
||||
Direct3DCreate9Ex_ret = reinterpret_cast<Direct3DCreate9Ex_type>(GetProcAddress_ret(hModule, lpProcName));
|
||||
return reinterpret_cast<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() {
|
||||
void CheckLoadD3d9Dll()
|
||||
{
|
||||
if (!(Direct3DCreate9_ret && Direct3DCreate9_ret != Direct3DCreate9)) {
|
||||
ASSERT(LoadD3d9Dll());
|
||||
ASSERT(Direct3DCreate9_ret && Direct3DCreate9_ret != Direct3DCreate9);
|
||||
@@ -132,7 +129,7 @@ namespace {
|
||||
unsigned int gl_ErrorState = 0;
|
||||
HINSTANCE gl_hThisInstance = nullptr;
|
||||
|
||||
extern "C" IDirect3D9* APIENTRY Direct3DCreate9(UINT SDKVersion)
|
||||
IDirect3D9* APIENTRY Direct3DCreate9(UINT SDKVersion)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9: uMod %p\n", Direct3DCreate9);
|
||||
|
||||
@@ -150,7 +147,7 @@ extern "C" IDirect3D9* APIENTRY Direct3DCreate9(UINT SDKVersion)
|
||||
return new uMod_IDirect3D9(pIDirect3D9_orig); //return our object instead of the "real one"
|
||||
}
|
||||
|
||||
extern "C" HRESULT APIENTRY Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
HRESULT APIENTRY Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9Ex: uMod %p\n", Direct3DCreate9Ex);
|
||||
|
||||
@@ -247,4 +244,3 @@ void ExitInstance()
|
||||
__except (EXCEPTION_CONTINUE_EXECUTION) { }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "Main.h"
|
||||
|
||||
import TextureFunction;
|
||||
import TextureClient;
|
||||
|
||||
//this function yields for the non switched texture object
|
||||
HRESULT APIENTRY uMod_IDirect3DCubeTexture9::QueryInterface(REFIID riid, void** ppvObj)
|
||||
{
|
||||
@@ -260,8 +263,8 @@ HashType uMod_IDirect3DCubeTexture9::GetHash() const
|
||||
}
|
||||
}
|
||||
|
||||
const int size = (GetBitsFromFormat(desc.Format) * desc.Width * desc.Height) / 8;
|
||||
const auto hash = GetCRC32(static_cast<char*>(d3dlr.pBits), size); //calculate the crc32 of the texture
|
||||
const int size = (TextureFunction::GetBitsFromFormat(desc.Format) * desc.Width * desc.Height) / 8;
|
||||
const auto hash = TextureFunction::GetCRC32(static_cast<char*>(d3dlr.pBits), size); //calculate the crc32 of the texture
|
||||
|
||||
// Only release surfaces after we're finished with d3dlr
|
||||
if (pResolvedSurface != nullptr) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Main.h"
|
||||
import TextureClient;
|
||||
|
||||
#ifndef RETURN_QueryInterface
|
||||
#define RETURN_QueryInterface 0x01000000L
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "Main.h"
|
||||
|
||||
import TextureFunction;
|
||||
import TextureClient;
|
||||
|
||||
//this function yields for the non switched texture object
|
||||
HRESULT APIENTRY uMod_IDirect3DTexture9::QueryInterface(REFIID riid, void** ppvObj)
|
||||
{
|
||||
@@ -318,8 +321,8 @@ HashType uMod_IDirect3DTexture9::GetHash() const
|
||||
}
|
||||
}
|
||||
|
||||
const int size = (GetBitsFromFormat(desc.Format) * desc.Width * desc.Height) / 8;
|
||||
const auto hash = GetCRC32(static_cast<char*>(d3dlr.pBits), size); //calculate the crc32 of the texture
|
||||
const int size = (TextureFunction::GetBitsFromFormat(desc.Format) * desc.Width * desc.Height) / 8;
|
||||
const auto hash = TextureFunction::GetCRC32(static_cast<char*>(d3dlr.pBits), size); //calculate the crc32 of the texture
|
||||
|
||||
// Only release surfaces after we're finished with d3dlr
|
||||
if (pOffscreenSurface != nullptr) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "Main.h"
|
||||
import TextureFunction;
|
||||
import TextureClient;
|
||||
|
||||
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::QueryInterface(REFIID riid, void** ppvObj)
|
||||
{
|
||||
@@ -257,8 +259,8 @@ HashType uMod_IDirect3DVolumeTexture9::GetHash() const
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
const int size = (TextureFunction::GetBitsFromFormat(desc.Format) * desc.Width * desc.Height * desc.Depth) / 8;
|
||||
const auto hash = TextureFunction::GetCRC32(static_cast<char*>(d3dlr.pBits), size); //calculate the crc32 of the texture
|
||||
|
||||
// Only release surfaces after we're finished with d3dlr
|
||||
if (pResolvedSurface != nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user