summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriwubcode <iwubcode@users.noreply.github.com>2020-02-12 21:10:44 -0600
committeriwubcode <iwubcode@users.noreply.github.com>2020-03-15 12:34:04 -0500
commitbba92019dc64b1c16eb7f55f870af41ea58243d1 (patch)
treeaa0d97576ceeb3243847f6503cfb760d0bc806c6
parent15acce847d44564afcc5b49ef26171fe4c4e51d2 (diff)
VideoCommon: Allow texture folders to be determined by a <gameid>.txt file
-rw-r--r--Source/Core/VideoCommon/HiresTextures.cpp89
-rw-r--r--Source/Core/VideoCommon/HiresTextures.h3
2 files changed, 72 insertions, 20 deletions
diff --git a/Source/Core/VideoCommon/HiresTextures.cpp b/Source/Core/VideoCommon/HiresTextures.cpp
index d70a6ab44e..bcc0cac4c9 100644
--- a/Source/Core/VideoCommon/HiresTextures.cpp
+++ b/Source/Core/VideoCommon/HiresTextures.cpp
@@ -17,6 +17,7 @@
#include <fmt/format.h>
+#include "Common/CommonPaths.h"
#include "Common/File.h"
#include "Common/FileSearch.h"
#include "Common/FileUtil.h"
@@ -86,26 +87,40 @@ void HiresTexture::Update()
}
const std::string& game_id = SConfig::GetInstance().GetGameID();
- const std::string texture_directory = GetTextureDirectory(game_id);
+ const std::set<std::string> texture_directories = GetTextureDirectories(game_id);
const std::vector<std::string> extensions{".png", ".dds"};
- const std::vector<std::string> texture_paths =
- Common::DoFileSearch({texture_directory}, extensions, /*recursive*/ true);
+ for (const auto& texture_directory : texture_directories)
+ {
+ const auto texture_paths =
+ Common::DoFileSearch({texture_directory}, extensions, /*recursive*/ true);
- const std::string code = game_id + "_";
+ bool failed_insert = false;
+ for (auto& path : texture_paths)
+ {
+ std::string filename;
+ SplitPath(path, nullptr, &filename, nullptr);
- for (auto& path : texture_paths)
- {
- std::string filename;
- SplitPath(path, nullptr, &filename, nullptr);
+ if (filename.substr(0, s_format_prefix.length()) == s_format_prefix)
+ {
+ const size_t arb_index = filename.rfind("_arb");
+ const bool has_arbitrary_mipmaps = arb_index != std::string::npos;
+ if (has_arbitrary_mipmaps)
+ filename.erase(arb_index, 4);
+
+ const auto [it, inserted] =
+ s_textureMap.try_emplace(filename, DiskTexture{path, has_arbitrary_mipmaps});
+ if (!inserted)
+ {
+ failed_insert = true;
+ }
+ }
+ }
- if (filename.substr(0, s_format_prefix.length()) == s_format_prefix)
+ if (failed_insert)
{
- const size_t arb_index = filename.rfind("_arb");
- const bool has_arbitrary_mipmaps = arb_index != std::string::npos;
- if (has_arbitrary_mipmaps)
- filename.erase(arb_index, 4);
- s_textureMap[filename] = {path, has_arbitrary_mipmaps};
+ ERROR_LOG(VIDEO, "One or more textures at path '%s' were already inserted",
+ texture_directory.c_str());
}
}
@@ -439,15 +454,51 @@ bool HiresTexture::LoadTexture(Level& level, const std::vector<u8>& buffer)
return true;
}
-std::string HiresTexture::GetTextureDirectory(const std::string& game_id)
+std::set<std::string> HiresTexture::GetTextureDirectories(const std::string& game_id)
{
+ std::set<std::string> result;
const std::string texture_directory = File::GetUserPath(D_HIRESTEXTURES_IDX) + game_id;
- // If there's no directory with the region-specific ID, look for a 3-character region-free one
- if (!File::Exists(texture_directory))
- return File::GetUserPath(D_HIRESTEXTURES_IDX) + game_id.substr(0, 3);
+ if (File::Exists(texture_directory))
+ {
+ result.insert(texture_directory);
+ }
+ else
+ {
+ // If there's no directory with the region-specific ID, look for a 3-character region-free one
+ const std::string region_free_directory =
+ File::GetUserPath(D_HIRESTEXTURES_IDX) + game_id.substr(0, 3);
+
+ if (File::Exists(region_free_directory))
+ {
+ result.insert(region_free_directory);
+ }
+ }
+
+ const auto match_gameid = [game_id](const std::string& filename) {
+ std::string basename;
+ SplitPath(filename, nullptr, &basename, nullptr);
+ return basename == game_id || basename == game_id.substr(0, 3);
+ };
+
+ // Look for any other directories that might be specific to the given gameid
+ const auto root_directory = File::GetUserPath(D_HIRESTEXTURES_IDX);
+ const auto files = Common::DoFileSearch({root_directory}, {".txt"}, true);
+ for (const auto& file : files)
+ {
+ if (match_gameid(file))
+ {
+ // The following code is used to calculate the top directory
+ // of a found gameid.txt file
+ // ex: <dolphin dir>/Load/Textures/My folder/gameids/<gameid>.txt
+ // would insert "<dolphin dir>/Load/Textures/My folder"
+ const auto directory_path = file.substr(root_directory.size());
+ const std::size_t first_path_separator_position = directory_path.find_first_of(DIR_SEP_CHR);
+ result.insert(root_directory + directory_path.substr(0, first_path_separator_position));
+ }
+ }
- return texture_directory;
+ return result;
}
HiresTexture::~HiresTexture()
diff --git a/Source/Core/VideoCommon/HiresTextures.h b/Source/Core/VideoCommon/HiresTextures.h
index 6d814b42a9..ec0b188154 100644
--- a/Source/Core/VideoCommon/HiresTextures.h
+++ b/Source/Core/VideoCommon/HiresTextures.h
@@ -5,6 +5,7 @@
#pragma once
#include <memory>
+#include <set>
#include <string>
#include <vector>
@@ -53,7 +54,7 @@ private:
static bool LoadTexture(Level& level, const std::vector<u8>& buffer);
static void Prefetch();
- static std::string GetTextureDirectory(const std::string& game_id);
+ static std::set<std::string> GetTextureDirectories(const std::string& game_id);
HiresTexture() {}
bool m_has_arbitrary_mipmaps;