diff --git a/.gitattributes b/.gitattributes index d8f7a9f..6f190b5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/OTM_DX9/OTM_ArrayHandler.cpp b/OTM_DX9/OTM_ArrayHandler.cpp index 0a46a85..bf76607 100644 --- a/OTM_DX9/OTM_ArrayHandler.cpp +++ b/OTM_DX9/OTM_ArrayHandler.cpp @@ -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; iReference>=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; iReference = 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); -} diff --git a/OTM_DX9/OTM_ArrayHandler.h b/OTM_DX9/OTM_ArrayHandler.h index c88b77a..d43ae6e 100644 --- a/OTM_DX9/OTM_ArrayHandler.h +++ b/OTM_DX9/OTM_ArrayHandler.h @@ -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 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 +OTM_TextureHandler::OTM_TextureHandler(void) +{ + Message("OTM_TextureHandler(void): %lu\n", this); + Number = 0; + FieldCounter = 0; + + Textures = NULL; +} + +template +OTM_TextureHandler::~OTM_TextureHandler(void) +{ + Message("~OTM_TextureHandler(void): %lu\n", this); + if (Textures!=NULL) + { + for (int i=0; i +int OTM_TextureHandler::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; iReference = Number++; + + return (RETURN_OK); +} + + +template +int OTM_TextureHandler::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_ */ diff --git a/OTM_DX9/OTM_IDirect3DCubeTexture9.cpp b/OTM_DX9/OTM_IDirect3DCubeTexture9.cpp new file mode 100644 index 0000000..9dd01b4 --- /dev/null +++ b/OTM_DX9/OTM_IDirect3DCubeTexture9.cpp @@ -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 . +*/ + +/* + * 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); +} + + diff --git a/OTM_DX9/OTM_IDirect3DCubeTexture9.h b/OTM_DX9/OTM_IDirect3DCubeTexture9.h new file mode 100644 index 0000000..5272afd --- /dev/null +++ b/OTM_DX9/OTM_IDirect3DCubeTexture9.h @@ -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 . +*/ + + +/* + * + * BIG THANKS TO Matthew L (Azorbix) + * (Direct3D StarterKit v3.0) + * + */ + + +#ifndef OTM_IDirect3DCubeTexture9_H +#define OTM_IDirect3DCubeTexture9_H + +#include +#include + +#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 diff --git a/OTM_DX9/OTM_IDirect3DDevice9.cpp b/OTM_DX9/OTM_IDirect3DDevice9.cpp index 51777e4..4057653 100644 --- a/OTM_DX9/OTM_IDirect3DDevice9.cpp +++ b/OTM_DX9/OTM_IDirect3DDevice9.cpp @@ -24,19 +24,28 @@ along with OpenTexMod. If not, see . 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)); } diff --git a/OTM_DX9/OTM_IDirect3DDevice9.h b/OTM_DX9/OTM_IDirect3DDevice9.h index 92b8d9b..78f301e 100644 --- a/OTM_DX9/OTM_IDirect3DDevice9.h +++ b/OTM_DX9/OTM_IDirect3DDevice9.h @@ -31,6 +31,8 @@ along with OpenTexMod. If not, see . #include #include #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; }; diff --git a/OTM_DX9/OTM_IDirect3DTexture9.cpp b/OTM_DX9/OTM_IDirect3DTexture9.cpp index bd7ba01..5ce4375 100644 --- a/OTM_DX9/OTM_IDirect3DTexture9.cpp +++ b/OTM_DX9/OTM_IDirect3DTexture9.cpp @@ -24,9 +24,32 @@ along with OpenTexMod. If not, see . #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); +} diff --git a/OTM_DX9/OTM_IDirect3DTexture9.h b/OTM_DX9/OTM_IDirect3DTexture9.h index 215fadb..2f56a09 100644 --- a/OTM_DX9/OTM_IDirect3DTexture9.h +++ b/OTM_DX9/OTM_IDirect3DTexture9.h @@ -37,7 +37,7 @@ along with OpenTexMod. If not, see . 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); }; diff --git a/OTM_DX9/OTM_IDirect3DVolumeTexture9.cpp b/OTM_DX9/OTM_IDirect3DVolumeTexture9.cpp new file mode 100644 index 0000000..171b0e0 --- /dev/null +++ b/OTM_DX9/OTM_IDirect3DVolumeTexture9.cpp @@ -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 . +*/ + +/* + * 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); +} diff --git a/OTM_DX9/OTM_IDirect3DVolumeTexture9.h b/OTM_DX9/OTM_IDirect3DVolumeTexture9.h new file mode 100644 index 0000000..b1cf30b --- /dev/null +++ b/OTM_DX9/OTM_IDirect3DVolumeTexture9.h @@ -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 . +*/ + + +/* + * + * BIG THANKS TO Matthew L (Azorbix) + * (Direct3D StarterKit v3.0) + * + */ + + +#ifndef OTM_IDirect3DVolumeTexture9_H +#define OTM_IDirect3DVolumeTexture9_H + +#include +#include + +#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 diff --git a/OTM_DX9/OTM_Main.h b/OTM_DX9/OTM_Main.h index cf3a75f..8095810 100644 --- a/OTM_DX9/OTM_Main.h +++ b/OTM_DX9/OTM_Main.h @@ -39,13 +39,17 @@ along with OpenTexMod. If not, see . + #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" diff --git a/OTM_DX9/OTM_TextureClient.cpp b/OTM_DX9/OTM_TextureClient.cpp index e3f0d2c..9425065 100644 --- a/OTM_DX9/OTM_TextureClient.cpp +++ b/OTM_DX9/OTM_TextureClient.cpp @@ -45,6 +45,10 @@ OTM_TextureClient::OTM_TextureClient(OTM_TextureServer* server, IDirect3DDevice9 NumberToMod = 0; FileToMod = NULL; } + else + { + for (int i=0; iSetLastCreatedTexture(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 && refFAKE) + for (int i=0; iReference; - if (ref>=0 && refCrossRef_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; jHash, 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 && refHash, 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 && refHash, 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; iRelease(); // we release the fake texture + for (int i=0; iRelease(); // 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; iQueryInterface( 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_oldRelease(); + for (int i=0; iRelease(); // we release the fake textures + if (FileToMod[pos_old].Textures!=NULL) delete [] FileToMod[pos_old].Textures; // we delete the memory pos_old++; } while (pos_newGetSingleTexture(); if (num_to_lookup>0) { int num = OriginalTextures.GetNumber(); for (int i=0; iCrossRef_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 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=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; jReference = index; } } } @@ -488,89 +570,126 @@ int OTM_TextureClient::UnlockMutex(void) +int OTM_TextureClient::LookUpToMod( MyTypeHash hash) +{ + if(NumberToMod>0) + { + if (hashFileToMod[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 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 (hashFileToMod[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 (++posHash); 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; jHash; - for (int i=0; iRelease(); - } - 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; jReference = 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; jReference = 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; iHash, 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); +} + + + + diff --git a/OTM_DX9/OTM_TextureClient.h b/OTM_DX9/OTM_TextureClient.h index 90b392f..35d938e 100644 --- a/OTM_DX9/OTM_TextureClient.h +++ b/OTM_DX9/OTM_TextureClient.h @@ -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 OriginalTextures; // stores the pointer to the OTM_IDirect3DTexture9 objects created by the game + OTM_TextureHandler OriginalVolumeTextures; // stores the pointer to the OTM_IDirect3DVolumeTexture9 objects created by the game + OTM_TextureHandler 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); }; diff --git a/OTM_DX9/OTM_TextureFunction.cpp b/OTM_DX9/OTM_TextureFunction.cpp new file mode 100644 index 0000000..82886e1 --- /dev/null +++ b/OTM_DX9/OTM_TextureFunction.cpp @@ -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>=1) + { + crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32POLY : 0); + } + } + return (crc); +} + diff --git a/OTM_DX9/OTM_TextureFunction.h b/OTM_DX9/OTM_TextureFunction.h new file mode 100644 index 0000000..166a10d --- /dev/null +++ b/OTM_DX9/OTM_TextureFunction.h @@ -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_ */ diff --git a/OTM_DX9/OTM_TextureServer.cpp b/OTM_DX9/OTM_TextureServer.cpp index ddfa2c9..ba7d5ec 100644 --- a/OTM_DX9/OTM_TextureServer.cpp +++ b/OTM_DX9/OTM_TextureServer.cpp @@ -23,8 +23,6 @@ along with OpenTexMod. If not, see . 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; ipData[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 ) diff --git a/OTM_DX9/makefile.gcc b/OTM_DX9/makefile.gcc index 7bbd891..1d2131d 100644 --- a/OTM_DX9/makefile.gcc +++ b/OTM_DX9/makefile.gcc @@ -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$@ diff --git a/OTM_DX9/makefile.vc b/OTM_DX9/makefile.vc index 48bcfb6..d399573 100644 --- a/OTM_DX9/makefile.vc +++ b/OTM_DX9/makefile.vc @@ -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 diff --git a/OTM_GUI/OTM_GUI.cpp b/OTM_GUI/OTM_GUI.cpp index 7e7c058..fa3fe69 100644 --- a/OTM_GUI/OTM_GUI.cpp +++ b/OTM_GUI/OTM_GUI.cpp @@ -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; iEigenschaften +erfährst du dann auch den Pfad der exe. \ No newline at end of file diff --git a/OTM_GUI/bin/README_English.txt b/OTM_GUI/bin/README_English.txt index 029d8ff..cb92f44 100644 --- a/OTM_GUI/bin/README_English.txt +++ b/OTM_GUI/bin/README_English.txt @@ -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 \ No newline at end of file +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. \ No newline at end of file