mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-22 00:59:18 +01:00
GfxPack: Refactor + better unicode support
This commit is contained in:
parent
67f7ce815c
commit
bffeb818d1
@ -209,7 +209,7 @@ bool GameProfile::Load(uint64_t title_id)
|
||||
m_gameName = std::string(game_name.begin(), game_name.end());
|
||||
trim(m_gameName.value());
|
||||
}
|
||||
IniParser iniParser(*profileContents, gameProfilePath.string());
|
||||
IniParser iniParser(*profileContents, _pathToUtf8(gameProfilePath));
|
||||
// parse ini
|
||||
while (iniParser.NextSection())
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ void GraphicPack2::LoadGraphicPack(fs::path graphicPackPath)
|
||||
return;
|
||||
std::vector<uint8> rulesData;
|
||||
fs_rules->extract(rulesData);
|
||||
IniParser iniParser(rulesData, rulesPath.string());
|
||||
IniParser iniParser(rulesData, _pathToUtf8(rulesPath));
|
||||
|
||||
if (!iniParser.NextSection())
|
||||
{
|
||||
@ -51,10 +51,9 @@ void GraphicPack2::LoadGraphicPack(fs::path graphicPackPath)
|
||||
cemuLog_log(LogType::Force, "{}: Unable to parse version", _pathToUtf8(rulesPath));
|
||||
return;
|
||||
}
|
||||
|
||||
if (versionNum > GP_LEGACY_VERSION)
|
||||
{
|
||||
GraphicPack2::LoadGraphicPack(_pathToUtf8(rulesPath), iniParser);
|
||||
GraphicPack2::LoadGraphicPack(rulesPath, iniParser);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -79,22 +78,22 @@ void GraphicPack2::LoadAll()
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphicPack2::LoadGraphicPack(const std::string& filename, IniParser& rules)
|
||||
bool GraphicPack2::LoadGraphicPack(const fs::path& rulesPath, IniParser& rules)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto gp = std::make_shared<GraphicPack2>(filename, rules);
|
||||
auto gp = std::make_shared<GraphicPack2>(rulesPath, rules);
|
||||
|
||||
// check if enabled and preset set
|
||||
const auto& config_entries = g_config.data().graphic_pack_entries;
|
||||
|
||||
// legacy absolute path checking for not breaking compatibility
|
||||
auto file = gp->GetFilename2();
|
||||
auto file = gp->GetRulesPath();
|
||||
auto it = config_entries.find(file.lexically_normal());
|
||||
if (it == config_entries.cend())
|
||||
{
|
||||
// check for relative path
|
||||
it = config_entries.find(MakeRelativePath(ActiveSettings::GetUserDataPath(), gp->GetFilename2()).lexically_normal());
|
||||
it = config_entries.find(_utf8ToPath(gp->GetNormalizedPathString()));
|
||||
}
|
||||
|
||||
if (it != config_entries.cend())
|
||||
@ -145,7 +144,7 @@ bool GraphicPack2::DeactivateGraphicPack(const std::shared_ptr<GraphicPack2>& gr
|
||||
const auto it = std::find_if(s_active_graphic_packs.begin(), s_active_graphic_packs.end(),
|
||||
[graphic_pack](const GraphicPackPtr& gp)
|
||||
{
|
||||
return gp->GetFilename() == graphic_pack->GetFilename();
|
||||
return gp->GetNormalizedPathString() == graphic_pack->GetNormalizedPathString();
|
||||
}
|
||||
);
|
||||
|
||||
@ -173,12 +172,12 @@ void GraphicPack2::ActivateForCurrentTitle()
|
||||
{
|
||||
if (gp->GetPresets().empty())
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Activate graphic pack: {}", gp->GetPath());
|
||||
cemuLog_log(LogType::Force, "Activate graphic pack: {}", gp->GetVirtualPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string logLine;
|
||||
logLine.assign(fmt::format("Activate graphic pack: {} [Presets: ", gp->GetPath()));
|
||||
logLine.assign(fmt::format("Activate graphic pack: {} [Presets: ", gp->GetVirtualPath()));
|
||||
bool isFirst = true;
|
||||
for (auto& itr : gp->GetPresets())
|
||||
{
|
||||
@ -249,8 +248,8 @@ std::unordered_map<std::string, GraphicPack2::PresetVar> GraphicPack2::ParsePres
|
||||
return vars;
|
||||
}
|
||||
|
||||
GraphicPack2::GraphicPack2(std::string filename, IniParser& rules)
|
||||
: m_filename(std::move(filename))
|
||||
GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
|
||||
: m_rulesPath(std::move(rulesPath))
|
||||
{
|
||||
// we're already in [Definition]
|
||||
auto option_version = rules.FindOption("version");
|
||||
@ -259,7 +258,7 @@ GraphicPack2::GraphicPack2(std::string filename, IniParser& rules)
|
||||
m_version = StringHelpers::ToInt(*option_version, -1);
|
||||
if (m_version < 0)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "{}: Invalid version", m_filename);
|
||||
cemuLog_log(LogType::Force, "{}: Invalid version", _pathToUtf8(m_rulesPath));
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
@ -305,7 +304,7 @@ GraphicPack2::GraphicPack2(std::string filename, IniParser& rules)
|
||||
cemuLog_log(LogType::Force, "[Definition] section from '{}' graphic pack must contain option: path", gp_name_log.has_value() ? *gp_name_log : "Unknown");
|
||||
throw std::exception();
|
||||
}
|
||||
m_path = *option_path;
|
||||
m_virtualPath = *option_path;
|
||||
|
||||
auto option_gp_name = rules.FindOption("name");
|
||||
if (option_gp_name)
|
||||
@ -508,6 +507,11 @@ bool GraphicPack2::Reload()
|
||||
return Activate();
|
||||
}
|
||||
|
||||
std::string GraphicPack2::GetNormalizedPathString() const
|
||||
{
|
||||
return _pathToUtf8(MakeRelativePath(ActiveSettings::GetUserDataPath(), GetRulesPath()).lexically_normal());
|
||||
}
|
||||
|
||||
bool GraphicPack2::ContainsTitleId(uint64_t title_id) const
|
||||
{
|
||||
const auto it = std::find_if(m_title_ids.begin(), m_title_ids.end(), [title_id](uint64 id) { return id == title_id; });
|
||||
@ -650,7 +654,7 @@ bool GraphicPack2::SetActivePreset(std::string_view category, std::string_view n
|
||||
|
||||
void GraphicPack2::LoadShaders()
|
||||
{
|
||||
fs::path path(m_filename);
|
||||
fs::path path = GetRulesPath();
|
||||
for (auto& it : fs::directory_iterator(path.remove_filename()))
|
||||
{
|
||||
if (!is_regular_file(it))
|
||||
@ -676,7 +680,7 @@ void GraphicPack2::LoadShaders()
|
||||
{
|
||||
std::ifstream file(p);
|
||||
if (!file.is_open())
|
||||
throw std::runtime_error(fmt::format("can't open graphic pack file: {}", p.filename().string()).c_str());
|
||||
throw std::runtime_error(fmt::format("can't open graphic pack file: {}", _pathToUtf8(p.filename())));
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
m_output_shader_source.reserve(file.tellg());
|
||||
@ -689,7 +693,7 @@ void GraphicPack2::LoadShaders()
|
||||
{
|
||||
std::ifstream file(p);
|
||||
if (!file.is_open())
|
||||
throw std::runtime_error(fmt::format("can't open graphic pack file: {}", p.filename().string()).c_str());
|
||||
throw std::runtime_error(fmt::format("can't open graphic pack file: {}", _pathToUtf8(p.filename())));
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
m_upscaling_shader_source.reserve(file.tellg());
|
||||
@ -702,7 +706,7 @@ void GraphicPack2::LoadShaders()
|
||||
{
|
||||
std::ifstream file(p);
|
||||
if (!file.is_open())
|
||||
throw std::runtime_error(fmt::format("can't open graphic pack file: {}", p.filename().string()).c_str());
|
||||
throw std::runtime_error(fmt::format("can't open graphic pack file: {}", _pathToUtf8(p.filename())));
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
m_downscaling_shader_source.reserve(file.tellg());
|
||||
@ -805,7 +809,7 @@ void GraphicPack2::AddConstantsForCurrentPreset(ExpressionParser& ep)
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicPack2::_iterateReplacedFiles(const fs::path& currentPath, std::wstring& internalPath, bool isAOC)
|
||||
void GraphicPack2::_iterateReplacedFiles(const fs::path& currentPath, bool isAOC)
|
||||
{
|
||||
uint64 currentTitleId = CafeSystem::GetForegroundTitleId();
|
||||
uint64 aocTitleId = (currentTitleId & 0xFFFFFFFFull) | 0x0005000c00000000ull;
|
||||
@ -833,7 +837,7 @@ void GraphicPack2::LoadReplacedFiles()
|
||||
return;
|
||||
m_patchedFilesLoaded = true;
|
||||
|
||||
fs::path gfxPackPath = _utf8ToPath(m_filename);
|
||||
fs::path gfxPackPath = GetRulesPath();
|
||||
gfxPackPath = gfxPackPath.remove_filename();
|
||||
|
||||
// /content/
|
||||
@ -843,10 +847,9 @@ void GraphicPack2::LoadReplacedFiles()
|
||||
std::error_code ec;
|
||||
if (fs::exists(contentPath, ec))
|
||||
{
|
||||
std::wstring internalPath(L"/vol/content/");
|
||||
// setup redirections
|
||||
fscDeviceRedirect_map();
|
||||
_iterateReplacedFiles(contentPath, internalPath, false);
|
||||
_iterateReplacedFiles(contentPath, false);
|
||||
}
|
||||
// /aoc/
|
||||
fs::path aocPath(gfxPackPath);
|
||||
@ -857,13 +860,9 @@ void GraphicPack2::LoadReplacedFiles()
|
||||
uint64 aocTitleId = CafeSystem::GetForegroundTitleId();
|
||||
aocTitleId = aocTitleId & 0xFFFFFFFFULL;
|
||||
aocTitleId |= 0x0005000c00000000ULL;
|
||||
wchar_t internalAocPath[128];
|
||||
swprintf(internalAocPath, sizeof(internalAocPath)/sizeof(wchar_t), L"/aoc/%016llx/", aocTitleId);
|
||||
|
||||
std::wstring internalPath(internalAocPath);
|
||||
// setup redirections
|
||||
fscDeviceRedirect_map();
|
||||
_iterateReplacedFiles(aocPath, internalPath, true);
|
||||
_iterateReplacedFiles(aocPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -886,14 +885,14 @@ bool GraphicPack2::Activate()
|
||||
return false;
|
||||
}
|
||||
|
||||
FileStream* fs_rules = FileStream::openFile2(_utf8ToPath(m_filename));
|
||||
FileStream* fs_rules = FileStream::openFile2(m_rulesPath);
|
||||
if (!fs_rules)
|
||||
return false;
|
||||
std::vector<uint8> rulesData;
|
||||
fs_rules->extract(rulesData);
|
||||
delete fs_rules;
|
||||
|
||||
IniParser rules({ (char*)rulesData.data(), rulesData.size()}, m_filename);
|
||||
IniParser rules({ (char*)rulesData.data(), rulesData.size()}, GetNormalizedPathString());
|
||||
|
||||
// load rules
|
||||
try
|
||||
@ -947,7 +946,7 @@ bool GraphicPack2::Activate()
|
||||
else if (anisotropyValue == 16)
|
||||
rule.overwrite_settings.anistropic_value = 4;
|
||||
else
|
||||
cemuLog_log(LogType::Force, "Invalid value {} for overwriteAnisotropy in graphic pack {}. Only the values 1, 2, 4, 8 or 16 are allowed.", anisotropyValue, m_filename);
|
||||
cemuLog_log(LogType::Force, "Invalid value {} for overwriteAnisotropy in graphic pack {}. Only the values 1, 2, 4, 8 or 16 are allowed.", anisotropyValue, GetNormalizedPathString());
|
||||
}
|
||||
m_texture_rules.emplace_back(rule);
|
||||
}
|
||||
@ -992,11 +991,11 @@ bool GraphicPack2::Activate()
|
||||
if (LatteTiming_getCustomVsyncFrequency(globalCustomVsyncFreq))
|
||||
{
|
||||
if (customVsyncFreq != globalCustomVsyncFreq)
|
||||
cemuLog_log(LogType::Force, "rules.txt error: Mismatching vsync frequency {} in graphic pack \'{}\'", customVsyncFreq, GetPath());
|
||||
cemuLog_log(LogType::Force, "rules.txt error: Mismatching vsync frequency {} in graphic pack \'{}\'", customVsyncFreq, GetVirtualPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Set vsync frequency to {} (graphic pack {})", customVsyncFreq, GetPath());
|
||||
cemuLog_log(LogType::Force, "Set vsync frequency to {} (graphic pack {})", customVsyncFreq, GetVirtualPath());
|
||||
LatteTiming_setCustomVsyncFrequency(customVsyncFreq);
|
||||
}
|
||||
}
|
||||
|
@ -97,20 +97,20 @@ public:
|
||||
};
|
||||
using PresetPtr = std::shared_ptr<Preset>;
|
||||
|
||||
GraphicPack2(std::string filename, IniParser& rules);
|
||||
GraphicPack2(fs::path rulesPath, IniParser& rules);
|
||||
|
||||
bool IsEnabled() const { return m_enabled; }
|
||||
bool IsActivated() const { return m_activated; }
|
||||
sint32 GetVersion() const { return m_version; }
|
||||
const std::string& GetFilename() const { return m_filename; }
|
||||
const fs::path GetFilename2() const { return fs::path(m_filename); }
|
||||
const fs::path GetRulesPath() const { return m_rulesPath; }
|
||||
std::string GetNormalizedPathString() const;
|
||||
bool RequiresRestart(bool changeEnableState, bool changePreset);
|
||||
bool Reload();
|
||||
|
||||
bool HasName() const { return !m_name.empty(); }
|
||||
|
||||
const std::string& GetName() const { return m_name.empty() ? m_path : m_name; }
|
||||
const std::string& GetPath() const { return m_path; }
|
||||
const std::string& GetName() const { return m_name.empty() ? m_virtualPath : m_name; }
|
||||
const std::string& GetVirtualPath() const { return m_virtualPath; } // returns the path in the gfx tree hierarchy
|
||||
const std::string& GetDescription() const { return m_description; }
|
||||
bool IsDefaultEnabled() const { return m_default_enabled; }
|
||||
|
||||
@ -164,7 +164,7 @@ public:
|
||||
static const std::vector<std::shared_ptr<GraphicPack2>>& GetGraphicPacks() { return s_graphic_packs; }
|
||||
static const std::vector<std::shared_ptr<GraphicPack2>>& GetActiveGraphicPacks() { return s_active_graphic_packs; }
|
||||
static void LoadGraphicPack(fs::path graphicPackPath);
|
||||
static bool LoadGraphicPack(const std::string& filename, class IniParser& rules);
|
||||
static bool LoadGraphicPack(const fs::path& rulesPath, class IniParser& rules);
|
||||
static bool ActivateGraphicPack(const std::shared_ptr<GraphicPack2>& graphic_pack);
|
||||
static bool DeactivateGraphicPack(const std::shared_ptr<GraphicPack2>& graphic_pack);
|
||||
static void ClearGraphicPacks();
|
||||
@ -208,11 +208,11 @@ private:
|
||||
parser.TryAddConstant(var.first, (TType)var.second.second);
|
||||
}
|
||||
|
||||
std::string m_filename;
|
||||
fs::path m_rulesPath;
|
||||
|
||||
sint32 m_version;
|
||||
std::string m_name;
|
||||
std::string m_path;
|
||||
std::string m_virtualPath;
|
||||
std::string m_description;
|
||||
|
||||
bool m_default_enabled = false;
|
||||
@ -257,7 +257,7 @@ private:
|
||||
CustomShader LoadShader(const fs::path& path, uint64 shader_base_hash, uint64 shader_aux_hash, GP_SHADER_TYPE shader_type) const;
|
||||
void ApplyShaderPresets(std::string& shader_source) const;
|
||||
void LoadReplacedFiles();
|
||||
void _iterateReplacedFiles(const fs::path& currentPath, std::wstring& internalPath, bool isAOC);
|
||||
void _iterateReplacedFiles(const fs::path& currentPath, bool isAOC);
|
||||
|
||||
// ram mappings
|
||||
std::vector<std::pair<MPTR, MPTR>> m_ramMappings;
|
||||
|
@ -71,19 +71,8 @@ void PatchErrorHandler::showStageErrorMessageBox()
|
||||
// returns true if at least one file was found even if it could not be successfully parsed
|
||||
bool GraphicPack2::LoadCemuPatches()
|
||||
{
|
||||
// todo - once we have updated to C++20 we can replace these with the new std::string functions
|
||||
auto startsWith = [](const std::wstring& str, const std::wstring& prefix)
|
||||
{
|
||||
return str.size() >= prefix.size() && 0 == str.compare(0, prefix.size(), prefix);
|
||||
};
|
||||
|
||||
auto endsWith = [](const std::wstring& str, const std::wstring& suffix)
|
||||
{
|
||||
return str.size() >= suffix.size() && 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix);
|
||||
};
|
||||
|
||||
bool foundPatches = false;
|
||||
fs::path path(_utf8ToPath(m_filename));
|
||||
fs::path path(m_rulesPath);
|
||||
path.remove_filename();
|
||||
for (auto& p : fs::directory_iterator(path))
|
||||
{
|
||||
@ -129,7 +118,7 @@ void GraphicPack2::LoadPatchFiles()
|
||||
if (LoadCemuPatches())
|
||||
return; // exit if at least one Cemu style patch file was found
|
||||
// fall back to Cemuhook patches.txt to guarantee backward compatibility
|
||||
fs::path path(_utf8ToPath(m_filename));
|
||||
fs::path path(m_rulesPath);
|
||||
path.remove_filename();
|
||||
path.append("patches.txt");
|
||||
FileStream* patchFile = FileStream::openFile2(path);
|
||||
|
@ -25,7 +25,7 @@ sint32 GraphicPack2::GetLengthWithoutComment(const char* str, size_t length)
|
||||
|
||||
void GraphicPack2::LogPatchesSyntaxError(sint32 lineNumber, std::string_view errorMsg)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Syntax error while parsing patch for graphic pack '{}':", this->GetFilename());
|
||||
cemuLog_log(LogType::Force, "Syntax error while parsing patch for graphic pack '{}':", _pathToUtf8(this->GetRulesPath()));
|
||||
if(lineNumber >= 0)
|
||||
cemuLog_log(LogType::Force, fmt::format("Line {0}: {1}", lineNumber, errorMsg));
|
||||
else
|
||||
|
@ -64,7 +64,7 @@ void GraphicPacksWindow2::FillGraphicPackList() const
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
if (boost::icontains(p->GetPath(), m_filter))
|
||||
if (boost::icontains(p->GetVirtualPath(), m_filter))
|
||||
found = true;
|
||||
else
|
||||
{
|
||||
@ -82,7 +82,7 @@ void GraphicPacksWindow2::FillGraphicPackList() const
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& path = p->GetPath();
|
||||
const auto& path = p->GetVirtualPath();
|
||||
auto tokens = TokenizeView(path, '/');
|
||||
auto node = root;
|
||||
for(size_t i=0; i<tokens.size(); i++)
|
||||
@ -329,7 +329,7 @@ void GraphicPacksWindow2::SaveStateToConfig()
|
||||
|
||||
for (const auto& gp : GraphicPack2::GetGraphicPacks())
|
||||
{
|
||||
auto filename = MakeRelativePath(ActiveSettings::GetUserDataPath(), _utf8ToPath(gp->GetFilename())).lexically_normal();
|
||||
auto filename = _utf8ToPath(gp->GetNormalizedPathString());
|
||||
if (gp->IsEnabled())
|
||||
{
|
||||
data.graphic_pack_entries.try_emplace(filename);
|
||||
@ -603,34 +603,29 @@ void GraphicPacksWindow2::OnCheckForUpdates(wxCommandEvent& event)
|
||||
{
|
||||
if (!CafeSystem::IsTitleRunning())
|
||||
{
|
||||
std::vector<GraphicPackPtr> old_packs = GraphicPack2::GetGraphicPacks();
|
||||
// remember virtual paths of all the enabled packs
|
||||
std::map<std::string, std::string> previouslyEnabledPacks;
|
||||
for(auto& it : GraphicPack2::GetGraphicPacks())
|
||||
{
|
||||
if(it->IsEnabled())
|
||||
previouslyEnabledPacks.emplace(it->GetNormalizedPathString(), it->GetVirtualPath());
|
||||
}
|
||||
// reload graphic packs
|
||||
RefreshGraphicPacks();
|
||||
FillGraphicPackList();
|
||||
|
||||
// check if enabled graphic packs are lost:
|
||||
const auto& new_packs = GraphicPack2::GetGraphicPacks();
|
||||
std::stringstream lost_packs;
|
||||
for(const auto& p : old_packs)
|
||||
// remove packs which are still present
|
||||
for(auto& it : GraphicPack2::GetGraphicPacks())
|
||||
previouslyEnabledPacks.erase(it->GetNormalizedPathString());
|
||||
if(!previouslyEnabledPacks.empty())
|
||||
{
|
||||
if (!p->IsEnabled())
|
||||
continue;
|
||||
|
||||
const auto it = std::find_if(new_packs.cbegin(), new_packs.cend(), [&p](const auto& gp)
|
||||
{
|
||||
return gp->GetFilename() == p->GetFilename();
|
||||
});
|
||||
|
||||
if(it == new_packs.cend())
|
||||
std::string lost_packs;
|
||||
for(auto& it : previouslyEnabledPacks)
|
||||
{
|
||||
lost_packs << p->GetPath() << "\n";
|
||||
lost_packs.append(it.second);
|
||||
lost_packs.push_back('\n');
|
||||
}
|
||||
}
|
||||
|
||||
const auto lost_packs_str = lost_packs.str();
|
||||
if (!lost_packs_str.empty())
|
||||
{
|
||||
wxString message = _("This update removed or renamed the following graphic packs:");
|
||||
message << "\n \n" << lost_packs_str << " \n" << _("You may need to set them up again.");
|
||||
message << "\n \n" << wxString::FromUTF8(lost_packs) << " \n" << _("You may need to set them up again.");
|
||||
wxMessageBox(message, _("Warning"), wxOK | wxCENTRE | wxICON_INFORMATION, this);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user