Improvements:

- Support for Volume and Cube textures.
This commit is contained in:
code@koerner-de.net
2011-11-07 19:39:35 +00:00
parent 202c90d9db
commit 7e1a8a72b4
22 changed files with 2293 additions and 486 deletions
+6
View File
@@ -8,13 +8,19 @@ OTM_DX9/OTM_DX9_dll_NO_INJECTION.def -text
OTM_DX9/OTM_Defines.h -text
OTM_DX9/OTM_IDirect3D9.cpp -text
OTM_DX9/OTM_IDirect3D9.h -text
OTM_DX9/OTM_IDirect3DCubeTexture9.cpp -text
OTM_DX9/OTM_IDirect3DCubeTexture9.h -text
OTM_DX9/OTM_IDirect3DDevice9.cpp -text
OTM_DX9/OTM_IDirect3DDevice9.h -text
OTM_DX9/OTM_IDirect3DTexture9.cpp -text
OTM_DX9/OTM_IDirect3DTexture9.h -text
OTM_DX9/OTM_IDirect3DVolumeTexture9.cpp -text
OTM_DX9/OTM_IDirect3DVolumeTexture9.h -text
OTM_DX9/OTM_Main.h -text
OTM_DX9/OTM_TextureClient.cpp -text
OTM_DX9/OTM_TextureClient.h -text
OTM_DX9/OTM_TextureFunction.cpp -text
OTM_DX9/OTM_TextureFunction.h -text
OTM_DX9/OTM_TextureServer.cpp -text
OTM_DX9/OTM_TextureServer.h -text
OTM_DX9/makefile.gcc -text
-111
View File
@@ -104,114 +104,3 @@ int OTM_FileHandler::Remove(TextureFileStruct* file)
return (RETURN_OK);
}
OTM_TextureHandler::OTM_TextureHandler(void)
{
Message("OTM_TextureHandler(void): %lu\n", this);
Number = 0;
FieldCounter = 0;
Textures = NULL;
}
OTM_TextureHandler::~OTM_TextureHandler(void)
{
Message("~OTM_TextureHandler(void): %lu\n", this);
if (Textures!=NULL)
{
for (int i=0; i<FieldCounter; i++) if (Textures[i] != NULL) delete [] Textures[i];
delete [] Textures;
}
}
int OTM_TextureHandler::Add(OTM_IDirect3DTexture9* pTexture)
{
Message("OTM_TextureHandler::Add( %lu): %lu\n", pTexture, this);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
if (pTexture->Reference>=0) return (RETURN_TEXTURE_ALLREADY_ADDED);
if (Number/FieldLength==FieldCounter)
{
OTM_IDirect3DTexture9*** temp = NULL;
try {temp = new OTM_IDirect3DTexture9**[FieldCounter+10];}
catch (...)
{
gl_ErrorState |= OTM_ERROR_MEMORY | OTM_ERROR_TEXTURE;
return (RETURN_NO_MEMORY);
}
for (int i=0; i<FieldCounter; i++) temp[i] = Textures[i];
for (int i=FieldCounter; i<FieldCounter+10; i++) temp[i] = NULL;
FieldCounter += 10;
if (Textures!=NULL) delete [] Textures;
Textures = temp;
}
if (Number%FieldLength==0)
{
try {if (Textures[Number/FieldLength]==NULL) Textures[Number/FieldLength] = new OTM_IDirect3DTexture9*[FieldLength];}
catch (...)
{
Textures[Number/FieldLength]=NULL;
gl_ErrorState |= OTM_ERROR_MEMORY | OTM_ERROR_TEXTURE;
return (RETURN_NO_MEMORY);
}
}
Textures[Number/FieldLength][Number%FieldLength] = pTexture;
pTexture->Reference = Number++;
return (RETURN_OK);
}
int OTM_TextureHandler::Remove(OTM_IDirect3DTexture9* pTexture) //will be called, if a texture is completely released
{
Message("OTM_TextureHandler::Remove( %lu): %lu\n", pTexture, this);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
int ref = pTexture->Reference;
if (ref<0) return (RETURN_OK); // returning if no TextureHandlerRef is set
if (ref<(--Number))
{
Textures[ref/FieldLength][ref%FieldLength] = Textures[Number/FieldLength][Number%FieldLength];
Textures[ref/FieldLength][ref%FieldLength]->Reference = ref;
}
return (RETURN_OK);
}
+110 -6
View File
@@ -29,8 +29,9 @@ typedef struct
bool ForceReload; // to force a reload of the texture (if it is already modded)
char* pData; // store texture file as file in memory
unsigned int Size; // size of file
int NumberOfTextures;
int Reference; // for a fast delete in the FileHandler
OTM_IDirect3DTexture9 *pTexture; // pointer to the fake texture
IDirect3DBaseTexture9 **Textures; // pointer to the fake textures
MyTypeHash Hash; // hash value
} TextureFileStruct;
@@ -56,24 +57,127 @@ protected:
TextureFileStruct*** Files;
};
class OTM_TextureHandler // array to store OTM_IDirect3DTexture9
template <class T>
class OTM_TextureHandler // array to store OTM_IDirect3DTexture9, OTM_IDirect3DVolumeTexture9 or OTM_IDirect3DCubeTexture9
{
public:
OTM_TextureHandler(void);
~OTM_TextureHandler(void);
int Add( OTM_IDirect3DTexture9* texture);
int Remove( OTM_IDirect3DTexture9* texture);
int Add( T* texture);
int Remove( T* texture);
int GetNumber(void) {return (Number);}
OTM_IDirect3DTexture9 *operator [] (int i) {if (i<0||i>=Number) return (NULL); else return (Textures[i/FieldLength][i%FieldLength]);}
T *operator [] (int i) {if (i<0||i>=Number) return (NULL); else return (Textures[i/FieldLength][i%FieldLength]);}
private:
static const int FieldLength = 1024;
long Number;
int FieldCounter;
OTM_IDirect3DTexture9*** Textures;
T*** Textures;
};
template <class T>
OTM_TextureHandler<T>::OTM_TextureHandler(void)
{
Message("OTM_TextureHandler(void): %lu\n", this);
Number = 0;
FieldCounter = 0;
Textures = NULL;
}
template <class T>
OTM_TextureHandler<T>::~OTM_TextureHandler(void)
{
Message("~OTM_TextureHandler(void): %lu\n", this);
if (Textures!=NULL)
{
for (int i=0; i<FieldCounter; i++) if (Textures[i] != NULL) delete [] Textures[i];
delete [] Textures;
}
}
template <class T>
int OTM_TextureHandler<T>::Add(T* pTexture)
{
Message("OTM_TextureHandler::Add( %lu): %lu\n", pTexture, this);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
if (pTexture->Reference>=0) return (RETURN_TEXTURE_ALLREADY_ADDED);
if (Number/FieldLength==FieldCounter)
{
T*** temp = NULL;
try {temp = new T**[FieldCounter+10];}
catch (...)
{
gl_ErrorState |= OTM_ERROR_MEMORY | OTM_ERROR_TEXTURE;
return (RETURN_NO_MEMORY);
}
for (int i=0; i<FieldCounter; i++) temp[i] = Textures[i];
for (int i=FieldCounter; i<FieldCounter+10; i++) temp[i] = NULL;
FieldCounter += 10;
if (Textures!=NULL) delete [] Textures;
Textures = temp;
}
if (Number%FieldLength==0)
{
try {if (Textures[Number/FieldLength]==NULL) Textures[Number/FieldLength] = new T*[FieldLength];}
catch (...)
{
Textures[Number/FieldLength]=NULL;
gl_ErrorState |= OTM_ERROR_MEMORY | OTM_ERROR_TEXTURE;
return (RETURN_NO_MEMORY);
}
}
Textures[Number/FieldLength][Number%FieldLength] = pTexture;
pTexture->Reference = Number++;
return (RETURN_OK);
}
template <class T>
int OTM_TextureHandler<T>::Remove(T* pTexture) //will be called, if a texture is completely released
{
Message("OTM_TextureHandler::Remove( %lu): %lu\n", pTexture, this);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
int ref = pTexture->Reference;
if (ref<0) return (RETURN_OK); // returning if no TextureHandlerRef is set
if (ref<(--Number))
{
Textures[ref/FieldLength][ref%FieldLength] = Textures[Number/FieldLength][Number%FieldLength];
Textures[ref/FieldLength][ref%FieldLength]->Reference = ref;
}
return (RETURN_OK);
}
#endif /* OTM_FIELDHANDLER_H_ */
+344
View File
@@ -0,0 +1,344 @@
/*
This file is part of OpenTexMod.
OpenTexMod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenTexMod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* some function (e.g. AddReff()) are presumed to work on the texture object which belong to them
* if this texture was switched, we must redirect this calls to the CrossRef_D3Dtex texture object
*/
#include "OTM_Main.h"
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DCubeTexture9::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 == OTM_IDirect3DTexture9
// 0x01000001L == OTM_IDirect3DVolumeTexture9
// 0x01000002L == OTM_IDirect3DCubeTexture9
*ppvObj = this;
return (0x01000002L);
}
HRESULT hRes;
if (CrossRef_D3Dtex!=NULL)
{
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 OTM_IDirect3DCubeTexture9::AddRef()
{
if (FAKE) return (1); //bug, this case should never happen
if (CrossRef_D3Dtex!=NULL)
{
return (CrossRef_D3Dtex->m_D3Dtex->AddRef());
}
else return (m_D3Dtex->AddRef());
}
//this function yields for the non switched texture object
ULONG APIENTRY OTM_IDirect3DCubeTexture9::Release()
{
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!=NULL) //if this texture is switched with a fake texture
{
OTM_IDirect3DCubeTexture9 *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);
if (((OTM_IDirect3DDevice9*)m_D3Ddev)->GetSingleCubeTexture()!=fake_texture) 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 (((OTM_IDirect3DDevice9*)m_D3Ddev)->GetLastCreatedCubeTexture()==this) ((OTM_IDirect3DDevice9*)m_D3Ddev)->SetLastCreatedCubeTexture( NULL);
else ((OTM_IDirect3DDevice9*) m_D3Ddev)->GetOTM_Client()->RemoveTexture(this); // remove this texture from the texture client
delete(this);
}
return (count);
}
HRESULT APIENTRY OTM_IDirect3DCubeTexture9::GetDevice(IDirect3DDevice9** ppDevice)
{
*ppDevice = m_D3Ddev;
return D3D_OK;
}
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DCubeTexture9::SetPrivateData(REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags)
{
if (CrossRef_D3Dtex!=NULL) 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 OTM_IDirect3DCubeTexture9::GetPrivateData(REFGUID refguid,void* pData,DWORD* pSizeOfData)
{
if (CrossRef_D3Dtex!=NULL) 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 OTM_IDirect3DCubeTexture9::FreePrivateData(REFGUID refguid)
{
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->FreePrivateData(refguid));
return (m_D3Dtex->FreePrivateData(refguid));
}
DWORD APIENTRY OTM_IDirect3DCubeTexture9::SetPriority(DWORD PriorityNew)
{
return (m_D3Dtex->SetPriority(PriorityNew));
}
DWORD APIENTRY OTM_IDirect3DCubeTexture9::GetPriority()
{
return (m_D3Dtex->GetPriority());
}
void APIENTRY OTM_IDirect3DCubeTexture9::PreLoad()
{
m_D3Dtex->PreLoad();
}
D3DRESOURCETYPE APIENTRY OTM_IDirect3DCubeTexture9::GetType()
{
return (m_D3Dtex->GetType());
}
DWORD APIENTRY OTM_IDirect3DCubeTexture9::SetLOD(DWORD LODNew)
{
return (m_D3Dtex->SetLOD(LODNew));
}
DWORD APIENTRY OTM_IDirect3DCubeTexture9::GetLOD()
{
return (m_D3Dtex->GetLOD());
}
DWORD APIENTRY OTM_IDirect3DCubeTexture9::GetLevelCount()
{
return (m_D3Dtex->GetLevelCount());
}
HRESULT APIENTRY OTM_IDirect3DCubeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType)
{
return (m_D3Dtex->SetAutoGenFilterType(FilterType));
}
D3DTEXTUREFILTERTYPE APIENTRY OTM_IDirect3DCubeTexture9::GetAutoGenFilterType()
{
return (m_D3Dtex->GetAutoGenFilterType());
}
void APIENTRY OTM_IDirect3DCubeTexture9::GenerateMipSubLevels()
{
m_D3Dtex->GenerateMipSubLevels();
}
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DCubeTexture9::AddDirtyRect(D3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect)
{
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->AddDirtyRect( FaceType, pDirtyRect));
return (m_D3Dtex->AddDirtyRect( FaceType, pDirtyRect));
}
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DCubeTexture9::GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc)
{
if (CrossRef_D3Dtex!=NULL) 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 OTM_IDirect3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9 **ppCubeMapSurface)
{
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->GetCubeMapSurface( FaceType, Level, ppCubeMapSurface));
return (m_D3Dtex->GetCubeMapSurface( FaceType, Level, ppCubeMapSurface));
}
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DCubeTexture9::LockRect( D3DCUBEMAP_FACES FaceType, UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags)
{
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->LockRect( FaceType, Level, pLockedRect, pRect, Flags));
return (m_D3Dtex->LockRect( FaceType, Level, pLockedRect, pRect, Flags));
}
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DCubeTexture9::UnlockRect( D3DCUBEMAP_FACES FaceType, UINT Level)
{
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->UnlockRect( FaceType, Level));
return (m_D3Dtex->UnlockRect( FaceType, Level));
}
int OTM_IDirect3DCubeTexture9::GetHash(MyTypeHash &hash)
{
hash=0u;
if (FAKE) return (RETURN_BAD_ARGUMENT);
IDirect3DCubeTexture9 *pTexture = m_D3Dtex;
if (CrossRef_D3Dtex!=NULL) pTexture = CrossRef_D3Dtex->m_D3Dtex;
//IDirect3DSurface9 *pOffscreenSurface = NULL;
//IDirect3DCubeTexture9 *pOffscreenTexture = NULL;
IDirect3DSurface9 *pResolvedSurface = NULL;
D3DLOCKED_RECT d3dlr;
D3DSURFACE_DESC desc;
if (pTexture->GetLevelDesc(0, &desc)!=D3D_OK) //get the format and the size of the texture
{
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: GetLevelDesc \n");
return (RETURN_GetLevelDesc_FAILED);
}
Message("OTM_IDirect3DCubeTexture9::GetHash() (%d %d) %d\n", desc.Width, desc.Height, desc.Format);
/*
if (desc.Pool==D3DPOOL_DEFAULT) //get the raw data of the texture
{
//Message("OTM_IDirect3DCubeTexture9::GetHash() (D3DPOOL_DEFAULT)\n");
IDirect3DSurface9 *pSurfaceLevel_orig = NULL;
if (pTexture->GetSurfaceLevel( 0, &pSurfaceLevel_orig)!=D3D_OK)
{
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: GetSurfaceLevel 1 (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
{
//Message("OTM_IDirect3DCubeTexture9::GetHash() MultiSampleType\n");
if (D3D_OK!=m_D3Ddev->CreateRenderTarget( desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pResolvedSurface, NULL ))
{
pSurfaceLevel_orig->Release();
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
if (D3D_OK!=m_D3Ddev->StretchRect( pSurfaceLevel_orig, NULL, pResolvedSurface, NULL, D3DTEXF_NONE ))
{
pSurfaceLevel_orig->Release();
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: StretchRect (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
pSurfaceLevel_orig = pResolvedSurface;
}
if (D3D_OK!=m_D3Ddev->CreateOffscreenPlainSurface( desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pOffscreenSurface, NULL))
{
pSurfaceLevel_orig->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: CreateOffscreenPlainSurface (D3DPOOL_DEFAULT)\n");
return (RETURN_TEXTURE_NOT_LOADED);
}
if (D3D_OK!=m_D3Ddev->GetRenderTargetData( pSurfaceLevel_orig, pOffscreenSurface))
{
pSurfaceLevel_orig->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
pOffscreenSurface->Release();
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
pSurfaceLevel_orig->Release();
if (pOffscreenSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
pOffscreenSurface->Release();
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
}
else
*/
if (pTexture->LockRect( D3DCUBEMAP_FACE_POSITIVE_X, 0, &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: LockRect 1\n");
if (pTexture->GetCubeMapSurface( D3DCUBEMAP_FACE_POSITIVE_X, 0, &pResolvedSurface)!=D3D_OK)
{
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: GetSurfaceLevel\n");
return (RETURN_LockRect_FAILED);
}
if (pResolvedSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
pResolvedSurface->Release();
Message("OTM_IDirect3DCubeTexture9::GetHash() Failed: LockRect 2\n");
return (RETURN_LockRect_FAILED);
}
}
int size = (GetBitsFromFormat( desc.Format) * desc.Width*desc.Height)/8;
hash = GetCRC32( (char*) d3dlr.pBits, size); //calculate the crc32 of the texture
/*
if (pOffscreenSurface!=NULL)
{
pOffscreenSurface->UnlockRect();
pOffscreenSurface->Release();
//pOffscreenTexture->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
}
else
*/
if (pResolvedSurface!=NULL)
{
pResolvedSurface->UnlockRect();
pResolvedSurface->Release();
}
else
{
pTexture->UnlockRect( D3DCUBEMAP_FACE_POSITIVE_X, 0); //unlock the raw data
}
Message("OTM_IDirect3DCubeTexture9::GetHash() %#lX (%d %d) %d = %d\n", hash, desc.Width, desc.Height, desc.Format, size);
return (RETURN_OK);
}
+126
View File
@@ -0,0 +1,126 @@
/*
This file is part of OpenTexMod.
OpenTexMod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenTexMod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
*/
/*
*
* BIG THANKS TO Matthew L (Azorbix)
* (Direct3D StarterKit v3.0)
*
*/
#ifndef OTM_IDirect3DCubeTexture9_H
#define OTM_IDirect3DCubeTexture9_H
#include <d3d9.h>
#include <d3dx9.h>
#include "OTM_Defines.h"
interface OTM_IDirect3DCubeTexture9 : public IDirect3DCubeTexture9
{
OTM_IDirect3DCubeTexture9(IDirect3DCubeTexture9 **ppTex, IDirect3DDevice9 *pIDirect3DDevice9)
{
m_D3Dtex = *ppTex; //Texture which will be displayed and will be passed to the game
m_D3Ddev = pIDirect3DDevice9; //device pointer
CrossRef_D3Dtex = NULL; //cross reference
// fake texture: store the pointer to the original OTM_IDirect3DCubeTexture9 object, needed if a fake texture is unselected
// original texture: stores the pointer to the fake texture object, is needed if original texture is deleted,
// thus the fake texture can also be deleted
Reference = -1; //need for fast deleting
Hash = 0u;
FAKE = false;
}
// callback interface
IDirect3DCubeTexture9 *m_D3Dtex;
OTM_IDirect3DCubeTexture9 *CrossRef_D3Dtex;
IDirect3DDevice9 *m_D3Ddev;
int Reference;
MyTypeHash Hash;
bool FAKE;
// original interface
STDMETHOD(QueryInterface) (REFIID riid, void** ppvObj);
STDMETHOD_(ULONG,AddRef)();
STDMETHOD_(ULONG,Release)();
STDMETHOD(GetDevice)(IDirect3DDevice9** ppDevice);
STDMETHOD(SetPrivateData)(REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags);
STDMETHOD(GetPrivateData)(REFGUID refguid,void* pData,DWORD* pSizeOfData);
STDMETHOD(FreePrivateData)(REFGUID refguid);
STDMETHOD_(DWORD, SetPriority)(DWORD PriorityNew);
STDMETHOD_(DWORD, GetPriority)();
STDMETHOD_(void, PreLoad)();
STDMETHOD_(D3DRESOURCETYPE, GetType)();
STDMETHOD_(DWORD, SetLOD)(DWORD LODNew);
STDMETHOD_(DWORD, GetLOD)();
STDMETHOD_(DWORD, GetLevelCount)();
STDMETHOD(SetAutoGenFilterType)(D3DTEXTUREFILTERTYPE FilterType);
STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)();
STDMETHOD_(void, GenerateMipSubLevels)();
STDMETHOD(AddDirtyRect)(D3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect);
STDMETHOD(GetLevelDesc)(UINT Level, D3DSURFACE_DESC *pDesc);
STDMETHOD(GetCubeMapSurface)(D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9 **ppCubeMapSurface);
STDMETHOD(LockRect)( D3DCUBEMAP_FACES FaceType, UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags);
STDMETHOD(UnlockRect)(D3DCUBEMAP_FACES FaceType, UINT Level);
int GetHash(MyTypeHash &hash);
};
inline void UnswitchTextures(OTM_IDirect3DCubeTexture9 *pTexture)
{
OTM_IDirect3DCubeTexture9* CrossRef = pTexture->CrossRef_D3Dtex;
if (CrossRef!=NULL)
{
// switch textures back
IDirect3DCubeTexture9* cpy = pTexture->m_D3Dtex;
pTexture->m_D3Dtex = CrossRef->m_D3Dtex;
CrossRef->m_D3Dtex = cpy;
// cancel the link
CrossRef->CrossRef_D3Dtex = NULL;
pTexture->CrossRef_D3Dtex = NULL;
}
}
inline int SwitchTextures( OTM_IDirect3DCubeTexture9 *pTexture1, OTM_IDirect3DCubeTexture9 *pTexture2)
{
if (pTexture1->m_D3Ddev == pTexture2->m_D3Ddev && pTexture1->CrossRef_D3Dtex == NULL && pTexture2->CrossRef_D3Dtex == NULL)
{
// make cross reference
pTexture1->CrossRef_D3Dtex = pTexture2;
pTexture2->CrossRef_D3Dtex = pTexture1;
// switch textures
IDirect3DCubeTexture9* cpy = pTexture2->m_D3Dtex;
pTexture2->m_D3Dtex = pTexture1->m_D3Dtex;
pTexture1->m_D3Dtex = cpy;
return (RETURN_OK);
}
else return (RETURN_TEXTURE_NOT_SWITCHED);
}
#endif
+419 -44
View File
@@ -24,19 +24,28 @@ along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
int OTM_IDirect3DDevice9::CreateSingleTexture(void)
{
if (SingleTexture!=NULL && SingleVolumeTexture!=NULL && SingleCubeTexture!=NULL && TextureColour==OTM_Client->TextureColour) return (RETURN_OK);
TextureColour = OTM_Client->TextureColour;
if (SingleTexture==NULL) //create texture
{
if( D3D_OK != CreateTexture(8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DTexture9**) &SingleTexture, NULL)) return (RETURN_TEXTURE_NOT_LOADED);
if( D3D_OK != CreateTexture(8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DTexture9**) &SingleTexture, NULL))
{
Message("OTM_IDirect3DDevice9::CreateSingleTexture(): CreateTexture Failed\n");
SingleTexture = NULL;
return (RETURN_TEXTURE_NOT_LOADED);
}
LastCreatedTexture = NULL; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture
SingleTexture->FAKE = true; //this is no texture created from by game
SingleTexture->Reference = -2;
}
TextureColour = OTM_Client->TextureColour;
{
D3DLOCKED_RECT d3dlr;
IDirect3DTexture9 *pD3Dtex = SingleTexture->m_D3Dtex;
if (D3D_OK!=pD3Dtex->LockRect(0, &d3dlr, 0, 0))
{
Message("OTM_IDirect3DDevice9::CreateSingleTexture(): LockRect Failed\n");
SingleTexture->Release();
SingleTexture=NULL;
return (RETURN_TEXTURE_NOT_LOADED);
@@ -46,6 +55,69 @@ int OTM_IDirect3DDevice9::CreateSingleTexture(void)
for (int i=0; i<8*8; i++) pDst[i] = TextureColour;
pD3Dtex->UnlockRect(0);
}
if (SingleVolumeTexture==NULL) //create texture
{
if( D3D_OK != CreateVolumeTexture(8, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DVolumeTexture9**) &SingleVolumeTexture, NULL))
{
Message("OTM_IDirect3DDevice9::CreateSingleTexture(): CreateVolumeTexture Failed\n");
SingleVolumeTexture = NULL;
return (RETURN_TEXTURE_NOT_LOADED);
}
LastCreatedVolumeTexture = NULL; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture
SingleVolumeTexture->FAKE = true; //this is no texture created from by game
SingleVolumeTexture->Reference = -2;
}
{
D3DLOCKED_BOX d3dlr;
IDirect3DVolumeTexture9 *pD3Dtex = SingleVolumeTexture->m_D3Dtex;
//LockBox)(UINT Level, D3DLOCKED_BOX *pLockedVolume, CONST D3DBOX *pBox,
if (D3D_OK!=pD3Dtex->LockBox(0, &d3dlr, 0, 0))
{
Message("OTM_IDirect3DDevice9::CreateSingleTexture(): LockBox Failed\n");
SingleVolumeTexture->Release();
SingleVolumeTexture=NULL;
return (RETURN_TEXTURE_NOT_LOADED);
}
DWORD *pDst = (DWORD*)d3dlr.pBits;
for (int i=0; i<8*8*8; i++) pDst[i] = TextureColour;
pD3Dtex->UnlockBox(0);
}
if (SingleCubeTexture==NULL) //create texture
{
if( D3D_OK != CreateCubeTexture(8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DCubeTexture9**) &SingleCubeTexture, NULL))
{
Message("OTM_IDirect3DDevice9::CreateSingleTexture(): CreateCubeTexture Failed\n");
SingleCubeTexture = NULL;
return (RETURN_TEXTURE_NOT_LOADED);
}
LastCreatedCubeTexture = NULL; // set LastCreatedTexture to NULL, cause LastCreatedTexture is equal SingleTexture
SingleCubeTexture->FAKE = true; //this is no texture created from by game
SingleCubeTexture->Reference = -2;
}
{
D3DLOCKED_RECT d3dlr;
IDirect3DCubeTexture9 *pD3Dtex = SingleCubeTexture->m_D3Dtex;
for (int c=0; c<6; c++)
{
if (D3D_OK!=pD3Dtex->LockRect( (D3DCUBEMAP_FACES) c, 0, &d3dlr, 0, 0))
{
Message("OTM_IDirect3DDevice9::CreateSingleTexture(): LockRect (Cube) Failed\n");
SingleCubeTexture->Release();
SingleCubeTexture=NULL;
return (RETURN_TEXTURE_NOT_LOADED);
}
DWORD *pDst = (DWORD*)d3dlr.pBits;
for (int i=0; i<8*8; i++) pDst[i] = TextureColour;
pD3Dtex->UnlockRect((D3DCUBEMAP_FACES)c, 0);
}
}
return (RETURN_OK);
}
@@ -57,11 +129,17 @@ OTM_IDirect3DDevice9::OTM_IDirect3DDevice9(IDirect3DDevice9* pOriginal, OTM_Text
OTM_Client = new OTM_TextureClient( OTM_Server, this); //get a new texture client for this device
LastCreatedTexture = NULL;
LastCreatedVolumeTexture = NULL;
LastCreatedCubeTexture = NULL;
m_pIDirect3DDevice9 = pOriginal; // store the pointer to original object
TextureColour = D3DCOLOR_ARGB(255,0,255,0);
CounterSaveSingleTexture = -1;
CounterSaveSingleTexture = -20;
SingleTextureMod = 0;
SingleTexture = NULL;
SingleVolumeTexture = NULL;
SingleCubeTexture = NULL;
OSD_Font = NULL;
OTM_Reference = 1;
}
@@ -102,6 +180,8 @@ ULONG OTM_IDirect3DDevice9::Release(void)
// and the target textures are released by the game.
if (SingleTexture!=NULL) SingleTexture->Release(); //this is the only texture we must release by ourself
if (SingleVolumeTexture!=NULL) SingleVolumeTexture->Release(); //this is the only texture we must release by ourself
if (SingleCubeTexture!=NULL) SingleCubeTexture->Release(); //this is the only texture we must release by ourself
if (OSD_Font!=NULL) OSD_Font->Release();
if (OTM_Client!=NULL) delete OTM_Client; //must be deleted at the end, because other releases might call a function of this object
@@ -226,11 +306,12 @@ void OTM_IDirect3DDevice9::GetGammaRamp(UINT iSwapChain,D3DGAMMARAMP* pRamp)
HRESULT OTM_IDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle)
{
//create real texture
//Message("OTM_IDirect3DDevice9::CreateTexture()\n");
HRESULT ret = (m_pIDirect3DDevice9->CreateTexture(Width,Height,Levels,Usage,Format,Pool,ppTexture,pSharedHandle));
if(ret != D3D_OK) return (ret);
//create fake texture
OTM_IDirect3DTexture9 *texture = new OTM_IDirect3DTexture9(ppTexture, this, Width, Height, Format);
OTM_IDirect3DTexture9 *texture = new OTM_IDirect3DTexture9(ppTexture, this);
if (texture) *ppTexture = texture;
if (LastCreatedTexture!=NULL) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
@@ -243,12 +324,40 @@ HRESULT OTM_IDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,D
HRESULT OTM_IDirect3DDevice9::CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,HANDLE* pSharedHandle)
{
return (m_pIDirect3DDevice9->CreateVolumeTexture(Width,Height,Depth,Levels,Usage,Format,Pool,ppVolumeTexture,pSharedHandle));
//create real texture
//Message("OTM_IDirect3DDevice9::CreateVolumeTexture()\n");
HRESULT ret = (m_pIDirect3DDevice9->CreateVolumeTexture(Width,Height,Depth, Levels,Usage,Format,Pool,ppVolumeTexture,pSharedHandle));
if(ret != D3D_OK) return (ret);
//create fake texture
OTM_IDirect3DVolumeTexture9 *texture = new OTM_IDirect3DVolumeTexture9(ppVolumeTexture, this);
if (texture) *ppVolumeTexture = texture;
if (LastCreatedVolumeTexture!=NULL) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
{
if ( OTM_Client!=NULL) OTM_Client->AddTexture( LastCreatedVolumeTexture);
}
LastCreatedVolumeTexture = texture;
return (ret);
}
HRESULT OTM_IDirect3DDevice9::CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle)
{
return(m_pIDirect3DDevice9->CreateCubeTexture(EdgeLength,Levels,Usage,Format,Pool,ppCubeTexture,pSharedHandle));
//create real texture
//Message("OTM_IDirect3DDevice9::CreateCubeTexture()\n");
HRESULT ret = (m_pIDirect3DDevice9->CreateCubeTexture(EdgeLength, Levels,Usage,Format,Pool,ppCubeTexture,pSharedHandle));
if(ret != D3D_OK) return (ret);
//create fake texture
OTM_IDirect3DCubeTexture9 *texture = new OTM_IDirect3DCubeTexture9( ppCubeTexture, this);
if (texture) *ppCubeTexture = texture;
if (LastCreatedCubeTexture!=NULL) //if a texture was loaded before, hopefully this texture contains now the data, so we can add it
{
if ( OTM_Client!=NULL) OTM_Client->AddTexture( LastCreatedCubeTexture);
}
LastCreatedCubeTexture = texture;
return (ret);
}
HRESULT OTM_IDirect3DDevice9::CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle)
@@ -278,17 +387,148 @@ HRESULT OTM_IDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface,CO
HRESULT OTM_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTexture,IDirect3DBaseTexture9* pDestinationTexture)
{
Message("OTM_IDirect3DDevice9::UpdateTexture( %lu, %lu): %lu\n", pSourceTexture, pDestinationTexture, this);
// we must pass the real texture objects
// if (dev != this) this texture was not initialized through our device and is thus no fake texture object
IDirect3DDevice9 *dev = NULL;
if (pSourceTexture != NULL && ((OTM_IDirect3DTexture9*)(pSourceTexture))->GetDevice(&dev) == D3D_OK)
OTM_IDirect3DTexture9* pSource = NULL;
OTM_IDirect3DVolumeTexture9* pSourceVolume = NULL;
OTM_IDirect3DCubeTexture9* pSourceCube = NULL;
IDirect3DBaseTexture9* cpy;
if( pSourceTexture != NULL )
{
if (dev == this) pSourceTexture = ((OTM_IDirect3DTexture9*)(pSourceTexture))->m_D3Dtex;
long int ret = pSourceTexture->QueryInterface( IID_IDirect3D9, (void**) &cpy);
switch (ret)
{
case 0x01000000L:
{
MyTypeHash hash;
pSource = (OTM_IDirect3DTexture9*)(pSourceTexture);
if (pSource->GetHash( hash) == RETURN_OK)
{
if (hash != pSource->Hash) // this hash has changed !!
{
pSource->Hash = hash;
if (pSource->CrossRef_D3Dtex!=NULL) UnswitchTextures(pSource);
OTM_Client->LookUpToMod( pSource);
}
}
else if (pSource->CrossRef_D3Dtex!=NULL) UnswitchTextures(pSource); // we better unswitch
// the source must be the original texture if not switched and the fake texture if it is switched
if (pSource->CrossRef_D3Dtex!=NULL) pSourceTexture = pSource->CrossRef_D3Dtex->m_D3Dtex;
else pSourceTexture = pSource->m_D3Dtex;
break;
}
case 0x01000001L:
{
MyTypeHash hash;
pSourceVolume = (OTM_IDirect3DVolumeTexture9*)(pSourceTexture);
if (pSourceVolume->GetHash( hash) == RETURN_OK)
{
if (hash != pSourceVolume->Hash) // this hash has changed !!
{
pSourceVolume->Hash = hash;
if (pSourceVolume->CrossRef_D3Dtex!=NULL) UnswitchTextures(pSourceVolume);
OTM_Client->LookUpToMod( pSourceVolume);
}
}
else if (pSourceVolume->CrossRef_D3Dtex!=NULL) UnswitchTextures(pSourceVolume); // we better unswitch
// the source must be the original texture if not switched and the fake texture if it is switched
if (pSourceVolume->CrossRef_D3Dtex!=NULL) pSourceTexture = pSourceVolume->CrossRef_D3Dtex->m_D3Dtex;
else pSourceTexture = pSourceVolume->m_D3Dtex;
break;
}
case 0x01000002L:
{
MyTypeHash hash;
pSourceCube = (OTM_IDirect3DCubeTexture9*)(pSourceTexture);
if (pSourceCube->GetHash( hash) == RETURN_OK)
{
if (hash != pSourceCube->Hash) // this hash has changed !!
{
pSourceCube->Hash = hash;
if (pSourceCube->CrossRef_D3Dtex!=NULL) UnswitchTextures(pSourceCube);
OTM_Client->LookUpToMod( pSourceCube);
}
}
else if (pSourceCube->CrossRef_D3Dtex!=NULL) UnswitchTextures(pSourceCube); // we better unswitch
// the source must be the original texture if not switched and the fake texture if it is switched
if (pSourceCube->CrossRef_D3Dtex!=NULL) pSourceTexture = pSourceCube->CrossRef_D3Dtex->m_D3Dtex;
else pSourceTexture = pSourceCube->m_D3Dtex;
break;
}
default:
break; // this is no fake texture and QueryInterface failed, because IDirect3DBaseTexture9 object cannot be a IDirect3D9 object ;)
}
}
if (pDestinationTexture != NULL && ((OTM_IDirect3DTexture9*)(pDestinationTexture))->GetDevice(&dev) == D3D_OK)
if (pDestinationTexture != NULL)
{
if (dev == this) pDestinationTexture = ((OTM_IDirect3DTexture9*)(pDestinationTexture))->m_D3Dtex;
long int ret = pSourceTexture->QueryInterface( IID_IDirect3D9, (void**) &cpy);
switch (ret)
{
case 0x01000000L:
{
OTM_IDirect3DTexture9* pDest = (OTM_IDirect3DTexture9*)(pDestinationTexture);
if (pSource!=NULL && pDest->Hash!=pSource->Hash)
{
pDest->Hash = pSource->Hash; // take over the hash
UnswitchTextures(pDest);
if (pSource->CrossRef_D3Dtex!=NULL)
{
OTM_IDirect3DTexture9 *cpy = pSource->CrossRef_D3Dtex;
UnswitchTextures(pSource);
SwitchTextures( cpy, pDest);
}
}
if (pDest->CrossRef_D3Dtex!=NULL) pDestinationTexture = pDest->CrossRef_D3Dtex->m_D3Dtex; // make sure to copy into the original texture
else pDestinationTexture = pDest->m_D3Dtex;
break;
}
case 0x01000001L:
{
OTM_IDirect3DVolumeTexture9* pDest = (OTM_IDirect3DVolumeTexture9*)(pDestinationTexture);
if (pSourceVolume!=NULL && pDest->Hash!=pSourceVolume->Hash)
{
pDest->Hash = pSourceVolume->Hash; // take over the hash
UnswitchTextures(pDest);
if (pSourceVolume->CrossRef_D3Dtex!=NULL)
{
OTM_IDirect3DVolumeTexture9 *cpy = pSourceVolume->CrossRef_D3Dtex;
UnswitchTextures(pSourceVolume);
SwitchTextures( cpy, pDest);
}
}
if (pDest->CrossRef_D3Dtex!=NULL) pDestinationTexture = pDest->CrossRef_D3Dtex->m_D3Dtex; // make sure to copy into the original texture
else pDestinationTexture = pDest->m_D3Dtex;
break;
}
case 0x01000002L:
{
OTM_IDirect3DCubeTexture9* pDest = (OTM_IDirect3DCubeTexture9*)(pDestinationTexture);
if (pSourceCube!=NULL && pDest->Hash!=pSourceCube->Hash)
{
pDest->Hash = pSourceCube->Hash; // take over the hash
UnswitchTextures(pDest);
if (pSourceCube->CrossRef_D3Dtex!=NULL)
{
OTM_IDirect3DCubeTexture9 *cpy = pSourceCube->CrossRef_D3Dtex;
UnswitchTextures(pSourceCube);
SwitchTextures( cpy, pDest);
}
}
if (pDest->CrossRef_D3Dtex!=NULL) pDestinationTexture = pDest->CrossRef_D3Dtex->m_D3Dtex; // make sure to copy into the original texture
else pDestinationTexture = pDest->m_D3Dtex;
break;
}
}
}
return(m_pIDirect3DDevice9->UpdateTexture(pSourceTexture,pDestinationTexture));
}
@@ -345,54 +585,138 @@ HRESULT OTM_IDirect3DDevice9::BeginScene(void)
if (LastCreatedTexture!=NULL) // add the last created texture
{
OTM_Client->AddTexture( LastCreatedTexture);
LastCreatedTexture = NULL;
}
if (LastCreatedVolumeTexture!=NULL) // add the last created texture
{
OTM_Client->AddTexture( LastCreatedVolumeTexture);
}
if (LastCreatedCubeTexture!=NULL) // add the last created texture
{
OTM_Client->AddTexture( LastCreatedCubeTexture);
}
OTM_Client->MergeUpdate(); // merge an update, if present
if (OTM_Client->BoolSaveSingleTexture)
{
if (SingleTexture==NULL) CreateSingleTexture();
if (SingleTexture!=NULL)
if (CreateSingleTexture()==0)
{
if (TextureColour!=OTM_Client->TextureColour) //if TextureColour has changed, dye the texture in the new colour
{
D3DLOCKED_RECT d3dlr;
IDirect3DTexture9 *pD3Dtex;
if (SingleTexture->CrossRef_D3Dtex==NULL) pD3Dtex = SingleTexture->m_D3Dtex;
else pD3Dtex = SingleTexture->CrossRef_D3Dtex->m_D3Dtex;
if (D3D_OK==pD3Dtex->LockRect(0, &d3dlr, 0, 0))
{
DWORD *pDst = (DWORD*)d3dlr.pBits;
TextureColour = OTM_Client->TextureColour;
for (int xy=0; xy < 8*8; xy++) *(pDst++) = TextureColour;
pD3Dtex->UnlockRect(0);
}
}
if (OTM_Client->KeyBack>0 && (GetAsyncKeyState( OTM_Client->KeyBack ) &1) ) //ask for the status of the back key
{
UnswitchTextures( SingleTexture); // can be called, even if texture is not switched
if (CounterSaveSingleTexture<0) CounterSaveSingleTexture = 0; //first initialization of the counter
else if (--CounterSaveSingleTexture<0) CounterSaveSingleTexture = OTM_Client->OriginalTextures.GetNumber() - 1;
UnswitchTextures( SingleVolumeTexture); // can be called, even if texture is not switched
UnswitchTextures( SingleCubeTexture); // can be called, even if texture is not switched
if (CounterSaveSingleTexture<-10) {CounterSaveSingleTexture = 0; SingleTextureMod=0;} //first initialization of the counter
else if (--CounterSaveSingleTexture<0)
{
if (--SingleTextureMod<0) SingleTextureMod=2;
switch (SingleTextureMod)
{
case 0:
CounterSaveSingleTexture = OTM_Client->OriginalTextures.GetNumber() - 1;
break;
case 1:
CounterSaveSingleTexture = OTM_Client->OriginalVolumeTextures.GetNumber() - 1;
break;
case 2:
CounterSaveSingleTexture = OTM_Client->OriginalCubeTextures.GetNumber() - 1;
break;
}
}
if (CounterSaveSingleTexture >= 0)
{
SwitchTextures( SingleTexture, OTM_Client->OriginalTextures[CounterSaveSingleTexture]);
SingleTexture->Hash = OTM_Client->OriginalTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
switch (SingleTextureMod)
{
case 0:
SwitchTextures( SingleTexture, OTM_Client->OriginalTextures[CounterSaveSingleTexture]);
SingleTexture->Hash = OTM_Client->OriginalTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
break;
case 1:
SwitchTextures( SingleVolumeTexture, OTM_Client->OriginalVolumeTextures[CounterSaveSingleTexture]);
SingleVolumeTexture->Hash = OTM_Client->OriginalVolumeTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
break;
case 2:
SwitchTextures( SingleCubeTexture, OTM_Client->OriginalCubeTextures[CounterSaveSingleTexture]);
SingleCubeTexture->Hash = OTM_Client->OriginalCubeTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
break;
}
}
}
if (OTM_Client->KeySave>0 && (GetAsyncKeyState( OTM_Client->KeySave ) &1) ) //ask for the status of the save key
{
OTM_Client->SaveTexture( SingleTexture); //after switching the SingleTexture holds the pointer to the original texture object
switch (SingleTextureMod)
{
case 0:
OTM_Client->SaveTexture( SingleTexture); //after switching the SingleTexture holds the pointer to the original texture object
break;
case 1:
OTM_Client->SaveTexture( SingleVolumeTexture); //after switching the SingleTexture holds the pointer to the original texture object
break;
case 2:
OTM_Client->SaveTexture( SingleCubeTexture); //after switching the SingleTexture holds the pointer to the original texture object
break;
}
}
if (OTM_Client->KeyNext>0 && (GetAsyncKeyState( OTM_Client->KeyNext ) &1) ) //ask for the status of the next key
{
UnswitchTextures( SingleTexture); // can be called, even if texture is not switched
if (CounterSaveSingleTexture<0) CounterSaveSingleTexture = 0; //first initialization of the counter
else if (++CounterSaveSingleTexture>=OTM_Client->OriginalTextures.GetNumber()) CounterSaveSingleTexture = 0;
if (CounterSaveSingleTexture < OTM_Client->OriginalTextures.GetNumber())
UnswitchTextures( SingleVolumeTexture); // can be called, even if texture is not switched
UnswitchTextures( SingleCubeTexture); // can be called, even if texture is not switched
if (CounterSaveSingleTexture<-10) {CounterSaveSingleTexture = 0; SingleTextureMod=0;} //first initialization of the counter
else
{
SwitchTextures( SingleTexture, OTM_Client->OriginalTextures[CounterSaveSingleTexture]);
SingleTexture->Hash = OTM_Client->OriginalTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
int num = 0;
switch (SingleTextureMod)
{
case 0:
num = OTM_Client->OriginalTextures.GetNumber();
break;
case 1:
num = OTM_Client->OriginalVolumeTextures.GetNumber();
break;
case 2:
num = OTM_Client->OriginalCubeTextures.GetNumber();
break;
}
if (++CounterSaveSingleTexture>=num)
{
if (++SingleTextureMod>2) SingleTextureMod=0;
switch (SingleTextureMod)
{
case 0:
CounterSaveSingleTexture = OTM_Client->OriginalTextures.GetNumber()>0 ? 0 : - 1;
break;
case 1:
CounterSaveSingleTexture = OTM_Client->OriginalVolumeTextures.GetNumber()>0 ? 0 : - 1;
break;
case 2:
CounterSaveSingleTexture = OTM_Client->OriginalCubeTextures.GetNumber()>0 ? 0 : - 1;
break;
}
}
}
if (CounterSaveSingleTexture >= 0)
{
switch (SingleTextureMod)
{
case 0:
SwitchTextures( SingleTexture, OTM_Client->OriginalTextures[CounterSaveSingleTexture]);
SingleTexture->Hash = OTM_Client->OriginalTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
break;
case 1:
SwitchTextures( SingleVolumeTexture, OTM_Client->OriginalVolumeTextures[CounterSaveSingleTexture]);
SingleVolumeTexture->Hash = OTM_Client->OriginalVolumeTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
break;
case 2:
SwitchTextures( SingleCubeTexture, OTM_Client->OriginalCubeTextures[CounterSaveSingleTexture]);
SingleCubeTexture->Hash = OTM_Client->OriginalCubeTextures[CounterSaveSingleTexture]->Hash; //set the hash for the display
break;
}
}
}
}
@@ -404,7 +728,7 @@ HRESULT OTM_IDirect3DDevice9::BeginScene(void)
HRESULT OTM_IDirect3DDevice9::EndScene(void)
{
if ( /*OTM_Client!=NULL &&*/ OTM_Client->BoolSaveSingleTexture && SingleTexture!=NULL && SingleTexture->CrossRef_D3Dtex!=NULL)
if ( /*OTM_Client!=NULL &&*/ OTM_Client->BoolSaveSingleTexture && SingleTexture!=NULL && SingleVolumeTexture!=NULL && SingleCubeTexture!=NULL)
{
if (OSD_Font==NULL) // create the font
{
@@ -416,7 +740,40 @@ HRESULT OTM_IDirect3DDevice9::EndScene(void)
}
char buffer[100];
sprintf_s( buffer, 100, "Actual texture: %4d (1..%d): %#lX", CounterSaveSingleTexture+1, OTM_Client->OriginalTextures.GetNumber(), SingleTexture->Hash);
buffer[0]=0;
switch (SingleTextureMod)
{
case 0:
{
if (SingleTexture->CrossRef_D3Dtex!=NULL) sprintf_s( buffer, 100, "normal texture: %4d (1..%d): %#lX", CounterSaveSingleTexture+1, OTM_Client->OriginalTextures.GetNumber(), SingleTexture->Hash);
else
{
if (OTM_Client->OriginalTextures.GetNumber()>0) sprintf_s( buffer, 100, "normal texture: nothing selected (1..%d)", OTM_Client->OriginalTextures.GetNumber());
else sprintf_s( buffer, 100, "normal texture: nothing loaded");
}
break;
}
case 1:
{
if (SingleVolumeTexture->CrossRef_D3Dtex!=NULL) sprintf_s( buffer, 100, "volume texture: %4d (1..%d): %#lX", CounterSaveSingleTexture+1, OTM_Client->OriginalVolumeTextures.GetNumber(), SingleVolumeTexture->Hash);
else
{
if (OTM_Client->OriginalVolumeTextures.GetNumber()>0) sprintf_s( buffer, 100, "volume texture: nothing selected (1..%d)", OTM_Client->OriginalVolumeTextures.GetNumber());
else sprintf_s( buffer, 100, "volume texture: nothing loaded");
}
break;
}
case 2:
{
if (SingleCubeTexture->CrossRef_D3Dtex!=NULL) sprintf_s( buffer, 100, "cube texture: %4d (1..%d): %#lX", CounterSaveSingleTexture+1, OTM_Client->OriginalCubeTextures.GetNumber(), SingleCubeTexture->Hash);
else
{
if (OTM_Client->OriginalCubeTextures.GetNumber()>0) sprintf_s( buffer, 100, "cube texture: nothing selected (1..%d)", OTM_Client->OriginalCubeTextures.GetNumber());
else sprintf_s( buffer, 100, "cube texture: nothing loaded");
}
break;
}
}
D3DVIEWPORT9 viewport;
GetViewport( &viewport);
RECT rct;
@@ -544,11 +901,29 @@ HRESULT OTM_IDirect3DDevice9::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pTe
// we must pass the real texture objects
// if (dev != this) this texture was not initialized through our device and is thus no fake texture object
IDirect3DDevice9 *dev = NULL;
//IDirect3DDevice9 *dev = NULL;
IDirect3DBaseTexture9* cpy;
if( pTexture != NULL )
{
long int ret = pTexture->QueryInterface( IID_IDirect3D9, (void**) &cpy);
switch (ret)
{
case 0x01000000L:
pTexture = ((OTM_IDirect3DTexture9*)(pTexture))->m_D3Dtex; break;
case 0x01000001L:
pTexture = ((OTM_IDirect3DVolumeTexture9*)(pTexture))->m_D3Dtex; break;
case 0x01000002L:
pTexture = ((OTM_IDirect3DCubeTexture9*)(pTexture))->m_D3Dtex; break;
default:
break; // this is no fake texture and QueryInterface failed, because IDirect3DBaseTexture9 object cannot be a IDirect3D9 object ;)
}
}
/*
if (pTexture != NULL && ((OTM_IDirect3DTexture9*)(pTexture))->GetDevice(&dev) == D3D_OK)
{
if(dev == this) pTexture = ((OTM_IDirect3DTexture9*)(pTexture))->m_D3Dtex;
}
*/
return (m_pIDirect3DDevice9->SetTexture(Stage, pTexture));
}
+21
View File
@@ -31,6 +31,8 @@ along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
#include <d3d9.h>
#include <d3dx9.h>
#include "OTM_IDirect3DTexture9.h"
#include "OTM_IDirect3DVolumeTexture9.h"
#include "OTM_IDirect3DCubeTexture9.h"
class OTM_IDirect3DDevice9 : public IDirect3DDevice9
{
@@ -163,21 +165,40 @@ public:
OTM_TextureClient* GetOTM_Client(void) {return (OTM_Client);}
OTM_IDirect3DTexture9* GetLastCreatedTexture(void) {return (LastCreatedTexture);}
int SetLastCreatedTexture(OTM_IDirect3DTexture9* pTexture) {LastCreatedTexture=pTexture; return (RETURN_OK);}
OTM_IDirect3DVolumeTexture9* GetLastCreatedVolumeTexture(void) {return (LastCreatedVolumeTexture);}
int SetLastCreatedVolumeTexture(OTM_IDirect3DVolumeTexture9* pTexture) {LastCreatedVolumeTexture=pTexture; return (RETURN_OK);}
OTM_IDirect3DCubeTexture9* GetLastCreatedCubeTexture(void) {return (LastCreatedCubeTexture);}
int SetLastCreatedCubeTexture(OTM_IDirect3DCubeTexture9* pTexture) {LastCreatedCubeTexture=pTexture; return (RETURN_OK);}
OTM_IDirect3DTexture9* GetSingleTexture(void) {return (SingleTexture);}
OTM_IDirect3DVolumeTexture9* GetSingleVolumeTexture(void) {return (SingleVolumeTexture);}
OTM_IDirect3DCubeTexture9* GetSingleCubeTexture(void) {return (SingleCubeTexture);}
private:
int CreateSingleTexture(void);
int CounterSaveSingleTexture;
OTM_IDirect3DTexture9* SingleTexture;
OTM_IDirect3DVolumeTexture9* SingleVolumeTexture;
OTM_IDirect3DCubeTexture9* SingleCubeTexture;
char SingleTextureMod;
D3DCOLOR TextureColour;
ID3DXFont *OSD_Font;
//D3DCOLOR FontColour;
int OTM_Reference;
IDirect3DDevice9* m_pIDirect3DDevice9;
OTM_IDirect3DTexture9* LastCreatedTexture;
OTM_IDirect3DVolumeTexture9* LastCreatedVolumeTexture;
OTM_IDirect3DCubeTexture9* LastCreatedCubeTexture;
OTM_TextureServer* OTM_Server;
OTM_TextureClient* OTM_Client;
};
+142 -4
View File
@@ -24,9 +24,32 @@ along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
#include "OTM_Main.h"
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DTexture9::QueryInterface(REFIID riid, void** ppvObj)
{
return (m_D3Dtex->QueryInterface(riid, 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 == OTM_IDirect3DTexture9
// 0x01000001L == OTM_IDirect3DVolumeTexture9
// 0x01000002L == OTM_IDirect3DCubeTexture9
*ppvObj = this;
return (0x01000000L);
}
HRESULT hRes;
if (CrossRef_D3Dtex!=NULL)
{
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
@@ -69,12 +92,11 @@ ULONG APIENTRY OTM_IDirect3DTexture9::Release()
if (count==0) //if this texture is released, we clean up
{
// remove this texture from the texture client
((OTM_IDirect3DDevice9*) m_D3Ddev)->GetOTM_Client()->RemoveTexture(this); //this is also valid for textures, which are released before we have add them
// if this texture is the LastCreatedTexture, the next time LastCreatedTexture would be added,
// the hash of a non existing texture would be calculated
if (((OTM_IDirect3DDevice9*)m_D3Ddev)->GetLastCreatedTexture()==this) ((OTM_IDirect3DDevice9*)m_D3Ddev)->SetLastCreatedTexture( NULL);
else ((OTM_IDirect3DDevice9*) m_D3Ddev)->GetOTM_Client()->RemoveTexture(this); // remove this texture from the texture client
delete(this);
}
return (count);
@@ -191,3 +213,119 @@ HRESULT APIENTRY OTM_IDirect3DTexture9::AddDirtyRect(CONST RECT* pDirtyRect)
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->AddDirtyRect(pDirtyRect));
return (m_D3Dtex->AddDirtyRect(pDirtyRect));
}
int OTM_IDirect3DTexture9::GetHash(MyTypeHash &hash)
{
hash=0u;
if (FAKE) return (RETURN_BAD_ARGUMENT);
IDirect3DTexture9 *pTexture = m_D3Dtex;
if (CrossRef_D3Dtex!=NULL) pTexture = CrossRef_D3Dtex->m_D3Dtex;
IDirect3DSurface9 *pOffscreenSurface = NULL;
//IDirect3DTexture9 *pOffscreenTexture = NULL;
IDirect3DSurface9 *pResolvedSurface = NULL;
D3DLOCKED_RECT d3dlr;
D3DSURFACE_DESC desc;
if (pTexture->GetLevelDesc(0, &desc)!=D3D_OK) //get the format and the size of the texture
{
Message("OTM_IDirect3DTexture9::GetHash() Failed: GetLevelDesc \n");
return (RETURN_GetLevelDesc_FAILED);
}
Message("OTM_IDirect3DTexture9::GetHash() (%d %d) %d\n", desc.Width, desc.Height, desc.Format);
if (desc.Pool==D3DPOOL_DEFAULT) //get the raw data of the texture
{
//Message("OTM_IDirect3DTexture9::GetHash() (D3DPOOL_DEFAULT)\n");
IDirect3DSurface9 *pSurfaceLevel_orig = NULL;
if (pTexture->GetSurfaceLevel( 0, &pSurfaceLevel_orig)!=D3D_OK)
{
Message("OTM_IDirect3DTexture9::GetHash() Failed: GetSurfaceLevel 1 (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
{
//Message("OTM_IDirect3DTexture9::GetHash() MultiSampleType\n");
if (D3D_OK!=m_D3Ddev->CreateRenderTarget( desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pResolvedSurface, NULL ))
{
pSurfaceLevel_orig->Release();
Message("OTM_IDirect3DTexture9::GetHash() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
if (D3D_OK!=m_D3Ddev->StretchRect( pSurfaceLevel_orig, NULL, pResolvedSurface, NULL, D3DTEXF_NONE ))
{
pSurfaceLevel_orig->Release();
Message("OTM_IDirect3DTexture9::GetHash() Failed: StretchRect (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
pSurfaceLevel_orig = pResolvedSurface;
}
if (D3D_OK!=m_D3Ddev->CreateOffscreenPlainSurface( desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pOffscreenSurface, NULL))
{
pSurfaceLevel_orig->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
Message("OTM_IDirect3DTexture9::GetHash() Failed: CreateOffscreenPlainSurface (D3DPOOL_DEFAULT)\n");
return (RETURN_TEXTURE_NOT_LOADED);
}
if (D3D_OK!=m_D3Ddev->GetRenderTargetData( pSurfaceLevel_orig, pOffscreenSurface))
{
pSurfaceLevel_orig->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
pOffscreenSurface->Release();
Message("OTM_IDirect3DTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
pSurfaceLevel_orig->Release();
if (pOffscreenSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
pOffscreenSurface->Release();
Message("OTM_IDirect3DTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
}
else if (pTexture->LockRect( 0, &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
Message("OTM_IDirect3DTexture9::GetHash() Failed: LockRect 1\n");
if (pTexture->GetSurfaceLevel(0, &pResolvedSurface)!=D3D_OK)
{
Message("OTM_IDirect3DTexture9::GetHash() Failed: GetSurfaceLevel\n");
return (RETURN_LockRect_FAILED);
}
if (pResolvedSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
pResolvedSurface->Release();
Message("OTM_IDirect3DTexture9::GetHash() Failed: LockRect 2\n");
return (RETURN_LockRect_FAILED);
}
}
int size = (GetBitsFromFormat( desc.Format) * desc.Width*desc.Height)/8;
hash = GetCRC32( (char*) d3dlr.pBits, size); //calculate the crc32 of the texture
if (pOffscreenSurface!=NULL)
{
pOffscreenSurface->UnlockRect();
pOffscreenSurface->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
}
else if (pResolvedSurface!=NULL)
{
pResolvedSurface->UnlockRect();
pResolvedSurface->Release();
}
else pTexture->UnlockRect(0);
Message("OTM_IDirect3DTexture9::GetHash() %#lX (%d %d) %d = %d\n", hash, desc.Width, desc.Height, desc.Format, size);
return (RETURN_OK);
}
+3 -1
View File
@@ -37,7 +37,7 @@ along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
interface OTM_IDirect3DTexture9 : public IDirect3DTexture9
{
OTM_IDirect3DTexture9(IDirect3DTexture9 **ppTex, IDirect3DDevice9 *pIDirect3DDevice9, UINT Width, UINT Height, D3DFORMAT Format)
OTM_IDirect3DTexture9(IDirect3DTexture9 **ppTex, IDirect3DDevice9 *pIDirect3DDevice9)
{
m_D3Dtex = *ppTex; //Texture which will be displayed and will be passed to the game
m_D3Ddev = pIDirect3DDevice9; //device pointer
@@ -81,6 +81,8 @@ interface OTM_IDirect3DTexture9 : public IDirect3DTexture9
STDMETHOD(LockRect)(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags);
STDMETHOD(UnlockRect)(UINT Level);
STDMETHOD(AddDirtyRect)(CONST RECT* pDirtyRect);
int GetHash(MyTypeHash &hash);
};
+365
View File
@@ -0,0 +1,365 @@
/*
This file is part of OpenTexMod.
OpenTexMod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenTexMod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* some function (e.g. AddReff()) are presumed to work on the texture object which belong to them
* if this texture was switched, we must redirect this calls to the CrossRef_D3Dtex texture object
*/
#include "OTM_Main.h"
HRESULT APIENTRY OTM_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 == OTM_IDirect3DTexture9
// 0x01000001L == OTM_IDirect3DVolumeTexture9
// 0x01000002L == OTM_IDirect3DCubeTexture9
*ppvObj = this;
return (0x01000001L);
}
HRESULT hRes;
if (CrossRef_D3Dtex!=NULL)
{
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 OTM_IDirect3DVolumeTexture9::AddRef()
{
if (FAKE) return (1); //bug, this case should never happen
if (CrossRef_D3Dtex!=NULL)
{
return (CrossRef_D3Dtex->m_D3Dtex->AddRef());
}
else return (m_D3Dtex->AddRef());
}
//this function yields for the non switched texture object
ULONG APIENTRY OTM_IDirect3DVolumeTexture9::Release()
{
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!=NULL) //if this texture is switched with a fake texture
{
OTM_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);
if (((OTM_IDirect3DDevice9*)m_D3Ddev)->GetSingleVolumeTexture()!=fake_texture) 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 (((OTM_IDirect3DDevice9*)m_D3Ddev)->GetLastCreatedVolumeTexture()==this) ((OTM_IDirect3DDevice9*)m_D3Ddev)->SetLastCreatedVolumeTexture( NULL);
else ((OTM_IDirect3DDevice9*) m_D3Ddev)->GetOTM_Client()->RemoveTexture(this); // remove this texture from the texture client
delete(this);
}
return (count);
}
HRESULT APIENTRY OTM_IDirect3DVolumeTexture9::GetDevice(IDirect3DDevice9** ppDevice)
{
*ppDevice = m_D3Ddev;
return D3D_OK;
}
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DVolumeTexture9::SetPrivateData(REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags)
{
if (CrossRef_D3Dtex!=NULL) 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 OTM_IDirect3DVolumeTexture9::GetPrivateData(REFGUID refguid,void* pData,DWORD* pSizeOfData)
{
if (CrossRef_D3Dtex!=NULL) 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 OTM_IDirect3DVolumeTexture9::FreePrivateData(REFGUID refguid)
{
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->FreePrivateData(refguid));
return (m_D3Dtex->FreePrivateData(refguid));
}
DWORD APIENTRY OTM_IDirect3DVolumeTexture9::SetPriority(DWORD PriorityNew)
{
return (m_D3Dtex->SetPriority(PriorityNew));
}
DWORD APIENTRY OTM_IDirect3DVolumeTexture9::GetPriority()
{
return (m_D3Dtex->GetPriority());
}
void APIENTRY OTM_IDirect3DVolumeTexture9::PreLoad()
{
m_D3Dtex->PreLoad();
}
D3DRESOURCETYPE APIENTRY OTM_IDirect3DVolumeTexture9::GetType()
{
return (m_D3Dtex->GetType());
}
DWORD APIENTRY OTM_IDirect3DVolumeTexture9::SetLOD(DWORD LODNew)
{
return (m_D3Dtex->SetLOD(LODNew));
}
DWORD APIENTRY OTM_IDirect3DVolumeTexture9::GetLOD()
{
return (m_D3Dtex->GetLOD());
}
DWORD APIENTRY OTM_IDirect3DVolumeTexture9::GetLevelCount()
{
return (m_D3Dtex->GetLevelCount());
}
HRESULT APIENTRY OTM_IDirect3DVolumeTexture9::SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType)
{
return (m_D3Dtex->SetAutoGenFilterType(FilterType));
}
D3DTEXTUREFILTERTYPE APIENTRY OTM_IDirect3DVolumeTexture9::GetAutoGenFilterType()
{
return (m_D3Dtex->GetAutoGenFilterType());
}
void APIENTRY OTM_IDirect3DVolumeTexture9::GenerateMipSubLevels()
{
m_D3Dtex->GenerateMipSubLevels();
}
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DVolumeTexture9::AddDirtyBox(CONST D3DBOX *pDirtyBox)
{
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->AddDirtyBox(pDirtyBox));
return (m_D3Dtex->AddDirtyBox(pDirtyBox));
}
//this function yields for the non switched texture object
HRESULT APIENTRY OTM_IDirect3DVolumeTexture9::GetLevelDesc(UINT Level, D3DVOLUME_DESC *pDesc)
{
if (CrossRef_D3Dtex!=NULL) 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 OTM_IDirect3DVolumeTexture9::GetVolumeLevel(UINT Level, IDirect3DVolume9 **ppVolumeLevel)
{
if (CrossRef_D3Dtex!=NULL) 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 OTM_IDirect3DVolumeTexture9::LockBox(UINT Level, D3DLOCKED_BOX *pLockedVolume, CONST D3DBOX *pBox ,DWORD Flags)
{
if (CrossRef_D3Dtex!=NULL) 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 OTM_IDirect3DVolumeTexture9::UnlockBox(UINT Level)
{
if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->UnlockBox(Level));
return (m_D3Dtex->UnlockBox(Level));
}
int OTM_IDirect3DVolumeTexture9::GetHash(MyTypeHash &hash)
{
hash=0u;
if (FAKE) return (RETURN_BAD_ARGUMENT);
IDirect3DVolumeTexture9 *pTexture = m_D3Dtex;
if (CrossRef_D3Dtex!=NULL) pTexture = CrossRef_D3Dtex->m_D3Dtex;
//IDirect3DVolume9 *pOffscreenSurface = NULL;
//IDirect3DVolumeTexture9 *pOffscreenTexture = NULL;
IDirect3DVolume9 *pResolvedSurface = NULL;
D3DLOCKED_BOX d3dlr;
D3DVOLUME_DESC desc;
if (pTexture->GetLevelDesc(0, &desc)!=D3D_OK) //get the format and the size of the texture
{
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: GetLevelDesc \n");
return (RETURN_GetLevelDesc_FAILED);
}
Message("OTM_IDirect3DVolumeTexture9::GetHash() (%d %d %d) %d\n", desc.Width, desc.Height, desc.Depth, desc.Format);
/*
if (desc.Pool==D3DPOOL_DEFAULT) //get the raw data of the texture
{
//Message("OTM_IDirect3DVolumeTexture9::GetHash() (D3DPOOL_DEFAULT)\n");
IDirect3DSurface9 *pSurfaceLevel_orig = NULL;
if (pTexture->GetSurfaceLevel( 0, &pSurfaceLevel_orig)!=D3D_OK)
{
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel 1 (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
/*
if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
{
//Message("OTM_IDirect3DVolumeTexture9::GetHash() MultiSampleType\n");
if (D3D_OK!=m_D3Ddev->CreateRenderTarget( desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &pResolvedSurface, NULL ))
{
pSurfaceLevel_orig->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
if (D3D_OK!=m_D3Ddev->StretchRect( pSurfaceLevel_orig, NULL, pResolvedSurface, NULL, D3DTEXF_NONE ))
{
pSurfaceLevel_orig->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: StretchRect (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
pSurfaceLevel_orig = pResolvedSurface;
}
*/
//CreateTexture(8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DVolumeTexture9**) &SingleTexture, NULL)
/*
if (D3D_OK!=m_D3Ddev->CreateTexture( desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &pOffscreenTexture, NULL))
{
pSurfaceLevel_orig->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: CreateTexture (D3DPOOL_DEFAULT)\n");
return (RETURN_TEXTURE_NOT_LOADED);
}
if (pOffscreenTexture->GetSurfaceLevel( 0, &pOffscreenSurface)!=D3D_OK)
{
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel 2 (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
if (D3D_OK!=m_D3Ddev->GetRenderTargetData( pSurfaceLevel_orig, pOffscreenSurface))
{
pSurfaceLevel_orig->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
pOffscreenSurface->Release();
pOffscreenTexture->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
pSurfaceLevel_orig->Release();
if (pOffscreenSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
pOffscreenSurface->Release();
pOffscreenTexture->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
*/
/*
if (D3D_OK!=m_D3Ddev->CreateOffscreenPlainSurface( desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pOffscreenSurface, NULL))
{
pSurfaceLevel_orig->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: CreateOffscreenPlainSurface (D3DPOOL_DEFAULT)\n");
return (RETURN_TEXTURE_NOT_LOADED);
}
if (D3D_OK!=m_D3Ddev->GetRenderTargetData( pSurfaceLevel_orig, pOffscreenSurface))
{
pSurfaceLevel_orig->Release();
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
pOffscreenSurface->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: GetRenderTargetData (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
pSurfaceLevel_orig->Release();
if (pOffscreenSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
if (pResolvedSurface!=NULL) pResolvedSurface->Release();
pOffscreenSurface->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: LockRect (D3DPOOL_DEFAULT)\n");
return (RETURN_LockRect_FAILED);
}
}
else
*/
if (pTexture->LockBox( 0, &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 1\n");
if (pTexture->GetVolumeLevel(0, &pResolvedSurface)!=D3D_OK)
{
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: GetSurfaceLevel\n");
return (RETURN_LockRect_FAILED);
}
if (pResolvedSurface->LockBox( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK)
{
pResolvedSurface->Release();
Message("OTM_IDirect3DVolumeTexture9::GetHash() Failed: LockRect 2\n");
return (RETURN_LockRect_FAILED);
}
}
int size = (GetBitsFromFormat( desc.Format) * desc.Width*desc.Height*desc.Depth)/8;
hash = GetCRC32( (char*) d3dlr.pBits, size); //calculate the crc32 of the texture
if (pResolvedSurface!=NULL)
{
pResolvedSurface->UnlockBox();
pResolvedSurface->Release();
}
else pTexture->UnlockBox(0);
Message("OTM_IDirect3DVolumeTexture9::GetHash() %#lX (%d %d) %d = %d\n", hash, desc.Width, desc.Height, desc.Format, size);
return (RETURN_OK);
}
+125
View File
@@ -0,0 +1,125 @@
/*
This file is part of OpenTexMod.
OpenTexMod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenTexMod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
*/
/*
*
* BIG THANKS TO Matthew L (Azorbix)
* (Direct3D StarterKit v3.0)
*
*/
#ifndef OTM_IDirect3DVolumeTexture9_H
#define OTM_IDirect3DVolumeTexture9_H
#include <d3d9.h>
#include <d3dx9.h>
#include "OTM_Defines.h"
interface OTM_IDirect3DVolumeTexture9 : public IDirect3DVolumeTexture9
{
OTM_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 **ppTex, IDirect3DDevice9 *pIDirect3DDevice9)
{
m_D3Dtex = *ppTex; //Texture which will be displayed and will be passed to the game
m_D3Ddev = pIDirect3DDevice9; //device pointer
CrossRef_D3Dtex = NULL; //cross reference
// fake texture: store the pointer to the original OTM_IDirect3DVolumeTexture9 object, needed if a fake texture is unselected
// original texture: stores the pointer to the fake texture object, is needed if original texture is deleted,
// thus the fake texture can also be deleted
Reference = -1; //need for fast deleting
Hash = 0u;
FAKE = false;
}
// callback interface
IDirect3DVolumeTexture9 *m_D3Dtex;
OTM_IDirect3DVolumeTexture9 *CrossRef_D3Dtex;
IDirect3DDevice9 *m_D3Ddev;
int Reference;
MyTypeHash Hash;
bool FAKE;
// original interface
STDMETHOD(QueryInterface) (REFIID riid, void** ppvObj);
STDMETHOD_(ULONG,AddRef)();
STDMETHOD_(ULONG,Release)();
STDMETHOD(GetDevice)(IDirect3DDevice9** ppDevice);
STDMETHOD(SetPrivateData)(REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags);
STDMETHOD(GetPrivateData)(REFGUID refguid,void* pData,DWORD* pSizeOfData);
STDMETHOD(FreePrivateData)(REFGUID refguid);
STDMETHOD_(DWORD, SetPriority)(DWORD PriorityNew);
STDMETHOD_(DWORD, GetPriority)();
STDMETHOD_(void, PreLoad)();
STDMETHOD_(D3DRESOURCETYPE, GetType)();
STDMETHOD_(DWORD, SetLOD)(DWORD LODNew);
STDMETHOD_(DWORD, GetLOD)();
STDMETHOD_(DWORD, GetLevelCount)();
STDMETHOD(SetAutoGenFilterType)(D3DTEXTUREFILTERTYPE FilterType);
STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)();
STDMETHOD_(void, GenerateMipSubLevels)();
STDMETHOD(AddDirtyBox)(CONST D3DBOX *pDirtyBox);
STDMETHOD(GetLevelDesc)(UINT Level, D3DVOLUME_DESC *pDesc);
STDMETHOD(GetVolumeLevel)(UINT Level, IDirect3DVolume9 **ppVolumeLevel);
STDMETHOD(LockBox)(UINT Level, D3DLOCKED_BOX *pLockedVolume, CONST D3DBOX *pBox, DWORD Flags);
STDMETHOD(UnlockBox)(UINT Level);
int GetHash(MyTypeHash &hash);
};
inline void UnswitchTextures(OTM_IDirect3DVolumeTexture9 *pTexture)
{
OTM_IDirect3DVolumeTexture9* CrossRef = pTexture->CrossRef_D3Dtex;
if (CrossRef!=NULL)
{
// switch textures back
IDirect3DVolumeTexture9* cpy = pTexture->m_D3Dtex;
pTexture->m_D3Dtex = CrossRef->m_D3Dtex;
CrossRef->m_D3Dtex = cpy;
// cancel the link
CrossRef->CrossRef_D3Dtex = NULL;
pTexture->CrossRef_D3Dtex = NULL;
}
}
inline int SwitchTextures( OTM_IDirect3DVolumeTexture9 *pTexture1, OTM_IDirect3DVolumeTexture9 *pTexture2)
{
if (pTexture1->m_D3Ddev == pTexture2->m_D3Ddev && pTexture1->CrossRef_D3Dtex == NULL && pTexture2->CrossRef_D3Dtex == NULL)
{
// make cross reference
pTexture1->CrossRef_D3Dtex = pTexture2;
pTexture2->CrossRef_D3Dtex = pTexture1;
// switch textures
IDirect3DVolumeTexture9* cpy = pTexture2->m_D3Dtex;
pTexture2->m_D3Dtex = pTexture1->m_D3Dtex;
pTexture1->m_D3Dtex = cpy;
return (RETURN_OK);
}
else return (RETURN_TEXTURE_NOT_SWITCHED);
}
#endif
+4
View File
@@ -39,13 +39,17 @@ along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
#include "../OTM_GlobalDefines.h"
#include "../OTM_Error.h"
#include "OTM_Defines.h"
#include "OTM_DX9_dll.h"
#include "OTM_TextureFunction.h"
#include "OTM_IDirect3D9.h"
#include "OTM_IDirect3DDevice9.h"
#include "OTM_IDirect3DCubeTexture9.h"
#include "OTM_IDirect3DTexture9.h"
#include "OTM_IDirect3DVolumeTexture9.h"
#include "OTM_ArrayHandler.h"
#include "OTM_TextureServer.h"
#include "OTM_TextureClient.h"
+391 -283
View File
@@ -45,6 +45,10 @@ OTM_TextureClient::OTM_TextureClient(OTM_TextureServer* server, IDirect3DDevice9
NumberToMod = 0;
FileToMod = NULL;
}
else
{
for (int i=0; i<NumberToMod; i++) {FileToMod[i].NumberOfTextures=0; FileToMod[i].Textures = NULL;}
}
}
Mutex = CreateMutex(NULL, false, NULL);
@@ -62,7 +66,11 @@ OTM_TextureClient::~OTM_TextureClient(void)
if (Mutex!=NULL) CloseHandle(Mutex);
if (Update!=NULL) delete [] Update;
if (FileToMod!=NULL) delete [] FileToMod;
if (FileToMod!=NULL)
{
for (int i=0; i<NumberToMod; i++) if (FileToMod[i].Textures!=NULL) delete [] FileToMod[i].Textures;
delete [] FileToMod;
}
}
@@ -71,109 +79,13 @@ int OTM_TextureClient::AddTexture( OTM_IDirect3DTexture9* pTexture)
((OTM_IDirect3DDevice9*)D3D9Device)->SetLastCreatedTexture(NULL); //this texture must no be added twice
if (pTexture->FAKE) return (RETURN_OK); // this is a fake texture
Message("OTM_TextureClient::AddTexture( %lu): %lu (thread: %lu)\n", pTexture, this, GetCurrentThread());
Message("OTM_TextureClient::AddTexture( %lu): %lu (thread: %lu)\n", pTexture, this, GetCurrentThreadId());
D3DLOCKED_RECT d3dlr;
if (pTexture->LockRect( 0, &d3dlr, NULL, 0)!=D3D_OK) //get the raw data of the texture
{
return (RETURN_LockRect_FAILED);
}
D3DSURFACE_DESC desc;
if (pTexture->GetLevelDesc(0, &desc)!=D3D_OK) //get the format and the size of the texture
{
pTexture->UnlockRect(0);
return (RETURN_GetLevelDesc_FAILED);
}
int size=0;
switch(desc.Format) //switch trough the formats to calculate the size of the raw data
{
case D3DFMT_A1: // 1-bit monochrome.
{
size = desc.Width*desc.Height/8;
break;
}
case D3DFMT_R3G3B2: // 8-bit RGB texture format using 3 bits for red, 3 bits for green, and 2 bits for blue.
case D3DFMT_A8: // 8-bit alpha only.
case D3DFMT_A8P8: // 8-bit color indexed with 8 bits of alpha.
case D3DFMT_P8: // 8-bit color indexed.
case D3DFMT_L8: // 8-bit luminance only.
case D3DFMT_A4L4: // 8-bit using 4 bits each for alpha and luminance.
case D3DFMT_FORCE_DWORD:
{
size = desc.Width*desc.Height;
break;
}
case D3DFMT_L6V5U5: // 16-bit bump-map format with luminance using 6 bits for luminance, and 5 bits each for v and u.
case D3DFMT_V8U8: // 16-bit bump-map format using 8 bits each for u and v data.
case D3DFMT_R5G6B5: // 16-bit RGB pixel format with 5 bits for red, 6 bits for green, and 5 bits for blue.
case D3DFMT_X1R5G5B5: // 16-bit pixel format where 5 bits are reserved for each color.
case D3DFMT_A1R5G5B5: // 16-bit pixel format where 5 bits are reserved for each color and 1 bit is reserved for alpha.
case D3DFMT_A4R4G4B4: // 16-bit ARGB pixel format with 4 bits for each channel.
case D3DFMT_A8R3G3B2: // 16-bit ARGB texture format using 8 bits for alpha, 3 bits each for red and green, and 2 bits for blue.
case D3DFMT_X4R4G4B4: // 16-bit RGB pixel format using 4 bits for each color.
case D3DFMT_L16: // 16-bit luminance only.
case D3DFMT_A8L8: // 16-bit using 8 bits each for alpha and luminance.
{
size = 2*desc.Width*desc.Height;
break;
}
case D3DFMT_R8G8B8: //24-bit RGB pixel format with 8 bits per channel.
{
size = 3*desc.Width*desc.Height;
break;
}
case D3DFMT_R32F: // 32-bit float format using 32 bits for the red channel.
case D3DFMT_X8L8V8U8: // 32-bit bump-map format with luminance using 8 bits for each channel.
case D3DFMT_A2W10V10U10: // 32-bit bump-map format using 2 bits for alpha and 10 bits each for w, v, and u.
case D3DFMT_Q8W8V8U8: // 32-bit bump-map format using 8 bits for each channel.
case D3DFMT_V16U16: // 32-bit bump-map format using 16 bits for each channel.
case D3DFMT_A8R8G8B8: // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
case D3DFMT_X8R8G8B8: // 32-bit RGB pixel format, where 8 bits are reserved for each color.
case D3DFMT_A2B10G10R10: // 32-bit pixel format using 10 bits for each color and 2 bits for alpha.
case D3DFMT_A8B8G8R8: // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
case D3DFMT_X8B8G8R8: // 32-bit RGB pixel format, where 8 bits are reserved for each color.
case D3DFMT_G16R16: // 32-bit pixel format using 16 bits each for green and red.
case D3DFMT_A2R10G10B10: // 32-bit pixel format using 10 bits each for red, green, and blue, and 2 bits for alpha.
{
size = 4*desc.Width*desc.Height;
break;
}
case D3DFMT_G32R32F: // 64-bit float format using 32 bits for the red channel and 32 bits for the green channel.
case D3DFMT_Q16W16V16U16: // 64-bit bump-map format using 16 bits for each component.
case D3DFMT_A16B16G16R16: // 64-bit pixel format using 16 bits for each component.
{
size = 8*desc.Width*desc.Height;
break;
}
case D3DFMT_A32B32G32R32F: // 128-bit float format using 32 bits for the each channel (alpha, blue, green, red).
{
size = 16*desc.Width*desc.Height;
break;
}
default: //compressed formats
{
size = desc.Width*desc.Height/2;
break;
}
}
//MyTypeHash hash = GetHash( (unsigned char*) d3dlr.pBits, size);
MyTypeHash hash = GetCRC32( (char*) d3dlr.pBits, size); //calculate the crc32 of the texture
if (pTexture->UnlockRect(0)!=D3D_OK) //unlock the raw data
{
return (RETURN_UnlockRect_FAILED);
}
MyTypeHash hash;
if (int ret = pTexture->GetHash( hash)) return (ret);
pTexture->Hash = hash;
if (BoolSaveAllTextures) SaveTexture(pTexture);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
@@ -183,40 +95,122 @@ int OTM_TextureClient::AddTexture( OTM_IDirect3DTexture9* pTexture)
return (LookUpToMod(pTexture)); // check if this texture should be modded
}
int OTM_TextureClient::AddTexture( OTM_IDirect3DVolumeTexture9* pTexture)
{
((OTM_IDirect3DDevice9*)D3D9Device)->SetLastCreatedVolumeTexture(NULL); //this texture must no be added twice
if (pTexture->FAKE) return (RETURN_OK); // this is a fake texture
Message("OTM_TextureClient::AddTexture( Volume: %lu): %lu (thread: %lu)\n", pTexture, this, GetCurrentThreadId());
MyTypeHash hash;
if (int ret = pTexture->GetHash( hash)) return (ret);
pTexture->Hash = hash;
if (BoolSaveAllTextures) SaveTexture(pTexture);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
OriginalVolumeTextures.Add( pTexture); // add the texture to the list of original texture
return (LookUpToMod(pTexture)); // check if this texture should be modded
}
int OTM_TextureClient::AddTexture( OTM_IDirect3DCubeTexture9* pTexture)
{
((OTM_IDirect3DDevice9*)D3D9Device)->SetLastCreatedCubeTexture(NULL); //this texture must no be added twice
if (pTexture->FAKE) return (RETURN_OK); // this is a fake texture
Message("OTM_TextureClient::AddTexture( Cube: %lu): %lu (thread: %lu)\n", pTexture, this, GetCurrentThreadId());
MyTypeHash hash;
if (int ret = pTexture->GetHash( hash)) return (ret);
pTexture->Hash = hash;
if (BoolSaveAllTextures) SaveTexture(pTexture);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
OriginalCubeTextures.Add( pTexture); // add the texture to the list of original texture
return (LookUpToMod(pTexture)); // check if this texture should be modded
}
int OTM_TextureClient::RemoveTexture( OTM_IDirect3DTexture9* pTexture) // is called from a texture, if it is finally released
{
Message("OTM_TextureClient::RemoveTexture( %lu, %#lX): %lu\n", pTexture, pTexture->Hash, this);
IDirect3DDevice9 *dev = NULL;
if (pTexture != NULL && pTexture->GetDevice(&dev) == D3D_OK)
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
if (pTexture->FAKE)
{
// this condition is senseless, since this function is only called if a OTM_IDirect3DTexture9 object is released
// and OTM_IDirect3DTexture9 object are created only from a OTM_IDirect3DDevice9 object, hence the pointers must be equal
if (dev == D3D9Device)
// we need to set the corresponding FileToMod[X].pTexture to NULL, to avoid a link to a non existing texture object
int ref = pTexture->Reference;
if (ref>=0 && ref<NumberToMod)
{
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
if (pTexture->FAKE)
for (int i=0; i<FileToMod[ref].NumberOfTextures; i++) if (FileToMod[ref].Textures[i] == pTexture)
{
// we need to set the corresponding FileToMod[X].pTexture to NULL, to avoid a link to a non existing texture object
int ref = pTexture->Reference;
if (ref>=0 && ref<NumberToMod && FileToMod[ref].pTexture==pTexture) FileToMod[ref].pTexture = NULL;
}
else
{
/* this is already done in the Release function of the original texture
if (pTexture->CrossRef_D3Dtex!=NULL)
{
OTM_IDirect3DTexture9* fake_texture = pTexture->CrossRef_D3Dtex;
UnswitchTextures(fake_texture);
fake_texture ->Release(); //this will call this->RemoveTexture again and the fake_texture will also be deleted from the FileToMod.
}
*/
return (OriginalTextures.Remove( pTexture)); //remove this texture form the list
FileToMod[ref].NumberOfTextures--;
for (int j=i; j<FileToMod[ref].NumberOfTextures; j++) FileToMod[ref].Textures[j] = FileToMod[ref].Textures[j+1];
}
}
}
else
{
return (OriginalTextures.Remove( pTexture)); //remove this texture form the list
}
return (RETURN_OK);
}
int OTM_TextureClient::RemoveTexture( OTM_IDirect3DVolumeTexture9* pTexture) // is called from a texture, if it is finally released
{
Message("OTM_TextureClient::RemoveTexture( Volume %lu, %#lX): %lu\n", pTexture, pTexture->Hash, this);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
if (pTexture->FAKE)
{
// we need to set the corresponding FileToMod[X].pTexture to NULL, to avoid a link to a non existing texture object
int ref = pTexture->Reference;
if (ref>=0 && ref<NumberToMod)
{
for (int i=0; i<FileToMod[ref].NumberOfTextures; i++) if (FileToMod[ref].Textures[i] == pTexture)
{
FileToMod[ref].NumberOfTextures--;
for (int j=i; j<FileToMod[ref].NumberOfTextures; j++) FileToMod[ref].Textures[j] = FileToMod[ref].Textures[j+1];
}
}
}
else
{
return (OriginalVolumeTextures.Remove( pTexture)); //remove this texture form the list
}
return (RETURN_OK);
}
int OTM_TextureClient::RemoveTexture( OTM_IDirect3DCubeTexture9* pTexture) // is called from a texture, if it is finally released
{
Message("OTM_TextureClient::RemoveTexture( Cube %lu, %#lX): %lu\n", pTexture, pTexture->Hash, this);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
if (pTexture->FAKE)
{
// we need to set the corresponding FileToMod[X].pTexture to NULL, to avoid a link to a non existing texture object
int ref = pTexture->Reference;
if (ref>=0 && ref<NumberToMod)
{
for (int i=0; i<FileToMod[ref].NumberOfTextures; i++) if (FileToMod[ref].Textures[i] == pTexture)
{
FileToMod[ref].NumberOfTextures--;
for (int j=i; j<FileToMod[ref].NumberOfTextures; j++) FileToMod[ref].Textures[j] = FileToMod[ref].Textures[j+1];
}
}
}
else
{
return (OriginalCubeTextures.Remove( pTexture)); //remove this texture form the list
}
return (RETURN_OK);
}
@@ -269,20 +263,51 @@ int OTM_TextureClient::SetGameName( wchar_t *name)
return (RETURN_OK);
}
int OTM_TextureClient::SaveTexture(OTM_IDirect3DTexture9* pTexture)
{
if (pTexture==NULL) return (RETURN_BAD_ARGUMENT);
if (SavePath[0]==0) {Message("OTM_TextureClient::SaveTexture( %#lX, %lu): %lu, SavePath not set\n", pTexture->Hash, pTexture->m_D3Dtex, this); return (RETURN_TEXTURE_NOT_SAVED);}
wchar_t file[MAX_PATH];
if (GameName[0]) swprintf_s( file, MAX_PATH, L"%ls\\%ls_%#lX.dds", SavePath, GameName, pTexture->Hash);
else swprintf_s( file, MAX_PATH, L"%ls\\%#lX.dds", SavePath, pTexture->Hash);
if (GameName[0]) swprintf_s( file, MAX_PATH, L"%ls\\%ls_T_%#lX.dds", SavePath, GameName, pTexture->Hash);
else swprintf_s( file, MAX_PATH, L"%ls\\T_%#lX.dds", SavePath, pTexture->Hash);
Message("OTM_TextureClient::SaveTexture( %ls): %lu\n", file, this);
if (D3D_OK!=D3DXSaveTextureToFileW( file, D3DXIFF_DDS, pTexture->m_D3Dtex, NULL)) return (RETURN_TEXTURE_NOT_SAVED);
return (RETURN_OK);
}
int OTM_TextureClient::SaveTexture(OTM_IDirect3DVolumeTexture9* pTexture)
{
if (pTexture==NULL) return (RETURN_BAD_ARGUMENT);
if (SavePath[0]==0) {Message("OTM_TextureClient::SaveTexture( %#lX, %lu): %lu, SavePath not set\n", pTexture->Hash, pTexture->m_D3Dtex, this); return (RETURN_TEXTURE_NOT_SAVED);}
wchar_t file[MAX_PATH];
if (GameName[0]) swprintf_s( file, MAX_PATH, L"%ls\\%ls_V_%#lX.dds", SavePath, GameName, pTexture->Hash);
else swprintf_s( file, MAX_PATH, L"%ls\\V_%#lX.dds", SavePath, pTexture->Hash);
Message("OTM_TextureClient::SaveTexture( %ls): %lu\n", file, this);
if (D3D_OK!=D3DXSaveTextureToFileW( file, D3DXIFF_DDS, pTexture->m_D3Dtex, NULL)) return (RETURN_TEXTURE_NOT_SAVED);
return (RETURN_OK);
}
int OTM_TextureClient::SaveTexture(OTM_IDirect3DCubeTexture9* pTexture)
{
if (pTexture==NULL) return (RETURN_BAD_ARGUMENT);
if (SavePath[0]==0) {Message("OTM_TextureClient::SaveTexture( %#lX, %lu): %lu, SavePath not set\n", pTexture->Hash, pTexture->m_D3Dtex, this); return (RETURN_TEXTURE_NOT_SAVED);}
wchar_t file[MAX_PATH];
if (GameName[0]) swprintf_s( file, MAX_PATH, L"%ls\\%ls_C_%#lX.dds", SavePath, GameName, pTexture->Hash);
else swprintf_s( file, MAX_PATH, L"%ls\\C_%#lX.dds", SavePath, pTexture->Hash);
Message("OTM_TextureClient::SaveTexture( %ls): %lu\n", file, this);
if (D3D_OK!=D3DXSaveTextureToFileW( file, D3DXIFF_DDS, pTexture->m_D3Dtex, NULL)) return (RETURN_TEXTURE_NOT_SAVED);
return (RETURN_OK);
}
int OTM_TextureClient::AddUpdate(TextureFileStruct* update, int number) //client must delete the update array
@@ -304,7 +329,7 @@ int OTM_TextureClient::MergeUpdate(void)
Message("MergeUpdate(): %lu\n", this);
for (int i=0; i<NumberOfUpdate; i++) Update[i].pTexture = NULL; // this is already done, but safety comes first ^^
for (int i=0; i<NumberOfUpdate; i++) {Update[i].NumberOfTextures=0; Update[i].Textures = NULL;} // this is already done, but safety comes first ^^
int pos_old=0;
int pos_new=0;
@@ -333,48 +358,95 @@ int OTM_TextureClient::MergeUpdate(void)
}
else if (FileToMod[pos_old].Hash < Update[pos_new].Hash) // this fake texture is not in the update
{
if (FileToMod[pos_old].pTexture!=NULL) FileToMod[pos_old].pTexture->Release(); // we release the fake texture
for (int i=0; i<FileToMod[pos_old].NumberOfTextures; i++) FileToMod[pos_old].Textures[i]->Release(); // we release the fake textures
if (FileToMod[pos_old].Textures!=NULL) delete [] FileToMod[pos_old].Textures; // we delete the memory
pos_old++; // we increase only the old counter by one
}
else // the hash value is the same, thus this texture is in the array FileToMod as well as in the array Update
{
if (FileToMod[pos_old].pTexture!=NULL)
if (Update[pos_new].ForceReload)
{
if (Update[pos_new].ForceReload)
if (FileToMod[pos_old].NumberOfTextures>0)
{
OTM_IDirect3DTexture9 *pTexture = FileToMod[pos_old].pTexture->CrossRef_D3Dtex;
FileToMod[pos_old].pTexture->Release(); // release the old fake texture
FileToMod[pos_old].pTexture = NULL;
if (pTexture!=NULL) // should always be the case
Update[pos_new].Textures = new IDirect3DBaseTexture9*[FileToMod[pos_old].NumberOfTextures];
}
for (int i=0; i<FileToMod[pos_old].NumberOfTextures; i++)
{
IDirect3DBaseTexture9 *base_texture;
int ret = FileToMod[pos_old].Textures[i]->QueryInterface( IID_IDirect3D9, (void**)&base_texture);
switch (ret)
{
OTM_IDirect3DTexture9 *fake_Texture;
if (int ret = LoadTexture( & (Update[pos_new]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
case 0x01000000L:
{
Message("MergeUpdate(): textures not switched %#lX\n", pTexture->Hash);
fake_Texture->Release();
OTM_IDirect3DTexture9 *pTexture = (OTM_IDirect3DTexture9*) FileToMod[pos_old].Textures[i];//
OTM_IDirect3DTexture9 *pRefTexture = pTexture->CrossRef_D3Dtex;
FileToMod[pos_old].Textures[i]->Release();
FileToMod[pos_old].Textures[i] = NULL;
OTM_IDirect3DTexture9 *fake_Texture;
if (int ret = LoadTexture( & (Update[pos_new]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
Message("MergeUpdate(): textures not switched %#lX\n", pTexture->Hash);
fake_Texture->Release();
}
else
{
Update[pos_new].Textures[Update[pos_new].NumberOfTextures++] = fake_Texture;
fake_Texture->Reference = pos_new;
}
break;
}
else
case 0x01000001L:
{
Update[pos_new].pTexture = fake_Texture;
fake_Texture->Reference = pos_new;
OTM_IDirect3DVolumeTexture9 *pTexture = (OTM_IDirect3DVolumeTexture9*) FileToMod[pos_old].Textures[i];//
OTM_IDirect3DVolumeTexture9 *pRefTexture = pTexture->CrossRef_D3Dtex;
FileToMod[pos_old].Textures[i]->Release();
FileToMod[pos_old].Textures[i] = NULL;
OTM_IDirect3DVolumeTexture9 *fake_Texture;
if (int ret = LoadTexture( & (Update[pos_new]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
Message("MergeUpdate(): textures not switched %#lX\n", pTexture->Hash);
fake_Texture->Release();
}
else
{
Update[pos_new].Textures[Update[pos_new].NumberOfTextures++] = fake_Texture;
fake_Texture->Reference = pos_new;
}
break;
}
case 0x01000002L:
{
OTM_IDirect3DCubeTexture9 *pTexture = (OTM_IDirect3DCubeTexture9*) FileToMod[pos_old].Textures[i];//
OTM_IDirect3DCubeTexture9 *pRefTexture = pTexture->CrossRef_D3Dtex;
FileToMod[pos_old].Textures[i]->Release();
FileToMod[pos_old].Textures[i] = NULL;
OTM_IDirect3DCubeTexture9 *fake_Texture;
if (int ret = LoadTexture( & (Update[pos_new]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
Message("MergeUpdate(): textures not switched %#lX\n", pTexture->Hash);
fake_Texture->Release();
}
else
{
Update[pos_new].Textures[Update[pos_new].NumberOfTextures++] = fake_Texture;
fake_Texture->Reference = pos_new;
}
break;
}
default:
break; // this is no fake texture and QueryInterface failed, because IDirect3DBaseTexture9 object cannot be a IDirect3D9 object ;)
}
}
else
{
Update[pos_new].pTexture = FileToMod[pos_old].pTexture;
Update[pos_new].pTexture->Reference = pos_new; // set the new reference, needed for a fast delete
}
}
/*
else
else // the texture might be loaded or not
{
// This texture is not loaded, because the game did not load the target texture,
// thus we need not to look later for this hash.
// -> There is nothing to do.
Update[pos_new].NumberOfTextures = FileToMod[pos_old].NumberOfTextures;
Update[pos_new].Textures = FileToMod[pos_old].Textures;
FileToMod[pos_old].Textures = NULL;
}
*/
// we increase both counters by one
pos_old++;
pos_new++;
@@ -383,7 +455,8 @@ int OTM_TextureClient::MergeUpdate(void)
while (pos_old<NumberToMod) //this fake textures are not in the Update
{
if (FileToMod[pos_old].pTexture!=NULL) FileToMod[pos_old].pTexture->Release();
for (int i=0; i<FileToMod[pos_old].NumberOfTextures; i++) FileToMod[pos_old].Textures[i]->Release(); // we release the fake textures
if (FileToMod[pos_old].Textures!=NULL) delete [] FileToMod[pos_old].Textures; // we delete the memory
pos_old++;
}
while (pos_new<NumberOfUpdate) //this fake textures are newly added
@@ -401,10 +474,14 @@ int OTM_TextureClient::MergeUpdate(void)
* thus Update[to_lookup[pos]].Hash is also sorted ascending!
*/
OTM_IDirect3DTexture9 *single_texture = ((OTM_IDirect3DDevice9*)D3D9Device)->GetSingleTexture();
if (num_to_lookup>0)
{
int num = OriginalTextures.GetNumber();
for (int i=0; i<num; i++)
if (OriginalTextures[i]->CrossRef_D3Dtex==NULL || OriginalTextures[i]->CrossRef_D3Dtex==single_texture)
// We need look only for textures, that are not switched or switched with the single_texture.
// The single_texture is a special texture, which you can toggle through all original texture, if save single texture is turned on.
{
MyTypeHash hash = OriginalTextures[i]->Hash;
@@ -412,48 +489,53 @@ int OTM_TextureClient::MergeUpdate(void)
int index = -1;
int pos = num_to_lookup/2;
int old_pos = -1;
int begin = 0;
int end = num_to_lookup-1;
// we look always in the middle of the interval and each step we halve the interval
while (old_pos!=pos) // if (old_pos==pos) the interval has a size of one or two -> we are finished
// We look in the middle of the interval and each step we halve the interval,
// unless we find the texture or the size of the interval is less than 3.
// Note: contradicting to normal C-code here the interval includes the index "begin" and "end"!
while (begin+1<end) // as long as the interval is longer than two
{
old_pos=pos;
//old_pos=pos;
if (hash > Update[to_lookup[pos]].Hash) // the new interval is the right half of the actual interval
{
begin = pos;
pos = (begin + end)/2;
begin = pos+1; // the new interval does not contain the index "pos"
pos = (begin + end)/2; // set "pos" somewhere inside the new intervall
}
else if (hash < Update[to_lookup[pos]].Hash) // the new interval is the left half of the actual interval
{
end = pos;
pos = (begin + end)/2;
end = pos-1; // the new interval does not contain the index "pos"
pos = (begin + end)/2; // set "pos" somewhere inside the new intervall
}
else {index = to_lookup[pos]; break;} // we hit the correct hash
}
if (index<0) // if we did not find the hash, it might be in the last interval, which has a size of one or two
if (index<0) // if we did not find the hash, it might be in the last interval
{
if (Update[to_lookup[pos]].Hash==hash) index = to_lookup[pos];
else if (++pos<num_to_lookup && Update[to_lookup[pos]].Hash==hash) index = to_lookup[pos];
for (int i=begin; i<=end; i++) if (Update[to_lookup[i]].Hash==hash) index = to_lookup[i];
}
if (index>=0) // target texture is loaded by the game
{
if (Update[index].pTexture==NULL) // if not this is a bug!!
if (OriginalTextures[i]->CrossRef_D3Dtex!=NULL) UnswitchTextures(OriginalTextures[i]); // this texture was switched with the single texture
OTM_IDirect3DTexture9 *fake_Texture;
if (int ret = LoadTexture( & (Update[index]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, OriginalTextures[i]))
{
OTM_IDirect3DTexture9 *fake_Texture;
if (int ret = LoadTexture( & (Update[index]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, OriginalTextures[i]))
{
Message("OTM_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash);
fake_Texture->Release();
}
else
{
Update[index].pTexture = fake_Texture;
fake_Texture->Reference = index;
}
Message("OTM_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash);
fake_Texture->Release();
}
else
{
IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[Update[index].NumberOfTextures+1];
for (int j=0; j<Update[index].NumberOfTextures; j++) temp[j] = Update[index].Textures[j];
if (Update[index].Textures!=NULL) delete [] Update[index].Textures;
Update[index].Textures = temp;
Update[index].Textures[Update[index].NumberOfTextures++] = fake_Texture;
fake_Texture->Reference = index;
}
}
}
@@ -488,89 +570,126 @@ int OTM_TextureClient::UnlockMutex(void)
int OTM_TextureClient::LookUpToMod( MyTypeHash hash)
{
if(NumberToMod>0)
{
if (hash<FileToMod[0].Hash || hash>FileToMod[NumberToMod-1].Hash) return (-1);
int pos = NumberToMod/2;
int begin = 0;
int end = NumberToMod-1;
// We look in the middle of the interval and each step we halve the interval,
// unless we find the texture or the size of the interval is less than 3.
// Note: contradicting to normal C-code here the interval includes the index "begin" and "end"!
while (begin+1<end) // as long as the interval is longer than two
{
if (hash > FileToMod[pos].Hash) // the new interval is the right half of the actual interval
{
begin = pos+1; // the new interval does not contain the index "pos"
pos = (begin + end)/2; // set "pos" somewhere inside the new intervall
}
else if (hash < FileToMod[pos].Hash) // the new interval is the left half of the actual interval
{
end = pos-1; // the new interval does not contain the index "pos"
pos = (begin + end)/2; // set "pos" somewhere inside the new intervall
}
else {return (pos); break;} // we hit the correct hash
}
for (int i=begin; i<=end; i++) if (FileToMod[i].Hash==hash) return (i);
}
return (-1);
}
int OTM_TextureClient::LookUpToMod( OTM_IDirect3DTexture9* pTexture) // should only be called for original textures
{
Message("OTM_TextureClient::LookUpToMod( %lu): hash: %#lX, %lu\n", pTexture, pTexture->Hash, this);
if (pTexture->CrossRef_D3Dtex!=NULL) return (RETURN_OK); // bug, this texture is already switched
int index = -1;
if(NumberToMod>0)
{
MyTypeHash hash = pTexture->Hash;
if (hash<FileToMod[0].Hash || hash>FileToMod[NumberToMod-1].Hash) return (RETURN_OK);
int pos = NumberToMod/2;
int old_pos = -1;
int begin = 0;
int end = NumberToMod-1;
// we look always in the middle of the interval and each step we halve the interval
while (old_pos!=pos) // if (old_pos==pos) the interval has a size of one or two -> we are finished
{
old_pos=pos;
if (hash > FileToMod[pos].Hash) // the new interval is the right half of the actual interval
{
begin = pos;
pos = (begin + end)/2;
}
else if (hash < FileToMod[pos].Hash) // the new interval is the left half of the actual interval
{
end = pos;
pos = (begin + end)/2;
}
else {index = pos; break;} // we hit the correct hash
}
if (index<0) // if we did not find the hash, it might be in the last interval, which has a size of one or two
{
if (FileToMod[pos].Hash==hash) index = pos;
else if (++pos<NumberToMod && FileToMod[pos].Hash==hash) index = pos;
}
}
int index = LookUpToMod( pTexture->Hash);
if (index>=0)
{
// if (FileToMod[index].pTexture!=NULL) the corresponding fake texture is already switched, thus the game has loaded textures with the same hash
if (FileToMod[index].pTexture==NULL)
OTM_IDirect3DTexture9 *fake_Texture;
if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
OTM_IDirect3DTexture9 *fake_Texture;
if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
Message("OTM_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash);
fake_Texture->Release();
}
else
{
FileToMod[index].pTexture = fake_Texture;
fake_Texture->Reference = index;
}
Message("OTM_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash);
fake_Texture->Release();
}
}
else
{
IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1];
for (int j=0; j<FileToMod[index].NumberOfTextures; j++) temp[j] = FileToMod[index].Textures[j];
/*
MyTypeHash hash = pTexture->Hash;
for (int i=0; i<NumberToMod; i++) if (hash == FileToMod[i].Hash)
{
// if (FileToMod[i].pTexture!=NULL) the corresponding fake texture is already switched, thus the game has loaded textures with the same hash
if (FileToMod[i].pTexture==NULL)
{
OTM_IDirect3DTexture9 *fake_Texture;
if (int ret = LoadTexture( & (FileToMod[i]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
Message("OTM_TextureClient::LookUpToMod(): textures not switched %#lX\n", hash);
fake_Texture->Release();
}
else
{
FileToMod[i].pTexture = fake_Texture;
fake_Texture->Reference = i;
}
if (FileToMod[index].Textures!=NULL) delete [] FileToMod[index].Textures;
FileToMod[index].Textures = temp;
FileToMod[index].Textures[FileToMod[index].NumberOfTextures++] = fake_Texture;
fake_Texture->Reference = index;
}
break;
}
*/
return (RETURN_OK);
}
int OTM_TextureClient::LookUpToMod( OTM_IDirect3DVolumeTexture9* pTexture) // should only be called for original textures
{
Message("OTM_TextureClient::LookUpToMod( Volume %lu): hash: %#lX, %lu\n", pTexture, pTexture->Hash, this);
if (pTexture->CrossRef_D3Dtex!=NULL) return (RETURN_OK); // bug, this texture is already switched
int index = LookUpToMod( pTexture->Hash);
if (index>=0)
{
OTM_IDirect3DVolumeTexture9 *fake_Texture;
if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
Message("OTM_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash);
fake_Texture->Release();
}
else
{
IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1];
for (int j=0; j<FileToMod[index].NumberOfTextures; j++) temp[j] = FileToMod[index].Textures[j];
if (FileToMod[index].Textures!=NULL) delete [] FileToMod[index].Textures;
FileToMod[index].Textures = temp;
FileToMod[index].Textures[FileToMod[index].NumberOfTextures++] = fake_Texture;
fake_Texture->Reference = index;
}
}
return (RETURN_OK);
}
int OTM_TextureClient::LookUpToMod( OTM_IDirect3DCubeTexture9* pTexture) // should only be called for original textures
{
Message("OTM_TextureClient::LookUpToMod( Cube %lu): hash: %#lX, %lu\n", pTexture, pTexture->Hash, this);
if (pTexture->CrossRef_D3Dtex!=NULL) return (RETURN_OK); // bug, this texture is already switched
int index = LookUpToMod( pTexture->Hash);
if (index>=0)
{
OTM_IDirect3DCubeTexture9 *fake_Texture;
if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret);
if (SwitchTextures( fake_Texture, pTexture))
{
Message("OTM_TextureClient::LookUpToMod(): textures not switched %#lX\n", FileToMod[index].Hash);
fake_Texture->Release();
}
else
{
IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1];
for (int j=0; j<FileToMod[index].NumberOfTextures; j++) temp[j] = FileToMod[index].Textures[j];
if (FileToMod[index].Textures!=NULL) delete [] FileToMod[index].Textures;
FileToMod[index].Textures = temp;
FileToMod[index].Textures[FileToMod[index].NumberOfTextures++] = fake_Texture;
fake_Texture->Reference = index;
}
}
return (RETURN_OK);
}
int OTM_TextureClient::LoadTexture( TextureFileStruct* file_in_memory, OTM_IDirect3DTexture9 **ppTexture) // to load fake texture from a file in memory
{
@@ -586,45 +705,34 @@ int OTM_TextureClient::LoadTexture( TextureFileStruct* file_in_memory, OTM_IDire
return (RETURN_OK);
}
/*
MyTypeHash OTM_TextureClient::GetHash(unsigned char *str, int len) // estimate the hash
int OTM_TextureClient::LoadTexture( TextureFileStruct* file_in_memory, OTM_IDirect3DVolumeTexture9 **ppTexture) // to load fake texture from a file in memory
{
MyTypeHash hash = 0;
for (int i=0; i<len; i++) hash = str[i] + (hash << 6) + (hash << 16) - hash;
return (hash);
}
*/
/*
*
* BIG THANKS TO RS !!
*
* who gave me his hashing algorithm (well or crc32 algorithm^^)
*
The hash function is CRC32 using polynomial 0xEDB88320.
However, the hashed data is calculated incorrectly in TexMod: it's simply BytesPerPixel * Width * Height, from the beginning of the data (that is mapped using LockRect).
The problem is that it doesn't take the pitch into account and BytesPerPixel may be wrong for some rare formats (not sure about that).
*/
#define CRC32POLY 0xEDB88320u /* CRC-32 Polynom */
#define ulCrc_in 0xffffffff
unsigned int OTM_TextureClient::GetCRC32( char *pcDatabuf, unsigned int ulDatalen)
{
unsigned int crc = ulCrc_in;
for (unsigned int idx = 0u; idx<ulDatalen; idx++)
Message("LoadTexture( Volume %lu, %lu, %#lX): %lu\n", file_in_memory, ppTexture, file_in_memory->Hash, this);
if (D3D_OK != D3DXCreateVolumeTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DVolumeTexture9 **) ppTexture))
{
unsigned int data = *pcDatabuf++;
for (unsigned int bit = 0u; bit<8u; bit++, data >>=1)
{
crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32POLY : 0);
}
*ppTexture=NULL;
return (RETURN_TEXTURE_NOT_LOADED);
}
return (crc);
(*ppTexture)->FAKE = true;
((OTM_IDirect3DDevice9*)D3D9Device)->SetLastCreatedVolumeTexture(NULL); //this texture is a fake texture and must not be added
Message("LoadTexture( Volume %lu, %#lX): DONE\n", *ppTexture, file_in_memory->Hash);
return (RETURN_OK);
}
int OTM_TextureClient::LoadTexture( TextureFileStruct* file_in_memory, OTM_IDirect3DCubeTexture9 **ppTexture) // to load fake texture from a file in memory
{
Message("LoadTexture( Cube %lu, %lu, %#lX): %lu\n", file_in_memory, ppTexture, file_in_memory->Hash, this);
if (D3D_OK != D3DXCreateCubeTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DCubeTexture9 **) ppTexture))
{
*ppTexture=NULL;
return (RETURN_TEXTURE_NOT_LOADED);
}
(*ppTexture)->FAKE = true;
((OTM_IDirect3DDevice9*)D3D9Device)->SetLastCreatedCubeTexture(NULL); //this texture is a fake texture and must not be added
Message("LoadTexture( Cube %lu, %#lX): DONE\n", *ppTexture, file_in_memory->Hash);
return (RETURN_OK);
}
+20 -3
View File
@@ -41,7 +41,12 @@ public:
~OTM_TextureClient(void);
int AddTexture( OTM_IDirect3DTexture9* tex); //called from OTM_IDirect3DDevice9::CreateTexture(...) or OTM_IDirect3DDevice9::BeginScene()
int AddTexture( OTM_IDirect3DVolumeTexture9* tex); //called from OTM_IDirect3DVolumeTexture9::CreateTexture(...) or OTM_IDirect3DDevice9::BeginScene()
int AddTexture( OTM_IDirect3DCubeTexture9* tex); //called from OTM_IDirect3DCubeTexture9::CreateTexture(...) or OTM_IDirect3DDevice9::BeginScene()
int RemoveTexture( OTM_IDirect3DTexture9* tex); //called from OTM_IDirect3DTexture9::Release()
int RemoveTexture( OTM_IDirect3DVolumeTexture9* tex); //called from OTM_IDirect3DVolumeTexture9::Release()
int RemoveTexture( OTM_IDirect3DCubeTexture9* tex); //called from OTM_IDirect3DCubeTexture9::Release()
int SaveAllTextures(bool val); //called from the Server
int SaveSingleTexture(bool val); //called from the Server
@@ -50,6 +55,9 @@ public:
int SetGameName( wchar_t *dir); //called from the Server
int SaveTexture(OTM_IDirect3DTexture9* pTexture); //called from OTM_IDirect3DDevice9::BeginScene() (save button) or from AddTexture(...) (SaveAllTextures)
int SaveTexture(OTM_IDirect3DVolumeTexture9* pTexture); //called from OTM_IDirect3DDevice9::BeginScene() (save button) or from AddTexture(...) (SaveAllTextures)
int SaveTexture(OTM_IDirect3DCubeTexture9* pTexture); //called from OTM_IDirect3DDevice9::BeginScene() (save button) or from AddTexture(...) (SaveAllTextures)
int SetKeyBack( int key) {if (key>0) KeyBack = key; return (RETURN_OK);} //called from the Server
@@ -63,8 +71,14 @@ public:
int AddUpdate(TextureFileStruct* update, int number); //called from the Server, client object must delete update array
int MergeUpdate(void); //called from OTM_IDirect3DDevice9::BeginScene()
int LookUpToMod( OTM_IDirect3DTexture9* pTexture); // called at the end AddTexture(...) and from Device->UpdateTexture(...)
int LookUpToMod( OTM_IDirect3DVolumeTexture9* pTexture); // called at the end AddTexture(...) and from Device->UpdateTexture(...)
int LookUpToMod( OTM_IDirect3DCubeTexture9* pTexture); // called at the end AddTexture(...) and from Device->UpdateTexture(...)
OTM_TextureHandler<OTM_IDirect3DTexture9> OriginalTextures; // stores the pointer to the OTM_IDirect3DTexture9 objects created by the game
OTM_TextureHandler<OTM_IDirect3DVolumeTexture9> OriginalVolumeTextures; // stores the pointer to the OTM_IDirect3DVolumeTexture9 objects created by the game
OTM_TextureHandler<OTM_IDirect3DCubeTexture9> OriginalCubeTextures; // stores the pointer to the OTM_IDirect3DCubeTexture9 objects created by the game
OTM_TextureHandler OriginalTextures; // stores the pointer to the OTM_IDirect3DTexture9 objects created by the game
bool BoolSaveAllTextures;
bool BoolSaveSingleTexture;
int KeyBack;
@@ -91,12 +105,15 @@ private:
TextureFileStruct* FileToMod; // array which stores the file in memory and the hash of each texture to be modded
int LookUpToMod( OTM_IDirect3DTexture9* pTexture); // called at the end AddTexture(...)
int LookUpToMod( MyTypeHash hash); // called from LookUpToMod(...);
int LoadTexture( TextureFileStruct* file_in_memory, OTM_IDirect3DTexture9 **ppTexture); // called if a target texture is found
int LoadTexture( TextureFileStruct* file_in_memory, OTM_IDirect3DVolumeTexture9 **ppTexture); // called if a target texture is found
int LoadTexture( TextureFileStruct* file_in_memory, OTM_IDirect3DCubeTexture9 **ppTexture); // called if a target texture is found
// and the corresponding fake texture should be loaded
//MyTypeHash GetHash(unsigned char *str, int len);
unsigned int GetCRC32(char *pcDatabuf, unsigned int ulDatalen);
//unsigned int GetCRC32(char *pcDatabuf, unsigned int ulDatalen);
};
+51
View File
@@ -0,0 +1,51 @@
/*
* OTM_TextureFunction.cpp
*
* Created on: 28.10.2011
* Author: marts
*/
#include "OTM_Main.h"
/*
MyTypeHash GetHash(unsigned char *str, int len) // estimate the hash
{
MyTypeHash hash = 0;
for (int i=0; i<len; i++) hash = str[i] + (hash << 6) + (hash << 16) - hash;
return (hash);
}
*/
/*
*
* BIG THANKS TO RS !!
*
* who gave me his hashing algorithm (well or crc32 algorithm^^)
*
The hash function is CRC32 using polynomial 0xEDB88320.
However, the hashed data is calculated incorrectly in TexMod: it's simply BytesPerPixel * Width * Height, from the beginning of the data (that is mapped using LockRect).
The problem is that it doesn't take the pitch into account and BytesPerPixel may be wrong for some rare formats (not sure about that).
*/
#define CRC32POLY 0xEDB88320u /* CRC-32 Polynom */
#define ulCrc_in 0xffffffff
unsigned int GetCRC32( char *pcDatabuf, unsigned int ulDatalen)
{
unsigned int crc = ulCrc_in;
for (unsigned int idx = 0u; idx<ulDatalen; idx++)
{
unsigned int data = *pcDatabuf++;
for (unsigned int bit = 0u; bit<8u; bit++, data >>=1)
{
crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32POLY : 0);
}
}
return (crc);
}
+96
View File
@@ -0,0 +1,96 @@
/*
* OTM_TextureFunction.h
*
* Created on: 28.10.2011
* Author: marts
*/
#ifndef OTM_TEXTUREFUNCTION_H_
#define OTM_TEXTUREFUNCTION_H_
unsigned int GetCRC32( char *pcDatabuf, unsigned int ulDatalen);
inline int GetBitsFromFormat(D3DFORMAT format)
{
switch(format) //switch trough the formats to calculate the size of the raw data
{
case D3DFMT_A1: // 1-bit monochrome.
{
return (1);
break;
}
case D3DFMT_R3G3B2: // 8-bit RGB texture format using 3 bits for red, 3 bits for green, and 2 bits for blue.
case D3DFMT_A8: // 8-bit alpha only.
case D3DFMT_A8P8: // 8-bit color indexed with 8 bits of alpha.
case D3DFMT_P8: // 8-bit color indexed.
case D3DFMT_L8: // 8-bit luminance only.
case D3DFMT_A4L4: // 8-bit using 4 bits each for alpha and luminance.
case D3DFMT_FORCE_DWORD:
{
return (8);
break;
}
case D3DFMT_L6V5U5: // 16-bit bump-map format with luminance using 6 bits for luminance, and 5 bits each for v and u.
case D3DFMT_V8U8: // 16-bit bump-map format using 8 bits each for u and v data.
case D3DFMT_R5G6B5: // 16-bit RGB pixel format with 5 bits for red, 6 bits for green, and 5 bits for blue.
case D3DFMT_X1R5G5B5: // 16-bit pixel format where 5 bits are reserved for each color.
case D3DFMT_A1R5G5B5: // 16-bit pixel format where 5 bits are reserved for each color and 1 bit is reserved for alpha.
case D3DFMT_A4R4G4B4: // 16-bit ARGB pixel format with 4 bits for each channel.
case D3DFMT_A8R3G3B2: // 16-bit ARGB texture format using 8 bits for alpha, 3 bits each for red and green, and 2 bits for blue.
case D3DFMT_X4R4G4B4: // 16-bit RGB pixel format using 4 bits for each color.
case D3DFMT_L16: // 16-bit luminance only.
case D3DFMT_A8L8: // 16-bit using 8 bits each for alpha and luminance.
{
return (16);
break;
}
case D3DFMT_R8G8B8: //24-bit RGB pixel format with 8 bits per channel.
{
return (24);
break;
}
case D3DFMT_R32F: // 32-bit float format using 32 bits for the red channel.
case D3DFMT_X8L8V8U8: // 32-bit bump-map format with luminance using 8 bits for each channel.
case D3DFMT_A2W10V10U10: // 32-bit bump-map format using 2 bits for alpha and 10 bits each for w, v, and u.
case D3DFMT_Q8W8V8U8: // 32-bit bump-map format using 8 bits for each channel.
case D3DFMT_V16U16: // 32-bit bump-map format using 16 bits for each channel.
case D3DFMT_A8R8G8B8: // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
case D3DFMT_X8R8G8B8: // 32-bit RGB pixel format, where 8 bits are reserved for each color.
case D3DFMT_A2B10G10R10: // 32-bit pixel format using 10 bits for each color and 2 bits for alpha.
case D3DFMT_A8B8G8R8: // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
case D3DFMT_X8B8G8R8: // 32-bit RGB pixel format, where 8 bits are reserved for each color.
case D3DFMT_G16R16: // 32-bit pixel format using 16 bits each for green and red.
case D3DFMT_A2R10G10B10: // 32-bit pixel format using 10 bits each for red, green, and blue, and 2 bits for alpha.
{
return (32);
break;
}
case D3DFMT_G32R32F: // 64-bit float format using 32 bits for the red channel and 32 bits for the green channel.
case D3DFMT_Q16W16V16U16: // 64-bit bump-map format using 16 bits for each component.
case D3DFMT_A16B16G16R16: // 64-bit pixel format using 16 bits for each component.
{
return (64);
break;
}
case D3DFMT_A32B32G32R32F: // 128-bit float format using 32 bits for the each channel (alpha, blue, green, red).
{
return (128);
break;
}
default: //compressed formats
{
return (4);
break;
}
}
}
#endif /* OTM_TEXTUREFUNCTION_H_ */
+8 -5
View File
@@ -23,8 +23,6 @@ along with OpenTexMod. If not, see <http://www.gnu.org/licenses/>.
OTM_TextureServer::OTM_TextureServer(wchar_t *game)
{
Message("OTM_TextureServer(void): %lu\n", this);
Message("sizeof(unsigned long)=%lu\n", sizeof(unsigned long));
Message("sizeof(DWORDLONG)=%lu\n", sizeof(DWORDLONG));
Mutex = CreateMutex(NULL, false, NULL);
@@ -212,7 +210,9 @@ int OTM_TextureServer::AddFile( char* buffer, unsigned int size, MyTypeHash has
for (unsigned int i=0; i<size; i++) temp->pData[i] = buffer[i];
temp->Size = size;
temp->pTexture = NULL;
temp->NumberOfTextures = 0;
temp->Reference = -1;
temp->Textures = NULL;
temp->Hash = hash;
if (new_file) temp->ForceReload = false; // no need to force a load of the texture
@@ -296,7 +296,9 @@ int OTM_TextureServer::AddFile(wchar_t* file_name, MyTypeHash hash, bool force)
}
temp->Size = size;
temp->pTexture = NULL;
temp->NumberOfTextures = 0;
temp->Reference = -1;
temp->Textures = NULL;
temp->Hash = hash;
if (new_file) temp->ForceReload = false;
@@ -500,8 +502,9 @@ int OTM_TextureServer::PropagateUpdate(OTM_TextureClient* client) // called from
a.ForceReload = b.ForceReload; \
a.pData = b.pData; \
a.Size = b.Size; \
a.NumberOfTextures = b.NumberOfTextures; \
a.Reference = b.Reference; \
a.pTexture = b.pTexture; \
a.Textures = b.Textures; \
a.Hash = b.Hash; }
int TextureFileStruct_Compare( const void * elem1, const void * elem2 )
+22 -7
View File
@@ -28,7 +28,7 @@ CXX = cl
CLINK = link.exe
DEFINES = /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "_WINDLL" /D "_MBCS"
CFLAGS = /I "C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include" /nologo /W3 /WX- /O2 ${DEFINES} ${precompiler_flag} /Gm- /EHsc /MT /GS /fp:precise /Zc:wchar_t
LFLAGS = /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86" /DLL "Winmm.lib" "d3dx9.lib" "user32.lib" "Kernel32.lib" ${def_file} /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO /NXCOMPAT:NO /MACHINE:X86
LFLAGS = /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86" /DLL "Winmm.lib" "d3dx9.lib" "dxguid.lib" "user32.lib" "Kernel32.lib" ${def_file} /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO /NXCOMPAT:NO /MACHINE:X86
obj = obj
bin = bin
@@ -36,7 +36,10 @@ bin = bin
objects = ${obj}\OTM_DX9_dll.${obj_suff} \
${obj}\OTM_IDirect3D9.${obj_suff} \
${obj}\OTM_IDirect3DDevice9.${obj_suff} \
${obj}\OTM_TextureFunction.${obj_suff} \
${obj}\OTM_IDirect3DTexture9.${obj_suff} \
${obj}\OTM_IDirect3DVolumeTexture9.${obj_suff} \
${obj}\OTM_IDirect3DCubeTexture9.${obj_suff} \
${obj}\OTM_ArrayHandler.${obj_suff} \
${obj}\OTM_TextureClient.${obj_suff} \
${obj}\OTM_TextureServer.${obj_suff}
@@ -46,7 +49,10 @@ headers = OTM_Main.h \
OTM_DX9_dll.h \
OTM_IDirect3D9.h \
OTM_IDirect3DDevice9.h \
OTM_TextureFunction.h \
OTM_IDirect3DTexture9.h \
OTM_IDirect3DVolumeTexture9.h \
OTM_IDirect3DCubeTexture9.h \
OTM_ArrayHandler.h \
OTM_TextureClient.h \
OTM_TextureServer.h
@@ -57,22 +63,31 @@ ${bin}\d3d9.dll: ${objects}
${obj}\OTM_DX9_dll.${obj_suff}: OTM_DX9_dll.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_IDirect3D9.${obj_suff}: OTM_IDirect3D9.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_IDirect3DDevice9.${obj_suff}: OTM_IDirect3DDevice9.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_TextureFunction.${obj_suff}: OTM_TextureFunction.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_IDirect3DTexture9.${obj_suff}: OTM_IDirect3DTexture9.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_IDirect3DVolumeTexture9.${obj_suff}: OTM_IDirect3DVolumeTexture9.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_IDirect3DCubeTexture9.${obj_suff}: OTM_IDirect3DCubeTexture9.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_ArrayHandler.${obj_suff}: OTM_ArrayHandler.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_TextureClient.${obj_suff}: OTM_TextureClient.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
${obj}\OTM_TextureServer.${obj_suff}: OTM_TextureServer.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@
+18 -3
View File
@@ -28,7 +28,7 @@ CXX = cl
CLINK = link.exe
DEFINES = /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "_WINDLL" /D "_MBCS"
CFLAGS = /I "C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include" /nologo /W3 /WX- /O2 $(DEFINES) $(precompiler_flag) /Gm- /EHsc /MT /GS /fp:precise /Zc:wchar_t
LFLAGS = /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86" /DLL "Winmm.lib" "d3dx9.lib" "user32.lib" "Kernel32.lib" $(def_file) /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO /NXCOMPAT:NO /MACHINE:X86
LFLAGS = /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86" /DLL "Winmm.lib" "d3dx9.lib" "dxguid.lib" "user32.lib" "Kernel32.lib" $(def_file) /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO /NXCOMPAT:NO /MACHINE:X86
obj = obj
bin = bin
@@ -36,7 +36,10 @@ bin = bin
objects = $(obj)\OTM_DX9_dll.$(obj_suff) \
$(obj)\OTM_IDirect3D9.$(obj_suff) \
$(obj)\OTM_IDirect3DDevice9.$(obj_suff) \
$(obj)\OTM_TextureFunction.$(obj_suff) \
$(obj)\OTM_IDirect3DTexture9.$(obj_suff) \
$(obj)\OTM_IDirect3DVolumeTexture9.$(obj_suff) \
$(obj)\OTM_IDirect3DCubeTexture9.$(obj_suff) \
$(obj)\OTM_ArrayHandler.$(obj_suff) \
$(obj)\OTM_TextureClient.$(obj_suff) \
$(obj)\OTM_TextureServer.$(obj_suff)
@@ -46,7 +49,10 @@ headers = OTM_Main.h \
OTM_DX9_dll.h \
OTM_IDirect3D9.h \
OTM_IDirect3DDevice9.h \
OTM_TextureFunction.h \
OTM_IDirect3DTexture9.h \
OTM_IDirect3DVolumeTexture9.h \
OTM_IDirect3DCubeTexture9.h \
OTM_ArrayHandler.h \
OTM_TextureClient.h \
OTM_TextureServer.h
@@ -63,9 +69,18 @@ $(obj)\OTM_IDirect3D9.$(obj_suff): OTM_IDirect3D9.cpp $(headers)
$(obj)\OTM_IDirect3DDevice9.$(obj_suff): OTM_IDirect3DDevice9.cpp $(headers)
$(CXX) $(CFLAGS) /c /Fo$@ OTM_IDirect3DDevice9.cpp
$(obj)\OTM_TextureFunction.$(obj_suff): OTM_TextureFunction.cpp $(headers)
$(CXX) $(CFLAGS) /c /Fo$@ OTM_TextureFunction.cpp
$(obj)\OTM_IDirect3DTexture9.$(obj_suff): OTM_IDirect3DTexture9.cpp $(headers)
$(CXX) $(CFLAGS) /c /Fo$@ OTM_IDirect3DTexture9.cpp
$(CXX) $(CFLAGS) /c /Fo$@ OTM_IDirect3DTexture9.cpp
$(obj)\OTM_IDirect3DVolumeTexture9.$(obj_suff): OTM_IDirect3DVolumeTexture9.cpp $(headers)
$(CXX) $(CFLAGS) /c /Fo$@ OTM_IDirect3DVolumeTexture9.cpp
$(obj)\OTM_IDirect3DCubeTexture9.$(obj_suff): OTM_IDirect3DCubeTexture9.cpp $(headers)
$(CXX) $(CFLAGS) /c /Fo$@ OTM_IDirect3DCubeTexture9.cpp
$(obj)\OTM_ArrayHandler.$(obj_suff): OTM_ArrayHandler.cpp $(headers)
$(CXX) $(CFLAGS) /c /Fo$@ OTM_ArrayHandler.cpp
+1 -5
View File
@@ -537,6 +537,7 @@ void OTM_Frame::OnMenuAcknowledgement(wxCommandEvent& WXUNUSED(event))
wxString title;
title << OTM_VERSION << " by ROTA";
wxString msg;
msg << "RS for coding the original TexMod and for information about the used hashing algorithm\n";
msg << "EvilAlex for translation into Russian and bug fixing";
wxMessageBox( msg, title, wxOK);
}
@@ -547,8 +548,6 @@ void OTM_Frame::OnMenuAddGame(wxCommandEvent& WXUNUSED(event))
wxString file_name = wxFileSelector( Language->ChooseGame, "", "", "exe", "binary (*.exe)|*.exe", wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
if ( !file_name.empty() )
{
//file_name = file_name.AfterLast('\\');
wxArrayString array;
if (GetHookedGames( array)) array.Empty();
@@ -656,9 +655,6 @@ int OTM_Frame::SetHookedGames( const wxArrayString &array)
if (!file.IsOpened()) {LastError << Language->Error_FileOpen << "\n" << name ; return -1;}
wxString content;
//wchar_t code = 0xFFFE;
//file.Write( content.wc_str(), 2);
int num = array.GetCount();
for (int i=0; i<num; i++)
{
+14 -10
View File
@@ -1,12 +1,12 @@
Warnung: Du verwendest diese Programm auf eigene Gefahr hin!
1) Wenn das Programm abstürzt wird du wahrscheinlich keinen Support
1) Wenn das Programm abstürzt, wirst du wahrscheinlich keinen Support
vom Spielehersteller bekommen. Aber du kannst den Fehler gerne
angeben unter http://code.google.com/p/texmod/issues/list
2) Spiele können detektieren ob sie verändert werde, daher riskierst du
angeben unter: http://code.google.com/p/texmod/issues/list
2) Spiele können detektieren, ob sie verändert werden, daher riskierst du
einen Bann deines online Accounts.
3) Dies ist eine open-source Projekt. Der Code kann von jedem erhalten, verändert
und kompiliert werden. Lade OpenTexMod nur von offiziellen Quellen runter,
denen du vertraust. Lade es selbst runter und verwende keine Versionen
denen du vertraust. Lade es selbst runter und verwende keine Versionen,
die du von Team- oder Gildenmitgliedern geschickt bekommen hast.
http://code.google.com/p/texmod/downloads/list
@@ -16,18 +16,19 @@ mit geliefert werden. Wenn diese dll auf deinem System nicht installiert ist, wi
darauf hinweisen.
Was kann OpenTexMod alpha V0.9?
Was kann OpenTexMod beta V1.0?
-einzelne Texturen aus einem Spiel extrahieren und speichern (Die Zieltextur kann im Spiel geändert werden.)
-alle Texturen aus einem Spiel extrahieren und speichern
-Texturen in ein Spiel laden und Zieltexturen ersetzen
-Support einzelner dds Texturen
-Support von zip-Dateien
-Support der originalen TexMod *.tpf Datein
Alle diese Optionen können während des Spieles an und aus geschaltet werden!
Du kannst also nach einer Textur suchen, diese speichern, sie anschließend
editieren, sie in das Spiel laden, sie nach bearbeiten und wieder in das
Spiel laden, ...
Spiel laden, ... oder Mods aktivieren und deaktivieren
und das alles ohne das Spiel neu starten zu müssen.
Randbemerkung: Wenn alle Texturen gespeichert werden sollen, so geschieht das nur,
@@ -40,7 +41,7 @@ Zip Dateien k
Dateinamen enthält. Jede Zeile sollte dem Format "hash|filename.dds" entsprechen.
Wenn es keine "texmod.def" Datei enthält, wird jede Datei entpackt und jene, deren
Namen auf das Wildcard "*_hash.dds" zutrifft, werden benutzt.
Die Zip Datei kann eine "Comment.txt" enthalten. Der Inhalte wird als Kommentar
Die Zip Datei kann eine "Comment.txt" Datei enthalten. Der Inhalte wird als Kommentar
in der GUI angezeigt.
Wenn du einzelne Dateien lädst, sollten diese dem Wildcard "*_hash.dds" entsprechen.
@@ -84,8 +85,8 @@ dieses Spiel das n
Um einen Mod zu laden, musst du das Häkchen vor den Namen setzen. Wenn du
den Mod entladen willst, entferne das Häkchen und klicke auf "Update".
Der Update Button lädt nur Veränderungen (wenn Pakete aus der Liste entfernt
wurden, du die Häkchen verändert hast oder sich die Reihenfolge geändert hat)
Der Update Button lädt nur Veränderungen (wenn 1) Pakete aus der Liste entfernt
wurden, 2) du die Häkchen verändert hast oder 3) sich die Reihenfolge geändert hat)
Der "neu laden" Button erzwingt das Neuladen von Festplatte (z.B. wenn du die
Texturen verändert hast).
@@ -99,4 +100,7 @@ Wie bekommt man OpenTexMod mit Steam zum Laufen?
OpenTexMod schaut auf den Namen und auf das Verzeichnis der ausgeführten Spiel-exe.
Daher solltest du nicht die steam.exe sondern die Spiel.exe hinzufügen.
z.B.: C:\Steam\SteamApps\acoount_name\portal\hl2.exe
z.B.: C:\Steam\SteamApps\acoount_name\portal\hl2.exe
Wenn du die entsprechende exe nicht findest, kannst du das Spiel normal starten und
über den TaskManager die entsprechende exe suchen. Über Rechstklick->Eigenschaften
erfährst du dann auch den Pfad der exe.
+7 -4
View File
@@ -12,18 +12,19 @@ OpenTexMod uses the D3DX9_43.dll. Due to the EULA this dll cannot be delivered t
If D3DX9_43.dll is not installed on your system, OpenTexMod will give you a hint at program start.
What can OpenTexMod alpha V0.9?
What can OpenTexMod beta V1.0?
-extract and save single textures from a DX9 game (the target texture can be toggled in the game)
-extract and save all textures from a DX9 game
-load textures into a game to replace target textures
-support single dds texture
-support zip-files as whole mod package
-support the original TexMod *.tpf files
All these options can be switched on or off, while the game is already running!
So you can search for a texture in the game, save it to disk, edit it,
load it into the game, edit it again and load it into the game again, ...
and all without a restart of the game.
load it into the game, edit it again and load it into the game again, ...,
actiavate or deactivate mods and all without a restart of the game.
side note: If "save all textures" is switched on, the texture will only be saved, if
the textures are loaded by the game and only in the moment they are loaded.
@@ -91,4 +92,6 @@ How to get OpenTexMod work together with Steam?
OpenTexMod looks for the name and the path of the executed binary.
Thus you shall not add the steam.exe but rather the game.exe
e.g.: C:\Steam\SteamApps\acoount_name\portal\hl2.exe
e.g.: C:\Steam\SteamApps\acoount_name\portal\hl2.exe
If you cannot find the exe, just start the game and use the TaskManager
to search for it. You can figure out the path through right click->properties.