diff --git a/.cproject b/.cproject index 2832acd..a4cf9ef 100644 --- a/.cproject +++ b/.cproject @@ -20,7 +20,7 @@ diff --git a/uMod_DX9/uMod_IDirect3DCubeTexture9.cpp b/uMod_DX9/uMod_IDirect3DCubeTexture9.cpp index a6caedb..823d3c0 100644 --- a/uMod_DX9/uMod_IDirect3DCubeTexture9.cpp +++ b/uMod_DX9/uMod_IDirect3DCubeTexture9.cpp @@ -42,17 +42,9 @@ HRESULT APIENTRY uMod_IDirect3DCubeTexture9::QueryInterface(REFIID riid, void** *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; - } + HRESULT hRes = m_D3Dtex->QueryInterface(riid, ppvObj); + if (*ppvObj==m_D3Dtex) *ppvObj=this; + return (hRes); } @@ -60,11 +52,7 @@ HRESULT APIENTRY uMod_IDirect3DCubeTexture9::QueryInterface(REFIID riid, void** ULONG APIENTRY uMod_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()); + return (m_D3Dtex->AddRef()); } //this function yields for the non switched texture object @@ -83,42 +71,18 @@ ULONG APIENTRY uMod_IDirect3DCubeTexture9::Release() } else { - if (CrossRef_D3Dtex!=NULL) //if this texture is switched with a fake texture - { - uMod_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 (ret == 0x01000000L) - { - if (((uMod_IDirect3DDevice9*) m_D3Ddev)->GetSingleCubeTexture()!=fake_texture) fake_texture->Release(); // we release the fake texture - } - else - { - if (((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetSingleCubeTexture()!=fake_texture) fake_texture->Release(); // we release the fake texture - } - } - } - else - { - count = m_D3Dtex->Release(); - } + count = m_D3Dtex->Release(); } if (count==0) //if this texture is released, we clean up { - // if this texture is the LastCreatedTexture, the next time LastCreatedTexture would be added, - // the hash of a non existing texture would be calculated if (ret == 0x01000000L) { - if (((uMod_IDirect3DDevice9*) m_D3Ddev)->GetLastCreatedCubeTexture()==this) ((uMod_IDirect3DDevice9*) m_D3Ddev)->SetLastCreatedCubeTexture( NULL); - else ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client + ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client } else { - if (((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetLastCreatedCubeTexture()==this) ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->SetLastCreatedCubeTexture( NULL); - else ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client + ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client } delete(this); @@ -135,21 +99,18 @@ HRESULT APIENTRY uMod_IDirect3DCubeTexture9::GetDevice(IDirect3DDevice9** ppDevi //this function yields for the non switched texture object HRESULT APIENTRY uMod_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 uMod_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 uMod_IDirect3DCubeTexture9::FreePrivateData(REFGUID refguid) { - if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->FreePrivateData(refguid)); return (m_D3Dtex->FreePrivateData(refguid)); } @@ -206,14 +167,12 @@ void APIENTRY uMod_IDirect3DCubeTexture9::GenerateMipSubLevels() //this function yields for the non switched texture object HRESULT APIENTRY uMod_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 uMod_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)); } @@ -223,9 +182,7 @@ HRESULT APIENTRY uMod_IDirect3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES Message( "uMod_IDirect3DCubeTexture9::GetCubeMapSurface( %d, %u, %p): %p\n", FaceType, Level, *ppCubeMapSurface, this); IDirect3DSurface9* pSurf; uMod_IDirect3DSurface9* puMod_Surf; - HRESULT ret; - if (CrossRef_D3Dtex!=NULL) ret = (CrossRef_D3Dtex->m_D3Dtex->GetCubeMapSurface( FaceType, Level, &pSurf)); - else ret = (m_D3Dtex->GetCubeMapSurface( FaceType, Level, &pSurf)); + HRESULT ret = (m_D3Dtex->GetCubeMapSurface( FaceType, Level, &pSurf)); if (SUCCEEDED(ret)) { @@ -240,35 +197,14 @@ HRESULT APIENTRY uMod_IDirect3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES //this function yields for the non switched texture object HRESULT APIENTRY uMod_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 uMod_IDirect3DCubeTexture9::UnlockRect( D3DCUBEMAP_FACES FaceType, UINT Level) { - if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->UnlockRect( FaceType, Level)); + Dirty = 1; return (m_D3Dtex->UnlockRect( FaceType, Level)); - - HRESULT ret; - if (CrossRef_D3Dtex!=NULL) ret = (CrossRef_D3Dtex->m_D3Dtex->UnlockRect( FaceType, Level)); - ret = (m_D3Dtex->UnlockRect( FaceType, Level)); - - DWORD64 crc64 = CRC64; - DWORD64 crc32 = CRC32; - ComputetHash(crc32>0); - if (crc64!=CRC64) - { - // device can be uMod_IDirect3DDevice9 object or a uMod_IDirect3DDevice9Ex object ! - void *cpy; - long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) - ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(this); - else - ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(this); - } - - return ret; } @@ -276,13 +212,19 @@ int uMod_IDirect3DCubeTexture9::ComputetHash( bool compute_crc) { if (FAKE) return (RETURN_BAD_ARGUMENT); IDirect3DCubeTexture9 *pTexture = m_D3Dtex; - if (CrossRef_D3Dtex!=NULL) pTexture = CrossRef_D3Dtex->m_D3Dtex; IDirect3DSurface9 *surface = NULL; if (compute_crc) InitCRC32(CRC32); InitCRC64(CRC64); + void *cpy; + uMod_IDirect3DDevice9 *dev = NULL; + uMod_IDirect3DDevice9Ex *devEx = NULL; + long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); + if (ret == 0x01000000L) dev = ((uMod_IDirect3DDevice9*)m_D3Ddev); + else devEx = ((uMod_IDirect3DDevice9Ex*) m_D3Ddev); + for (int site = 0; site<6; site++) { if (pTexture->GetCubeMapSurface( (D3DCUBEMAP_FACES) site, 0, &surface)!=D3D_OK) @@ -290,96 +232,10 @@ int uMod_IDirect3DCubeTexture9::ComputetHash( bool compute_crc) Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetSurfaceLevel\n"); return (RETURN_LockRect_FAILED); } - ((uMod_IDirect3DDevice9*)(m_D3Ddev))->ComputetHash( CRC64, CRC32, surface, compute_crc); - + if (dev!=NULL) ret = dev->ComputeCRC( CRC64, CRC32, surface, compute_crc); + else ret = devEx->ComputeCRC( CRC64, CRC32, surface, compute_crc); surface->Release(); + if (ret!=RETURN_OK) return (ret); } return (RETURN_OK); } - -/* -int uMod_IDirect3DCubeTexture9::ComputetHash( bool compute_crc) -{ - if (FAKE) return (RETURN_BAD_ARGUMENT); - IDirect3DCubeTexture9 *pTexture = m_D3Dtex; - if (CrossRef_D3Dtex!=NULL) pTexture = CrossRef_D3Dtex->m_D3Dtex; - - 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("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetLevelDesc \n"); - return (RETURN_GetLevelDesc_FAILED); - } - int bits_per_pixel = GetBitsFromFormat( desc.Format); - unsigned int size; - unsigned int h_max = desc.Height; - if (desc.Format == D3DFMT_DXT1) // 8 bytes per block - { - h_max /= 4; // divided by block size - size = desc.Width*2; // desc.Width/4 * 8 - } - else if ( desc.Format==D3DFMT_DXT2 || desc.Format==D3DFMT_DXT3 || desc.Format==D3DFMT_DXT4 || desc.Format==D3DFMT_DXT5 ) // 16 bytes per block - { - h_max /= 4; // divided by block size - size = desc.Width*4; // desc.Width/4 * 16 - } - else size = (bits_per_pixel * desc.Width)/8; - - Hash = HASH_INIT_VALUE; - - Message("uMod_IDirect3DCubeTexture9::GetHash() (%d %d) %d\n", desc.Width, desc.Height, desc.Format); - - for (int site = 0; site<6; site++) - { - if (pTexture->LockRect( ( _D3DCUBEMAP_FACES) site, 0, &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK) - { - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: LockRect 1\n"); - if (pTexture->GetCubeMapSurface( ( _D3DCUBEMAP_FACES) site, 0, &pResolvedSurface)!=D3D_OK) - { - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: GetSurfaceLevel\n"); - return (RETURN_LockRect_FAILED); - } - if (pResolvedSurface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK) - { - pResolvedSurface->Release(); - Message("uMod_IDirect3DCubeTexture9::GetHash() Failed: LockRect 2\n"); - return (RETURN_LockRect_FAILED); - } - } - - { - unsigned char *data = (unsigned char*) d3dlr.pBits; - - for (unsigned int h=0; hUnlockRect(); - pResolvedSurface->Release(); - pResolvedSurface=NULL; - } - else - { - pTexture->UnlockRect( ( _D3DCUBEMAP_FACES) site, 0); //unlock the raw data - } - } - - Message("uMod_IDirect3DCubeTexture9::GetHash() %#llX %#LX (%d %d) %d\n", Hash, CRC, desc.Width, desc.Height, desc.Format); - return (RETURN_OK); -} -*/ - diff --git a/uMod_DX9/uMod_IDirect3DCubeTexture9.h b/uMod_DX9/uMod_IDirect3DCubeTexture9.h index edd9b4b..f882611 100644 --- a/uMod_DX9/uMod_IDirect3DCubeTexture9.h +++ b/uMod_DX9/uMod_IDirect3DCubeTexture9.h @@ -49,6 +49,7 @@ public: CRC64 = 0u; CRC32 = 0u; FAKE = false; + Dirty = 1; } IDirect3DCubeTexture9 *m_D3Dtex; //!< pointer to the real IDirect3DCubeTexture9 object @@ -58,6 +59,7 @@ public: DWORD64 CRC64; //!< computed hash value for this game texture. DWORD32 CRC32; //!< computed crc32 value for this game texture. bool FAKE; //!< True if this texture is was loaded by uMod (fake texture) + unsigned char Dirty; // original interface STDMETHOD(QueryInterface) (REFIID riid, void** ppvObj); @@ -88,40 +90,4 @@ public: int ComputetHash( bool compute_crc); }; - - -inline void UnswitchTextures(uMod_IDirect3DCubeTexture9 *pTexture) -{ - uMod_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( uMod_IDirect3DCubeTexture9 *pTexture1, uMod_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/uMod_DX9/uMod_IDirect3DDevice9.cpp b/uMod_DX9/uMod_IDirect3DDevice9.cpp index 50b50b1..18734f7 100644 --- a/uMod_DX9/uMod_IDirect3DDevice9.cpp +++ b/uMod_DX9/uMod_IDirect3DDevice9.cpp @@ -42,14 +42,14 @@ int uMod_IDirect3DDevice9::CreateSingleTexture(void) TextureColour = uMod_Client->TextureColour; if (SingleTexture==NULL) //create texture { + SetNextTextureIsFake(true); if( D3D_OK != CreateTexture(8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DTexture9**) &SingleTexture, NULL)) { Message( PRE_MESSAGE "::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->FAKE = true; //this is no texture created by the game SingleTexture->Reference = -2; } @@ -78,14 +78,14 @@ int uMod_IDirect3DDevice9::CreateSingleTexture(void) if (SingleVolumeTexture==NULL) //create texture { + SetNextTextureIsFake(true); if( D3D_OK != CreateVolumeTexture(8, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DVolumeTexture9**) &SingleVolumeTexture, NULL)) { Message( PRE_MESSAGE "::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->FAKE = true; //this is no texture created by the game SingleVolumeTexture->Reference = -2; } @@ -112,14 +112,14 @@ int uMod_IDirect3DDevice9::CreateSingleTexture(void) } if (SingleCubeTexture==NULL) //create texture { + SetNextTextureIsFake(true); if( D3D_OK != CreateCubeTexture(8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, (IDirect3DCubeTexture9**) &SingleCubeTexture, NULL)) { Message( PRE_MESSAGE "::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->FAKE = true; //this is no texture created by the game SingleCubeTexture->Reference = -2; } @@ -154,7 +154,7 @@ int uMod_IDirect3DDevice9::CreateSingleTexture(void) -int uMod_IDirect3DDevice9::ComputetHash( DWORD64 &CRC64, DWORD32 &CRC32, IDirect3DSurface9 *surface, bool compute_crc) +int uMod_IDirect3DDevice9::ComputeCRC( DWORD64 &CRC64, DWORD32 &CRC32, IDirect3DSurface9 *surface, bool compute_crc) { IDirect3DSurface9 *offscreen_surface = NULL; D3DLOCKED_RECT d3dlr; @@ -166,17 +166,17 @@ int uMod_IDirect3DDevice9::ComputetHash( DWORD64 &CRC64, DWORD32 &CRC32, IDirect if (surface->GetDesc(&desc)!=D3D_OK) //get the format and the size of the texture { - Message("ComputetHash() Failed: GetLevelDesc \n"); + Message("ComputeCRC() Failed: GetLevelDesc \n"); return (RETURN_GetLevelDesc_FAILED); } - Message("ComputetHash() (%d %d) F%d T%d U%d P%d M(%d %d)\n", desc.Width, desc.Height, - desc.Format, desc.Type, desc.Usage, desc.Pool, desc.MultiSampleType, desc.MultiSampleQuality); + Message("ComputeCRC() (%d %d) F%d T%d U%d P%d M(%d %d) : %p %p\n", desc.Width, desc.Height, + desc.Format, desc.Type, desc.Usage, desc.Pool, desc.MultiSampleType, desc.MultiSampleQuality, surface, this); if (surface->LockRect( &d3dlr, NULL, D3DLOCK_READONLY)!=D3D_OK) { - Message("ComputetHash() Failed: surface->LockRect()\n"); + Message("ComputeCRC() Failed: surface->LockRect()\n"); } else { @@ -188,7 +188,7 @@ int uMod_IDirect3DDevice9::ComputetHash( DWORD64 &CRC64, DWORD32 &CRC32, IDirect { if (surface->GetDC( (HDC*) &buffer)!=D3D_OK) { - Message("ComputetHash() Failed: surface->GetDC()\n"); + Message("ComputeCRC() Failed: surface->GetDC()\n"); buffer = NULL; } } @@ -202,12 +202,12 @@ int uMod_IDirect3DDevice9::ComputetHash( DWORD64 &CRC64, DWORD32 &CRC32, IDirect { if (D3D_OK!=m_pIDirect3DDevice9->CreateRenderTarget( desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &resolved_surface, NULL )) { - Message("ComputetHash() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n"); + Message("ComputeCRC() Failed: CreateRenderTarget (D3DPOOL_DEFAULT)\n"); return (RETURN_LockRect_FAILED); } if (D3D_OK!=m_pIDirect3DDevice9->StretchRect( surface, NULL, resolved_surface, NULL, D3DTEXF_NONE )) { - Message("ComputetHash() Failed: StretchRect (D3DPOOL_DEFAULT)\n"); + Message("ComputeCRC() Failed: StretchRect (D3DPOOL_DEFAULT)\n"); return (RETURN_LockRect_FAILED); } } @@ -304,31 +304,24 @@ int uMod_IDirect3DDevice9::ComputetHash( DWORD64 &CRC64, DWORD32 &CRC32, IDirect } - Message("ComputetHash() %#llX %#LX (%d %d) %d\n", CRC64, CRC32, desc.Width, desc.Height, desc.Format); + Message("ComputeCRC() %#llX %#LX (%d %d) %d\n", CRC64, CRC32, desc.Width, desc.Height, desc.Format); return (RETURN_OK); } -int uMod_IDirect3DDevice9::CheckForChangeSurface(uMod_IDirect3DSurface9 *surface) +int uMod_IDirect3DDevice9::CheckForChangeSurface(uMod_IDirect3DSurface9 *surface, bool render_target) { if (surface!=NULL) { if (surface->m_D3DTex!=NULL) { - DWORD64 crc64 = surface->m_D3DTex->CRC64; - DWORD32 crc32 = surface->m_D3DTex->CRC32; - surface->m_D3DTex->ComputetHash(crc32>0); - if (crc64!=surface->m_D3DTex->CRC64) - uMod_Client->CRCHasChanged(surface->m_D3DTex); + if (render_target && (uMod_Client!=NULL && ! uMod_Client->BoolComputeRenderTargets)) + surface->m_D3DTex->Dirty = 20; + else + surface->m_D3DTex->Dirty = 1; } else if (surface->m_D3DCubeTex!=NULL) - { - DWORD64 crc64 = surface->m_D3DCubeTex->CRC64; - DWORD32 crc32 = surface->m_D3DCubeTex->CRC32; - surface->m_D3DCubeTex->ComputetHash(crc32>0); - if (crc64!=surface->m_D3DCubeTex->CRC64) - uMod_Client->CRCHasChanged(surface->m_D3DCubeTex); - } + surface->m_D3DCubeTex->Dirty = 1; } return (0); } @@ -352,9 +345,6 @@ uMod_IDirect3DDevice9::uMod_IDirect3DDevice9( IDirect3DDevice9* pOriginal, uMod_ TextureColour = uMod_Client->TextureColour; NextTextureIsFake = false; - LastCreatedTexture = NULL; - LastCreatedVolumeTexture = NULL; - LastCreatedCubeTexture = NULL; m_pIDirect3DDevice9 = pOriginal; // store the pointer to original object CounterSaveSingleTexture = -20; @@ -406,7 +396,7 @@ ULONG uMod_IDirect3DDevice9::AddRef(void) ULONG uMod_IDirect3DDevice9::Release(void) { - if (--uMod_Reference==0) //if our counter drops to zero, the real device will be deleted, so we clean up before + if (--uMod_Reference<=0) //if our counter drops to zero, the real device will be deleted, so we clean up before { // we must not release the fake textures, cause they are released if the target textures are released // and the target textures are released by the game. @@ -417,9 +407,6 @@ ULONG uMod_IDirect3DDevice9::Release(void) if (OSD_Font!=NULL) OSD_Font->Release(); if (pSprite!=NULL) pSprite->Release(); - if (uMod_Client!=NULL) delete uMod_Client; //must be deleted at the end, because other releases might call a function of this object - - uMod_Client = NULL; SingleTexture = NULL; SingleVolumeTexture = NULL; SingleCubeTexture = NULL; @@ -431,10 +418,15 @@ ULONG uMod_IDirect3DDevice9::Release(void) Message("%lu = " PRE_MESSAGE "::Release(): %p\n", count, this); if (uMod_Reference!=count) //bug { - Message("Error in " PRE_MESSAGE "::Release(): %lu!=%lu\n", uMod_Reference, count); + Message("Error in " PRE_MESSAGE "::Release(): %d!=%lu\n", uMod_Reference, count); } - if (count==0u) delete(this); + if (count==0u) + { + if (uMod_Client!=NULL) delete uMod_Client; //must be deleted at the end, because other releases might call a function of this object + uMod_Client = NULL; + delete(this); + } return (count); } @@ -552,7 +544,7 @@ void uMod_IDirect3DDevice9::GetGammaRamp(UINT iSwapChain,D3DGAMMARAMP* pRamp) HRESULT uMod_IDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle) { //create real texture - //Message("uMod_IDirect3DDevice9::CreateTexture()\n"); + //Message("uMod_IDirect3DDevice9::CreateTexture() %p\n", this); HRESULT ret = (m_pIDirect3DDevice9->CreateTexture(Width,Height,Levels,Usage,Format,Pool,ppTexture,pSharedHandle)); if(ret != D3D_OK) return (ret); @@ -560,11 +552,20 @@ HRESULT uMod_IDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels, uMod_IDirect3DTexture9 *texture = new uMod_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 + if (NextTextureIsFake) { - if ( uMod_Client!=NULL) uMod_Client->AddTexture( LastCreatedTexture); + NextTextureIsFake = false; + texture->FAKE = true; + texture->Dirty = 0; } - LastCreatedTexture = texture; + else + { + texture->FAKE = false; + texture->Dirty = 1; + uMod_Client->AddTexture( texture); + } + + //Message("uMod_IDirect3DDevice9::CreateTexture() END %p\n", this); return (ret); } @@ -579,11 +580,18 @@ HRESULT uMod_IDirect3DDevice9::CreateVolumeTexture(UINT Width,UINT Height,UINT D uMod_IDirect3DVolumeTexture9 *texture = new uMod_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 (NextTextureIsFake) { - if ( uMod_Client!=NULL) uMod_Client->AddTexture( LastCreatedVolumeTexture); + NextTextureIsFake = false; + texture->FAKE = true; + texture->Dirty = 0; + } + else + { + texture->FAKE = false; + texture->Dirty = 1; + uMod_Client->AddTexture( texture); } - LastCreatedVolumeTexture = texture; return (ret); } @@ -598,11 +606,18 @@ HRESULT uMod_IDirect3DDevice9::CreateCubeTexture(UINT EdgeLength,UINT Levels,DWO uMod_IDirect3DCubeTexture9 *texture = new uMod_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 (NextTextureIsFake) { - if ( uMod_Client!=NULL) uMod_Client->AddTexture( LastCreatedCubeTexture); + NextTextureIsFake = false; + texture->FAKE = true; + texture->Dirty = 0; + } + else + { + texture->FAKE = false; + texture->Dirty = 1; + uMod_Client->AddTexture( texture); } - LastCreatedCubeTexture = texture; return (ret); } @@ -618,11 +633,13 @@ HRESULT uMod_IDirect3DDevice9::CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORM HRESULT uMod_IDirect3DDevice9::CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { + Message("uMod_IDirect3DDevice9::CreateRenderTarget() %p\n", this); return(m_pIDirect3DDevice9->CreateRenderTarget(Width,Height,Format,MultiSample,MultisampleQuality,Lockable,ppSurface,pSharedHandle)); } HRESULT uMod_IDirect3DDevice9::CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { + Message("uMod_IDirect3DDevice9::CreateDepthStencilSurface() %p\n", this); return(m_pIDirect3DDevice9->CreateDepthStencilSurface(Width,Height,Format,MultiSample,MultisampleQuality,Discard,ppSurface,pSharedHandle)); } @@ -632,9 +649,11 @@ HRESULT uMod_IDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface,C uMod_IDirect3DSurface9* pSource = NULL; uMod_IDirect3DSurface9* pDest = NULL; + IDirect3DSurface9* fake_surface = NULL; IDirect3DSurface9* cpy; DWORD64 crc64=0ULL; DWORD32 crc32=0u; + HRESULT ret; if( pSourceSurface != NULL ) { @@ -642,12 +661,31 @@ HRESULT uMod_IDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface,C if (ret == 0x01000000L) { pSource = (uMod_IDirect3DSurface9*) pSourceSurface; + + // test if we can us the hash (only for textures) if (pSourceRect==NULL && pSource->m_D3DTex!=NULL) { - crc64 = pSource->m_D3DTex->CRC64; - crc32 = pSource->m_D3DTex->CRC32; + if (!pSource->m_D3DTex->Dirty) + { + crc64 = pSource->m_D3DTex->CRC64; + crc32 = pSource->m_D3DTex->CRC32; + } } - pSourceSurface = pSource->m_D3Dsurf; + + // if the source surface belongs to a texture and this texture is switch -> we take the fake texture + if (pDest->m_D3DTex!=NULL) + { + if (pDest->m_D3DTex->CrossRef_D3Dtex!=NULL) + { + ret = pDest->m_D3DTex->CrossRef_D3Dtex->m_D3Dtex->GetSurfaceLevel( 0, &fake_surface); + if (FAILED(ret)) + fake_surface = NULL; + } + } + if (fake_surface==NULL) + pSourceSurface = pSource->m_D3Dsurf; + else + pSourceSurface = fake_surface; } } if( pDestinationSurface != NULL ) @@ -664,33 +702,29 @@ HRESULT uMod_IDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface,C { pDest->m_D3DTex->CRC64 = crc64; pDest->m_D3DTex->CRC32 = crc32; - UnswitchTextures(pDest->m_D3DTex); + if (pDest->m_D3DTex->CrossRef_D3Dtex!=NULL) + { + if (pDest->m_D3DTex->CrossRef_D3Dtex->Reference<0) + UnswitchTextures( pDest->m_D3DTex); + else pDest->m_D3DTex->CrossRef_D3Dtex->Release(); + } uMod_Client->LookUpToMod( pDest->m_D3DTex); } else // compute the CRC again { if (pDest->m_D3DTex!=NULL) - { - if (pDest->m_D3DTex->ComputetHash(uMod_Client->BoolComputeCRC) == RETURN_OK) - { - UnswitchTextures(pDest->m_D3DTex); - uMod_Client->LookUpToMod( pDest->m_D3DTex); - } - } + pDest->m_D3DTex->Dirty=1; else if (pDest->m_D3DCubeTex!=NULL) - { - if (pDest->m_D3DCubeTex->ComputetHash(uMod_Client->BoolComputeCRC) == RETURN_OK) - { - UnswitchTextures(pDest->m_D3DCubeTex); - uMod_Client->LookUpToMod( pDest->m_D3DCubeTex); - } - } + pDest->m_D3DCubeTex->Dirty=1; } pDestinationSurface = pDest->m_D3Dsurf; } } - return(m_pIDirect3DDevice9->UpdateSurface(pSourceSurface,pSourceRect,pDestinationSurface,pDestPoint)); + ret = m_pIDirect3DDevice9->UpdateSurface(pSourceSurface,pSourceRect,pDestinationSurface,pDestPoint); + + if (fake_surface!=NULL) fake_surface->Release(); + return (ret); } HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTexture,IDirect3DBaseTexture9* pDestinationTexture) @@ -711,19 +745,10 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu case 0x01000000L: { pSource = (uMod_IDirect3DTexture9*)(pSourceTexture); - DWORD64 crc64 = pSource->CRC64; - DWORD32 crc32 = pSource->CRC32; - if (pSource->ComputetHash( crc32>0 ) == RETURN_OK) - { - if (crc64 != pSource->CRC64 || (crc32>0 && crc32 != pSource->CRC32) ) // this hash has changed !! - { - UnswitchTextures(pSource); - uMod_Client->LookUpToMod( pSource); - } - } - else UnswitchTextures(pSource); // we better unswitch + if (pSource->Dirty) + uMod_Client->ComputeCRC(pSource); - // the source must be the original texture if not switched and the fake texture if it is switched + // if the source texture is switched we take the fake texture as source if (pSource->CrossRef_D3Dtex!=NULL) pSourceTexture = pSource->CrossRef_D3Dtex->m_D3Dtex; else pSourceTexture = pSource->m_D3Dtex; break; @@ -731,19 +756,10 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu case 0x01000001L: { pSourceVolume = (uMod_IDirect3DVolumeTexture9*)(pSourceTexture); - DWORD64 crc64 = pSourceVolume->CRC64; - DWORD32 crc32 = pSourceVolume->CRC32; - if (pSourceVolume->ComputetHash( crc32>0 ) == RETURN_OK) - { - if (crc64 != pSourceVolume->CRC64 || (crc32>0 && crc32 != pSource->CRC32) ) // this hash has changed !! - { - UnswitchTextures(pSourceVolume); - uMod_Client->LookUpToMod( pSourceVolume); - } - } - else UnswitchTextures(pSourceVolume); // we better unswitch + if (pSourceVolume->Dirty) + uMod_Client->ComputeCRC(pSourceVolume); - // the source must be the original texture if not switched and the fake texture if it is switched + // if the source texture is switched we take the fake texture as source if (pSourceVolume->CrossRef_D3Dtex!=NULL) pSourceTexture = pSourceVolume->CrossRef_D3Dtex->m_D3Dtex; else pSourceTexture = pSourceVolume->m_D3Dtex; break; @@ -751,19 +767,10 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu case 0x01000002L: { pSourceCube = (uMod_IDirect3DCubeTexture9*)(pSourceTexture); - DWORD64 crc64 = pSourceCube->CRC64; - DWORD32 crc32 = pSourceCube->CRC32; - if (pSourceCube->ComputetHash( crc32>0 ) == RETURN_OK) - { - if (crc64 != pSourceCube->CRC64 || (crc32>0 && crc32 != pSource->CRC32) ) // this hash has changed !! - { - UnswitchTextures(pSourceCube); - uMod_Client->LookUpToMod( pSourceCube); - } - } - else UnswitchTextures(pSourceCube); // we better unswitch + if (pSourceCube->Dirty) + uMod_Client->ComputeCRC(pSourceCube); - // the source must be the original texture if not switched and the fake texture if it is switched + // if the source texture is switched we take the fake texture as source if (pSourceCube->CrossRef_D3Dtex!=NULL) pSourceTexture = pSourceCube->CrossRef_D3Dtex->m_D3Dtex; else pSourceTexture = pSourceCube->m_D3Dtex; break; @@ -787,21 +794,22 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu { pDest->CRC64 = pSource->CRC64; // take over the hash pDest->CRC32 = pSource->CRC32; // take over the hash + pDest->Dirty = 0; - UnswitchTextures(pDest); // we can always unswitch ! + if (pDest->CrossRef_D3Dtex!=NULL) + { + if (pDest->CrossRef_D3Dtex->Reference<0) + UnswitchTextures(pDest); + else pDest->CrossRef_D3Dtex->Release(); + } pDestinationTexture = pDest->m_D3Dtex; // set the correct destination texture if (pSource->CrossRef_D3Dtex!=NULL) { uMod_Client->LookUpToMod( pDest); - //uMod_IDirect3DTexture9 *cpy = pSource->CrossRef_D3Dtex; - //UnswitchTextures(pSource); - //SwitchTextures( cpy, pDest); } } - else if (pDest->ComputetHash( uMod_Client->BoolComputeCRC ) == RETURN_OK) // we must compute the crc - { - uMod_Client->LookUpToMod( pDest); - } + else + pDest->Dirty=1; break; } case 0x01000001L: @@ -812,21 +820,22 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu { pDest->CRC64 = pSourceVolume->CRC64; // take over the hash pDest->CRC32 = pSource->CRC32; // take over the hash + pDest->Dirty = 0; - UnswitchTextures(pDest); // we can always unswitch ! + if (pDest->CrossRef_D3Dtex!=NULL) + { + if (pDest->CrossRef_D3Dtex->Reference<0) + UnswitchTextures(pDest); + else pDest->CrossRef_D3Dtex->Release(); + } pDestinationTexture = pDest->m_D3Dtex; // set the correct destination texture if (pSourceVolume->CrossRef_D3Dtex!=NULL) { uMod_Client->LookUpToMod( pDest); - //uMod_IDirect3DVolumeTexture9 *cpy = pSourceVolume->CrossRef_D3Dtex; - //UnswitchTextures(pSourceVolume); - //SwitchTextures( cpy, pDest); } } - else if (pDest->ComputetHash( uMod_Client->BoolComputeCRC ) == RETURN_OK) // we must compute the crc - { - uMod_Client->LookUpToMod( pDest); - } + else + pDest->Dirty=1; break; } case 0x01000002L: @@ -837,21 +846,22 @@ HRESULT uMod_IDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTextu { pDest->CRC64 = pSourceCube->CRC64; // take over the hash pDest->CRC32 = pSource->CRC32; // take over the hash + pDest->Dirty = 0; - UnswitchTextures(pDest); // we can always unswitch ! + if (pDest->CrossRef_D3Dtex!=NULL) + { + if (pDest->CrossRef_D3Dtex->Reference<0) + UnswitchTextures(pDest); + else pDest->CrossRef_D3Dtex->Release(); + } pDestinationTexture = pDest->m_D3Dtex; // set the correct destination texture if (pSourceCube->CrossRef_D3Dtex!=NULL) { uMod_Client->LookUpToMod( pDest); - //uMod_IDirect3DCubeTexture9 *cpy = pSourceCube->CrossRef_D3Dtex; - //UnswitchTextures(pSourceCube); - //SwitchTextures( cpy, pDest); } } - else if (pDest->ComputetHash( uMod_Client->BoolComputeCRC ) == RETURN_OK) // we must compute the crc - { - uMod_Client->LookUpToMod( pDest); - } + else + pDest->Dirty=1; break; } default: @@ -954,12 +964,14 @@ HRESULT uMod_IDirect3DDevice9::ColorFill(IDirect3DSurface9* pSurface,CONST RECT* HRESULT uMod_IDirect3DDevice9::CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle) { - return(m_pIDirect3DDevice9->CreateOffscreenPlainSurface(Width,Height,Format,Pool,ppSurface,pSharedHandle)); + HRESULT ret = m_pIDirect3DDevice9->CreateOffscreenPlainSurface(Width,Height,Format,Pool,ppSurface,pSharedHandle); + Message( PRE_MESSAGE "::CreateOffscreenPlainSurface(%u, %u, %d, %d): %p, %p\n", Width, Height, Format, Pool, *ppSurface, this); + return (ret); } HRESULT uMod_IDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget) { - Message( PRE_MESSAGE "::SetRenderTarget( %u, %p): %p\n", RenderTargetIndex, pRenderTarget, this); + //Message( PRE_MESSAGE "::SetRenderTarget( %u, %p): %p\n", RenderTargetIndex, pRenderTarget, this); { IDirect3DSurface9 *back_buffer; NormalRendering = false; @@ -976,7 +988,10 @@ HRESULT uMod_IDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex,IDirect3D long int ret = pRenderTarget->QueryInterface( IID_IDirect3D9, (void**) &cpy); if (ret == 0x01000000L) { - pRenderTarget = ((uMod_IDirect3DSurface9*)pRenderTarget)->m_D3Dsurf; + uMod_IDirect3DSurface9 *Surf=((uMod_IDirect3DSurface9*)pRenderTarget); + pRenderTarget = Surf->m_D3Dsurf; + + CheckForChangeSurface(Surf, true); } } return (m_pIDirect3DDevice9->SetRenderTarget(RenderTargetIndex,pRenderTarget)); @@ -1009,23 +1024,12 @@ HRESULT uMod_IDirect3DDevice9::GetDepthStencilSurface(IDirect3DSurface9** ppZSte HRESULT uMod_IDirect3DDevice9::BeginScene(void) { + //Message("uMod_IDirect3DDevice9::BeginScene\n"); if ( uMod_Client!=NULL) { - if (LastCreatedTexture!=NULL) // add the last created texture - { - uMod_Client->AddTexture( LastCreatedTexture); - } - if (LastCreatedVolumeTexture!=NULL) // add the last created texture - { - uMod_Client->AddTexture( LastCreatedVolumeTexture); - } - if (LastCreatedCubeTexture!=NULL) // add the last created texture - { - uMod_Client->AddTexture( LastCreatedCubeTexture); - } uMod_Client->MergeUpdate(); // merge an update, if present - if (uMod_Client->Bool_CheckAgainNonAdded) uMod_Client->CheckAgainNonAdded(); + //if (uMod_Client->Bool_CheckAgainNonAdded) uMod_Client->CheckAgainNonAdded(); if (uMod_Client->BoolSaveSingleTexture) { @@ -1060,17 +1064,32 @@ HRESULT uMod_IDirect3DDevice9::BeginScene(void) switch (SingleTextureMod) { case 0: - SwitchTextures( SingleTexture, uMod_Client->OriginalTextures[CounterSaveSingleTexture]); - SingleTexture->CRC64 = uMod_Client->OriginalTextures[CounterSaveSingleTexture]->CRC64; //set the CRC64 for the display + { + uMod_IDirect3DTexture9 *tex = uMod_Client->OriginalTextures[CounterSaveSingleTexture]; + if (tex->Dirty) + uMod_Client->ComputeCRC(tex); + SwitchTextures( SingleTexture, tex); + SingleTexture->CRC64 = tex->CRC64; //set the CRC64 for the display break; + } case 1: - SwitchTextures( SingleVolumeTexture, uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]); - SingleVolumeTexture->CRC64 = uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]->CRC64; //set the CRC64 for the display + { + uMod_IDirect3DVolumeTexture9 *tex = uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]; + if (tex->Dirty) + uMod_Client->ComputeCRC(tex); + SwitchTextures( SingleVolumeTexture, tex); + SingleVolumeTexture->CRC64 = tex->CRC64; //set the CRC64 for the display break; + } case 2: - SwitchTextures( SingleCubeTexture, uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]); - SingleCubeTexture->CRC64 = uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]->CRC64; //set the CRC64 for the display + { + uMod_IDirect3DCubeTexture9 *tex = uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]; + if (tex->Dirty) + uMod_Client->ComputeCRC(tex); + SwitchTextures( SingleCubeTexture, tex); + SingleCubeTexture->CRC64 = tex->CRC64; //set the CRC64 for the display break; + } } } } @@ -1080,13 +1099,13 @@ HRESULT uMod_IDirect3DDevice9::BeginScene(void) switch (SingleTextureMod) { case 0: - uMod_Client->SaveTexture( SingleTexture); //after switching the SingleTexture holds the pointer to the original texture object + uMod_Client->SaveTexture( SingleTexture->CrossRef_D3Dtex); break; case 1: - uMod_Client->SaveTexture( SingleVolumeTexture); //after switching the SingleTexture holds the pointer to the original texture object + uMod_Client->SaveTexture( SingleVolumeTexture->CrossRef_D3Dtex); break; case 2: - uMod_Client->SaveTexture( SingleCubeTexture); //after switching the SingleTexture holds the pointer to the original texture object + uMod_Client->SaveTexture( SingleCubeTexture->CrossRef_D3Dtex); break; } } @@ -1136,17 +1155,32 @@ HRESULT uMod_IDirect3DDevice9::BeginScene(void) switch (SingleTextureMod) { case 0: - SwitchTextures( SingleTexture, uMod_Client->OriginalTextures[CounterSaveSingleTexture]); - SingleTexture->CRC64 = uMod_Client->OriginalTextures[CounterSaveSingleTexture]->CRC64; //set the CRC64 for the display + { + uMod_IDirect3DTexture9 *tex = uMod_Client->OriginalTextures[CounterSaveSingleTexture]; + if (tex->Dirty) + uMod_Client->ComputeCRC(tex); + SwitchTextures( SingleTexture, tex); + SingleTexture->CRC64 = tex->CRC64; //set the CRC64 for the display break; + } case 1: - SwitchTextures( SingleVolumeTexture, uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]); - SingleVolumeTexture->CRC64 = uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]->CRC64; //set the CRC64 for the display + { + uMod_IDirect3DVolumeTexture9 *tex = uMod_Client->OriginalVolumeTextures[CounterSaveSingleTexture]; + if (tex->Dirty) + uMod_Client->ComputeCRC(tex); + SwitchTextures( SingleVolumeTexture, tex); + SingleVolumeTexture->CRC64 = tex->CRC64; //set the CRC64 for the display break; + } case 2: - SwitchTextures( SingleCubeTexture, uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]); - SingleCubeTexture->CRC64 = uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]->CRC64; //set the CRC64 for the display + { + uMod_IDirect3DCubeTexture9 *tex = uMod_Client->OriginalCubeTextures[CounterSaveSingleTexture]; + if (tex->Dirty) + uMod_Client->ComputeCRC(tex); + SwitchTextures( SingleCubeTexture, tex); + SingleCubeTexture->CRC64 = tex->CRC64; //set the CRC64 for the display break; + } } } } @@ -1160,9 +1194,11 @@ HRESULT uMod_IDirect3DDevice9::BeginScene(void) HRESULT uMod_IDirect3DDevice9::EndScene(void) { + //Message("uMod_IDirect3DDevice9::EndScene\n"); if ( uMod_Client!=NULL && NormalRendering && uMod_Client->BoolSaveSingleTexture && SingleTexture!=NULL && SingleVolumeTexture!=NULL && SingleCubeTexture!=NULL) { D3DVIEWPORT9 viewport; + D3DSURFACE_DESC desc; GetViewport( &viewport); if (SingleTexture->CrossRef_D3Dtex!=NULL && uMod_Client->BoolShowSingleTexture) @@ -1173,8 +1209,7 @@ HRESULT uMod_IDirect3DDevice9::EndScene(void) } if (pSprite!=NULL) { - D3DSURFACE_DESC desc; - SingleTexture->m_D3Dtex->GetLevelDesc(0, &desc); + SingleTexture->CrossRef_D3Dtex->m_D3Dtex->GetLevelDesc(0, &desc); D3DXMATRIX scale; float factorx, factory; @@ -1190,7 +1225,7 @@ HRESULT uMod_IDirect3DDevice9::EndScene(void) D3DXMatrixScaling(&scale, factorx, factorx, 1.0f); pSprite->SetTransform(&scale); } - pSprite->Draw(SingleTexture->m_D3Dtex,NULL,NULL,NULL,0xFFFFFFFF); + pSprite->Draw(SingleTexture->CrossRef_D3Dtex->m_D3Dtex,NULL,NULL,NULL,0xFFFFFFFF); pSprite->End(); } @@ -1211,7 +1246,14 @@ HRESULT uMod_IDirect3DDevice9::EndScene(void) { case 0: { - if (SingleTexture->CrossRef_D3Dtex!=NULL) sprintf_s( buffer, 256, "normal texture: %4d (1..%d): %#llX", CounterSaveSingleTexture+1, uMod_Client->OriginalTextures.GetNumber(), SingleTexture->CRC64); + if (SingleTexture->CrossRef_D3Dtex!=NULL) + { + if (SingleTexture->Dirty==0) sprintf_s( buffer, 256, "normal texture: %4d (1..%d): (%dX%d, %d) %#llX", CounterSaveSingleTexture+1, uMod_Client->OriginalTextures.GetNumber(), desc.Width, desc.Height, desc.Format, SingleTexture->CRC64); + else if (SingleTexture->Dirty<10) sprintf_s( buffer, 256, "normal texture: %4d (1..%d): (%dX%d, %d) \"dirty\" ", CounterSaveSingleTexture+1, uMod_Client->OriginalTextures.GetNumber(), desc.Width, desc.Height, desc.Format); + else if (SingleTexture->Dirty==10) sprintf_s( buffer, 256, "normal texture: %4d (1..%d): (%dX%d, %d) \"no hash\"", CounterSaveSingleTexture+1, uMod_Client->OriginalTextures.GetNumber(), desc.Width, desc.Height, desc.Format); + else if (SingleTexture->Dirty==20) sprintf_s( buffer, 256, "normal texture: %4d (1..%d): (%dX%d, %d) \"render target\"", CounterSaveSingleTexture+1, uMod_Client->OriginalTextures.GetNumber(), desc.Width, desc.Height, desc.Format); + else sprintf_s( buffer, 256, "normal texture: %4d (1..%d): (%dX%d, %d) \"unknown\"", CounterSaveSingleTexture+1, uMod_Client->OriginalTextures.GetNumber(), desc.Width, desc.Height, desc.Format); + } else { if (uMod_Client->OriginalTextures.GetNumber()>0) sprintf_s( buffer, 256, "normal texture: %4d (1..%d): nothing selected ", CounterSaveSingleTexture+1, uMod_Client->OriginalTextures.GetNumber()); @@ -1373,12 +1415,34 @@ HRESULT uMod_IDirect3DDevice9::SetTexture(DWORD Stage, IDirect3DBaseTexture9* pT switch (ret) { case 0x01000000L: - pTexture = ((uMod_IDirect3DTexture9*)(pTexture))->m_D3Dtex; break; + { + uMod_IDirect3DTexture9 *tex = ((uMod_IDirect3DTexture9*)(pTexture)); + if (tex->Dirty) + uMod_Client->ComputeCRC( tex); + if (tex->CrossRef_D3Dtex!=NULL) pTexture = tex->CrossRef_D3Dtex->m_D3Dtex; + else pTexture = tex->m_D3Dtex; + break; + } case 0x01000001L: - pTexture = ((uMod_IDirect3DVolumeTexture9*)(pTexture))->m_D3Dtex; break; + { + uMod_IDirect3DVolumeTexture9 *tex = ((uMod_IDirect3DVolumeTexture9*)(pTexture)); + if (tex->Dirty) + uMod_Client->ComputeCRC( tex); + if (tex->CrossRef_D3Dtex!=NULL) pTexture = tex->CrossRef_D3Dtex->m_D3Dtex; + else pTexture = tex->m_D3Dtex; + break; + } case 0x01000002L: - pTexture = ((uMod_IDirect3DCubeTexture9*)(pTexture))->m_D3Dtex; break; + { + uMod_IDirect3DCubeTexture9 *tex = ((uMod_IDirect3DCubeTexture9*)(pTexture)); + if (tex->Dirty) + uMod_Client->ComputeCRC( tex); + if (tex->CrossRef_D3Dtex!=NULL) pTexture = tex->CrossRef_D3Dtex->m_D3Dtex; + else pTexture = tex->m_D3Dtex; + break; + } default: + Message("this is a non hooked texture object: %p\n", pTexture); break; // this is no fake texture and QueryInterface failed, because IDirect3DBaseTexture9 object cannot be a IDirect3D9 object ;) } } diff --git a/uMod_DX9/uMod_IDirect3DDevice9.h b/uMod_DX9/uMod_IDirect3DDevice9.h index eef6778..0fee887 100644 --- a/uMod_DX9/uMod_IDirect3DDevice9.h +++ b/uMod_DX9/uMod_IDirect3DDevice9.h @@ -169,24 +169,14 @@ public: uMod_TextureClient_DX9* GetuMod_Client(void) {return (uMod_Client);} - uMod_IDirect3DTexture9* GetLastCreatedTexture(void) {return (LastCreatedTexture);} - int SetLastCreatedTexture(uMod_IDirect3DTexture9* pTexture) {LastCreatedTexture=pTexture; return (RETURN_OK);} - - uMod_IDirect3DVolumeTexture9* GetLastCreatedVolumeTexture(void) {return (LastCreatedVolumeTexture);} - int SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* pTexture) {LastCreatedVolumeTexture=pTexture; return (RETURN_OK);} - - uMod_IDirect3DCubeTexture9* GetLastCreatedCubeTexture(void) {return (LastCreatedCubeTexture);} - int SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* pTexture) {LastCreatedCubeTexture=pTexture; return (RETURN_OK);} - - uMod_IDirect3DTexture9* GetSingleTexture(void) {return (SingleTexture);} uMod_IDirect3DVolumeTexture9* GetSingleVolumeTexture(void) {return (SingleVolumeTexture);} uMod_IDirect3DCubeTexture9* GetSingleCubeTexture(void) {return (SingleCubeTexture);} - int ComputetHash( DWORD64 &CRC64, DWORD32 &CRC32, IDirect3DSurface9 *surface, bool compute_crc); - int CheckForChangeSurface(uMod_IDirect3DSurface9 *surface); + int ComputeCRC( DWORD64 &CRC64, DWORD32 &CRC32, IDirect3DSurface9 *surface, bool compute_crc); + int CheckForChangeSurface(uMod_IDirect3DSurface9 *surface, bool render_target=false); - void SetNextTextureIsFake(void) {NextTextureIsFake=true;} + void SetNextTextureIsFake(bool val = true) {NextTextureIsFake=val;} private: int CreateSingleTexture(void); @@ -208,9 +198,6 @@ public: int uMod_Reference; bool NextTextureIsFake; - uMod_IDirect3DTexture9* LastCreatedTexture; - uMod_IDirect3DVolumeTexture9* LastCreatedVolumeTexture; - uMod_IDirect3DCubeTexture9* LastCreatedCubeTexture; uMod_TextureServer* uMod_Server; uMod_TextureClient_DX9* uMod_Client; diff --git a/uMod_DX9/uMod_IDirect3DDevice9Ex.h b/uMod_DX9/uMod_IDirect3DDevice9Ex.h index 4325c8d..3dece9e 100644 --- a/uMod_DX9/uMod_IDirect3DDevice9Ex.h +++ b/uMod_DX9/uMod_IDirect3DDevice9Ex.h @@ -181,24 +181,15 @@ public: uMod_TextureClient_DX9* GetuMod_Client(void) {return (uMod_Client);} - uMod_IDirect3DTexture9* GetLastCreatedTexture(void) {return (LastCreatedTexture);} - int SetLastCreatedTexture(uMod_IDirect3DTexture9* pTexture) {LastCreatedTexture=pTexture; return (RETURN_OK);} - - uMod_IDirect3DVolumeTexture9* GetLastCreatedVolumeTexture(void) {return (LastCreatedVolumeTexture);} - int SetLastCreatedVolumeTexture(uMod_IDirect3DVolumeTexture9* pTexture) {LastCreatedVolumeTexture=pTexture; return (RETURN_OK);} - - uMod_IDirect3DCubeTexture9* GetLastCreatedCubeTexture(void) {return (LastCreatedCubeTexture);} - int SetLastCreatedCubeTexture(uMod_IDirect3DCubeTexture9* pTexture) {LastCreatedCubeTexture=pTexture; return (RETURN_OK);} - - uMod_IDirect3DTexture9* GetSingleTexture(void) {return (SingleTexture);} uMod_IDirect3DVolumeTexture9* GetSingleVolumeTexture(void) {return (SingleVolumeTexture);} uMod_IDirect3DCubeTexture9* GetSingleCubeTexture(void) {return (SingleCubeTexture);} - int ComputetHash( DWORD64 &CRC64, DWORD32 &CRC32, IDirect3DSurface9 *surface, bool compute_crc); - int CheckForChangeSurface(uMod_IDirect3DSurface9 *surface); + int ComputeCRC( DWORD64 &CRC64, DWORD32 &CRC32, IDirect3DSurface9 *surface, bool compute_crc); + int CheckForChangeSurface(uMod_IDirect3DSurface9 *surface, bool render_target=false); + + void SetNextTextureIsFake(bool val = true) {NextTextureIsFake=val;} - void SetNextTextureIsFake(void) {NextTextureIsFake=true;} private: int CreateSingleTexture(void); @@ -220,9 +211,6 @@ public: int uMod_Reference; bool NextTextureIsFake; - uMod_IDirect3DTexture9* LastCreatedTexture; - uMod_IDirect3DVolumeTexture9* LastCreatedVolumeTexture; - uMod_IDirect3DCubeTexture9* LastCreatedCubeTexture; uMod_TextureServer* uMod_Server; uMod_TextureClient_DX9* uMod_Client; diff --git a/uMod_DX9/uMod_IDirect3DSurface9.cpp b/uMod_DX9/uMod_IDirect3DSurface9.cpp index 768b4ca..34de687 100644 --- a/uMod_DX9/uMod_IDirect3DSurface9.cpp +++ b/uMod_DX9/uMod_IDirect3DSurface9.cpp @@ -26,7 +26,7 @@ along with Universal Modding Engine. If not, see HRESULT uMod_IDirect3DSurface9::QueryInterface(REFIID riid, void** ppvObj) { - Message( "uMod_IDirect3DSurface9::uMod_IDirect3DSurface9(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::uMod_IDirect3DSurface9(): %p\n", this); if (riid==IID_IDirect3D9) { // This function should never be called with IID_IDirect3D9 by the game @@ -50,14 +50,14 @@ HRESULT uMod_IDirect3DSurface9::QueryInterface(REFIID riid, void** ppvObj) ULONG uMod_IDirect3DSurface9::AddRef() { - Message( "uMod_IDirect3DSurface9::AddRef(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::AddRef(): %p\n", this); RefCounter++; return m_D3Dsurf->AddRef(); } ULONG uMod_IDirect3DSurface9::Release() { - Message( "uMod_IDirect3DSurface9::Release(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::Release(): %p\n", this); // this object might be created by uMod_IDirect3DTexture9::GetSurfaceLevel // thus the RefCounter might be zero although m_D3Dsurf->Release() does not delete // the m_D3Dsurf object @@ -68,55 +68,55 @@ ULONG uMod_IDirect3DSurface9::Release() HRESULT uMod_IDirect3DSurface9::GetDevice( IDirect3DDevice9** ppDevice) { - Message( "uMod_IDirect3DSurface9::GetDevice(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::GetDevice(): %p\n", this); *ppDevice = m_D3Ddev; return 0; } HRESULT uMod_IDirect3DSurface9::SetPrivateData( REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) { - Message( "uMod_IDirect3DSurface9::SetPrivateData(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::SetPrivateData(): %p\n", this); return m_D3Dsurf->SetPrivateData( refguid, pData, SizeOfData, Flags); } HRESULT uMod_IDirect3DSurface9::GetPrivateData( REFGUID refguid,void* pData,DWORD* pSizeOfData) { - Message( "uMod_IDirect3DSurface9::GetPrivateData(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::GetPrivateData(): %p\n", this); return m_D3Dsurf->GetPrivateData( refguid, pData, pSizeOfData); } HRESULT uMod_IDirect3DSurface9::FreePrivateData( REFGUID refguid) { - Message( "uMod_IDirect3DSurface9::FreePrivateData(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::FreePrivateData(): %p\n", this); return m_D3Dsurf->FreePrivateData( refguid); } DWORD uMod_IDirect3DSurface9::SetPriority(DWORD PriorityNew) { - Message( "uMod_IDirect3DSurface9::SetPriority(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::SetPriority(): %p\n", this); return m_D3Dsurf->SetPriority(PriorityNew); } DWORD uMod_IDirect3DSurface9::GetPriority() { - Message( "uMod_IDirect3DSurface9::GetPriority(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::GetPriority(): %p\n", this); return m_D3Dsurf->GetPriority(); } void uMod_IDirect3DSurface9::PreLoad() { - Message( "uMod_IDirect3DSurface9::PreLoad(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::PreLoad(): %p\n", this); return m_D3Dsurf->PreLoad(); } D3DRESOURCETYPE uMod_IDirect3DSurface9::GetType() { - Message( "uMod_IDirect3DSurface9::GetType(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::GetType(): %p\n", this); return m_D3Dsurf->GetType(); } HRESULT uMod_IDirect3DSurface9::GetContainer( REFIID riid,void** ppContainer) { - Message( "uMod_IDirect3DSurface9::GetContainer(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::GetContainer(): %p\n", this); HRESULT ret = m_D3Dsurf->GetContainer( riid, ppContainer); //return the uMod_IDirect3DTexture9 object @@ -136,100 +136,44 @@ HRESULT uMod_IDirect3DSurface9::GetContainer( REFIID riid,void** ppContainer) HRESULT uMod_IDirect3DSurface9::GetDesc( D3DSURFACE_DESC *pDesc) { - Message( "uMod_IDirect3DSurface9::GetDesc(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::GetDesc(): %p\n", this); return m_D3Dsurf->GetDesc( pDesc); } HRESULT uMod_IDirect3DSurface9::LockRect( D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) { - Message( "uMod_IDirect3DSurface9::LockRect(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::LockRect(): %p\n", this); return m_D3Dsurf->LockRect( pLockedRect, pRect, Flags); } HRESULT uMod_IDirect3DSurface9::UnlockRect() { - Message( "uMod_IDirect3DSurface9::UnlockRect(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::UnlockRect(): %p\n", this); HRESULT ret = m_D3Dsurf->UnlockRect(); - if (m_D3DTex!=NULL) - { - DWORD64 crc64 = m_D3DTex->CRC64; - DWORD64 crc32 = m_D3DTex->CRC32; - m_D3DTex->ComputetHash(crc32>0); - if (crc64!=m_D3DTex->CRC64) - { - // device can be uMod_IDirect3DDevice9 object or a uMod_IDirect3DDevice9Ex object ! - void *cpy; - long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) - ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(m_D3DTex); - else - ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(m_D3DTex); - } - } - else if (m_D3DCubeTex!=NULL) - { - DWORD64 crc64 = m_D3DCubeTex->CRC64; - DWORD64 crc32 = m_D3DCubeTex->CRC32; - m_D3DCubeTex->ComputetHash(crc32>0); - if (crc64!=m_D3DCubeTex->CRC64) - { - // device can be uMod_IDirect3DDevice9 object or a uMod_IDirect3DDevice9Ex object ! - void *cpy; - long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) - ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(m_D3DCubeTex); - else - ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(m_D3DCubeTex); - } - } + if (m_D3DTex!=NULL && !m_D3DTex->FAKE) + m_D3DTex->Dirty=1; + else if (m_D3DCubeTex!=NULL && !m_D3DCubeTex->FAKE) + m_D3DCubeTex->Dirty = 1; return ret; } HRESULT uMod_IDirect3DSurface9::GetDC( HDC *phdc) { - Message( "uMod_IDirect3DSurface9::GetDC(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::GetDC(): %p\n", this); return m_D3Dsurf->GetDC( phdc); } HRESULT uMod_IDirect3DSurface9::ReleaseDC( HDC hdc) { - Message( "uMod_IDirect3DSurface9::ReleaseDC(): %p\n", this); + //Message( "uMod_IDirect3DSurface9::ReleaseDC(): %p\n", this); HRESULT ret = m_D3Dsurf->ReleaseDC( hdc); - if (m_D3DTex!=NULL) - { - DWORD64 crc64 = m_D3DTex->CRC64; - DWORD64 crc32 = m_D3DTex->CRC32; - m_D3DTex->ComputetHash(crc32>0); - if (crc64!=m_D3DTex->CRC64) - { - // device can be uMod_IDirect3DDevice9 object or a uMod_IDirect3DDevice9Ex object ! - void *cpy; - long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) - ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(m_D3DTex); - else - ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(m_D3DTex); - } - } - else if (m_D3DCubeTex!=NULL) - { - DWORD64 crc64 = m_D3DCubeTex->CRC64; - DWORD64 crc32 = m_D3DCubeTex->CRC32; - m_D3DCubeTex->ComputetHash(crc32>0); - if (crc64!=m_D3DCubeTex->CRC64) - { - // device can be uMod_IDirect3DDevice9 object or a uMod_IDirect3DDevice9Ex object ! - void *cpy; - long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) - ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(m_D3DCubeTex); - else - ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(m_D3DCubeTex); - } - } + if (m_D3DTex!=NULL && !m_D3DTex->FAKE) + m_D3DTex->Dirty=1; + else if (m_D3DCubeTex!=NULL && !m_D3DCubeTex->FAKE) + m_D3DCubeTex->Dirty = 1; return ret; } diff --git a/uMod_DX9/uMod_IDirect3DTexture9.cpp b/uMod_DX9/uMod_IDirect3DTexture9.cpp index 28b333f..a20a6b9 100644 --- a/uMod_DX9/uMod_IDirect3DTexture9.cpp +++ b/uMod_DX9/uMod_IDirect3DTexture9.cpp @@ -42,17 +42,9 @@ HRESULT APIENTRY uMod_IDirect3DTexture9::QueryInterface(REFIID riid, void** ppvO *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; - } + HRESULT hRes = m_D3Dtex->QueryInterface(riid, ppvObj); + if (*ppvObj==m_D3Dtex) *ppvObj=this; + return (hRes); } @@ -60,17 +52,13 @@ HRESULT APIENTRY uMod_IDirect3DTexture9::QueryInterface(REFIID riid, void** ppvO ULONG APIENTRY uMod_IDirect3DTexture9::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()); + return (m_D3Dtex->AddRef()); } //this function yields for the non switched texture object ULONG APIENTRY uMod_IDirect3DTexture9::Release() { - Message("uMod_IDirect3DTexture9::Release(): %p\n", this); + //Message("uMod_IDirect3DTexture9::Release(): %p\n", this); void *cpy; long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); @@ -83,48 +71,24 @@ ULONG APIENTRY uMod_IDirect3DTexture9::Release() } else { - if (CrossRef_D3Dtex!=NULL) //if this texture is switched with a fake texture - { - uMod_IDirect3DTexture9 *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 (ret == 0x01000000L) - { - if (((uMod_IDirect3DDevice9*) m_D3Ddev)->GetSingleTexture()!=fake_texture) fake_texture->Release(); // we release the fake texture - } - else - { - if (((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetSingleTexture()!=fake_texture) fake_texture->Release(); // we release the fake texture - } - } - } - else - { - count = m_D3Dtex->Release(); - } + count = m_D3Dtex->Release(); } if (count==0) //if this texture is released, we clean up { - // if this texture is the LastCreatedTexture, the next time LastCreatedTexture would be added, - // the hash of a non existing texture would be calculated if (ret == 0x01000000L) { - if (((uMod_IDirect3DDevice9*) m_D3Ddev)->GetLastCreatedTexture()==this) ((uMod_IDirect3DDevice9*) m_D3Ddev)->SetLastCreatedTexture( NULL); - else ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client + ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client } else { - if (((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetLastCreatedTexture()==this) ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->SetLastCreatedTexture( NULL); - else ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client + ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client } delete(this); } - Message("uMod_IDirect3DTexture9::Release() end: %p\n", this); + //Message("uMod_IDirect3DTexture9::Release() end: %p\n", this); return (count); } @@ -137,21 +101,18 @@ HRESULT APIENTRY uMod_IDirect3DTexture9::GetDevice(IDirect3DDevice9** ppDevice) //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DTexture9::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 uMod_IDirect3DTexture9::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 uMod_IDirect3DTexture9::FreePrivateData(REFGUID refguid) { - if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->FreePrivateData(refguid)); return (m_D3Dtex->FreePrivateData(refguid)); } @@ -208,7 +169,6 @@ void APIENTRY uMod_IDirect3DTexture9::GenerateMipSubLevels() //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DTexture9::GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc) { - if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->GetLevelDesc(Level, pDesc)); return (m_D3Dtex->GetLevelDesc(Level, pDesc)); } @@ -218,9 +178,7 @@ HRESULT APIENTRY uMod_IDirect3DTexture9::GetSurfaceLevel(UINT Level, IDirect3DSu Message( "uMod_IDirect3DTexture9::GetSurfaceLevel( %u, %p): %p\n", Level, *ppSurfaceLevel, this); IDirect3DSurface9* pSurf; uMod_IDirect3DSurface9* puMod_Surf; - HRESULT ret; - if (CrossRef_D3Dtex!=NULL) ret = (CrossRef_D3Dtex->m_D3Dtex->GetSurfaceLevel(Level, &pSurf)); - else ret = (m_D3Dtex->GetSurfaceLevel(Level, &pSurf)); + HRESULT ret = (m_D3Dtex->GetSurfaceLevel(Level, &pSurf)); if (SUCCEEDED(ret)) { @@ -235,38 +193,19 @@ HRESULT APIENTRY uMod_IDirect3DTexture9::GetSurfaceLevel(UINT Level, IDirect3DSu //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DTexture9::LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) { - if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->LockRect(Level, pLockedRect, pRect, Flags)); return (m_D3Dtex->LockRect(Level, pLockedRect, pRect, Flags)); } //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DTexture9::UnlockRect(UINT Level) { - HRESULT ret; - if (CrossRef_D3Dtex!=NULL) ret = (CrossRef_D3Dtex->m_D3Dtex->UnlockRect(Level)); - ret = (m_D3Dtex->UnlockRect(Level)); - - DWORD64 crc64 = CRC64; - DWORD64 crc32 = CRC32; - ComputetHash(crc32>0); - if (crc64!=CRC64) - { - // device can be uMod_IDirect3DDevice9 object or a uMod_IDirect3DDevice9Ex object ! - void *cpy; - long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) - ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(this); - else - ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->CRCHasChanged(this); - } - - return ret; + Dirty =1; + return (m_D3Dtex->UnlockRect(Level)); } //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DTexture9::AddDirtyRect(CONST RECT* pDirtyRect) { - if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->AddDirtyRect(pDirtyRect)); return (m_D3Dtex->AddDirtyRect(pDirtyRect)); } @@ -275,7 +214,6 @@ int uMod_IDirect3DTexture9::ComputetHash( bool compute_crc) { if (FAKE) return (RETURN_BAD_ARGUMENT); IDirect3DTexture9 *pTexture = m_D3Dtex; - if (CrossRef_D3Dtex!=NULL) pTexture = CrossRef_D3Dtex->m_D3Dtex; IDirect3DSurface9 *surface = NULL; @@ -286,9 +224,14 @@ int uMod_IDirect3DTexture9::ComputetHash( bool compute_crc) } if (compute_crc) InitCRC32(CRC32); + else CRC32 = 0u; InitCRC64(CRC64); - ((uMod_IDirect3DDevice9*)(m_D3Ddev))->ComputetHash( CRC64, CRC32, surface, compute_crc); + + void *cpy; + long ret = m_D3Ddev->QueryInterface( IID_IDirect3DTexture9, &cpy); + if (ret == 0x01000000L) ret = ((uMod_IDirect3DDevice9*)m_D3Ddev)->ComputeCRC( CRC64, CRC32, surface, compute_crc); + else ret = ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->ComputeCRC( CRC64, CRC32, surface, compute_crc); surface->Release(); - return (RETURN_OK); + return (ret); } diff --git a/uMod_DX9/uMod_IDirect3DTexture9.h b/uMod_DX9/uMod_IDirect3DTexture9.h index d7ccc35..a692d17 100644 --- a/uMod_DX9/uMod_IDirect3DTexture9.h +++ b/uMod_DX9/uMod_IDirect3DTexture9.h @@ -40,7 +40,7 @@ class uMod_IDirect3DTexture9 : public IDirect3DTexture9 public: uMod_IDirect3DTexture9(IDirect3DTexture9 **ppTex, IDirect3DDevice9 *pIDirect3DDevice9) { - Message( "uMod_IDirect3DTexture9::uMod_IDirect3DTexture9(%p %p): %p\n", *ppTex, pIDirect3DDevice9, this); + //Message( "uMod_IDirect3DTexture9::uMod_IDirect3DTexture9(%p %p): %p\n", *ppTex, pIDirect3DDevice9, this); 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 @@ -51,6 +51,7 @@ public: CRC64 = 0u; CRC32 = 0u; FAKE = false; + Dirty = 1; } IDirect3DTexture9 *m_D3Dtex; //!< pointer to the real IDirect3DCubeTexture9 object @@ -60,6 +61,7 @@ public: DWORD64 CRC64; //!< computed hash value for this game texture. DWORD32 CRC32; //!< computed crc32 value for this game texture. bool FAKE; //!< True if this texture is was loaded by uMod (fake texture) + unsigned char Dirty; // original interface STDMETHOD(QueryInterface) (REFIID riid, void** ppvObj); @@ -88,40 +90,4 @@ public: int ComputetHash( bool compute_crc); }; - - -inline void UnswitchTextures(uMod_IDirect3DTexture9 *pTexture) -{ - uMod_IDirect3DTexture9* CrossRef = pTexture->CrossRef_D3Dtex; - if (CrossRef!=NULL) - { - // switch textures back - IDirect3DTexture9* 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( uMod_IDirect3DTexture9 *pTexture1, uMod_IDirect3DTexture9 *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 - IDirect3DTexture9* 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/uMod_DX9/uMod_IDirect3DVolumeTexture9.cpp b/uMod_DX9/uMod_IDirect3DVolumeTexture9.cpp index bce8e86..a93008d 100644 --- a/uMod_DX9/uMod_IDirect3DVolumeTexture9.cpp +++ b/uMod_DX9/uMod_IDirect3DVolumeTexture9.cpp @@ -40,17 +40,9 @@ HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::QueryInterface(REFIID riid, void* *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; - } + HRESULT hRes = m_D3Dtex->QueryInterface(riid, ppvObj); + if (*ppvObj==m_D3Dtex) *ppvObj=this; + return (hRes); } @@ -58,11 +50,7 @@ HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::QueryInterface(REFIID riid, void* ULONG APIENTRY uMod_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()); + return (m_D3Dtex->AddRef()); } //this function yields for the non switched texture object @@ -81,42 +69,18 @@ ULONG APIENTRY uMod_IDirect3DVolumeTexture9::Release() } else { - if (CrossRef_D3Dtex!=NULL) //if this texture is switched with a fake texture - { - uMod_IDirect3DVolumeTexture9 *fake_texture = CrossRef_D3Dtex; - count = fake_texture->m_D3Dtex->Release(); //release the original texture - if (count==0) //if texture is released we switch the textures back - { - UnswitchTextures(this); - if (ret == 0x01000000L) - { - if (((uMod_IDirect3DDevice9*) m_D3Ddev)->GetSingleVolumeTexture()!=fake_texture) fake_texture->Release(); // we release the fake texture - } - else - { - if (((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetSingleVolumeTexture()!=fake_texture) fake_texture->Release(); // we release the fake texture - } - } - } - else - { - count = m_D3Dtex->Release(); - } + count = m_D3Dtex->Release(); } if (count==0) //if this texture is released, we clean up { - // if this texture is the LastCreatedTexture, the next time LastCreatedTexture would be added, - // the hash of a non existing texture would be calculated if (ret == 0x01000000L) { - if (((uMod_IDirect3DDevice9*) m_D3Ddev)->GetLastCreatedVolumeTexture()==this) ((uMod_IDirect3DDevice9*) m_D3Ddev)->SetLastCreatedVolumeTexture( NULL); - else ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client + ((uMod_IDirect3DDevice9*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client } else { - if (((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetLastCreatedVolumeTexture()==this) ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->SetLastCreatedVolumeTexture( NULL); - else ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client + ((uMod_IDirect3DDevice9Ex*) m_D3Ddev)->GetuMod_Client()->RemoveTexture(this); // remove this texture from the texture client } delete(this); @@ -133,21 +97,18 @@ HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::GetDevice(IDirect3DDevice9** ppDe //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::SetPrivateData(REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) { - if (CrossRef_D3Dtex!=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 uMod_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 uMod_IDirect3DVolumeTexture9::FreePrivateData(REFGUID refguid) { - if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->FreePrivateData(refguid)); return (m_D3Dtex->FreePrivateData(refguid)); } @@ -206,34 +167,32 @@ void APIENTRY uMod_IDirect3DVolumeTexture9::GenerateMipSubLevels() //this function yields for the non switched texture object HRESULT APIENTRY uMod_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 uMod_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 uMod_IDirect3DVolumeTexture9::GetVolumeLevel(UINT Level, IDirect3DVolume9 **ppVolumeLevel) { - if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->GetVolumeLevel(Level, ppVolumeLevel)); + Dirty=1; return (m_D3Dtex->GetVolumeLevel(Level, ppVolumeLevel)); } //this function yields for the non switched texture object HRESULT APIENTRY uMod_IDirect3DVolumeTexture9::LockBox(UINT Level, D3DLOCKED_BOX *pLockedVolume, CONST D3DBOX *pBox ,DWORD Flags) { - if (CrossRef_D3Dtex!=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 uMod_IDirect3DVolumeTexture9::UnlockBox(UINT Level) { + Dirty=1; if (CrossRef_D3Dtex!=NULL) return (CrossRef_D3Dtex->m_D3Dtex->UnlockBox(Level)); return (m_D3Dtex->UnlockBox(Level)); } @@ -243,7 +202,6 @@ int uMod_IDirect3DVolumeTexture9::ComputetHash( bool compute_crc) { 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; diff --git a/uMod_DX9/uMod_IDirect3DVolumeTexture9.h b/uMod_DX9/uMod_IDirect3DVolumeTexture9.h index 7a73e9b..9c79f1e 100644 --- a/uMod_DX9/uMod_IDirect3DVolumeTexture9.h +++ b/uMod_DX9/uMod_IDirect3DVolumeTexture9.h @@ -50,6 +50,7 @@ public: CRC64 = 0u; CRC32 = 0u; FAKE = false; + Dirty = 1; } IDirect3DVolumeTexture9 *m_D3Dtex; //!< pointer to the real IDirect3DCubeTexture9 object @@ -59,6 +60,7 @@ public: DWORD64 CRC64; //!< computed hash value for this game texture. DWORD32 CRC32; //!< computed crc32 value for this game texture. bool FAKE; //!< True if this texture is was loaded by uMod (fake texture) + unsigned char Dirty; // original interface STDMETHOD(QueryInterface) (REFIID riid, void** ppvObj); @@ -88,40 +90,4 @@ public: int ComputetHash( bool compute_crc); }; - - -inline void UnswitchTextures(uMod_IDirect3DVolumeTexture9 *pTexture) -{ - uMod_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( uMod_IDirect3DVolumeTexture9 *pTexture1, uMod_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/uMod_DX9/uMod_TextureClient_DX9.cpp b/uMod_DX9/uMod_TextureClient_DX9.cpp index e689d62..b222a9a 100644 --- a/uMod_DX9/uMod_TextureClient_DX9.cpp +++ b/uMod_DX9/uMod_TextureClient_DX9.cpp @@ -27,7 +27,8 @@ uMod_TextureClient_DX9::uMod_TextureClient_DX9( IDirect3DDevice9* device, const { Message("uMod_TextureClient_DX9::uMod_TextureClient_DX9(void): %p\n", this); D3D9Device = device; - Bool_CheckAgainNonAdded = false; + BoolComputeCRC32 = false; + //Bool_CheckAgainNonAdded = false; } uMod_TextureClient_DX9::~uMod_TextureClient_DX9(void) @@ -38,135 +39,31 @@ uMod_TextureClient_DX9::~uMod_TextureClient_DX9(void) int uMod_TextureClient_DX9::AddTexture( uMod_IDirect3DTexture9* pTexture) { - void *cpy; - long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) ((uMod_IDirect3DDevice9*)D3D9Device)->SetLastCreatedTexture(NULL); //this texture must no be added twice - else ((uMod_IDirect3DDevice9Ex*) D3D9Device)->SetLastCreatedTexture(NULL); //this texture must no be added twice - if (pTexture->FAKE) return (RETURN_OK); // this is a fake texture Message("uMod_TextureClient_DX9::AddTexture( %p): %p (thread: %lu)\n", pTexture, this, GetCurrentThreadId()); - - if (int ret = pTexture->ComputetHash( BoolComputeCRC)) - { - Bool_CheckAgainNonAdded = true; - NonAdded_OriginalTextures.Add( pTexture); - return (ret); - } - - if (BoolSaveAllTextures) SaveTexture(pTexture, true); - - if (gl_ErrorState & uMod_ERROR_FATAL) return (RETURN_FATAL_ERROR); - OriginalTextures.Add( pTexture); // add the texture to the list of original texture - return (LookUpToMod(pTexture)); // check if this texture should be modded + return (RETURN_OK); } int uMod_TextureClient_DX9::AddTexture( uMod_IDirect3DVolumeTexture9* pTexture) { - void *cpy; - long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) ((uMod_IDirect3DDevice9*)D3D9Device)->SetLastCreatedVolumeTexture(NULL); //this texture must no be added twice - else ((uMod_IDirect3DDevice9Ex*) D3D9Device)->SetLastCreatedVolumeTexture(NULL); //this texture must no be added twice - if (pTexture->FAKE) return (RETURN_OK); // this is a fake texture Message("uMod_TextureClient_DX9::AddTexture( Volume: %p): %p (thread: %lu)\n", pTexture, this, GetCurrentThreadId()); - - if (int ret = pTexture->ComputetHash( BoolComputeCRC)) - { - Bool_CheckAgainNonAdded = true; - NonAdded_OriginalVolumeTextures.Add( pTexture); - return (ret); - } - - if (BoolSaveAllTextures) SaveTexture(pTexture, true); - - if (gl_ErrorState & uMod_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 + return (RETURN_OK); } int uMod_TextureClient_DX9::AddTexture( uMod_IDirect3DCubeTexture9* pTexture) { - void *cpy; - long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) ((uMod_IDirect3DDevice9*)D3D9Device)->SetLastCreatedCubeTexture(NULL); //this texture must no be added twice - else ((uMod_IDirect3DDevice9Ex*) D3D9Device)->SetLastCreatedCubeTexture(NULL); //this texture must no be added twice - if (pTexture->FAKE) return (RETURN_OK); // this is a fake texture Message("uMod_TextureClient_DX9::AddTexture( Cube: %p): %p (thread: %lu)\n", pTexture, this, GetCurrentThreadId()); - - if (int ret = pTexture->ComputetHash( BoolComputeCRC)) - { - Bool_CheckAgainNonAdded = true; - NonAdded_OriginalCubeTextures.Add( pTexture); - return (ret); - } - - if (BoolSaveAllTextures) SaveTexture(pTexture, true); - - if (gl_ErrorState & uMod_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 uMod_TextureClient_DX9::CheckAgainNonAdded(void) -{ - Message("uMod_TextureClient_DX9::CheckAgainNonAdded( %u, %u, %u): %p\n", NonAdded_OriginalTextures.GetNumber(), - NonAdded_OriginalVolumeTextures.GetNumber(), NonAdded_OriginalCubeTextures.GetNumber(), this); - - Bool_CheckAgainNonAdded = false; - - int num = NonAdded_OriginalTextures.GetNumber(); - for (int i=num-1; i>=0; i--) - { - uMod_IDirect3DTexture9* pTexture = NonAdded_OriginalTextures[i]; - - if (pTexture->ComputetHash( BoolComputeCRC) == RETURN_OK) - { - NonAdded_OriginalTextures.Remove(pTexture); - if (BoolSaveAllTextures) SaveTexture(pTexture, true); - OriginalTextures.Add( pTexture); // add the texture to the list of original texture - LookUpToMod(pTexture); // check if this texture should be modded - } - } - - num = NonAdded_OriginalVolumeTextures.GetNumber(); - for (int i=num-1; i>=0; i--) - { - uMod_IDirect3DVolumeTexture9* pTexture = NonAdded_OriginalVolumeTextures[i]; - - if (pTexture->ComputetHash( BoolComputeCRC) == RETURN_OK) - { - NonAdded_OriginalVolumeTextures.Remove(pTexture); - if (BoolSaveAllTextures) SaveTexture(pTexture, true); - OriginalVolumeTextures.Add( pTexture); // add the texture to the list of original texture - LookUpToMod(pTexture); // check if this texture should be modded - } - } - - num = NonAdded_OriginalCubeTextures.GetNumber(); - for (int i=num-1; i>=0; i--) - { - uMod_IDirect3DCubeTexture9* pTexture = NonAdded_OriginalCubeTextures[i]; - - if (pTexture->ComputetHash( BoolComputeCRC) == RETURN_OK) - { - NonAdded_OriginalCubeTextures.Remove(pTexture); - if (BoolSaveAllTextures) SaveTexture(pTexture, true); - OriginalCubeTextures.Add( pTexture); // add the texture to the list of original texture - LookUpToMod(pTexture); // check if this texture should be modded - } - } - Message("uMod_TextureClient_DX9::CheckAgainNonAdded() END: %p\n", this); return (RETURN_OK); } @@ -181,6 +78,8 @@ int uMod_TextureClient_DX9::RemoveTexture( uMod_IDirect3DTexture9* pTexture) // int ref = pTexture->Reference; if (ref>=0 && refReference; if (ref>=0 && refReference; if (ref>=0 && refFAKE) return (RETURN_OK); + if (tex->Dirty>10) return (RETURN_OK); + + DWORD64 crc64 = tex->CRC64; + DWORD64 crc32 = tex->CRC32; + if (tex->ComputetHash(BoolComputeCRC32)!=(RETURN_OK)) + { + tex->Dirty++; + return (RETURN_OK); + } + tex->Dirty = 0; + + if (crc64!=tex->CRC64 || crc32!=tex->CRC32) + { + if (tex->CrossRef_D3Dtex!=NULL) + { + if (tex->CrossRef_D3Dtex->Reference<0) + UnswitchTextures( tex); + else + tex->CrossRef_D3Dtex->Release(); + } + if (BoolSaveAllTextures) SaveTexture( tex, true); + LookUpToMod( tex); + } + + return (RETURN_OK); +} + +int uMod_TextureClient_DX9::ComputeCRC( uMod_IDirect3DVolumeTexture9* tex) +{ + if (tex->FAKE) return (RETURN_OK); + if (tex->Dirty>10) return (RETURN_OK); + + DWORD64 crc64 = tex->CRC64; + DWORD64 crc32 = tex->CRC32; + if (tex->ComputetHash(BoolComputeCRC32)!=(RETURN_OK)) + { + tex->Dirty++; + return (RETURN_OK); + } + tex->Dirty = 0; + + if (crc64!=tex->CRC64) + { + if (tex->CrossRef_D3Dtex!=NULL) + { + if (tex->CrossRef_D3Dtex->Reference<0) + UnswitchTextures( tex); + else + tex->CrossRef_D3Dtex->Release(); + } + if (BoolSaveAllTextures) SaveTexture( tex, true); + LookUpToMod( tex); + } + + return (RETURN_OK); +} + +int uMod_TextureClient_DX9::ComputeCRC( uMod_IDirect3DCubeTexture9* tex) +{ + if (tex->FAKE) return (RETURN_OK); + if (tex->Dirty>10) return (RETURN_OK); + + DWORD64 crc64 = tex->CRC64; + DWORD64 crc32 = tex->CRC32; + if (tex->ComputetHash(BoolComputeCRC32)!=(RETURN_OK)) + { + tex->Dirty++; + return (RETURN_OK); + } + tex->Dirty = 0; + + if (crc64!=tex->CRC64) + { + if (tex->CrossRef_D3Dtex!=NULL) + { + if (tex->CrossRef_D3Dtex->Reference<0) + UnswitchTextures( tex); + else + tex->CrossRef_D3Dtex->Release(); + } + if (BoolSaveAllTextures) SaveTexture( tex, true); + LookUpToMod( tex); + } + + return (RETURN_OK); +} int uMod_TextureClient_DX9::SaveAllTextures(bool val) { @@ -279,6 +274,20 @@ int uMod_TextureClient_DX9::SaveSingleTexture(bool val) return (RETURN_OK); } +int uMod_TextureClient_DX9::SupportTPF(bool val) +{ + BoolComputeCRC32 = val; + int num = OriginalTextures.GetNumber(); + for (int i=0; iDirty = true; + + num = OriginalVolumeTextures.GetNumber(); + for (int i=0; iDirty = true; + + num = OriginalCubeTextures.GetNumber(); + for (int i=0; iDirty = true; + + return (RETURN_OK); +} int uMod_TextureClient_DX9::SaveTexture(uMod_IDirect3DTexture9* pTexture, bool save_all) { @@ -551,28 +560,29 @@ int uMod_TextureClient_DX9::MergeUpdate(void) while (pos_old Update[pos_new].Hash) // this fake texture is new + if (FileToMod[pos_old].Content()->Hash > Update[pos_new].Content()->Hash) // this fake texture is new { to_lookup[num_to_lookup++] = pos_new++; // keep this fake texture in mind, we must search later for it through all original textures // we increase only the new counter by one } - else if (FileToMod[pos_old].Hash < Update[pos_new].Hash) // this fake texture is not in the update + else if (FileToMod[pos_old].Content()->Hash < Update[pos_new].Content()->Hash) // this fake texture is not in the update { + /* for (int i=FileToMod[pos_old].NumberOfTextures-1; i>=0; i--) ((IDirect3DBaseTexture9*) FileToMod[pos_old].Textures[i])->Release(); // we release the fake textures if (FileToMod[pos_old].Textures!=NULL) delete [] FileToMod[pos_old].Textures; // we delete the memory FileToMod[pos_old].NumberOfTextures = 0; FileToMod[pos_old].Textures = NULL; - + */ 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 (Update[pos_new].ForceReload) + if (Update[pos_new].Content()->ForceReload) { if (FileToMod[pos_old].NumberOfTextures>0) { - Update[pos_new].Textures = (void**) new IDirect3DBaseTexture9*[FileToMod[pos_old].NumberOfTextures]; + Update[pos_new].Textures = (IUnknown**) new IDirect3DBaseTexture9*[FileToMod[pos_old].NumberOfTextures]; } for (int i=0; iCRC64); @@ -609,7 +619,7 @@ int uMod_TextureClient_DX9::MergeUpdate(void) i--; //after the Release of the old fake texture FileToMod[pos_old].Textures[i] is overwritten by entries with index greater than i uMod_IDirect3DVolumeTexture9 *fake_Texture; - if (int ret = LoadTexture( & (Update[pos_new]), &fake_Texture)) return (ret); + if (int ret = LoadTexture( Update[pos_new].Content(), &fake_Texture)) return (ret); if (SwitchTextures( fake_Texture, pRefTexture)) { Message("MergeUpdate(): textures not switched %#llX\n", pRefTexture->CRC64); @@ -630,7 +640,7 @@ int uMod_TextureClient_DX9::MergeUpdate(void) i--; //after the Release of the old fake texture FileToMod[pos_old].Textures[i] is overwritten by entries with index greater than i uMod_IDirect3DCubeTexture9 *fake_Texture; - if (int ret = LoadTexture( & (Update[pos_new]), &fake_Texture)) return (ret); + if (int ret = LoadTexture( Update[pos_new].Content(), &fake_Texture)) return (ret); if (SwitchTextures( fake_Texture, pRefTexture)) { Message("MergeUpdate(): textures not switched %#llX\n", pRefTexture->CRC64); @@ -660,7 +670,7 @@ int uMod_TextureClient_DX9::MergeUpdate(void) pos_new++; } } - +/* while (pos_old=0; i--) @@ -670,6 +680,7 @@ int uMod_TextureClient_DX9::MergeUpdate(void) FileToMod[pos_old].Textures = NULL; pos_old++; } + */ while (pos_newReference<0) // this texture was not added before or it is a fake texture ! - return AddTexture( pTexture); - else - return LookUpToMod( pTexture); -} - -int uMod_TextureClient_DX9::CRCHasChanged( uMod_IDirect3DCubeTexture9* pTexture) -{ - UnswitchTextures(pTexture); - if (pTexture->Reference<0) // this texture was not added before or it is a fake texture ! - return AddTexture( pTexture); - else - return LookUpToMod( pTexture); -} - int uMod_TextureClient_DX9::LookUpToMod( uMod_IDirect3DTexture9* pTexture, int num_index_list, int *index_list) // should only be called for original textures { Message("uMod_TextureClient_DX9::LookUpToMod( %p): hash: %#llX, %p\n", pTexture, pTexture->CRC64, this); @@ -763,14 +755,17 @@ int uMod_TextureClient_DX9::LookUpToMod( uMod_IDirect3DTexture9* pTexture, int n if (index>=0) { uMod_IDirect3DTexture9 *fake_Texture; - if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret); + if (int ret = LoadTexture( FileToMod[index].Content(), &fake_Texture)) return (ret); if (SwitchTextures( fake_Texture, pTexture)) { - Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Hash); + Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Content()->Hash); fake_Texture->Release(); } else { + fake_Texture->Reference = index; + FileToMod[index].AddTexture( fake_Texture); + /* IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1]; for (int j=0; jReference = index; + */ } } - else if (BoolComputeCRC && pTexture->CRC32>0) + else if (BoolComputeCRC32 && pTexture->CRC32>0) { index = GetIndex( pTexture->CRC32, num_index_list, index_list); if (index>=0) { uMod_IDirect3DTexture9 *fake_Texture; - if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret); + if (int ret = LoadTexture( FileToMod[index].Content(), &fake_Texture)) return (ret); if (SwitchTextures( fake_Texture, pTexture)) { - Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Hash); + Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Content()->Hash); fake_Texture->Release(); } else { + fake_Texture->Reference = index; + FileToMod[index].AddTexture(fake_Texture); + /* IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1]; for (int j=0; jReference = index; + */ } } } @@ -817,14 +816,17 @@ int uMod_TextureClient_DX9::LookUpToMod( uMod_IDirect3DVolumeTexture9* pTexture, if (index>=0) { uMod_IDirect3DVolumeTexture9 *fake_Texture; - if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret); + if (int ret = LoadTexture( FileToMod[index].Content(), &fake_Texture)) return (ret); if (SwitchTextures( fake_Texture, pTexture)) { - Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Hash); + Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Content()->Hash); fake_Texture->Release(); } else { + fake_Texture->Reference = index; + FileToMod[index].AddTexture(fake_Texture); + /* IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1]; for (int j=0; jReference = index; + */ } } - else if (BoolComputeCRC && pTexture->CRC32>0) + else if (BoolComputeCRC32 && pTexture->CRC32>0) { index = GetIndex( pTexture->CRC32, num_index_list, index_list); if (index>=0) { uMod_IDirect3DVolumeTexture9 *fake_Texture; - if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret); + if (int ret = LoadTexture( FileToMod[index].Content(), &fake_Texture)) return (ret); if (SwitchTextures( fake_Texture, pTexture)) { - Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Hash); + Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Content()->Hash); fake_Texture->Release(); } else { + fake_Texture->Reference = index; + FileToMod[index].AddTexture(fake_Texture); + /* IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1]; for (int j=0; jReference = index; + */ } } } @@ -871,14 +878,17 @@ int uMod_TextureClient_DX9::LookUpToMod( uMod_IDirect3DCubeTexture9* pTexture, i if (index>=0) { uMod_IDirect3DCubeTexture9 *fake_Texture; - if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret); + if (int ret = LoadTexture( FileToMod[index].Content(), &fake_Texture)) return (ret); if (SwitchTextures( fake_Texture, pTexture)) { - Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Hash); + Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Content()->Hash); fake_Texture->Release(); } else { + fake_Texture->Reference = index; + FileToMod[index].AddTexture(fake_Texture); + /* IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1]; for (int j=0; jReference = index; + */ } } - else if (BoolComputeCRC && pTexture->CRC32>0) + else if (BoolComputeCRC32 && pTexture->CRC32>0) { index = GetIndex( pTexture->CRC32, num_index_list, index_list); if (index>=0) { uMod_IDirect3DCubeTexture9 *fake_Texture; - if (int ret = LoadTexture( & (FileToMod[index]), &fake_Texture)) return (ret); + if (int ret = LoadTexture( FileToMod[index].Content(), &fake_Texture)) return (ret); if (SwitchTextures( fake_Texture, pTexture)) { - Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Hash); + Message("uMod_TextureClient_DX9::LookUpToMod(): textures not switched %#llX\n", FileToMod[index].Content()->Hash); fake_Texture->Release(); } else { + fake_Texture->Reference = index; + FileToMod[index].AddTexture(fake_Texture); + /* IDirect3DBaseTexture9 **temp = new IDirect3DBaseTexture9*[FileToMod[index].NumberOfTextures+1]; for (int j=0; jReference = index; + */ } } } @@ -920,63 +935,97 @@ int uMod_TextureClient_DX9::LookUpToMod( uMod_IDirect3DCubeTexture9* pTexture, i -int uMod_TextureClient_DX9::LoadTexture( TextureFileStruct* file_in_memory, uMod_IDirect3DTexture9 **ppTexture) // to load fake texture from a file in memory +int uMod_TextureClient_DX9::LoadTexture( const TextureFileContent* file, uMod_IDirect3DTexture9 **ppTexture) // to load fake texture from a file in memory { - Message("LoadTexture( %p, %p, %#llX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this); - if (D3D_OK != D3DXCreateTextureFromFileInMemoryEx( D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DTexture9 **) ppTexture)) - //if (D3D_OK != D3DXCreateTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DTexture9 **) ppTexture)) + Message("uMod_TextureClient_DX9::LoadTexture( %p, %p, %#llX): %p\n", file, ppTexture, file->Hash, this); + + void *cpy; + long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); + if (ret == 0x01000000L) + { + uMod_IDirect3DDevice9* device = ((uMod_IDirect3DDevice9*)D3D9Device); + device->SetNextTextureIsFake(true); + } + else + { + uMod_IDirect3DDevice9Ex* deviceEx = ((uMod_IDirect3DDevice9Ex*) D3D9Device); + deviceEx->SetNextTextureIsFake(true); + } + + HRESULT res = D3DERR_INVALIDCALL; + + if (file->pData!=NULL) res = D3DXCreateTextureFromFileInMemoryEx( D3D9Device, file->pData, file->Size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DTexture9 **) ppTexture); + else if (file->pFileName != NULL) res = D3DXCreateTextureFromFileExW( D3D9Device, file->pFileName, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DTexture9 **) ppTexture); + + if (res != D3D_OK) { *ppTexture=NULL; return (RETURN_TEXTURE_NOT_LOADED); } - (*ppTexture)->FAKE = true; - void *cpy; - long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) ((uMod_IDirect3DDevice9*)D3D9Device)->SetLastCreatedTexture(NULL); //this texture must no be added twice - else ((uMod_IDirect3DDevice9Ex*) D3D9Device)->SetLastCreatedTexture(NULL); //this texture must no be added twice - - Message("LoadTexture( %p, %#llX): DONE\n", *ppTexture, file_in_memory->Hash); + Message("uMod_TextureClient_DX9::LoadTexture( %p, %#llX): DONE\n", *ppTexture, file->Hash); return (RETURN_OK); } -int uMod_TextureClient_DX9::LoadTexture( TextureFileStruct* file_in_memory, uMod_IDirect3DVolumeTexture9 **ppTexture) // to load fake texture from a file in memory +int uMod_TextureClient_DX9::LoadTexture( const TextureFileContent* file, uMod_IDirect3DVolumeTexture9 **ppTexture) // to load fake texture from a file in memory { - Message("LoadTexture( Volume %p, %p, %#llX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this); - if (D3D_OK != D3DXCreateVolumeTextureFromFileInMemoryEx( D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DVolumeTexture9 **) ppTexture)) - //if (D3D_OK != D3DXCreateVolumeTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DVolumeTexture9 **) ppTexture)) + Message("uMod_TextureClient_DX9::LoadTexture( Volume %p, %p, %#llX): %p\n", file, ppTexture, file->Hash, this); + + void *cpy; + long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); + if (ret == 0x01000000L) + { + uMod_IDirect3DDevice9* device = ((uMod_IDirect3DDevice9*)D3D9Device); + device->SetNextTextureIsFake(true); + } + else + { + uMod_IDirect3DDevice9Ex* deviceEx = ((uMod_IDirect3DDevice9Ex*) D3D9Device); + deviceEx->SetNextTextureIsFake(true); + } + + HRESULT res = D3DERR_INVALIDCALL; + if (file->pData!=NULL) res = D3DXCreateVolumeTextureFromFileInMemoryEx( D3D9Device, file->pData, file->Size, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DVolumeTexture9 **) ppTexture); + else if (file->pFileName != NULL) res = D3DXCreateVolumeTextureFromFileExW( D3D9Device, file->pFileName, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DVolumeTexture9 **) ppTexture); + + if (res != D3D_OK) { *ppTexture=NULL; return (RETURN_TEXTURE_NOT_LOADED); } - (*ppTexture)->FAKE = true; - void *cpy; - long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) ((uMod_IDirect3DDevice9*)D3D9Device)->SetLastCreatedVolumeTexture(NULL); //this texture must no be added twice - else ((uMod_IDirect3DDevice9Ex*) D3D9Device)->SetLastCreatedVolumeTexture(NULL); //this texture must no be added twice - - Message("LoadTexture( Volume %p, %#llX): DONE\n", *ppTexture, file_in_memory->Hash); + Message("uMod_TextureClient_DX9::LoadTexture( Volume %p, %#llX): DONE\n", *ppTexture, file->Hash); return (RETURN_OK); } -int uMod_TextureClient_DX9::LoadTexture( TextureFileStruct* file_in_memory, uMod_IDirect3DCubeTexture9 **ppTexture) // to load fake texture from a file in memory +int uMod_TextureClient_DX9::LoadTexture( const TextureFileContent* file, uMod_IDirect3DCubeTexture9 **ppTexture) // to load fake texture from a file in memory { - Message("LoadTexture( Cube %p, %p, %#llX): %p\n", file_in_memory, ppTexture, file_in_memory->Hash, this); - if (D3D_OK != D3DXCreateCubeTextureFromFileInMemoryEx( D3D9Device, file_in_memory->pData, file_in_memory->Size, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DCubeTexture9 **) ppTexture)) - //if (D3D_OK != D3DXCreateCubeTextureFromFileInMemory( D3D9Device, file_in_memory->pData, file_in_memory->Size, (IDirect3DCubeTexture9 **) ppTexture)) + Message("uMod_TextureClient_DX9::LoadTexture( Cube %p, %p, %#llX): %p\n", file, ppTexture, file->Hash, this); + + void *cpy; + long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); + if (ret == 0x01000000L) + { + uMod_IDirect3DDevice9* device = ((uMod_IDirect3DDevice9*)D3D9Device); + device->SetNextTextureIsFake(true); + } + else + { + uMod_IDirect3DDevice9Ex* deviceEx = ((uMod_IDirect3DDevice9Ex*) D3D9Device); + deviceEx->SetNextTextureIsFake(true); + } + + HRESULT res = D3DERR_INVALIDCALL; + if (file->pData!=NULL) res = D3DXCreateCubeTextureFromFileInMemoryEx( D3D9Device, file->pData, file->Size, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DCubeTexture9 **) ppTexture); + else if (file->pFileName != NULL) res = D3DXCreateCubeTextureFromFileExW( D3D9Device, file->pFileName, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, (IDirect3DCubeTexture9 **) ppTexture); + + if (res != D3D_OK) { *ppTexture=NULL; return (RETURN_TEXTURE_NOT_LOADED); } - (*ppTexture)->FAKE = true; - void *cpy; - long ret = D3D9Device->QueryInterface( IID_IDirect3DTexture9, &cpy); - if (ret == 0x01000000L) ((uMod_IDirect3DDevice9*)D3D9Device)->SetLastCreatedCubeTexture(NULL); //this texture must no be added twice - else ((uMod_IDirect3DDevice9Ex*) D3D9Device)->SetLastCreatedCubeTexture(NULL); //this texture must no be added twice - - Message("LoadTexture( Cube %p, %#llX): DONE\n", *ppTexture, file_in_memory->Hash); + Message("uMod_TextureClient_DX9::LoadTexture( Cube %p, %#llX): DONE\n", *ppTexture, file->Hash); return (RETURN_OK); } diff --git a/uMod_DX9/uMod_TextureClient_DX9.h b/uMod_DX9/uMod_TextureClient_DX9.h index 4e49ee3..d8edac1 100644 --- a/uMod_DX9/uMod_TextureClient_DX9.h +++ b/uMod_DX9/uMod_TextureClient_DX9.h @@ -86,9 +86,21 @@ public: */ int RemoveTexture( uMod_IDirect3DCubeTexture9* tex); + + int ComputeCRC( uMod_IDirect3DTexture9* tex); + int ComputeCRC( uMod_IDirect3DVolumeTexture9* tex); + int ComputeCRC( uMod_IDirect3DCubeTexture9* tex); + int SaveAllTextures(bool val); //called from the Server int SaveSingleTexture(bool val); //called from the Server + /** + * Enable/Disable the hashing with CRC32, which is needed to support also tpf mods (called from the mainloop). + * @param[in] val + * @return + */ + virtual int SupportTPF(bool val); + /** * called from uMod_IDirect3DDevice9::BeginScene() (save button) or from AddTexture(...) (SaveAllTextures) * @param[in] pTexture @@ -115,8 +127,6 @@ public: int MergeUpdate(void); //called from uMod_IDirect3DDevice9::BeginScene() - int CRCHasChanged( uMod_IDirect3DTexture9* pTexture); - int CRCHasChanged( uMod_IDirect3DCubeTexture9* pTexture); int LookUpToMod( uMod_IDirect3DTexture9* pTexture, int num_index_list=0, int *index_list=(int*)0); // called at the end AddTexture(...) and from Device->UpdateTexture(...) @@ -128,19 +138,13 @@ public: uMod_TextureHandler OriginalVolumeTextures; // stores the pointer to the uMod_IDirect3DVolumeTexture9 objects created by the game uMod_TextureHandler OriginalCubeTextures; // stores the pointer to the uMod_IDirect3DCubeTexture9 objects created by the game - - // if the has could not be calculated for a texture it is not considered in the original texture list, - // but it is now added into the following lists and we try to calculate the hash once again later - int CheckAgainNonAdded(void); - bool Bool_CheckAgainNonAdded; - uMod_TextureHandler NonAdded_OriginalTextures; // stores the pointer to the uMod_IDirect3DTexture9 objects created by the game - uMod_TextureHandler NonAdded_OriginalVolumeTextures; // stores the pointer to the uMod_IDirect3DVolumeTexture9 objects created by the game - uMod_TextureHandler NonAdded_OriginalCubeTextures; // stores the pointer to the uMod_IDirect3DCubeTexture9 objects created by the game + bool BoolComputeCRC32; //!< if true also the crc32 is calculated, which is need to support tpf private: IDirect3DDevice9* D3D9Device; + /** * Save the texture into a file (reagrding the various file formats. * @param[in] pTexture @@ -156,16 +160,37 @@ private: */ bool SaveTextureFilterFormat(D3DFORMAT format); - int LoadTexture( TextureFileStruct* file_in_memory, uMod_IDirect3DTexture9 **ppTexture); // called if a target texture is found - int LoadTexture( TextureFileStruct* file_in_memory, uMod_IDirect3DVolumeTexture9 **ppTexture); // called if a target texture is found - int LoadTexture( TextureFileStruct* file_in_memory, uMod_IDirect3DCubeTexture9 **ppTexture); // called if a target texture is found + int LoadTexture( const TextureFileContent* file, uMod_IDirect3DTexture9 **ppTexture); // called if a target texture is found + int LoadTexture( const TextureFileContent* file, uMod_IDirect3DVolumeTexture9 **ppTexture); // called if a target texture is found + int LoadTexture( const TextureFileContent* file, uMod_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); }; +template +inline void UnswitchTextures(T *pTexture) +{ + T* CrossRef = pTexture->CrossRef_D3Dtex; + if (CrossRef!=NULL) + { + // cancel the link + CrossRef->CrossRef_D3Dtex = NULL; + pTexture->CrossRef_D3Dtex = NULL; + } +} + +template +inline int SwitchTextures( T *pTexture1, T *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; + + return (RETURN_OK); + } + else return (RETURN_TEXTURE_NOT_SWITCHED); +} #endif /* uMod_TEXTUREHANDLER_HPP_ */ diff --git a/uMod_DXMain/uMod_ArrayHandler.cpp b/uMod_DXMain/uMod_ArrayHandler.cpp index df8c34f..36b9faf 100644 --- a/uMod_DXMain/uMod_ArrayHandler.cpp +++ b/uMod_DXMain/uMod_ArrayHandler.cpp @@ -21,88 +21,57 @@ along with Universal Modding Engine. If not, see #include "uMod_Main.h" - - - -/* - - -uMod_FileHandler::uMod_FileHandler(void) +TextureFileContent::TextureFileContent() : ForceReload(false), pFileName(NULL), pData(NULL), Size(0u), Reference(-1), Hash(0u), RefCounter(1) { - Message("uMod_FileHandler(void): %p\n", this); - Number = 0; - FieldCounter = 0; - Files = NULL; } -uMod_FileHandler::~uMod_FileHandler(void) +TextureFileContent::~TextureFileContent() { - Message("~uMod_FileHandler(void): %p\n", this); - if (Files!=NULL) - { - for (int i=0; iReference>=0) return (RETURN_UPDATE_ALLREADY_ADDED); - - if (Number/FieldLength==FieldCounter) // get more memory - { - TextureFileStruct*** temp = NULL; - try {temp = new TextureFileStruct**[FieldCounter+10];} - catch (...) - { - gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_TEXTURE; - return (RETURN_NO_MEMORY); - } - - for (int i=0; iReference = Number++; //set the reference for a fast deleting - - return (RETURN_OK); + if (pFileName!=NULL) delete [] pFileName; + if (pData!=NULL) delete [] pData; } -int uMod_FileHandler::Remove(TextureFileStruct* file) -{ - Message("uMod_FileHandler::Remove(%p): %p\n", file, this); - if (gl_ErrorState & uMod_ERROR_FATAL) return (RETURN_FATAL_ERROR); - int ref = file->Reference; - if (ref<0) return (RETURN_OK); // returning if no Reference is set - file->Reference = -1; //set reference outside of bound - if (ref<(--Number)) //if reference is unequal to Number-1 we copy the last entry to the index "ref" - { - Files[ref/FieldLength][ref%FieldLength] = Files[Number/FieldLength][Number%FieldLength]; - Files[ref/FieldLength][ref%FieldLength]->Reference = ref; //set the new reference entry - } - return (RETURN_OK); + +TextureEntry::TextureEntry(void) : TexContent(NULL), NumberOfTextures(0), Textures(NULL) +{ } -*/ + +TextureEntry::~TextureEntry() +{ + //for (int i=0; iRelease(); + if (Textures!=NULL) delete [] Textures; + if (TexContent!=NULL) TexContent->Release(); +} + + +void TextureEntry::SetContent(TextureFileContent *content) +{ + if (TexContent!=NULL) TexContent->Release(); + TexContent = content; + if (TexContent!=NULL) TexContent->AddRef(); +} + +int TextureEntry::AddTexture(IUnknown* tex) +{ + IUnknown** temp = new IUnknown*[NumberOfTextures+1]; + for (int i=0; i #include "..\uMod_GlobalDefines.h" /** - * On entry hold the pointer to the fake texture data (file content) - * and the pointer to all game texture which are replaced by this texture. + * On entry hold the pointer to the fake texture data (file content) or the filename. + * + * An object is created for each texture to be modded from the server. */ -typedef struct +class TextureFileContent { +public: + TextureFileContent(); + ~TextureFileContent(); + + int AddRef(void) {return ++RefCounter;} + int Release(void) {if (--RefCounter==0) {delete this; return 0;} else return RefCounter;} + bool ForceReload; //!< to force a reload of the texture (only important, if it is already modded) - char* pData; //!< store texture file as file in memory + wchar_t* pFileName; //!< store the texture file name (if available) + char* pData; //!< store texture file as file in memory (if available) unsigned int Size; //!< size of file (\a pData) - int NumberOfTextures; //!< Number of textures loaded by the game, which match the hash and thus are switched int Reference; //!< for a fast delete in the FileHandler - void **Textures; //!< pointer to all texture loade by the game, which match the hash and thus are switched DWORD64 Hash; //!< hash value -} TextureFileStruct; + +private: + int RefCounter; +}; + + +/** + * One object holds a pointer to the data (\a TextureFileContent) + * and a Reference to all generated fake texture. + * + * An object is created for each texture to be modded from the server for each client separately. + */ +class TextureEntry +{ +public: + TextureEntry(void); + ~TextureEntry(); + + int AddTexture(IUnknown *tex); + int RemoveTexture(IUnknown* tex); + + void SetContent(TextureFileContent *content); + const TextureFileContent * Content() {return TexContent;} + + + + TextureFileContent *TexContent; + int NumberOfTextures; //!< Number of textures loaded by the game, which match the hash and thus are switched + IUnknown **Textures; //!< pointer to all texture loaded by the game, which match the hash and thus are switched; +}; @@ -87,7 +123,7 @@ private: -typedef uMod_TextureHandler uMod_FileHandler; +typedef uMod_TextureHandler uMod_FileHandler; @@ -122,7 +158,7 @@ uMod_TextureHandler::~uMod_TextureHandler(void) template int uMod_TextureHandler::Add(T* entry) { - Message("uMod_TextureHandler::Add( %p): %p\n", entry, this); + //Message("uMod_TextureHandler::Add( %p): %p\n", entry, this); if (gl_ErrorState & uMod_ERROR_FATAL) return (RETURN_FATAL_ERROR); if (entry->Reference>=0) return (RETURN_TEXTURE_ALLREADY_ADDED); @@ -168,7 +204,7 @@ int uMod_TextureHandler::Add(T* entry) template int uMod_TextureHandler::Remove(T* entry) //will be called, if a texture is completely released { - Message("uMod_TextureHandler::Remove( %p): %p\n", entry, this); + //Message("uMod_TextureHandler::Remove( %p): %p\n", entry, this); if (gl_ErrorState & uMod_ERROR_FATAL) return (RETURN_FATAL_ERROR); int ref = entry->Reference; diff --git a/uMod_DXMain/uMod_TextureClient.cpp b/uMod_DXMain/uMod_TextureClient.cpp index 5fb1216..b1b9039 100644 --- a/uMod_DXMain/uMod_TextureClient.cpp +++ b/uMod_DXMain/uMod_TextureClient.cpp @@ -28,7 +28,6 @@ uMod_TextureClient::uMod_TextureClient(const int version) : Version(version) BoolSaveAllTextures = false; BoolSaveSingleTexture = false; BoolShowTextureString = false; - BoolComputeCRC = false; KeyBack = 0; KeySave = 0; @@ -63,11 +62,13 @@ uMod_TextureClient::~uMod_TextureClient(void) if (Mutex!=NULL) CloseHandle(Mutex); if (Update!=NULL) delete [] Update; - if (FileToMod!=NULL) + if (FileToMod!=NULL) delete [] FileToMod; + /* { for (int i=0; iFileToMod[NumberToMod-1].Hash) return (-1); + if (hashHash || hash>FileToMod[NumberToMod-1].Content()->Hash) return (-1); int pos = NumberToMod/2; int begin = 0; int end = NumberToMod-1; @@ -162,23 +163,23 @@ int uMod_TextureClient::GetIndex( DWORD64 hash, int num_index_list, int *index_l // 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 + if (hash > FileToMod[pos].Content()->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 interval } - else if (hash < FileToMod[pos].Hash) // the new interval is the left half of the actual interval + else if (hash < FileToMod[pos].Content()->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 interval } else {return (pos); break;} // we hit the correct hash } - for ( pos=begin; pos<=end; pos++) if (FileToMod[pos].Hash==hash) return (pos); + for ( pos=begin; pos<=end; pos++) if (FileToMod[pos].Content()->Hash==hash) return (pos); } else { - if (hashFileToMod[index_list[num_index_list-1]].Hash) return (-1); + if (hashHash || hash>FileToMod[index_list[num_index_list-1]].Content()->Hash) return (-1); int pos = num_index_list/2; int begin = 0; int end = num_index_list-1; @@ -188,19 +189,19 @@ int uMod_TextureClient::GetIndex( DWORD64 hash, int num_index_list, int *index_l // Note: contradicting to normal C-code here the interval includes the index "begin" and "end"! while (begin+1 FileToMod[index_list[pos]].Hash) // the new interval is the right half of the actual interval + if (hash > FileToMod[index_list[pos]].Content()->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 interval } - else if (hash < FileToMod[index_list[pos]].Hash) // the new interval is the left half of the actual interval + else if (hash < FileToMod[index_list[pos]].Content()->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 interval } else {return (index_list[pos]); break;} // we hit the correct hash } - for ( pos=begin; pos<=end; pos++) if (FileToMod[index_list[pos]].Hash==hash) return (index_list[pos]); + for ( pos=begin; pos<=end; pos++) if (FileToMod[index_list[pos]].Content()->Hash==hash) return (index_list[pos]); } } return (-1); diff --git a/uMod_DXMain/uMod_TextureClient.h b/uMod_DXMain/uMod_TextureClient.h index d398d15..65ce7ab 100644 --- a/uMod_DXMain/uMod_TextureClient.h +++ b/uMod_DXMain/uMod_TextureClient.h @@ -80,9 +80,16 @@ public: * @param[in] val * @return */ - int SupportTPF(bool val) {BoolComputeCRC = val; return (RETURN_OK);} + virtual int SupportTPF(bool val) = 0; /** + * Enable/Disable the computation of the hash of render targets. + * @param[in] val + * @return + */ + int ComputeRenderTargets(bool val) {BoolComputeRenderTargets = val; return (RETURN_OK);} + + /**ComputeRenderTargets * Set the directory, wher the texture should be stored (called from the server) * @param dir * @return RETURN_OK on success @@ -165,7 +172,7 @@ public: * @param number number of entries * @return RETURN_OK on success */ - int AddUpdate(TextureFileStruct* update, int number); + int AddUpdate(TextureEntry* update, int number); /** @@ -179,7 +186,8 @@ public: bool BoolSaveSingleTexture; //!< true if "save single texture" mode is enabled bool BoolShowTextureString; //!< true if a string should be displayed during "save single texture" mode is enabled bool BoolShowSingleTexture; //!< true if the texture should be displayed during "save single texture" mode is enabled - bool BoolComputeCRC; //!< if true also the crc32 is calculated, which is need to support tpf + bool BoolComputeRenderTargets; //!< true if the hash of render targets should be computed (very slow because each frame the hash must be recomputed) + int KeyBack; //!< key value for going to the previous texture int KeySave; //!< key value for saving the current texture @@ -200,7 +208,7 @@ public: wchar_t SavePath[MAX_PATH]; //!< saving directory wchar_t GameName[MAX_PATH]; //!< game name - TextureFileStruct* Update; //!< array which stores the file in memory and the hash of each texture to be modded + TextureEntry* Update; //!< array which stores the file in memory and the hash of each texture to be modded int NumberOfUpdate; //!< number of texture to be modded /** @@ -216,7 +224,7 @@ public: HANDLE Mutex; //!< The mutex protect the AddUpdate and MergeUpdate function to be called simultaneously. int NumberToMod; //!< number of texture to be modded - TextureFileStruct* FileToMod; //!< array which stores the file in memory and the hash of each texture to be modded + TextureEntry* FileToMod; //!< array which stores the file in memory and the hash of each texture to be modded /** * Find the given hash value in the \a FileToMod list. A vector with index can be passed. If so, only these index are considered in the search diff --git a/uMod_DXMain/uMod_TextureServer.cpp b/uMod_DXMain/uMod_TextureServer.cpp index 8ed3ad7..deccf13 100644 --- a/uMod_DXMain/uMod_TextureServer.cpp +++ b/uMod_DXMain/uMod_TextureServer.cpp @@ -81,17 +81,7 @@ uMod_TextureServer::~uMod_TextureServer(void) //delete the files in memory int num = CurrentMod.GetNumber(); for (int i = 0; i < num; i++) - { - delete [] CurrentMod[i]->pData; //delete the file content of the texture - delete CurrentMod[i]; //delete the structure - } - - num = OldMod.GetNumber(); - for (int i = 0; i < num; i++) - { - delete [] OldMod[i]->pData; //delete the file content of the texture - delete OldMod[i]; //delete the structure - } + CurrentMod[i]->Release(); if (Clients != NULL) delete [] Clients; @@ -101,7 +91,7 @@ uMod_TextureServer::~uMod_TextureServer(void) Pipe.Out = INVALID_HANDLE_VALUE; } -int uMod_TextureServer::AddClient(uMod_TextureClient *client, TextureFileStruct* &update, int &number, const int version) // called from a client +int uMod_TextureServer::AddClient(uMod_TextureClient *client, TextureEntry* &update, int &number, const int version) // called from a client { Message("AddClient(%p): %p\n", client, this); if (int ret = LockMutex()) @@ -219,7 +209,7 @@ int uMod_TextureServer::AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool gl_ErrorState |= uMod_ERROR_SERVER; return (ret); } - TextureFileStruct* temp = NULL; + TextureFileContent* temp = NULL; int num = CurrentMod.GetNumber(); for (int i=0; iHash == hash) //look through all current textures @@ -231,20 +221,54 @@ int uMod_TextureServer::AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool return (RETURN_OK); // we still have added this texture } } - if (temp==NULL) // if not found, look through all old textures + + bool new_file = true; + if (temp!=NULL) //if it was found, we delete the old file content { - num = OldMod.GetNumber(); - for (int i=0; iHash == hash) + new_file = false; + if (temp->pData!=NULL) delete [] temp->pData; + temp->pData = NULL; + if (temp->pFileName!=NULL) delete [] temp->pFileName; + temp->pFileName = NULL; + } + else //if it was not found, we need to create a new object + { + new_file = true; + temp = new TextureFileContent; + } + + temp->pData = buffer; + temp->Size = (unsigned int) size; + temp->Hash = hash; + + //if (new_file) temp->ForceReload = false; // no need to force a load of the texture + //else + temp->ForceReload = force; + + Message("uMod_TextureServer::End AddFile(%#llX)\n", hash); + if (new_file) CurrentMod.Add(temp); // new files must be added to the list of the CurrentMod + + return (UnlockMutex()); +} + +int uMod_TextureServer::AddFile( wchar_t* file_name, DWORD64 hash, bool force) +{ + Message("uMod_TextureServer::AddFile( %ls, %#llX, %d): %p\n", file_name, hash, force, this); + if (int ret = LockMutex()) + { + gl_ErrorState |= uMod_ERROR_SERVER; + return (ret); + } + TextureFileContent* temp = NULL; + + int num = CurrentMod.GetNumber(); + for (int i=0; iHash == hash) //look through all current textures + { + if (force) {temp = CurrentMod[i]; break;} // we need to reload it + else { - temp = OldMod[i]; - OldMod.Remove(temp); - CurrentMod.Add(temp); - if (force) break; // we must reload it - else - { - if (buffer!=NULL) delete [] buffer; - return (RETURN_OK); // we should not reload it - } + if (file_name!=NULL) delete [] file_name; + return (RETURN_OK); // we still have added this texture } } @@ -254,21 +278,16 @@ int uMod_TextureServer::AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool new_file = false; if (temp->pData!=NULL) delete [] temp->pData; temp->pData = NULL; + if (temp->pFileName!=NULL) delete [] temp->pFileName; + temp->pFileName = NULL; } else //if it was not found, we need to create a new object { new_file = true; - temp = new TextureFileStruct; - temp->Reference = -1; + temp = new TextureFileContent; } - temp->pData = buffer; - - for (unsigned int i=0; ipData[i] = buffer[i]; - - temp->Size = (unsigned int) size; - temp->NumberOfTextures = 0; - temp->Textures = NULL; + temp->pFileName = file_name; temp->Hash = hash; //if (new_file) temp->ForceReload = false; // no need to force a load of the texture @@ -276,12 +295,11 @@ int uMod_TextureServer::AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool temp->ForceReload = force; Message("uMod_TextureServer::End AddFile(%#llX)\n", hash); - if (new_file) CurrentMod.Add(temp); // new files must be added to the list of the CurrentMod+ + if (new_file) CurrentMod.Add(temp); // new files must be added to the list of the CurrentMod return (UnlockMutex()); } - int uMod_TextureServer::RemoveFile(DWORD64 hash) // called from Mainloop() { Message("RemoveFile( %#llx): %p\n", hash, this); @@ -294,9 +312,10 @@ int uMod_TextureServer::RemoveFile(DWORD64 hash) // called from Mainloop() int num = CurrentMod.GetNumber(); for (int i = 0; i < num; i++) if (CurrentMod[i]->Hash == hash) { - TextureFileStruct* temp = CurrentMod[i]; + TextureFileContent* temp = CurrentMod[i]; CurrentMod.Remove(temp); - return (OldMod.Add(temp)); + temp->Release(); + return 0; } return (UnlockMutex()); } @@ -386,6 +405,23 @@ int uMod_TextureServer::SupportTPF(bool val) // called from Mainloop() return (UnlockMutex()); } +int uMod_TextureServer::ComputeRenderTargets(bool val) // called from Mainloop() +{ + if (BoolComputeRenderTargets == val) return (RETURN_OK); + BoolComputeRenderTargets = val; + + if (int ret = LockMutex()) + { + gl_ErrorState |= uMod_ERROR_SERVER; + return (ret); + } + for (int i = 0; i < NumberOfClients; i++) + { + Clients[i]->ComputeRenderTargets(BoolComputeRenderTargets); + } + return (UnlockMutex()); +} + int uMod_TextureServer::SetSaveDirectory(wchar_t *dir) // called from Mainloop() { Message("uMod_TextureServer::SetSaveDirectory( %ls): %p\n", dir, this); @@ -582,7 +618,7 @@ int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called fr } if (client != NULL) { - TextureFileStruct* update; + TextureEntry* update; int number; if (int ret = PrepareUpdate( update, number)) return (ret); client->AddUpdate(update, number); @@ -591,7 +627,7 @@ int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called fr { for (int i=0; iAddUpdate(update, number); @@ -612,32 +648,34 @@ int uMod_TextureServer::PropagateUpdate(uMod_TextureClient* client) // called fr int TextureFileStruct_Compare( const void * elem1, const void * elem2 ) { - TextureFileStruct *tex1 = (TextureFileStruct*)elem1; - TextureFileStruct *tex2 = (TextureFileStruct*)elem2; - if (tex1->Hash < tex2->Hash) return (-1); - if (tex1->Hash > tex2->Hash) return (+1); + TextureEntry *tex1 = (TextureEntry*)elem1; + TextureEntry *tex2 = (TextureEntry*)elem2; + if (tex1->Content()->Hash < tex2->Content()->Hash) return (-1); + if (tex1->Content()->Hash > tex2->Content()->Hash) return (+1); return (0); } -int uMod_TextureServer::PrepareUpdate(TextureFileStruct* &update, int &number) // called from the PropagateUpdate() and AddClient. +int uMod_TextureServer::PrepareUpdate(TextureEntry* &update, int &number) // called from the PropagateUpdate() and AddClient. // Prepare an update for one client. The allocated memory must deleted by the client. { update = NULL; number = 0; - TextureFileStruct* temp = NULL; + TextureEntry* temp = NULL; int num = CurrentMod.GetNumber(); if (num>0) { - try {temp = new TextureFileStruct[num];} + try {temp = new TextureEntry[num];} catch (...) { gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER; return (RETURN_NO_MEMORY); } - for (int i=0; iValue; - Message("MainLoop: CONTROL_ADD_TEXTURE (%#lX %u, %u %u): %p\n", commands->Hash, size, sizeof(MsgStruct), sizeof(char), this); - if (pos + sizeof(MsgStruct) + size <= num) AddFile( (wchar_t*) &buffer[pos + sizeof(MsgStruct)], commands->Hash, force); - //update_textures = true; - force = false; + texture_size = commands->Value; + texture_received = 0u; + texture_hash = commands->Hash; + texture_force=true; + texture_file_name=true; + Message("MainLoop: CONTROL_FORCE_RELOAD_TEXTURE (%#llX %llu, %p): %p\n", texture_hash, texture_size, texture_data, this); + break; + } + case CONTROL_ADD_TEXTURE: + { + texture_size = commands->Value; + texture_received = 0u; + texture_hash = commands->Hash; + texture_force=false; + texture_file_name=true; + Message("MainLoop: CONTROL_TEXTURE (%#llX %llu, %p): %p\n", texture_hash, texture_size, texture_data, this); break; } - */ case CONTROL_FORCE_RELOAD_TEXTURE_DATA: { texture_size = commands->Value; texture_received = 0u; texture_hash = commands->Hash; texture_force=true; - try - { - texture_data = new char[(unsigned int) texture_size]; - } - catch (...) - { - texture_size = 0u; - texture_data = (char*)0; - gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER; - } + texture_file_name=false; Message("MainLoop: CONTROL_FORCE_RELOAD_TEXTURE_DATA (%#llX %llu, %p): %p\n", texture_hash, texture_size, texture_data, this); break; } @@ -755,17 +811,8 @@ int uMod_TextureServer::MainLoop(void) // run as a separated thread texture_size = commands->Value; texture_received = 0u; texture_hash = commands->Hash; - texture_force=true; - try - { - texture_data = new char[(unsigned int) texture_size]; - } - catch (...) - { - texture_size = 0u; - texture_data = (char*)0; - gl_ErrorState |= uMod_ERROR_MEMORY | uMod_ERROR_SERVER; - } + texture_force=false; + texture_file_name=false; Message("MainLoop: CONTROL_ADD_TEXTURE_DATA (%#llX %llu, %p): %p\n", texture_hash, texture_size, texture_data, this); break; } @@ -812,6 +859,13 @@ int uMod_TextureServer::MainLoop(void) // run as a separated thread else SupportTPF(true); break; } + case CONTROL_COMPUTE_RENDER_TARGETS: + { + Message("MainLoop: CONTROL_COMPUTE_RENDER_TARGETS (%#llX): %p\n", commands->Value, this); + if (commands->Value == 0) ComputeRenderTargets(false); + else ComputeRenderTargets(true); + break; + } case CONTROL_SET_DIR: { Message("MainLoop: CONTROL_SET_DIR (%ls): %p\n", (wchar_t*) &buffer[pos + sizeof(MsgStruct)], this); diff --git a/uMod_DXMain/uMod_TextureServer.h b/uMod_DXMain/uMod_TextureServer.h index ea5077f..76c47fc 100644 --- a/uMod_DXMain/uMod_TextureServer.h +++ b/uMod_DXMain/uMod_TextureServer.h @@ -54,7 +54,7 @@ public: * @param[in] version The device version (DX9, DX9EX, DX10, or DX101) * @return RETURN_OK on success */ - int AddClient(uMod_TextureClient *client, TextureFileStruct* &update, int &number, const int version); // called from a Client + int AddClient(uMod_TextureClient *client, TextureEntry* &update, int &number, const int version); // called from a Client /** * On destruction of client, it disconnect from the server. @@ -98,7 +98,7 @@ private: int AddFile( char* buffer, DWORD64 size, DWORD64 hash, bool force); // called from Mainloop(), if the content of the texture is sent /** - * Add a file to the list of texture to be modded (called from the mainloop). Not supported anymore! + * Add a file to the list of texture to be modded (called from the mainloop). * @param[in] file_name Name and path to the file to be loaded. * @param[in] hash hash of the texture to be replaced * @param[in] force set to TRUE to force a reload of the texture @@ -148,6 +148,12 @@ private: */ int SupportTPF(bool val); // called from Mainloop() + /** + * Enable/Disable the computation of the hash of render targets (called from the mainloop). + * @param[in] val + * @return + */ + int ComputeRenderTargets(bool val); // called from Mainloop() /** * Set saving directory (called from the mainloop). * @param[in] dir @@ -238,7 +244,7 @@ private: * @param[out] number * @return */ - int PrepareUpdate(TextureFileStruct* &update, int &number); + int PrepareUpdate(TextureEntry* &update, int &number); /** * Locks the mutex. @@ -258,6 +264,7 @@ private: bool BoolShowTextureString; bool BoolShowSingleTexture; bool BoolSupportTPF; + bool BoolComputeRenderTargets; //!< true if the hash of render targets should be computed (very slow because each frame the hash must be recomputed) wchar_t SavePath[MAX_PATH]; wchar_t GameName[MAX_PATH]; @@ -283,8 +290,6 @@ private: int LenghtOfClients; uMod_FileHandler CurrentMod; // hold the file content of texture - uMod_FileHandler OldMod; // hold the file content of texture which were added previously but are not needed any more - // this is needed, because a texture clients might not have merged the last update and thus hold pointers to the file content of old textures }; diff --git a/uMod_GUI/uMod_File.cpp b/uMod_GUI/uMod_File.cpp index e3d7388..9b0d29a 100644 --- a/uMod_GUI/uMod_File.cpp +++ b/uMod_GUI/uMod_File.cpp @@ -31,6 +31,7 @@ along with Universal Modding Engine. If not, see uMod_File::uMod_File(void) { Loaded=false; + myExtractArchivesToDisk = false; XORed=false; FileInMemory=(char*)0; MemoryLength=0u; @@ -40,6 +41,7 @@ uMod_File::uMod_File(void) uMod_File::uMod_File(const wxString &file) { Loaded=false; + myExtractArchivesToDisk = false; XORed=false; FileInMemory=(char*)0; MemoryLength=0u; @@ -54,39 +56,46 @@ uMod_File::~uMod_File(void) } -bool uMod_File::FileSupported(void) +bool uMod_File::FileSupported(void) const { wxString file_type = FileName.AfterLast( '.'); - if (file_type == "zip") return true; - if (file_type == "tpf") return true; - if (file_type == "bmp") return true; - if (file_type == "jpg") return true; - if (file_type == "tga") return true; - if (file_type == "png") return true; - if (file_type == "dds") return true; - if (file_type == "ppm") return true; + return FileSupported(file_type); +} - return false; +bool uMod_File::FileSupported( const wxString &suffix) const +{ + if (PackageFile(suffix)) return true; + return SingleFile(suffix); } -bool uMod_File::PackageFile(void) +bool uMod_File::PackageFile(void) const { wxString file_type = FileName.AfterLast( '.'); - if (file_type == "zip") return true; - if (file_type == "tpf") return true; + return PackageFile(file_type); +} + +bool uMod_File::PackageFile( const wxString &suffix) const +{ + if (suffix == "zip") return true; + if (suffix == "tpf") return true; return false; } -bool uMod_File::SingleFile(void) +bool uMod_File::SingleFile(void) const { wxString file_type = FileName.AfterLast( '.'); - if (file_type == "bmp") return true; - if (file_type == "jpg") return true; - if (file_type == "tga") return true; - if (file_type == "png") return true; - if (file_type == "dds") return true; - if (file_type == "ppm") return true; + return SingleFile(file_type); +} + +bool uMod_File::SingleFile( const wxString &suffix) const +{ + if (suffix == "bmp") return true; + if (suffix == "jpg") return true; + if (suffix == "tga") return true; + if (suffix == "png") return true; + if (suffix == "dds") return true; + if (suffix == "ppm") return true; return false; } @@ -200,19 +209,31 @@ int uMod_File::AddFile( uMod_TreeViewNode* node) return -1; } - if (int ret = ReadFile()) return ret; - uMod_TextureElement *texture = new uMod_TextureElement(); - if (texture->Content().SetSize(FileLen)) + if (ExtractArchivesToDisk()) { - LastError << Language->Error_Memory; - texture->Release(); - return -1; + texture->ExtractedFile() = FileName; + texture->Content().SetSize(0); } - char *data = texture->Content().Data(); + else + { + if (int ret = ReadFile()) + { + texture->Release(); + return ret; + } - for (unsigned int i=0; iContent().SetSize(FileLen)) + { + LastError << Language->Error_Memory; + texture->Release(); + return -1; + } + char *data = texture->Content().Data(); + + for (unsigned int i=0; iHash() = temp_hash; texture->File() = FileName; @@ -247,6 +268,7 @@ int uMod_File::GetContentTemplate(const wxString &content, uMod_TreeViewNode* no int uMod_File::GetContentTemplate_ZIP( const uMod_TreeViewNode_ArrayPtr &list_node, uMod_TreeViewNode* node) { SetFile(node->myElement->File()); + if (!FileSupported()) { LastError << Language->Error_FileNotSupported <<"\n" << FileName; @@ -294,6 +316,7 @@ int uMod_File::GetContentTemplate_ZIP( const uMod_TreeViewNode_ArrayPtr &list_no { if (texture->Content().SetSize(ze.unc_size)) { + texture->Error() = uMod_TextureElement::MemoryError; texture->Comment() = Language->Error_Memory; continue; } @@ -302,13 +325,26 @@ int uMod_File::GetContentTemplate_ZIP( const uMod_TreeViewNode_ArrayPtr &list_no ZRESULT rz = UnzipItem( ZIP_Handle, index, data, ze.unc_size); if (rz!=ZR_OK && rz!=ZR_MORE) { + texture->Error() = uMod_TextureElement::ZIPError; texture->Content().SetSize(0); texture->Comment() = Language->Error_Unzip; texture->Comment() <<" : " << FileName << " ==>> " << file; } + + if (ExtractArchivesToDisk()) + { + wxString file_name = file; + + if (!WriteContentToDisk( file_name, texture->Content().Data(), texture->Content().Len())) + { + texture->Content().SetSize(0); + texture->ExtractedFile() = file_name; + } + } } else { + texture->Error() = uMod_TextureElement::ZIPError; texture->Content().SetSize(0); texture->Comment() = Language->Error_Unzip; texture->Comment() << " : " << FileName << " -> " << file; @@ -340,22 +376,32 @@ int uMod_File::GetContentTemplate_SF( const uMod_TreeViewNode_ArrayPtr &list_nod uMod_TextureElement *texture = (uMod_TextureElement*) list_node[i]->myElement; SetFile( texture->File()); - if (int ret = ReadFile()) + if (ExtractArchivesToDisk()) { - texture->Comment() = Language->Error_FileRead; - texture->Comment() << " : " << texture->File(); - continue; + texture->ExtractedFile() = FileName; + texture->Content().SetSize(0); } - - if (texture->Content().SetSize(FileLen)) + else { - texture->Comment() = Language->Error_Memory; - texture->Comment() << " : " << texture->File(); - continue; - } - char *data = texture->Content().Data(); + if (int ret = ReadFile()) + { + texture->Error() = uMod_TextureElement::DiskError; + texture->Comment() = Language->Error_FileRead; + texture->Comment() << " : " << texture->File(); + continue; + } - for (unsigned int i=0; iContent().SetSize(FileLen)) + { + texture->Error() = uMod_TextureElement::MemoryError; + texture->Comment() = Language->Error_Memory; + texture->Comment() << " : " << texture->File(); + continue; + } + char *data = texture->Content().Data(); + + for (unsigned int i=0; iStatus() = uMod_TextureElement::Activate; } @@ -465,6 +511,18 @@ int uMod_File::AddContent( const char* pw, uMod_TreeViewNode* node) texture->File() = file; texture->Status() = uMod_TextureElement::Activate; + if (ExtractArchivesToDisk()) + { + wxString file_name = file; + + if (!WriteContentToDisk( file_name, texture->Content().Data(), texture->Content().Len())) + { + texture->Content().SetSize(0); + texture->ExtractedFile() = file_name; + } + } + + uMod_TreeViewNode *node_texture = new uMod_TreeViewNode( node, texture); node->Append(node_texture); texture->Release(); @@ -547,8 +605,10 @@ int uMod_File::AddContent( const char* pw, uMod_TreeViewNode* node) FindZipItem( ZIP_Handle, file.wc_str(), false, &index, &ze); // look for texture if (index>=0) { + if (texture->Content().SetSize(ze.unc_size)) { + texture->Error() = uMod_TextureElement::MemoryError; texture->Comment() = Language->Error_Memory; continue; } @@ -557,12 +617,25 @@ int uMod_File::AddContent( const char* pw, uMod_TreeViewNode* node) ZRESULT rz = UnzipItem( ZIP_Handle, index, data, ze.unc_size); if (rz!=ZR_OK && rz!=ZR_MORE) { + texture->Error() = uMod_TextureElement::ZIPError; texture->Content().SetSize(0); texture->Comment() = Language->Error_Unzip; } + + if (ExtractArchivesToDisk()) + { + wxString file_name = file; + + if (!WriteContentToDisk( file_name, texture->Content().Data(), texture->Content().Len())) + { + texture->Content().SetSize(0); + texture->ExtractedFile() = file_name; + } + } } else { + texture->Error() = uMod_TextureElement::ZIPError; texture->Content().SetSize(0); texture->Comment() = Language->Error_Unzip; CloseZip(ZIP_Handle); //somehow we need to close and to reopen the zip handle, otherwise the program crashes @@ -582,7 +655,7 @@ int uMod_File::AddContent( const char* pw, uMod_TreeViewNode* node) } - //we load each dds file + //we load each supported file { CloseZip(ZIP_Handle); //somehow we need to close and to reopen the zip handle, otherwise the program crashes ZIP_Handle = OpenZip( FileInMemory, FileLen, pw); @@ -647,7 +720,7 @@ int uMod_File::AddContent( const char* pw, uMod_TreeViewNode* node) } name = file.AfterLast( '.'); - if (name!="dds") + if (!SingleFile(name)) { texture->Release(); continue; @@ -669,6 +742,17 @@ int uMod_File::AddContent( const char* pw, uMod_TreeViewNode* node) texture->File() = ze.name; texture->Status() = uMod_TextureElement::Activate; + if (ExtractArchivesToDisk()) + { + wxString file_name = file; + + if (!WriteContentToDisk( file_name, texture->Content().Data(), texture->Content().Len())) + { + texture->Content().SetSize(0); + texture->ExtractedFile() = file_name; + } + } + uMod_TreeViewNode *node_texture = new uMod_TreeViewNode( node, texture); node->Append(node_texture); texture->Release(); @@ -685,3 +769,26 @@ int uMod_File::AddContent( const char* pw, uMod_TreeViewNode* node) } return 0; } + + +int uMod_File::WriteContentToDisk( wxString& file , char* data, int len) +{ + if (data == NULL || len<=0) return -1; + + wxString package_name = FileName; + package_name = package_name.AfterLast('\\'); + + wxString file_name = ExtractPath; + file_name << "\\" << package_name << "." << file; + + wxFile dat; + dat.Open( file_name, wxFile::write); + if (!dat.IsOpened()) {LastError << Language->Error_FileOpen <<"\n" << FileName; return -1;} + + unsigned int result = dat.Write( data, len); + dat.Close(); + if (result!=len) return -1; + + file = file_name; + return 0; +} diff --git a/uMod_GUI/uMod_File.h b/uMod_GUI/uMod_File.h index 2a73f2b..c2bea20 100644 --- a/uMod_GUI/uMod_File.h +++ b/uMod_GUI/uMod_File.h @@ -28,9 +28,12 @@ public: uMod_File(const wxString &file); ~uMod_File(void); - bool FileSupported(void); - bool PackageFile(void); - bool SingleFile(void); + bool FileSupported(void) const; + bool FileSupported( const wxString &suffix) const; + bool PackageFile(void) const; + bool PackageFile( const wxString &suffix) const; + bool SingleFile(void) const; + bool SingleFile( const wxString &suffix) const; //int AddSingleFileToNode( uMod_TreeViewNode* node); int GetContentTemplate(const wxString &content, uMod_TreeViewNode* node); @@ -41,8 +44,13 @@ public: int GetContent( uMod_TreeViewNode* node); int SetFile(const wxString &file) {FileName=file;Loaded=false; return 0;} - wxString GetFile(void) {return FileName;} + const wxString& GetFile(void) const {return FileName;} + int SetExtractPath(const wxString &path) {ExtractPath=path; if (path.Len()>0) myExtractArchivesToDisk=true; else myExtractArchivesToDisk=false; return 0;} + const wxString& GetExtractPath(void) const {return ExtractPath;} + + const bool &ExtractArchivesToDisk(void) const {return myExtractArchivesToDisk;} + bool &ExtractArchivesToDisk(void) {return myExtractArchivesToDisk;} wxString LastError; @@ -63,7 +71,12 @@ private: int GetContentTemplate_ZIP( const uMod_TreeViewNode_ArrayPtr &list_node, uMod_TreeViewNode* node); int GetContentTemplate_SF( const uMod_TreeViewNode_ArrayPtr &list_node, uMod_TreeViewNode* node); + int WriteContentToDisk( wxString& file , char* data, int len); + wxString FileName; + wxString ExtractPath; + bool myExtractArchivesToDisk; + bool Loaded; bool XORed; char *FileInMemory; diff --git a/uMod_GUI/uMod_GameInfo.cpp b/uMod_GUI/uMod_GameInfo.cpp index a0ac60b..3fbe492 100644 --- a/uMod_GUI/uMod_GameInfo.cpp +++ b/uMod_GUI/uMod_GameInfo.cpp @@ -34,13 +34,12 @@ uMod_GameInfo::~uMod_GameInfo(void) void uMod_GameInfo::Init(void) { - myShowCollPane = false; + myShowCollCapturePane = false; SaveSingleTexture = false; SaveAllTextures = false; myShowSingleTextureString = false; myShowSingleTexture = false; - mySupportTPF = false; KeyBack = -1; KeySave = -1; @@ -64,6 +63,16 @@ void uMod_GameInfo::Init(void) SavePath << "\\textures"; OpenPath.Empty(); + + + myShowCollSettingsPane = false; + mySupportTPF = false; + myComputeRenderTargets = false; + myExtractTexturesToDisk = true; + myDeleteExtractedTexturesOnDisk = false; + + ExtractPath = wxGetCwd(); + ExtractPath << "\\ExtractedMods"; } int uMod_GameInfo::SaveToString( wxString &content ) @@ -72,7 +81,7 @@ int uMod_GameInfo::SaveToString( wxString &content ) wxString temp; - temp.Printf( "ShowCollPane:%d\n", myShowCollPane); + temp.Printf( "ShowCollCapturePane:%d\n", myShowCollCapturePane); content << temp; if (SavePath.Len()>0) @@ -96,9 +105,6 @@ int uMod_GameInfo::SaveToString( wxString &content ) temp.Printf( "ShowSingleTexture:%d\n", myShowSingleTexture); content << temp; - temp.Printf( "SupportTPF:%d\n", mySupportTPF); - content << temp; - if (KeyBack>=0) { temp.Printf( "KeyBack:%d\n", KeyBack); @@ -141,6 +147,32 @@ int uMod_GameInfo::SaveToString( wxString &content ) content << temp; temp.Printf( L"TextureColour:%u,%u,%u,%u\n", TextureColour[0], TextureColour[1], TextureColour[2], TextureColour[3]); content << temp; + + + + temp.Printf( "ShowCollSettingsPane:%d\n", myShowCollSettingsPane); + content << temp; + + temp.Printf( "SupportTPF:%d\n", mySupportTPF); + content << temp; + + temp.Printf( "ComputeRenderTargets:%d\n", myComputeRenderTargets); + content << temp; + + temp.Printf( "ExtractTexturesToDisk:%d\n", myExtractTexturesToDisk); + content << temp; + + temp.Printf( "DeleteExtractedTexturesOnDisk:%d\n", myDeleteExtractedTexturesOnDisk); + content << temp; + + if (ExtractPath.Len()>0) + { + temp.Printf( "ExtractPath:%ls\n", ExtractPath.wc_str()); + content << temp; + } + + + return 0; } @@ -163,11 +195,11 @@ int uMod_GameInfo::LoadFromString( const wxString &content) line = token.GetNextToken(); command = line.BeforeFirst(':'); - if (command == "ShowCollPane") + if (command == "ShowCollCapturePane") { temp = line.AfterFirst(':'); - if (temp.Len()>0 && temp[0]=='0') myShowCollPane = false; - else myShowCollPane = true; + if (temp.Len()>0 && temp[0]=='0') myShowCollCapturePane = false; + else myShowCollCapturePane = true; } else if (command == "SavePath") SavePath = line.AfterFirst(':'); else if (command == "OpenPath") OpenPath = line.AfterFirst(':'); @@ -195,12 +227,6 @@ int uMod_GameInfo::LoadFromString( const wxString &content) if (temp.Len()>0 && temp[0]=='0') myShowSingleTexture = false; else myShowSingleTexture = true; } - else if (command == "SupportTPF") - { - temp = line.AfterFirst(':'); - if (temp.Len()>0 && temp[0]=='0') mySupportTPF = false; - else mySupportTPF = true; - } else if (command == "KeyBack") { temp = line.AfterFirst(':'); @@ -315,6 +341,37 @@ int uMod_GameInfo::LoadFromString( const wxString &content) if (temp.ToLong( &colour)) TextureColour[i] = colour; } } + if (command == "ShowCollSettingsPane") + { + temp = line.AfterFirst(':'); + if (temp.Len()>0 && temp[0]=='0') myShowCollSettingsPane = false; + else myShowCollSettingsPane = true; + } + else if (command == "SupportTPF") + { + temp = line.AfterFirst(':'); + if (temp.Len()>0 && temp[0]=='0') mySupportTPF = false; + else mySupportTPF = true; + } + else if (command == "ComputeRenderTargets") + { + temp = line.AfterFirst(':'); + if (temp.Len()>0 && temp[0]=='0') myComputeRenderTargets = false; + else myComputeRenderTargets = true; + } + else if (command == "ExtractTexturesToDisk") + { + temp = line.AfterFirst(':'); + if (temp.Len()>0 && temp[0]=='0') myExtractTexturesToDisk = false; + else myExtractTexturesToDisk = true; + } + else if (command == "DeleteExtractedTexturesOnDisk") + { + temp = line.AfterFirst(':'); + if (temp.Len()>0 && temp[0]=='0') myDeleteExtractedTexturesOnDisk = false; + else myDeleteExtractedTexturesOnDisk = true; + } + else if (command == "ExtractPath") ExtractPath = line.AfterFirst(':'); } if (SaveAllTextures && SaveSingleTexture) { @@ -340,7 +397,7 @@ int uMod_GameInfo::SetSaveAllTextures(bool val) uMod_GameInfo& uMod_GameInfo::operator = (const uMod_GameInfo &rhs) { - myShowCollPane = rhs.myShowCollPane; + myShowCollCapturePane = rhs.myShowCollCapturePane; SaveSingleTexture = rhs.SaveSingleTexture; SaveAllTextures = rhs.SaveAllTextures; @@ -368,6 +425,13 @@ uMod_GameInfo& uMod_GameInfo::operator = (const uMod_GameInfo &rhs) SavePath = rhs.SavePath; OpenPath = rhs.OpenPath; + ExtractPath = rhs.ExtractPath; + + myShowCollSettingsPane = rhs.myShowCollSettingsPane; + mySupportTPF = rhs.mySupportTPF; + myComputeRenderTargets = rhs.myComputeRenderTargets; + myExtractTexturesToDisk = rhs.myExtractTexturesToDisk; + ExtractPath = rhs.ExtractPath; return *this; } diff --git a/uMod_GUI/uMod_GameInfo.h b/uMod_GUI/uMod_GameInfo.h index a63c664..2cb487e 100644 --- a/uMod_GUI/uMod_GameInfo.h +++ b/uMod_GUI/uMod_GameInfo.h @@ -41,13 +41,28 @@ public: - bool &ShowCollPane(void) {return myShowCollPane;} - const bool &ShowCollPane(void) const {return myShowCollPane;} + bool &ShowCollCapturePane(void) {return myShowCollCapturePane;} + const bool &ShowCollCapturePane(void) const {return myShowCollCapturePane;} + + bool &ShowCollSettingsPane(void) {return myShowCollSettingsPane;} + const bool &ShowCollSettingsPane(void) const {return myShowCollSettingsPane;} bool &SupportTPF(void) {return mySupportTPF;} const bool &SupportTPF(void) const {return mySupportTPF;} + bool &ComputeRenderTargets(void) {return myComputeRenderTargets;} + const bool &ComputeRenderTargets(void) const {return myComputeRenderTargets;} + + bool &ExtractTexturesToDisk(void) {return myExtractTexturesToDisk;} + const bool &ExtractTexturesToDisk(void) const {return myExtractTexturesToDisk;} + + bool &DeleteExtractedTexturesOnDisk(void) {return myDeleteExtractedTexturesOnDisk;} + const bool &DeleteExtractedTexturesOnDisk(void) const {return myDeleteExtractedTexturesOnDisk;} + + int SetExtractPath(const wxString &path) {ExtractPath=path; return 0;} + const wxString& GetExtractPath(void) const {return ExtractPath;} + int SetSaveSingleTexture(bool val); bool GetSaveSingleTexture(void) const {return SaveSingleTexture;} @@ -107,17 +122,22 @@ public: int SetOpenPath(const wxString &path) {OpenPath=path; return 0;} - wxString GetOpenPath(void) const {return OpenPath;} + const wxString& GetOpenPath(void) const {return OpenPath;} int SetSavePath(const wxString &path) {SavePath=path; return 0;} - wxString GetSavePath(void) const {return SavePath;} + const wxString& GetSavePath(void) const {return SavePath;} uMod_GameInfo& operator = (const uMod_GameInfo &rhs); private: - bool myShowCollPane; + bool myShowCollCapturePane; + bool myShowCollSettingsPane; bool mySupportTPF; + bool myComputeRenderTargets; + bool myExtractTexturesToDisk; + bool myDeleteExtractedTexturesOnDisk; + wxString ExtractPath; bool SaveSingleTexture; bool SaveAllTextures; diff --git a/uMod_GUI/uMod_GamePage.cpp b/uMod_GUI/uMod_GamePage.cpp index 03d0f88..8ba75cc 100644 --- a/uMod_GUI/uMod_GamePage.cpp +++ b/uMod_GUI/uMod_GamePage.cpp @@ -33,10 +33,13 @@ EVT_CHECKBOX( ID_SaveAllTexture, uMod_GamePage::OnCheckBox) EVT_CHECKBOX( ID_ShowSingleTextureString, uMod_GamePage::OnCheckBox) EVT_CHECKBOX( ID_UseSizeFilter, uMod_GamePage::OnCheckBox) EVT_CHECKBOX( ID_UseFormatFilter, uMod_GamePage::OnCheckBox) -EVT_BUTTON(ID_SetFormatFilter, uMod_GamePage::OnButtonFormatFilter) +EVT_CHECKBOX( ID_ExtractTextures, uMod_GamePage::OnCheckBox) + EVT_BUTTON(ID_Button_Update, uMod_GamePage::OnButtonUpdate) +EVT_BUTTON(ID_SetFormatFilter, uMod_GamePage::OnButtonFormatFilter) EVT_BUTTON(ID_Button_SavePath, uMod_GamePage::OnButtonSavePath) +EVT_BUTTON(ID_Button_ExtractPath, uMod_GamePage::OnButtonExtractPath) EVT_BUTTON(ID_FontColour, uMod_GamePage::OnButtonColour) @@ -70,7 +73,11 @@ uMod_GamePage::uMod_GamePage( wxNotebook *parent, const wxString &exe, int injec //SetBackgroundColour( wxColour( "LIGHT GREY")); + //set the two colour buttons into one horizontal sizer + wxBoxSizer *temp_sizer; MainSizer = new wxBoxSizer(wxVERTICAL); + UpdateButton = new wxButton( this, ID_Button_Update, Language->ButtonUpdate, wxDefaultPosition, wxSize(100,24)); + //initialize injection string switch (InjectionMethod) @@ -86,12 +93,18 @@ uMod_GamePage::uMod_GamePage( wxNotebook *parent, const wxString &exe, int injec break; case INVALID_GAME_PAGE: DX_DLL_Info = new wxTextCtrl(this, wxID_ANY, Language->InvalidGamePage, wxDefaultPosition, wxDefaultSize, wxTE_READONLY); + UpdateButton->Enable(false); break; default: DX_DLL_Info = new wxTextCtrl(this, wxID_ANY, "BUG^^ injection:", wxDefaultPosition, wxDefaultSize, wxTE_READONLY); break; } - MainSizer->Add( (wxWindow*) DX_DLL_Info, 0, wxEXPAND, 0); + temp_sizer = new wxBoxSizer(wxHORIZONTAL); + temp_sizer->Add( (wxWindow*) DX_DLL_Info, 1, wxEXPAND|wxALL, 0); + temp_sizer->AddSpacer(10); + temp_sizer->Add( (wxWindow*) UpdateButton, 0, wxEXPAND|wxALL, 0); + temp_sizer->AddSpacer(10); + MainSizer->Add( temp_sizer, 0, wxEXPAND, 0); // initialize template string TemplateFile = new wxTextCtrl(this, wxID_ANY, Language->TextCtrlTemplate, wxDefaultPosition, wxDefaultSize, wxTE_READONLY); @@ -103,13 +116,13 @@ uMod_GamePage::uMod_GamePage( wxNotebook *parent, const wxString &exe, int injec // // create collapsible pane - CollPane = new wxCollapsiblePane(this, ID_CollPane, Language->CollapseTextureCapture,wxDefaultPosition,wxDefaultSize,wxCP_NO_TLW_RESIZE); + CollCapturePane = new wxCollapsiblePane(this, ID_CollPane, Language->CollapseTextureCapture,wxDefaultPosition,wxDefaultSize,wxCP_NO_TLW_RESIZE); - CollSizer = new wxBoxSizer(wxVERTICAL); + CollCaptureSizer = new wxBoxSizer(wxVERTICAL); // get window inside the collapsible pane - wxWindow *win = CollPane->GetPane(); + wxWindow *win = CollCapturePane->GetPane(); // this sizer contains the left save-single-texture part and the right save-all-texture part TextureSizer = new wxBoxSizer(wxHORIZONTAL); @@ -132,15 +145,14 @@ uMod_GamePage::uMod_GamePage( wxNotebook *parent, const wxString &exe, int injec SingleTextureSizer->Add( (wxWindow*) ShowSingleTextureString, 0, wxEXPAND| wxBOTTOM | wxLEFT | wxRIGHT, 5); - //set the two colour buttons into one horizontal sizer - wxBoxSizer *temp_sizer = new wxBoxSizer(wxHORIZONTAL); + temp_sizer = new wxBoxSizer(wxHORIZONTAL); FontColour = new wxButton( SingleTexturePanel, ID_FontColour, Language->FontColour, wxDefaultPosition, wxSize(100,24)); FontColour->Enable(false); //siable the font color, per default ShowSingleTextureString is not checked - temp_sizer->Add( FontColour, 0, wxEXPAND, 0); + temp_sizer->Add( (wxWindow*) FontColour, 0, wxEXPAND, 0); temp_sizer->AddSpacer(10); TextureColour = new wxButton( SingleTexturePanel, ID_TextureColour, Language->TextureColour, wxDefaultPosition, wxSize(100,24)); - temp_sizer->Add( TextureColour, 0, wxEXPAND, 0); + temp_sizer->Add( (wxWindow*) TextureColour, 0, wxEXPAND, 0); temp_sizer->AddStretchSpacer(); SingleTextureSizer->Add( temp_sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); @@ -214,12 +226,12 @@ uMod_GamePage::uMod_GamePage( wxNotebook *parent, const wxString &exe, int injec - //combine both texture sizer - TextureSizer->Add( SingleTexturePanel, 1, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - TextureSizer->Add( AllTexturePanel, 1, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); + TextureSizer->Add( SingleTexturePanel, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); + TextureSizer->Add( AllTexturePanel, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); + TextureSizer->AddStretchSpacer(); - CollSizer->Add( TextureSizer, 1, wxEXPAND, 0); + CollCaptureSizer->Add( TextureSizer, 1, wxEXPAND, 0); wxArrayString choices; choices.Add("BMP"); @@ -230,7 +242,7 @@ uMod_GamePage::uMod_GamePage( wxNotebook *parent, const wxString &exe, int injec choices.Add("PPM"); FileFormats = new uMod_CheckBoxArray( win, choices, -1); FileFormats->SetValue( Game.FileFormat()); - CollSizer->Add( (wxWindow*) FileFormats, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); + CollCaptureSizer->Add( (wxWindow*) FileFormats, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); @@ -243,22 +255,65 @@ uMod_GamePage::uMod_GamePage( wxNotebook *parent, const wxString &exe, int injec SavePath = new wxTextCtrl(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY); temp_sizer->Add( (wxWindow*) SavePath, 1, wxEXPAND, 0); - temp_sizer->AddSpacer(30); - UpdateButton = new wxButton( win, ID_Button_Update, Language->ButtonUpdate, wxDefaultPosition, wxSize(100,24)); - temp_sizer->Add( (wxWindow*) UpdateButton, 0, wxEXPAND|wxALL, 0); - - CollSizer->Add( temp_sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); + CollCaptureSizer->Add( temp_sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - win->SetSizer(CollSizer); - CollSizer->SetSizeHints(win); + win->SetSizer(CollCaptureSizer); + CollCaptureSizer->SetSizeHints(win); - MainSizer->Add(CollPane, 0, wxEXPAND, 5); + MainSizer->Add(CollCapturePane, 0, wxEXPAND, 5); MainSizer->AddSpacer(10); + + // + // settings part + // + + // create collapsible pane + CollSettingsPane = new wxCollapsiblePane(this, ID_CollPane, Language->CollapseModSettings,wxDefaultPosition,wxDefaultSize,wxCP_NO_TLW_RESIZE); + + + CollSettingsSizer = new wxBoxSizer(wxVERTICAL); + + // get window inside the collapsible pane + win = CollSettingsPane->GetPane(); + CollSettingsPanel = new wxPanel(win); + + + SupportTPF = new wxCheckBox( win, wxID_ANY, Language->SupportTPF); + CollSettingsSizer->Add( (wxWindow*) SupportTPF, 0, wxEXPAND, 0); + + ComputeRenderTargets = new wxCheckBox( win, wxID_ANY, Language->ComputeRenderTargets); + CollSettingsSizer->Add( (wxWindow*) ComputeRenderTargets, 0, wxEXPAND, 0); + + ExtractTexturesToDisk = new wxCheckBox( win, ID_ExtractTextures, Language->ExtractTexturesToDisk); + CollSettingsSizer->Add( (wxWindow*) ExtractTexturesToDisk, 0, wxEXPAND, 0); + + DeleteExtractedTexturesOnDisk = new wxCheckBox( win, wxID_ANY, Language->DeleteExtractedTexturesOnDisk); + CollSettingsSizer->Add( (wxWindow*) DeleteExtractedTexturesOnDisk, 0, wxEXPAND, 0); + + + // add extract path string + temp_sizer = new wxBoxSizer(wxHORIZONTAL); + ExtractPathButton = new wxButton( win, ID_Button_ExtractPath, Language->ExtractPath, wxDefaultPosition, wxSize(100,24)); + temp_sizer->Add( (wxWindow*) ExtractPathButton, 0, wxEXPAND|wxALL, 0); + + temp_sizer->AddSpacer(5); + ExtractPath = new wxTextCtrl(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY); + temp_sizer->Add( (wxWindow*) ExtractPath, 1, wxEXPAND, 0); + + CollSettingsSizer->Add( temp_sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); + + + win->SetSizer(CollSettingsSizer); + CollSettingsSizer->SetSizeHints(win); + + MainSizer->Add( (wxWindow*)CollSettingsPane, 0, wxEXPAND, 5); + MainSizer->AddSpacer(10); + // // initialize the treeview for the mod packages // @@ -329,6 +384,8 @@ uMod_GamePage::~uMod_GamePage(void) { GetSettings(); SaveTemplate("auto_save"); + + ViewModel->DeleteAllPackages(Game.DeleteExtractedTexturesOnDisk()); } int uMod_GamePage::SetSavePath( const wxString &path) @@ -340,7 +397,11 @@ int uMod_GamePage::SetSavePath( const wxString &path) int uMod_GamePage::AddPackage( const wxString &file_name) { - if (ViewModel->AddPackage(file_name)) + wxString extract_path; + if (Game.ExtractTexturesToDisk()) + extract_path = Game.GetExtractPath(); + + if (ViewModel->AddPackage(file_name, extract_path)) { LastError << ViewModel->LastError; return -1; @@ -350,8 +411,12 @@ int uMod_GamePage::AddPackage( const wxString &file_name) int uMod_GamePage::AddPackages(const wxString *files, int num) { + wxString extract_path; + if (Game.ExtractTexturesToDisk()) + extract_path = Game.GetExtractPath(); + wxArrayString strings( num, files); - if (ViewModel->AddPackages( strings)) + if (ViewModel->AddPackages( strings, extract_path)) { LastError << ViewModel->LastError; return -1; @@ -361,7 +426,11 @@ int uMod_GamePage::AddPackages(const wxString *files, int num) int uMod_GamePage::AddPackages(const wxArrayString &files) { - if (ViewModel->AddPackages( files)) + wxString extract_path; + if (Game.ExtractTexturesToDisk()) + extract_path = Game.GetExtractPath(); + + if (ViewModel->AddPackages( files, extract_path)) { LastError << ViewModel->LastError; return -1; @@ -475,7 +544,7 @@ int uMod_GamePage::SetInfo(void) int uMod_GamePage::GetSettings(void) { - Game.ShowCollPane() = CollPane->IsExpanded(); + Game.ShowCollCapturePane() = CollCapturePane->IsExpanded(); int key_back = KeyBack->GetKey(); int key_save = KeySave->GetKey(); @@ -510,6 +579,14 @@ int uMod_GamePage::GetSettings(void) Game.UseFormatFilter() = UseFormatFilter->GetValue(); FileFormats->GetValue(Game.FileFormat()); + + + Game.ShowCollSettingsPane() = CollSettingsPane->IsExpanded(); + Game.SupportTPF() = SupportTPF->GetValue(); + Game.ComputeRenderTargets() = ComputeRenderTargets->GetValue(); + Game.ExtractTexturesToDisk() = ExtractTexturesToDisk->GetValue(); + Game.DeleteExtractedTexturesOnDisk() = DeleteExtractedTexturesOnDisk->GetValue(); + return 0; } @@ -541,6 +618,8 @@ int uMod_GamePage::ReloadGame(void) wxString content; SaveTemplateToString(content); + + ViewModel->DeleteAllPackages(Game.DeleteExtractedTexturesOnDisk()); return LoadTemplateFromString(content); } @@ -704,7 +783,11 @@ int uMod_GamePage::LoadTemplateFromString( const wxString &content_orig) Game.LoadFromString(content); } - if (ViewModel->AddPackagesFromTemplate( packages)) + wxString extract_path; + if (Game.ExtractTexturesToDisk()) + extract_path = Game.GetExtractPath(); + + if (ViewModel->AddPackagesFromTemplate( packages, extract_path)) { LastError << ViewModel->LastError; } @@ -721,7 +804,7 @@ int uMod_GamePage::LoadTemplateFromString( const wxString &content_orig) int uMod_GamePage::LoadGameData(const uMod_GameInfo &game) { - CollPane->Collapse( !game.ShowCollPane()); + CollCapturePane->Collapse( !game.ShowCollCapturePane()); if (game.ShowSingleTextureString()) @@ -801,6 +884,27 @@ int uMod_GamePage::LoadGameData(const uMod_GameInfo &game) SavePath->SetValue( game.GetSavePath()); + CollSettingsPane->Collapse( !game.ShowCollSettingsPane()); + SupportTPF->SetValue( game.SupportTPF()); + ComputeRenderTargets->SetValue( game.ComputeRenderTargets()); + ExtractTexturesToDisk->SetValue( game.ExtractTexturesToDisk()); + DeleteExtractedTexturesOnDisk->SetValue( game.DeleteExtractedTexturesOnDisk()); + ExtractPath->SetValue(game.GetExtractPath()); + + if (game.ExtractTexturesToDisk()) + { + DeleteExtractedTexturesOnDisk->Enable(); + ExtractPathButton->Enable(); + ExtractPath->Enable(); + } + else + { + DeleteExtractedTexturesOnDisk->Enable(false); + ExtractPathButton->Enable(false); + ExtractPath->Enable(false); + } + + // The wxCollapsiblePane could be hide/shown thus we must manually layout and refresh the sizer and the window // let the main sizer refresh its content MainSizer->Layout(); @@ -903,6 +1007,22 @@ void uMod_GamePage::OnCheckBox(wxCommandEvent& event) FontColour->Enable(false); break; } + case ID_ExtractTextures: + { + if (ExtractTexturesToDisk->GetValue()) + { + DeleteExtractedTexturesOnDisk->Enable(); + ExtractPathButton->Enable(); + ExtractPath->Enable(); + } + else + { + DeleteExtractedTexturesOnDisk->Enable(false); + ExtractPathButton->Enable(false); + ExtractPath->Enable(false); + } + break; + } default: break; } @@ -1053,6 +1173,17 @@ void uMod_GamePage::OnButtonSavePath(wxCommandEvent& WXUNUSED(event)) } } +void uMod_GamePage::OnButtonExtractPath(wxCommandEvent& WXUNUSED(event)) +{ + wxString dir = wxDirSelector( Language->ChooseDir, Game.GetExtractPath()); + if ( !dir.empty() ) + { + Game.SetExtractPath(dir); + ExtractPath->SetValue( dir); + } +} + + void uMod_GamePage::OnButtonUpdate(wxCommandEvent& WXUNUSED(event)) { UpdateGame(); @@ -1194,8 +1325,6 @@ void uMod_GamePage::OnContextMenu( wxDataViewEvent &event ) menu.Append( ID_RemoveSelectedPackages, Language->MenuRemoveSelectedPackages); menu.Append( ID_Update, Language->MenuUpdate); menu.Append( ID_Reload, Language->MenuReload); - menu.AppendCheckItem( ID_SupportTPF, Language->MenuSupportTPF); - menu.Check(ID_SupportTPF, Game.SupportTPF()); // if no node is selected, there is nothing to delete ^^ if (node == (uMod_TreeViewNode*) 0) @@ -1209,7 +1338,6 @@ void uMod_GamePage::OnContextMenu( wxDataViewEvent &event ) { menu.Enable(ID_Update, false); menu.Enable(ID_Reload, false); - menu.Enable(ID_SupportTPF, false); } // if nothing is selected, we cannot deleted selected packages ;) @@ -1238,9 +1366,6 @@ void uMod_GamePage::OnContextMenu( wxDataViewEvent &event ) case ID_Reload: ReloadGame(); break; - case ID_SupportTPF: - Game.SupportTPF() = menu.IsChecked(ID_SupportTPF); - break; default: break; } @@ -1289,7 +1414,7 @@ int uMod_GamePage::UpdateLanguage(void) TemplateFile->SetValue( path); - CollPane->SetLabel(Language->CollapseTextureCapture); + CollCapturePane->SetLabel(Language->CollapseTextureCapture); SaveSingleTexture->SetLabel( Language->CheckBoxSaveSingleTexture); ShowSingleTextureString->SetLabel( Language->CheckBoxShowStringSaveSingleTexture); @@ -1318,6 +1443,14 @@ int uMod_GamePage::UpdateLanguage(void) SavePath->SetValue( Game.GetSavePath()); + CollSettingsPane->SetLabel(Language->CollapseModSettings); + + SupportTPF->SetLabel( Language->SupportTPF); + ComputeRenderTargets->SetLabel( Language->ComputeRenderTargets); + ExtractTexturesToDisk->SetLabel( Language->ExtractTexturesToDisk); + DeleteExtractedTexturesOnDisk->SetLabel( Language->DeleteExtractedTexturesOnDisk); + ExtractPathButton->SetLabel( Language->ExtractPath); + ViewCtrl->GetColumn(0)->SetTitle(Language->Title); ViewCtrl->GetColumn(3)->SetTitle(Language->Author); ViewCtrl->GetColumn(4)->SetTitle(Language->Comment); diff --git a/uMod_GUI/uMod_GamePage.h b/uMod_GUI/uMod_GamePage.h index c68833c..5034806 100644 --- a/uMod_GUI/uMod_GamePage.h +++ b/uMod_GUI/uMod_GamePage.h @@ -96,6 +96,12 @@ public: */ void OnButtonSavePath(wxCommandEvent& event); + /** + * Gets called, when the Extract-path button is pressed + * @param event + */ + void OnButtonExtractPath(wxCommandEvent& event); + /** * Gets called, when the update-path button is pressed * @param event @@ -191,13 +197,14 @@ private: wxString TemplateName; + wxButton *UpdateButton; wxBoxSizer *MainSizer; wxTextCtrl *DX_DLL_Info; wxTextCtrl *TemplateFile; - wxCollapsiblePane *CollPane; - wxBoxSizer *CollSizer; + wxCollapsiblePane *CollCapturePane; + wxBoxSizer *CollCaptureSizer; wxBoxSizer *TextureSizer; @@ -233,10 +240,25 @@ private: uMod_CheckBoxArray *FileFormats; - wxButton *UpdateButton; wxButton *SavePathButton; wxTextCtrl *SavePath; + + + wxCollapsiblePane *CollSettingsPane; + wxBoxSizer *CollSettingsSizer; + wxPanel *CollSettingsPanel; + + + wxCheckBox *SupportTPF; + wxCheckBox *ComputeRenderTargets; + wxCheckBox *ExtractTexturesToDisk; + wxCheckBox *DeleteExtractedTexturesOnDisk; + + wxButton *ExtractPathButton; + wxTextCtrl *ExtractPath; + + wxDataViewCtrl *ViewCtrl; uMod_TreeViewModel *ViewModel; wxDataViewItem *LastDataViewItem; diff --git a/uMod_GUI/uMod_Language.cpp b/uMod_GUI/uMod_Language.cpp index f9d1e99..133e4f0 100644 --- a/uMod_GUI/uMod_Language.cpp +++ b/uMod_GUI/uMod_Language.cpp @@ -203,9 +203,14 @@ int uMod_Language::LoadLanguage(const wxString &name) CheckEntry( command, msg, MenuRemoveSelectedPackages) CheckEntry( command, msg, MenuUpdate) CheckEntry( command, msg, MenuReload) - CheckEntry( command, msg, MenuSupportTPF) CheckEntry( command, msg, ButtonUpdate) CheckEntry( command, msg, ButtonDirectory) + CheckEntry( command, msg, CollapseModSettings) + CheckEntry( command, msg, SupportTPF) + CheckEntry( command, msg, ComputeRenderTargets) + CheckEntry( command, msg, ExtractTexturesToDisk) + CheckEntry( command, msg, DeleteExtractedTexturesOnDisk) + CheckEntry( command, msg, ExtractPath) CheckEntry( command, msg, ChooseFile) CheckEntry( command, msg, ChooseDir) CheckEntry( command, msg, MultipleSingleFiles) @@ -310,10 +315,16 @@ int uMod_Language::LoadDefault(void) MenuUpdate = "Update"; MenuReload = "Update (reload)"; - MenuSupportTPF = "Support TPF-Mods"; ButtonUpdate = "Update"; ButtonDirectory = "Set save directory"; + CollapseModSettings = "Settings"; + SupportTPF = "Support TPF-Mods"; + ComputeRenderTargets = "Compute hash also from rendering targets"; + ExtractTexturesToDisk = "Extract texture to disk (recommended for huge mod packages)"; + DeleteExtractedTexturesOnDisk = "Delete extracted textures if uMod is closed"; + ExtractPath = "Extract directory"; + ChooseFile = "Choose a file"; ChooseDir = "Choose a directory"; diff --git a/uMod_GUI/uMod_Language.h b/uMod_GUI/uMod_Language.h index 1cb0bed..2efce11 100644 --- a/uMod_GUI/uMod_Language.h +++ b/uMod_GUI/uMod_Language.h @@ -56,10 +56,16 @@ public: wxString MenuRemoveSelectedPackages; wxString MenuUpdate; wxString MenuReload; - wxString MenuSupportTPF; wxString ButtonUpdate; wxString ButtonDirectory; + wxString CollapseModSettings; + wxString SupportTPF; + wxString ComputeRenderTargets; + wxString ExtractTexturesToDisk; + wxString DeleteExtractedTexturesOnDisk; + wxString ExtractPath; + wxString ChooseFile; wxString ChooseDir; diff --git a/uMod_GUI/uMod_Main.h b/uMod_GUI/uMod_Main.h index 4ddd5d6..8bd3b06 100644 --- a/uMod_GUI/uMod_Main.h +++ b/uMod_GUI/uMod_Main.h @@ -28,6 +28,7 @@ along with Universal Modding Engine. If not, see #define __WXMSW__ #define NOPCH #define _UNICODE +#define wxUSE_GUI 1 #define wxUSE_NOTEBOOK 1 #define wxUSE_CHECKBOX 1 #define wxUSE_THREADS 1 @@ -129,6 +130,10 @@ enum ID_SetFormatFilter, ID_Button_SavePath, + ID_Button_ExtractPath, + + ID_ExtractTextures, + ID_DataViewCtrl, ID_ContextMenu, }; diff --git a/uMod_GUI/uMod_ModElement.cpp b/uMod_GUI/uMod_ModElement.cpp index 06eee25..7ff3a2a 100644 --- a/uMod_GUI/uMod_ModElement.cpp +++ b/uMod_GUI/uMod_ModElement.cpp @@ -9,6 +9,29 @@ #include "uMod_Main.h" + + +int uMod_ModElement::Release() +{ + if (--myCounter==0) + { + delete this; + return 0; + } + else + return myCounter; +} + + + +void uMod_TextureElement::DeleteFileOnDisk(void) +{ + //wxMessageBox(myExtractedFile, "here"); + if (!myExtractedFile.IsEmpty()) + if (wxFileExists(myExtractedFile)) + wxRemoveFile(myExtractedFile); +} + int Compare_uMod_TextureElement(uMod_TextureElement* a,uMod_TextureElement* b) { if ( a->Hash() < b->Hash()) return -1; diff --git a/uMod_GUI/uMod_ModElement.h b/uMod_GUI/uMod_ModElement.h index 4674821..b87a02c 100644 --- a/uMod_GUI/uMod_ModElement.h +++ b/uMod_GUI/uMod_ModElement.h @@ -38,6 +38,7 @@ public: { if (myData!=(T*)0) delete [] myData; myData = (T*)0; + myLen = 0; if (size<=0) return 0; try {myData = new T[size];} @@ -75,12 +76,23 @@ public: NONE }; - uMod_ModElement( enumType t, enumStatus s = NONE) : myType(t), myStatus(s), myCounter(1) {} + enum enumError + { + OK=0, + MemoryError, + ZIPError, + DiskError, + HashError + }; + + + uMod_ModElement( enumType t, enumStatus s = NONE) : myType(t), myStatus(s), myError(OK), myCounter(1) {} virtual ~uMod_ModElement() {} int AddRef(void) {return ++myCounter;} - int Release(void) {if (--myCounter==0) {delete this;} return myCounter;} + int Release(); + virtual void DeleteFileOnDisk(void) {} const wxString &File(void) const {return myFile;} wxString &File(void) {return myFile;} @@ -101,6 +113,9 @@ public: const enumStatus &Status(void) const {return myStatus;} enumStatus &Status(void) {return myStatus;} + const enumError &Error(void) const {return myError;} + enumError &Error(void) {return myError;} + private: wxString myFile; @@ -109,6 +124,7 @@ private: wxString myComment; const enumType myType; enumStatus myStatus; + enumError myError; int myCounter; @@ -128,16 +144,21 @@ public: uMod_TextureElement() : uMod_ModElement(Texture) {} virtual ~uMod_TextureElement() {} + virtual void DeleteFileOnDisk(void); uMod_Data &Content(void) {return myContent;} - const DWORD64 &Hash(void) const {return myHash;} DWORD64 &Hash(void) {return myHash;} + const wxString &ExtractedFile(void) const {return myExtractedFile;} + wxString &ExtractedFile(void) {return myExtractedFile;} + private: uMod_Data myContent; DWORD64 myHash; + wxString myExtractedFile; + diff --git a/uMod_GUI/uMod_Sender.cpp b/uMod_GUI/uMod_Sender.cpp index f5786fc..0f7e083 100644 --- a/uMod_GUI/uMod_Sender.cpp +++ b/uMod_GUI/uMod_Sender.cpp @@ -101,17 +101,11 @@ int uMod_Sender::Send( const uMod_GameInfo &game, const uMod_GameInfo &game_old, SendBool( game.GetSaveAllTextures(), CONTROL_SAVE_ALL); SendBool(game.SupportTPF(), CONTROL_SUPPORT_TPF); + SendBool(game.ComputeRenderTargets(), CONTROL_COMPUTE_RENDER_TARGETS); SendPath(game.GetSavePath()); - /* - wxString path; - path = game.GetSavePath(); - if (path!=game_old.GetSavePath()) SendPath(path); -*/ - - - if ( OldTextures== (uMod_TextureElement_SortedArrayPtr*)0) OldTextures = new uMod_TextureElement_SortedArrayPtr( Compare_uMod_TextureElement ); + if ( OldTextures == (uMod_TextureElement_SortedArrayPtr*)0) OldTextures = new uMod_TextureElement_SortedArrayPtr( Compare_uMod_TextureElement ); //uMod_TextureElement_SortedArrayPtr* current_textures = new uMod_TextureElement_SortedArrayPtr( Compare_uMod_TextureElement ); @@ -162,6 +156,7 @@ int uMod_Sender::SendTextures(const uMod_TextureElement_SortedArrayPtr &old_tex, MsgStruct *msg; int buffer_pos = 0; + // both arrays are sorted // we go through both arrays in parallel while (old_posContent().Len(); + + if (size==0) + { + send_data = false; + size = tex->ExtractedFile().Len(); + if (size==0) return 0; + size++; + size*=sizeof(wchar_t); + } + if ((sizeof(MsgStruct) + buffer_pos) >=BIG_BUFSIZE) //the buffer is full { if (int ret = SendToGame( Buffer, buffer_pos)) return ret; @@ -232,12 +238,22 @@ int uMod_Sender::AddTexture( uMod_TextureElement *tex, int &buffer_pos) msg = (MsgStruct*) &Buffer[buffer_pos]; msg->Hash = tex->Hash(); msg->Value = size; - msg->Control = CONTROL_FORCE_RELOAD_TEXTURE_DATA; + if (send_data) + msg->Control = CONTROL_FORCE_RELOAD_TEXTURE_DATA; + else + msg->Control = CONTROL_FORCE_RELOAD_TEXTURE; + buffer_pos += sizeof(MsgStruct); - const char* temp = tex->Content().Data(); + const char* temp = NULL; + + if (send_data) + temp = tex->Content().Data(); + else + temp = (const char*) tex->ExtractedFile().wc_str(); + if (temp!=(char*)0) { unsigned int l = 0u; @@ -252,8 +268,7 @@ int uMod_Sender::AddTexture( uMod_TextureElement *tex, int &buffer_pos) } } - if (LastError.Len()>0) return 1; - else return 0; + return 0; } int uMod_Sender::RemoveTexture( uMod_TextureElement *tex, int &buffer_pos) @@ -272,8 +287,7 @@ int uMod_Sender::RemoveTexture( uMod_TextureElement *tex, int &buffer_pos) buffer_pos += sizeof(MsgStruct); - if (LastError.Len()>0) return 1; - else return 0; + return 0; } int uMod_Sender::SendKey(int key, int ctr) diff --git a/uMod_GUI/uMod_TreeView.cpp b/uMod_GUI/uMod_TreeView.cpp index 7abb19c..aa3b56d 100644 --- a/uMod_GUI/uMod_TreeView.cpp +++ b/uMod_GUI/uMod_TreeView.cpp @@ -180,15 +180,17 @@ int uMod_TreeViewModel::CreateSingleNode() return 0; } -int uMod_TreeViewModel::AddPackage(const wxString &file_name) +int uMod_TreeViewModel::AddPackage(const wxString &file_name, const wxString &extract_path) { uMod_File file( file_name); + if (! file.FileSupported()) { LastError << Language->Error_FileNotSupported << "\n" << file_name; return -1; } bool single_file = file.SingleFile(); + file.SetExtractPath(extract_path); uMod_TreeViewNode *node; @@ -231,10 +233,11 @@ int uMod_TreeViewModel::AddPackage(const wxString &file_name) return 0; } -int uMod_TreeViewModel::AddPackages(const wxArrayString &files) +int uMod_TreeViewModel::AddPackages(const wxArrayString &files, const wxString &extract_path) { LastError.Empty(); uMod_File file; + file.SetExtractPath(extract_path); wxDataViewItemArray added_items; wxDataViewItemArray added_single_items; @@ -299,11 +302,12 @@ int uMod_TreeViewModel::AddPackages(const wxArrayString &files) } -int uMod_TreeViewModel::AddPackagesFromTemplate(const wxArrayString &packages) +int uMod_TreeViewModel::AddPackagesFromTemplate(const wxArrayString &packages, const wxString &extract_path) { LastError.Empty(); uMod_File file; + file.SetExtractPath(extract_path); wxDataViewItemArray added_items; DeleteAllPackages(); @@ -345,16 +349,21 @@ int uMod_TreeViewModel::AddPackagesFromTemplate(const wxArrayString &packages) } -int uMod_TreeViewModel::DeletePackage( const wxDataViewItem &item) +int uMod_TreeViewModel::DeletePackage( const wxDataViewItem &item, bool delete_files_on_disk) { uMod_TreeViewNode *node = (uMod_TreeViewNode*) item.GetID(); if (node) { if (node->GetParent()== (uMod_TreeViewNode*) 0 ) { + if (delete_files_on_disk) + DeleteFileOfPackage( node); + + if (node == SingleTextureNode) + SingleTextureNode = (uMod_TreeViewNode*) 0; + myPackages.Remove( node); delete node; - if (node == SingleTextureNode) SingleTextureNode = (uMod_TreeViewNode*) 0; wxDataViewItem parent( (void*) 0 ); @@ -366,7 +375,7 @@ int uMod_TreeViewModel::DeletePackage( const wxDataViewItem &item) return 2; } -int uMod_TreeViewModel::DeletePackages( const wxDataViewItemArray &items) +int uMod_TreeViewModel::DeletePackages( const wxDataViewItemArray &items, bool delete_files_on_disk) { int num = items.GetCount(); wxDataViewItemArray deleted_items; @@ -377,9 +386,15 @@ int uMod_TreeViewModel::DeletePackages( const wxDataViewItemArray &items) { if (node->GetParent()== (uMod_TreeViewNode*) 0 ) { + if (delete_files_on_disk) + DeleteFileOfPackage( node); + + if (node == SingleTextureNode) + SingleTextureNode = (uMod_TreeViewNode*) 0; + myPackages.Remove( node); delete node; - if (node == SingleTextureNode) SingleTextureNode = (uMod_TreeViewNode*) 0; + deleted_items.Add( items[i]); } } @@ -389,13 +404,20 @@ int uMod_TreeViewModel::DeletePackages( const wxDataViewItemArray &items) return 0; } -int uMod_TreeViewModel::DeleteAllPackages(void) +int uMod_TreeViewModel::DeleteAllPackages(bool delete_files_on_disk) { wxDataViewItemArray deleted_items; + + for (unsigned int i=0; iparent1->parent2->current_group) + wxArrayInt counter; // this array store the actual index position for each group in the hierarchy + + buffer.Add(node); + counter.Add(0); + + while (!buffer.IsEmpty()) + { + int pos = buffer.GetCount()-1; + unsigned int index = counter[pos]; + + if (index < buffer[pos]->myChildren.GetCount()) // it has still children + { + buffer[pos]->myChildren[index]->myElement->DeleteFileOnDisk(); + + if (buffer[pos]->myChildren[index]->myElement->Type() == uMod_ModElement::Group) + { + buffer.Add(buffer[pos]->myChildren[index]); + counter.Add(0); + } + + counter[pos]++; + } + else // finished this group + { + buffer.RemoveAt(pos); + counter.RemoveAt(pos); + } + } + + return 0; +} + int uMod_TreeViewModel::GetActiveTexture( uMod_TextureElement_SortedArrayPtr &texture) { texture.Empty(); @@ -445,7 +506,7 @@ int uMod_TreeViewModel::GetActiveTexture( uMod_TextureElement_SortedArrayPtr &te { uMod_TextureElement *tex = (uMod_TextureElement*) buffer[pos]->myChildren[index]->myElement; - if (tex->Content().Len()>0 && ((active[pos]>0) || (tex->Status()==uMod_ModElement::Activate))) + if ((tex->Content().Len()>0 || tex->ExtractedFile().Len()>0) && ((active[pos]>0) || (tex->Status()==uMod_ModElement::Activate))) { if( wxNOT_FOUND == texture.Index(tex)) { diff --git a/uMod_GUI/uMod_TreeView.h b/uMod_GUI/uMod_TreeView.h index 8e816b8..bf46206 100644 --- a/uMod_GUI/uMod_TreeView.h +++ b/uMod_GUI/uMod_TreeView.h @@ -31,42 +31,42 @@ class uMod_TreeViewNode { public: uMod_TreeViewNode( uMod_TreeViewNode* parent, uMod_ModElement *element) : myParent(parent), myElement(element) + { + myElement->AddRef(); + } + + ~uMod_TreeViewNode() + { + // free all our children nodes + size_t count = myChildren.GetCount(); + for (size_t i = 0; i < count; i++) { - myElement->AddRef(); + uMod_TreeViewNode *child = myChildren[i]; + delete child; } + myElement->Release(); + } - ~uMod_TreeViewNode() - { - // free all our children nodes - size_t count = myChildren.GetCount(); - for (size_t i = 0; i < count; i++) - { - uMod_TreeViewNode *child = myChildren[i]; - delete child; - } - myElement->Release(); - } + bool IsContainer() const {if (myElement->Type() == uMod_ModElement::Group) return true; else return false;} - bool IsContainer() const {if (myElement->Type() == uMod_ModElement::Group) return true; else return false;} + uMod_TreeViewNode* GetParent() {return myParent;} - uMod_TreeViewNode* GetParent() {return myParent;} + uMod_TreeViewNode_ArrayPtr& GetChildren() {return myChildren;} - uMod_TreeViewNode_ArrayPtr& GetChildren() {return myChildren;} + uMod_TreeViewNode* GetNthChild( unsigned int n ) {return myChildren.Item( n);} - uMod_TreeViewNode* GetNthChild( unsigned int n ) {return myChildren.Item( n);} + void Insert( uMod_TreeViewNode* child, unsigned int n) {myChildren.Insert( child, n);} - void Insert( uMod_TreeViewNode* child, unsigned int n) {myChildren.Insert( child, n);} + void Append( uMod_TreeViewNode* child ) {myChildren.Add( child );} - void Append( uMod_TreeViewNode* child ) {myChildren.Add( child );} - - unsigned int GetChildCount() const {return myChildren.GetCount();} + unsigned int GetChildCount() const {return myChildren.GetCount();} public: // public to avoid getters/setters - uMod_ModElement *myElement; + uMod_ModElement *myElement; //private: - uMod_TreeViewNode* myParent; - uMod_TreeViewNode_ArrayPtr myChildren; + uMod_TreeViewNode* myParent; + uMod_TreeViewNode_ArrayPtr myChildren; }; @@ -81,7 +81,7 @@ public: virtual unsigned int GetColumnCount() const { - return 5; + return 5; } virtual wxString GetColumnType( unsigned int col ) const @@ -108,14 +108,14 @@ public: // implementation of uMod functions int CreateSingleNode(void); - int AddPackage(const wxString &file_name); - int AddPackages(const wxArrayString &files); - int AddPackagesFromTemplate(const wxArrayString &packages); - - int DeletePackage( const wxDataViewItem &item); - int DeletePackages( const wxDataViewItemArray &item); - int DeleteAllPackages(void); + int AddPackage(const wxString &file_name, const wxString &extract_path); + int AddPackages(const wxArrayString &files, const wxString &extract_path); + int AddPackagesFromTemplate(const wxArrayString &packages, const wxString &extract_path); + int DeletePackage( const wxDataViewItem &item, bool delete_files_on_disk = false); + int DeletePackages( const wxDataViewItemArray &item, bool delete_files_on_disk = false); + int DeleteAllPackages( bool delete_files_on_disk = false); + int DeleteFileOfPackage(uMod_TreeViewNode *node); int GetActiveTexture( uMod_TextureElement_SortedArrayPtr &texture); diff --git a/uMod_GlobalDefines.h b/uMod_GlobalDefines.h index 01606eb..1841fa1 100644 --- a/uMod_GlobalDefines.h +++ b/uMod_GlobalDefines.h @@ -27,7 +27,7 @@ along with Universal Modding Engine. If not, see * This struct is the basic of the communication between dll and GUI. For each command send through the pipe a control value is set to MsgStruct::Control. * The MsgStruct::Value can store various information (e.g. key values, boolean, or length of data). * - * If mor date should be send, Control is set to one of the intended values and value to the amount of data in byte. + * If more date should be send, Control is set to one of the intended values and value to the amount of data in byte. * After the MsgStruct is send also the data is send through the pipe. */ typedef struct @@ -43,14 +43,14 @@ typedef struct typedef struct { HANDLE In; //!< Incoming pipe - HANDLE Out; //!< Outgoning pipe + HANDLE Out; //!< Outgoing pipe } PipeStruct; #define uMod_APP_DX9 L"uMod_DX9.txt" #define uMod_APP_DIR L"uMod" -#define uMod_VERSION_char "uMod V 2.0 alpha (r53)" -#define uMod_VERSION L"uMod V 2.0 alpha (r53)" +#define uMod_VERSION_char "uMod V 2.0 alpha (r54)" +#define uMod_VERSION L"uMod V 2.0 alpha (r54)" #define PIPE_uMod2Game L"\\\\.\\pipe\\uMod2Game" #define PIPE_Game2uMod L"\\\\.\\pipe\\Game2uMod" @@ -85,6 +85,7 @@ typedef struct #define CONTROL_SAVE_FORMAT 50 #define CONTROL_SUPPORT_TPF 60 +#define CONTROL_COMPUTE_RENDER_TARGETS 61 #define CONTROL_GAME_EXIT 100 #define CONTROL_ADD_CLIENT 101