GS: Use C strings for filenames in texture loading

This commit is contained in:
TellowKrinkle
2026-10-07 14:10:46 -04:00
committed by Ty
parent 2ddbf1a3ee
commit f00cb4cec3
3 changed files with 19 additions and 21 deletions
@@ -19,8 +19,8 @@ struct LoaderDefinition
GSTextureReplacements::ReplacementTextureLoader loader; GSTextureReplacements::ReplacementTextureLoader loader;
}; };
static bool PNGLoader(const std::string& filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image); static bool PNGLoader(const char* filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image);
static bool DDSLoader(const std::string& filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image); static bool DDSLoader(const char* filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image);
static constexpr LoaderDefinition s_loaders[] = { static constexpr LoaderDefinition s_loaders[] = {
{"png", PNGLoader}, {"png", PNGLoader},
@@ -146,7 +146,7 @@ static void ConvertTexture_R8G8B8(u32 width, u32 height, std::vector<u8>& data,
// PNG Handlers // PNG Handlers
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool PNGLoader(const std::string& filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image) bool PNGLoader(const char* filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image)
{ {
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (!png_ptr) if (!png_ptr)
@@ -163,7 +163,7 @@ bool PNGLoader(const std::string& filename, GSTextureReplacements::ReplacementTe
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
}); });
auto fp = FileSystem::OpenManagedCFile(filename.c_str(), "rb"); auto fp = FileSystem::OpenManagedCFile(filename, "rb");
if (!fp) if (!fp)
return false; return false;
@@ -568,7 +568,7 @@ static bool ParseDDSHeader(std::FILE* fp, DDSLoadInfo* info)
return true; return true;
} }
static bool ReadDDSMipLevel(std::FILE* fp, const std::string& filename, u32 mip_level, const DDSLoadInfo& info, u32 width, u32 height, std::vector<u8>& data, u32& pitch, u32 size) static bool ReadDDSMipLevel(std::FILE* fp, const char* filename, u32 mip_level, const DDSLoadInfo& info, u32 width, u32 height, std::vector<u8>& data, u32& pitch, u32 size)
{ {
// D3D11 cannot handle block compressed textures where the first mip level is // D3D11 cannot handle block compressed textures where the first mip level is
// not a multiple of the block size. // not a multiple of the block size.
@@ -578,7 +578,7 @@ static bool ReadDDSMipLevel(std::FILE* fp, const std::string& filename, u32 mip_
Console.Error( Console.Error(
"Invalid dimensions for DDS texture %s. For compressed textures of this format, " "Invalid dimensions for DDS texture %s. For compressed textures of this format, "
"the width/height of the first mip level must be a multiple of %u.", "the width/height of the first mip level must be a multiple of %u.",
filename.c_str(), info.block_size); filename, info.block_size);
return false; return false;
} }
@@ -593,9 +593,9 @@ static bool ReadDDSMipLevel(std::FILE* fp, const std::string& filename, u32 mip_
return true; return true;
} }
bool DDSLoader(const std::string& filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image) bool DDSLoader(const char* filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image)
{ {
auto fp = FileSystem::OpenManagedCFile(filename.c_str(), "rb"); auto fp = FileSystem::OpenManagedCFile(filename, "rb");
if (!fp) if (!fp)
return false; return false;
+10 -12
View File
@@ -102,7 +102,7 @@ namespace GSTextureReplacements
{ {
static TextureName CreateTextureName(const GSTextureCache::HashCacheKey& hash, u32 miplevel); static TextureName CreateTextureName(const GSTextureCache::HashCacheKey& hash, u32 miplevel);
static GSTextureCache::HashCacheKey HashCacheKeyFromTextureName(const TextureName& tn); static GSTextureCache::HashCacheKey HashCacheKeyFromTextureName(const TextureName& tn);
static std::optional<TextureName> ParseReplacementName(const std::string& filename); static std::optional<TextureName> ParseReplacementName(const char* filename);
static std::string GetGameTextureDirectory(); static std::string GetGameTextureDirectory();
static std::string GetDumpFilename(const TextureName& name, u32 level); static std::string GetDumpFilename(const TextureName& name, u32 level);
template <GSTexture::Format format> template <GSTexture::Format format>
@@ -189,7 +189,7 @@ GSTextureCache::HashCacheKey GSTextureReplacements::HashCacheKeyFromTextureName(
return key; return key;
} }
std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std::string& filename) std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const char* filename)
{ {
TextureName ret; TextureName ret;
ret.miplevel = 0; ret.miplevel = 0;
@@ -197,7 +197,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
GSTextureCache::SourceRegion full_region; GSTextureCache::SourceRegion full_region;
char extension_dot; char extension_dot;
if (std::sscanf(filename.c_str(), TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING "%c", &ret.TEX0Hash, &ret.CLUTHash, if (std::sscanf(filename, TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING "%c", &ret.TEX0Hash, &ret.CLUTHash,
&ret.region_width, &ret.region_height, &ret.bits, &extension_dot) == 6 && &ret.region_width, &ret.region_height, &ret.bits, &extension_dot) == 6 &&
extension_dot == '.') extension_dot == '.')
{ {
@@ -205,7 +205,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
return ret; return ret;
} }
if (std::sscanf(filename.c_str(), TEXTURE_FILENAME_REGION_FORMAT_STRING "%c", &ret.TEX0Hash, if (std::sscanf(filename, TEXTURE_FILENAME_REGION_FORMAT_STRING "%c", &ret.TEX0Hash,
&ret.region_width, &ret.region_height, &ret.bits, &extension_dot) == 5 && &ret.region_width, &ret.region_height, &ret.bits, &extension_dot) == 5 &&
extension_dot == '.') extension_dot == '.')
{ {
@@ -215,7 +215,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
} }
// Allow loading of dumped textures from older versions that included the full region bits. // Allow loading of dumped textures from older versions that included the full region bits.
if (std::sscanf(filename.c_str(), TEXTURE_FILENAME_OLD_REGION_CLUT_FORMAT_STRING "%c", &ret.TEX0Hash, &ret.CLUTHash, if (std::sscanf(filename, TEXTURE_FILENAME_OLD_REGION_CLUT_FORMAT_STRING "%c", &ret.TEX0Hash, &ret.CLUTHash,
&full_region.bits, &ret.bits, &extension_dot) == 5 && &full_region.bits, &ret.bits, &extension_dot) == 5 &&
extension_dot == '.') extension_dot == '.')
{ {
@@ -225,7 +225,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
return ret; return ret;
} }
if (std::sscanf(filename.c_str(), TEXTURE_FILENAME_OLD_REGION_FORMAT_STRING "%c", &ret.TEX0Hash, &full_region.bits, if (std::sscanf(filename, TEXTURE_FILENAME_OLD_REGION_FORMAT_STRING "%c", &ret.TEX0Hash, &full_region.bits,
&ret.bits, &extension_dot) == 4 && &ret.bits, &extension_dot) == 4 &&
extension_dot == '.') extension_dot == '.')
{ {
@@ -239,7 +239,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
ret.region_width = 0; ret.region_width = 0;
ret.region_height = 0; ret.region_height = 0;
if (std::sscanf(filename.c_str(), TEXTURE_FILENAME_CLUT_FORMAT_STRING "%c", &ret.TEX0Hash, &ret.CLUTHash, &ret.bits, if (std::sscanf(filename, TEXTURE_FILENAME_CLUT_FORMAT_STRING "%c", &ret.TEX0Hash, &ret.CLUTHash, &ret.bits,
&extension_dot) == 4 && &extension_dot) == 4 &&
extension_dot == '.') extension_dot == '.')
{ {
@@ -247,8 +247,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
return ret; return ret;
} }
if (std::sscanf(filename.c_str(), TEXTURE_FILENAME_FORMAT_STRING "%c", &ret.TEX0Hash, &ret.bits, &extension_dot) == if (std::sscanf(filename, TEXTURE_FILENAME_FORMAT_STRING "%c", &ret.TEX0Hash, &ret.bits, &extension_dot) == 3 &&
3 &&
extension_dot == '.') extension_dot == '.')
{ {
ret.RemoveUnusedBits(); ret.RemoveUnusedBits();
@@ -416,11 +415,10 @@ void GSTextureReplacements::ReloadReplacementMap()
if (!FileSystem::FindFiles(replacement_dir.c_str(), "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE, &files)) if (!FileSystem::FindFiles(replacement_dir.c_str(), "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE, &files))
return; return;
std::string filename;
for (FILESYSTEM_FIND_DATA& fd : files) for (FILESYSTEM_FIND_DATA& fd : files)
{ {
// file format we can handle? // file format we can handle?
filename = Path::GetFileName(fd.FileName); const char* filename = Path::GetFileName(fd.FileName).data(); // GetFileName takes a substring from the end, so the null terminator is preserved
if (!GetLoader(filename)) if (!GetLoader(filename))
continue; continue;
@@ -429,7 +427,7 @@ void GSTextureReplacements::ReloadReplacementMap()
if (!name.has_value()) if (!name.has_value())
continue; continue;
DbgCon.WriteLn("Found %ux%u replacement '%.*s'", name->Width(), name->Height(), static_cast<int>(filename.size()), filename.data()); DbgCon.WriteLn("Found %ux%u replacement '%s'", name->Width(), name->Height(), filename);
s_replacement_texture_filenames.emplace(name.value(), std::move(fd.FileName)); s_replacement_texture_filenames.emplace(name.value(), std::move(fd.FileName));
// zero out the CLUT hash, because we need this for checking if there's any replacements with this hash when using paltex // zero out the CLUT hash, because we need this for checking if there's any replacements with this hash when using paltex
@@ -54,7 +54,7 @@ namespace GSTextureReplacements
u32 GetLoadedTextureCount(); u32 GetLoadedTextureCount();
/// Loader will take a filename and interpret the format (e.g. DDS, PNG, etc). /// Loader will take a filename and interpret the format (e.g. DDS, PNG, etc).
using ReplacementTextureLoader = bool (*)(const std::string& filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image); using ReplacementTextureLoader = bool (*)(const char* filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image);
ReplacementTextureLoader GetLoader(const std::string_view filename); ReplacementTextureLoader GetLoader(const std::string_view filename);
/// Saves an image buffer to a PNG file (for dumping). /// Saves an image buffer to a PNG file (for dumping).