diff --git a/Source/Core/VideoCommon/Src/HiresTextures.cpp b/Source/Core/VideoCommon/Src/HiresTextures.cpp index 16a19eb41e..61dbe7b57f 100644 --- a/Source/Core/VideoCommon/Src/HiresTextures.cpp +++ b/Source/Core/VideoCommon/Src/HiresTextures.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "SOIL.h" #include "CommonPaths.h" #include "FileUtil.h" @@ -34,26 +35,26 @@ void Init(const char *gameCode) CFileSearch::XStringVector Directories; Directories.push_back(std::string(FULL_HIRES_TEXTURES_DIR)); - for(u32 i = 0; i < Directories.size(); i++) + for (u32 i = 0; i < Directories.size(); i++) { File::FSTEntry FST_Temp; File::ScanDirectoryTree(Directories.at(i).c_str(), FST_Temp); - for(u32 j = 0; j < FST_Temp.children.size(); j++) + for (u32 j = 0; j < FST_Temp.children.size(); j++) { - if(FST_Temp.children.at(j).isDirectory) + if (FST_Temp.children.at(j).isDirectory) { bool duplicate = false; NormalizeDirSep(&(FST_Temp.children.at(j).physicalName)); - for(u32 k = 0; k < Directories.size(); k++) + for (u32 k = 0; k < Directories.size(); k++) { NormalizeDirSep(&Directories.at(k)); - if(strcmp(Directories.at(k).c_str(), FST_Temp.children.at(j).physicalName.c_str()) == 0) + if (strcmp(Directories.at(k).c_str(), FST_Temp.children.at(j).physicalName.c_str()) == 0) { duplicate = true; break; } } - if(!duplicate) + if (!duplicate) Directories.push_back(FST_Temp.children.at(j).physicalName.c_str()); } } @@ -64,18 +65,21 @@ void Init(const char *gameCode) Extensions.push_back("*.bmp"); Extensions.push_back("*.tga"); Extensions.push_back("*.dds"); + Extensions.push_back("*.jpg"); // Why not? Could be useful for large photo-like textures CFileSearch FileSearch(Extensions, Directories); const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); + char code[MAX_PATH]; + sprintf(code, "%s_", gameCode); - if(rFilenames.size() > 0) + if (rFilenames.size() > 0) { - for(u32 i = 0; i < rFilenames.size(); i++) + for (u32 i = 0; i < rFilenames.size(); i++) { std::string FileName; SplitPath(rFilenames[i], NULL, &FileName, NULL); - if(FileName.substr(0, strlen(gameCode)).compare(gameCode) == 0 && textureMap.find(FileName) == textureMap.end()) + if (FileName.substr(0, strlen(code)).compare(code) == 0 && textureMap.find(FileName) == textureMap.end()) textureMap.insert(std::map::value_type(FileName, rFilenames[i])); } } @@ -86,7 +90,7 @@ void Shutdown() textureMap.clear(); } -PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, u8 *data) +PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int texformat, u8 *data) { std::string key(fileName); @@ -96,6 +100,7 @@ PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, u8 *da int width; int height; int channels; + u8 *temp = SOIL_load_image(textureMap[key].c_str(), &width, &height, &channels, SOIL_LOAD_RGBA); if (temp == NULL) { @@ -110,11 +115,34 @@ PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, u8 *da return PC_TEX_FMT_NONE; } - memcpy(data, temp, width*height*4); + int offset = 0; + PC_TexFormat returnTex; + + switch (texformat) + { + case GX_TF_I4: + case GX_TF_I8: + case GX_TF_IA4: + case GX_TF_IA8: + for (int i = 0; i < width * height * 4; i += 4) + { + // Rather than use a luminosity function, just use the most intense color for luminance + data[offset++] = *std::max_element(temp+i, temp+i+3); + data[offset++] = temp[i+3]; + } + returnTex = PC_TEX_FMT_IA8; + break; + default: + memcpy(data, temp, width*height*4); + returnTex = PC_TEX_FMT_RGBA32; + break; + } + *pWidth = width; *pHeight = height; SOIL_free_image_data(temp); - return PC_TEX_FMT_RGBA32; + INFO_LOG(VIDEO, "loading custom texture from %s", textureMap[key].c_str()); + return returnTex; } } diff --git a/Source/Core/VideoCommon/Src/HiresTextures.h b/Source/Core/VideoCommon/Src/HiresTextures.h index d20e79b7da..8b5d51fec7 100644 --- a/Source/Core/VideoCommon/Src/HiresTextures.h +++ b/Source/Core/VideoCommon/Src/HiresTextures.h @@ -26,7 +26,7 @@ namespace HiresTextures { void Init(const char *gameCode); void Shutdown(); -PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, u8 *data); +PC_TexFormat GetHiresTex(const char *fileName, int *pWidth, int *pHeight, int texformat, u8 *data); }; #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index c8ae106990..ab16b99851 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -332,7 +332,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width //Make an entry in the table TCacheEntry& entry = textures[texID]; - PC_TexFormat dfmt = PC_TEX_FMT_NONE; + PC_TexFormat dfmt = PC_TEX_FMT_NONE; if (g_Config.bHiresTextures) { @@ -341,16 +341,14 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width int oldWidth = width; int oldHeight = height; sprintf(texPathTemp, "%s_%08x_%i", ((struct SConfig *)globals->config)->m_LocalCoreStartupParameter.GetUniqueID().c_str(), texHash, tex_format); - dfmt = HiresTextures::GetHiresTex(texPathTemp, &width, &height, temp); - + dfmt = HiresTextures::GetHiresTex(texPathTemp, &width, &height, tex_format, temp); + if (dfmt != PC_TEX_FMT_NONE) { expandedWidth = width; expandedHeight = height; - entry.size_in_bytes = sizeof(temp); entry.scaleX = (float) width / oldWidth; entry.scaleY = (float) height / oldHeight; - INFO_LOG(VIDEO, "loading custom texture from %s", texPathTemp); } } @@ -462,7 +460,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width if (g_Config.bDumpTextures) // dump texture to file { char szTemp[MAX_PATH]; - + &m_LastFilename sprintf(szTemp, "%s/%s_%08x_%i.tga", FULL_DUMP_TEXTURES_DIR, ((struct SConfig *)globals->config)->m_LocalCoreStartupParameter.GetUniqueID().c_str(), texHash, tex_format); if (!File::Exists(szTemp)) {