Attempt at fixing the colors of loaded "hi-res" replacement textures in D3D. Fixes issue 2074. Delete some obsolete commented-out code.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4916 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2010-01-21 19:31:48 +00:00
parent 49d9180266
commit 9893122a58
4 changed files with 31 additions and 168 deletions

View File

@ -101,7 +101,7 @@ PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int te
{ {
std::string key(fileName); std::string key(fileName);
if(textureMap.find(key) == textureMap.end()) if (textureMap.find(key) == textureMap.end())
return PC_TEX_FMT_NONE; return PC_TEX_FMT_NONE;
int width; int width;
@ -142,7 +142,7 @@ PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int te
returnTex = PC_TEX_FMT_IA8; returnTex = PC_TEX_FMT_IA8;
break; break;
default: default:
memcpy(data, temp, width*height*4); memcpy(data, temp, width * height * 4);
returnTex = PC_TEX_FMT_RGBA32; returnTex = PC_TEX_FMT_RGBA32;
break; break;
} }

View File

@ -21,7 +21,7 @@
namespace D3D 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; u32* pBuffer = (u32*)buffer;
LPDIRECT3DTEXTURE9 pTexture; LPDIRECT3DTEXTURE9 pTexture;
@ -148,7 +148,7 @@ LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFOR
return pTexture; 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; u32* pBuffer = (u32*)buffer;
int level = 0; int level = 0;
@ -162,16 +162,29 @@ void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int w
fmt = D3DFMT_A8L8; fmt = D3DFMT_A8L8;
bExpand = true; bExpand = true;
} }
switch(fmt) switch (fmt)
{ {
case D3DFMT_A8R8G8B8: case D3DFMT_A8R8G8B8:
{ if (!swap_r_b) {
for (int y = 0; y < height; y++) 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); memcpy(pBits, pIn, width * 4);
pIn += pitch; 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; break;
case D3DFMT_L8: case D3DFMT_L8:

View File

@ -21,8 +21,8 @@
namespace D3D namespace D3D
{ {
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt = D3DFMT_A8R8G8B8); 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); 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); LPDIRECT3DTEXTURE9 CreateRenderTarget(const int width, const int height);
LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height); LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height);
LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt); LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt);

View File

@ -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) TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt)
{ {
if (address == 0) 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]; TCacheEntry& entry = textures[texID];
PC_TexFormat pcfmt = PC_TEX_FMT_NONE; PC_TexFormat pcfmt = PC_TEX_FMT_NONE;
if (g_ActiveConfig.bHiresTextures) if (g_ActiveConfig.bHiresTextures)
{ {
//Load Custom textures // Load Custom textures
char texPathTemp[MAX_PATH]; char texPathTemp[MAX_PATH];
int oldWidth = width; int oldWidth = width;
int oldHeight = height; 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); pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
D3DFORMAT d3d_fmt; D3DFORMAT d3d_fmt;
bool swap_r_b = false;
switch (pcfmt) { switch (pcfmt) {
case PC_TEX_FMT_BGRA32: case PC_TEX_FMT_BGRA32:
d3d_fmt = D3DFMT_A8R8G8B8;
break;
case PC_TEX_FMT_RGBA32: case PC_TEX_FMT_RGBA32:
d3d_fmt = D3DFMT_A8R8G8B8; d3d_fmt = D3DFMT_A8R8G8B8;
swap_r_b = true;
break; break;
case PC_TEX_FMT_RGB565: case PC_TEX_FMT_RGB565:
d3d_fmt = D3DFMT_R5G6B5; d3d_fmt = D3DFMT_R5G6B5;
@ -426,9 +276,9 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
entry.isRenderTarget = false; entry.isRenderTarget = false;
entry.isNonPow2 = false;//((width & (width - 1)) || (height & (height - 1))); entry.isNonPow2 = false;//((width & (width - 1)) || (height & (height - 1)));
if (!skip_texture_create) { 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 { } 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.frameCount = frameCount;
entry.w = width; entry.w = width;