diff --git a/Source/Core/VideoCommon/Src/HiresTextures.cpp b/Source/Core/VideoCommon/Src/HiresTextures.cpp index 8fb819a6bc..0d92a14c2f 100644 --- a/Source/Core/VideoCommon/Src/HiresTextures.cpp +++ b/Source/Core/VideoCommon/Src/HiresTextures.cpp @@ -101,7 +101,7 @@ PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int te { std::string key(fileName); - if(textureMap.find(key) == textureMap.end()) + if (textureMap.find(key) == textureMap.end()) return PC_TEX_FMT_NONE; int width; @@ -142,7 +142,7 @@ PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int te returnTex = PC_TEX_FMT_IA8; break; default: - memcpy(data, temp, width*height*4); + memcpy(data, temp, width * height * 4); returnTex = PC_TEX_FMT_RGBA32; break; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp index d9ca8b4f09..e3ae4c4c85 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.cpp @@ -21,7 +21,7 @@ namespace D3D { -LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt) +LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b) { u32* pBuffer = (u32*)buffer; LPDIRECT3DTEXTURE9 pTexture; @@ -148,7 +148,7 @@ LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFOR return pTexture; } -void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height,const int pitch, D3DFORMAT fmt) +void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b) { u32* pBuffer = (u32*)buffer; int level = 0; @@ -162,16 +162,29 @@ void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int w fmt = D3DFMT_A8L8; bExpand = true; } - switch(fmt) + switch (fmt) { case D3DFMT_A8R8G8B8: - { + if (!swap_r_b) { for (int y = 0; y < height; y++) { - u32* pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch)); + u32 *pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch)); memcpy(pBits, pIn, width * 4); pIn += pitch; } + } else { + for (int y = 0; y < height; y++) + { + u8 *pIn8 = (u8 *)pIn; + u8 *pBits = (u8 *)((u8*)Lock.pBits + (y * Lock.Pitch)); + for (int x = 0; x < width * 4; x += 4) { + pBits[x + 0] = pIn8[x + 2]; + pBits[x + 1] = pIn8[x + 1]; + pBits[x + 2] = pIn8[x + 0]; + pBits[x + 3] = pIn8[x + 3]; + } + pIn += pitch; + } } break; case D3DFMT_L8: diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.h index e9fe580177..c1dbb13289 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DTexture.h @@ -21,8 +21,8 @@ namespace D3D { - LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt = D3DFMT_A8R8G8B8); - void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height,const int pitch, D3DFORMAT fmt); + LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt = D3DFMT_A8R8G8B8, bool swap_r_b = false); + void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b); LPDIRECT3DTEXTURE9 CreateRenderTarget(const int width, const int height); LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height); LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 74124abdda..9f2f4beb97 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -136,160 +136,6 @@ void TextureCache::Cleanup() } } -//TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt) -//{ -// if (address == 0) -// return NULL; -// -// u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address); -// int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16; -// int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16; -// int expandedWidth = (width + bsw) & (~bsw); -// int expandedHeight = (height + bsh) & (~bsh); -// -// u32 hash_value; -// u32 texID = address; -// u32 texHash; -// -// if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bDumpTextures) -// { -// texHash = TexDecoder_GetSafeTextureHash(ptr, expandedWidth, expandedHeight, tex_format, 0); -// if (g_ActiveConfig.bSafeTextureCache) -// hash_value = texHash; -// if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) -// { -// // WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up) -// // tlut size can be up to 32768B (GX_TF_C14X2) but Safer == Slower. -// // This trick (to change the texID depending on the TLUT addr) is a trick to get around -// // an issue with metroid prime's fonts, where it has multiple sets of fonts on top of -// // each other stored in a single texture, and uses the palette to make different characters -// // visible or invisible. Thus, unless we want to recreate the textures for every drawn character, -// // we must make sure that texture with different tluts get different IDs. -// u32 tlutHash = TexDecoder_GetTlutHash(&texMem[tlutaddr], (tex_format == GX_TF_C4) ? 32 : 128); -// texHash ^= tlutHash; -// if (g_ActiveConfig.bSafeTextureCache) -// texID ^= tlutHash; -// } -// } -// -// bool skip_texture_create = false; -// TexCache::iterator iter = textures.find(texID); -// -// if (iter != textures.end()) -// { -// TCacheEntry &entry = iter->second; -// -// if (!g_ActiveConfig.bSafeTextureCache) -// hash_value = ((u32 *)ptr)[0]; -// -// if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash))) -// { -// entry.frameCount = frameCount; -// D3D::SetTexture(stage, entry.texture); -// return &entry; -// } -// else -// { -// // Let's reload the new texture data into the same texture, -// // instead of destroying it and having to create a new one. -// // Might speed up movie playback very, very slightly. -// -// if (width == entry.w && height==entry.h &&(tex_format | (tlutfmt << 16)) == entry.fmt) -// { -// skip_texture_create = true; -// } -// else -// { -// entry.Destroy(false); -// textures.erase(iter); -// } -// } -// } -// -// //PC_TexFormat pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, height, tex_format, tlutaddr, tlutfmt); -// PC_TexFormat pcfmt = GetPC_TexFormat(tex_format, tlutfmt); -// -// D3DFORMAT d3d_fmt; -// switch (pcfmt) { -// case PC_TEX_FMT_BGRA32: -// case PC_TEX_FMT_RGBA32: -// d3d_fmt = D3DFMT_A8R8G8B8; -// break; -// case PC_TEX_FMT_RGB565: -// d3d_fmt = D3DFMT_R5G6B5; -// break; -// case PC_TEX_FMT_IA4_AS_IA8: -// d3d_fmt = D3DFMT_A8L8; -// break; -// case PC_TEX_FMT_I8: -// case PC_TEX_FMT_I4_AS_I8: -// d3d_fmt = D3DFMT_A8L8; -// break; -// case PC_TEX_FMT_IA8: -// d3d_fmt = D3DFMT_A8L8; -// break; -// case PC_TEX_FMT_DXT1: -// d3d_fmt = D3DFMT_DXT1; -// break; -// } -// -// //Make an entry in the table -// TCacheEntry& entry = textures[texID]; -// entry.addr = address; -// entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, tex_format); -// entry.isRenderTarget = false; -// entry.isNonPow2 = ((width & (width - 1)) || (height & (height - 1))); -// if (!skip_texture_create) { -// entry.texture = D3D::CreateOnlyTexture2D(width, height, d3d_fmt); -// } -// D3DLOCKED_RECT Lock; -// entry.texture->LockRect(0, &Lock, NULL,D3DLOCK_DISCARD); -// TexDecoder_DirectDecode((u8*)Lock.pBits,ptr,expandedWidth,height,Lock.Pitch,tex_format,tlutaddr,tlutfmt); -// entry.texture->UnlockRect(0); -// entry.oldpixel = ((u32 *)ptr)[0]; -// if (g_ActiveConfig.bSafeTextureCache) -// entry.hash = hash_value; -// else -// { -// entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF); -// ((u32 *)ptr)[0] = entry.hash; -// } -// entry.frameCount = frameCount; -// entry.w = width; -// entry.h = height; -// entry.fmt = tex_format | (tlutfmt << 16); -// -// if (g_ActiveConfig.bDumpTextures) -// { -// // dump texture to file -// char szTemp[MAX_PATH]; -// char szDir[MAX_PATH]; -// const char* uniqueId = globals->unique_id; -// bool bCheckedDumpDir = false; -// sprintf(szDir, "%s/%s", FULL_DUMP_TEXTURES_DIR, uniqueId); -// if (!bCheckedDumpDir) -// { -// if (!File::Exists(szDir) || !File::IsDirectory(szDir)) -// File::CreateDir(szDir); -// -// bCheckedDumpDir = true; -// } -// sprintf(szTemp, "%s/%s_%08x_%i.png", szDir, uniqueId, texHash, tex_format); -// //sprintf(szTemp, "%s\\txt_%04i_%i.png", g_Config.texDumpPath.c_str(), counter++, format); <-- Old method -// if (!File::Exists(szTemp)) -// D3DXSaveTextureToFileA(szTemp,D3DXIFF_BMP,entry.texture,0); -// } -// -// INCSTAT(stats.numTexturesCreated); -// SETSTAT(stats.numTexturesAlive, (int)textures.size()); -// -// //Set the texture! -// D3D::SetTexture(stage, entry.texture); -// -// DEBUGGER_PAUSE_LOG_AT(NEXT_NEW_TEXTURE,true,{printf("A new texture (%d x %d) is loaded", width, height);}); -// return &entry; -//} - TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt) { if (address == 0) @@ -360,13 +206,13 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, } } - //Make an entry in the table + // Make an entry in the table TCacheEntry& entry = textures[texID]; PC_TexFormat pcfmt = PC_TEX_FMT_NONE; if (g_ActiveConfig.bHiresTextures) { - //Load Custom textures + // Load Custom textures char texPathTemp[MAX_PATH]; int oldWidth = width; int oldHeight = height; @@ -383,14 +229,18 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, } } - if(pcfmt == PC_TEX_FMT_NONE) + if (pcfmt == PC_TEX_FMT_NONE) pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt); D3DFORMAT d3d_fmt; + bool swap_r_b = false; switch (pcfmt) { case PC_TEX_FMT_BGRA32: + d3d_fmt = D3DFMT_A8R8G8B8; + break; case PC_TEX_FMT_RGBA32: d3d_fmt = D3DFMT_A8R8G8B8; + swap_r_b = true; break; case PC_TEX_FMT_RGB565: d3d_fmt = D3DFMT_R5G6B5; @@ -426,9 +276,9 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, entry.isRenderTarget = false; entry.isNonPow2 = false;//((width & (width - 1)) || (height & (height - 1))); if (!skip_texture_create) { - entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt); + entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b); } else { - D3D::ReplaceTexture2D(entry.texture, (BYTE*)temp, width, height, expandedWidth, d3d_fmt); + D3D::ReplaceTexture2D(entry.texture, (BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b); } entry.frameCount = frameCount; entry.w = width;