mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-15 23:19:30 +00:00
ae2c93fc32
* remove d3dx9.dll dependency (still requires dx legacy sdk for development, but not for end users) * fix * Fix to allow gMod to be loaded as "d3d9.dll" Don't check for d3d9 functions when checking dll's, its not that deep. Fix to allow gMod to load "d3d9.dll" using the default method rather than defaulting to system directory * use d3dx sdk for wic texture loading until we figure out how to load volume/cube textures without it * fix jons commit * 1.5.7 * create warning message * pass correct pointer type, shouldn't matter but lets see * use Warning instead of Message for failed actions * need to use d3dpool_managed... * use specialised methods * actually do something in the Direct3DCreate9Ex method? * spaces * test loading WIC textures with modified WICTextureLoader9.cpp * include * Hook into GetProcAddress instead of d3d9 dll * extern "C" the Direct3DCreate9/Ex functions * turn on debug messages * add back in creating of our replacement textures, woopsies * add messages back in, not loading yet, debug later * remove SingleTexture stuff * dont rely on d3dx anymore :) * Tidied up assertion error box Added logic to use gmod as d3d9.dll or gmod.dll Added check to avoid recursive calls to create d3d9 * Remove unused func
275 lines
9.0 KiB
C++
275 lines
9.0 KiB
C++
#include "Main.h"
|
|
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::QueryInterface(REFIID riid, void** ppvObj)
|
|
{
|
|
if (riid == IID_IDirect3D9) {
|
|
// This function should never be called with IID_IDirect3D9 by the game
|
|
// thus this call comes from our own dll to ask for the texture type
|
|
// 0x01000000L == uMod_IDirect3DTexture9
|
|
// 0x01000001L == uMod_IDirect3DVolumeTexture9
|
|
// 0x01000002L == uMod_IDirect3DCubeTexture9
|
|
|
|
*ppvObj = this;
|
|
return 0x01000001L;
|
|
}
|
|
HRESULT hRes;
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
hRes = CrossRef_D3Dtex->m_D3Dtex->QueryInterface(riid, ppvObj);
|
|
if (*ppvObj == CrossRef_D3Dtex->m_D3Dtex) {
|
|
*ppvObj = this;
|
|
}
|
|
}
|
|
else {
|
|
hRes = m_D3Dtex->QueryInterface(riid, ppvObj);
|
|
if (*ppvObj == m_D3Dtex) {
|
|
*ppvObj = this;
|
|
}
|
|
}
|
|
return hRes;
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
ULONG APIENTRY uMod_IDirect3DVolumeTexture9::AddRef()
|
|
{
|
|
if (FAKE) {
|
|
return 1; //bug, this case should never happen
|
|
}
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->AddRef();
|
|
}
|
|
return m_D3Dtex->AddRef();
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
ULONG APIENTRY uMod_IDirect3DVolumeTexture9::Release()
|
|
{
|
|
Message("uMod_IDirect3DVolumeTexture9::Release(): %p\n", this);
|
|
|
|
void* cpy;
|
|
const long ret = m_D3Ddev->QueryInterface(IID_IDirect3DTexture9, &cpy);
|
|
|
|
ULONG count;
|
|
if (FAKE) {
|
|
UnswitchTextures(this);
|
|
count = m_D3Dtex->Release(); //count must be zero, cause we don't call AddRef of fake_textures
|
|
}
|
|
else {
|
|
if (CrossRef_D3Dtex != nullptr) //if this texture is switched with a fake texture
|
|
{
|
|
uMod_IDirect3DVolumeTexture9* fake_texture = CrossRef_D3Dtex;
|
|
count = fake_texture->m_D3Dtex->Release(); //release the original texture
|
|
if (count == 0) //if texture is released we switch the textures back
|
|
{
|
|
UnswitchTextures(this);
|
|
fake_texture->Release(); // we release the fake texture
|
|
}
|
|
}
|
|
else {
|
|
count = m_D3Dtex->Release();
|
|
}
|
|
}
|
|
|
|
if (count == 0) //if this texture is released, we clean up
|
|
{
|
|
// if this texture is the LastCreatedTexture, the next time LastCreatedTexture would be added,
|
|
// the hash of a non existing texture would be calculated
|
|
if (ret == 0x01000000L) {
|
|
if (static_cast<uMod_IDirect3DDevice9*>(m_D3Ddev)->GetLastCreatedVolumeTexture() == this) {
|
|
static_cast<uMod_IDirect3DDevice9*>(m_D3Ddev)->SetLastCreatedVolumeTexture(nullptr);
|
|
}
|
|
else {
|
|
static_cast<uMod_IDirect3DDevice9*>(m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client
|
|
}
|
|
}
|
|
else {
|
|
if (static_cast<uMod_IDirect3DDevice9Ex*>(m_D3Ddev)->GetLastCreatedVolumeTexture() == this) {
|
|
static_cast<uMod_IDirect3DDevice9Ex*>(m_D3Ddev)->SetLastCreatedVolumeTexture(nullptr);
|
|
}
|
|
else {
|
|
static_cast<uMod_IDirect3DDevice9Ex*>(m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client
|
|
}
|
|
}
|
|
|
|
delete this;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::GetDevice(IDirect3DDevice9** ppDevice)
|
|
{
|
|
*ppDevice = m_D3Ddev;
|
|
return D3D_OK;
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::SetPrivateData(REFGUID refguid,CONST void* pData, DWORD SizeOfData, DWORD Flags)
|
|
{
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->SetPrivateData(refguid, pData, SizeOfData, Flags);
|
|
}
|
|
return m_D3Dtex->SetPrivateData(refguid, pData, SizeOfData, Flags);
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::GetPrivateData(REFGUID refguid, void* pData, DWORD* pSizeOfData)
|
|
{
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->GetPrivateData(refguid, pData, pSizeOfData);
|
|
}
|
|
return m_D3Dtex->GetPrivateData(refguid, pData, pSizeOfData);
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::FreePrivateData(REFGUID refguid)
|
|
{
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->FreePrivateData(refguid);
|
|
}
|
|
return m_D3Dtex->FreePrivateData(refguid);
|
|
}
|
|
|
|
DWORD APIENTRY uMod_IDirect3DVolumeTexture9::SetPriority(DWORD PriorityNew)
|
|
{
|
|
return m_D3Dtex->SetPriority(PriorityNew);
|
|
}
|
|
|
|
DWORD APIENTRY uMod_IDirect3DVolumeTexture9::GetPriority()
|
|
{
|
|
return m_D3Dtex->GetPriority();
|
|
}
|
|
|
|
void APIENTRY uMod_IDirect3DVolumeTexture9::PreLoad()
|
|
{
|
|
m_D3Dtex->PreLoad();
|
|
}
|
|
|
|
D3DRESOURCETYPE APIENTRY uMod_IDirect3DVolumeTexture9::GetType()
|
|
{
|
|
return m_D3Dtex->GetType();
|
|
}
|
|
|
|
DWORD APIENTRY uMod_IDirect3DVolumeTexture9::SetLOD(DWORD LODNew)
|
|
{
|
|
return m_D3Dtex->SetLOD(LODNew);
|
|
}
|
|
|
|
DWORD APIENTRY uMod_IDirect3DVolumeTexture9::GetLOD()
|
|
{
|
|
return m_D3Dtex->GetLOD();
|
|
}
|
|
|
|
DWORD APIENTRY uMod_IDirect3DVolumeTexture9::GetLevelCount()
|
|
{
|
|
return m_D3Dtex->GetLevelCount();
|
|
}
|
|
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType)
|
|
{
|
|
return m_D3Dtex->SetAutoGenFilterType(FilterType);
|
|
}
|
|
|
|
D3DTEXTUREFILTERTYPE APIENTRY uMod_IDirect3DVolumeTexture9::GetAutoGenFilterType()
|
|
{
|
|
return m_D3Dtex->GetAutoGenFilterType();
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->AddDirtyBox(pDirtyBox);
|
|
}
|
|
return m_D3Dtex->AddDirtyBox(pDirtyBox);
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::GetLevelDesc(UINT Level, D3DVOLUME_DESC* pDesc)
|
|
{
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->GetLevelDesc(Level, pDesc);
|
|
}
|
|
return m_D3Dtex->GetLevelDesc(Level, pDesc);
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::GetVolumeLevel(UINT Level, IDirect3DVolume9** ppVolumeLevel)
|
|
{
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->GetVolumeLevel(Level, ppVolumeLevel);
|
|
}
|
|
return m_D3Dtex->GetVolumeLevel(Level, ppVolumeLevel);
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::LockBox(UINT Level, D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags)
|
|
{
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->LockBox(Level, pLockedVolume, pBox, Flags);
|
|
}
|
|
return m_D3Dtex->LockBox(Level, pLockedVolume, pBox, Flags);
|
|
}
|
|
|
|
//this function yields for the non switched texture object
|
|
HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::UnlockBox(UINT Level)
|
|
{
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
return CrossRef_D3Dtex->m_D3Dtex->UnlockBox(Level);
|
|
}
|
|
return m_D3Dtex->UnlockBox(Level);
|
|
}
|
|
|
|
HashType uMod_IDirect3DVolumeTexture9::GetHash() const
|
|
{
|
|
if (FAKE) {
|
|
return 0;
|
|
}
|
|
IDirect3DVolumeTexture9* pTexture = m_D3Dtex;
|
|
if (CrossRef_D3Dtex != nullptr) {
|
|
pTexture = CrossRef_D3Dtex->m_D3Dtex;
|
|
}
|
|
|
|
IDirect3DVolume9* pResolvedSurface = nullptr;
|
|
D3DLOCKED_BOX d3dlr;
|
|
D3DVOLUME_DESC desc;
|
|
|
|
if (pTexture->GetLevelDesc(0, &desc) != D3D_OK) //get the format and the size of the texture
|
|
{
|
|
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) {
|
|
Warning("uMod_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 1\n");
|
|
if (pTexture->GetVolumeLevel(0, &pResolvedSurface) != D3D_OK) {
|
|
Warning("uMod_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel\n");
|
|
return 0;
|
|
}
|
|
if (pResolvedSurface->LockBox(&d3dlr, nullptr, D3DLOCK_READONLY) != D3D_OK) {
|
|
pResolvedSurface->Release();
|
|
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
|
|
|
|
// Only release surfaces after we're finished with d3dlr
|
|
if (pResolvedSurface != nullptr) {
|
|
pResolvedSurface->UnlockBox();
|
|
pResolvedSurface->Release();
|
|
}
|
|
else {
|
|
pTexture->UnlockBox(0);
|
|
}
|
|
|
|
Message("uMod_IDirect3DVolumeTexture9::GetHash() %#lX (%d %d) %d = %d\n", hash, desc.Width, desc.Height, desc.Format, size);
|
|
return hash;
|
|
}
|