mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-11 16:49:28 +02:00
VideoCommon: add logic to read a GraphicsMod from configuration
This commit is contained in:
@ -0,0 +1,191 @@
|
||||
// Copyright 2022 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModGroup.h"
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/FileSearch.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include "VideoCommon/GraphicsModSystem/Config/GraphicsMod.h"
|
||||
#include "VideoCommon/GraphicsModSystem/Constants.h"
|
||||
#include "VideoCommon/HiresTextures.h"
|
||||
|
||||
GraphicsModGroupConfig::GraphicsModGroupConfig(const std::string& game_id) : m_game_id(game_id)
|
||||
{
|
||||
}
|
||||
|
||||
GraphicsModGroupConfig::~GraphicsModGroupConfig() = default;
|
||||
|
||||
GraphicsModGroupConfig::GraphicsModGroupConfig(const GraphicsModGroupConfig&) = default;
|
||||
|
||||
GraphicsModGroupConfig::GraphicsModGroupConfig(GraphicsModGroupConfig&&) = default;
|
||||
|
||||
GraphicsModGroupConfig& GraphicsModGroupConfig::operator=(const GraphicsModGroupConfig&) = default;
|
||||
|
||||
GraphicsModGroupConfig& GraphicsModGroupConfig::operator=(GraphicsModGroupConfig&&) = default;
|
||||
|
||||
void GraphicsModGroupConfig::Load()
|
||||
{
|
||||
const std::string file_path = GetPath();
|
||||
|
||||
std::set<std::string> known_paths;
|
||||
if (File::Exists(file_path))
|
||||
{
|
||||
std::string json_data;
|
||||
if (!File::ReadFileToString(file_path, json_data))
|
||||
{
|
||||
ERROR_LOG_FMT(VIDEO, "Failed to load graphics mod group json file '{}'", file_path);
|
||||
return;
|
||||
}
|
||||
|
||||
picojson::value root;
|
||||
const auto error = picojson::parse(root, json_data);
|
||||
|
||||
if (!error.empty())
|
||||
{
|
||||
ERROR_LOG_FMT(VIDEO,
|
||||
"Failed to load graphics mod group json file '{}' due to parse error: {}",
|
||||
file_path, error);
|
||||
return;
|
||||
}
|
||||
if (!root.is<picojson::object>())
|
||||
{
|
||||
ERROR_LOG_FMT(
|
||||
VIDEO,
|
||||
"Failed to load graphics mod group json file '{}' due to root not being an object!",
|
||||
file_path);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mods = root.get("mods");
|
||||
if (mods.is<picojson::array>())
|
||||
{
|
||||
for (const auto& mod_json : mods.get<picojson::array>())
|
||||
{
|
||||
if (mod_json.is<picojson::object>())
|
||||
{
|
||||
const auto& mod_json_obj = mod_json.get<picojson::object>();
|
||||
auto graphics_mod = GraphicsModConfig::Create(&mod_json_obj);
|
||||
if (!graphics_mod)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
graphics_mod->DeserializeFromProfile(mod_json_obj);
|
||||
|
||||
auto mod_full_path = graphics_mod->GetAbsolutePath();
|
||||
known_paths.insert(std::move(mod_full_path));
|
||||
m_graphics_mods.push_back(*graphics_mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto try_add_mod = [&known_paths, this](const std::string& dir,
|
||||
GraphicsModConfig::Source source) {
|
||||
auto file = dir + DIR_SEP + "metadata.json";
|
||||
UnifyPathSeparators(file);
|
||||
if (known_paths.find(file) != known_paths.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto mod = GraphicsModConfig::Create(file, source);
|
||||
if (mod)
|
||||
{
|
||||
m_graphics_mods.push_back(*mod);
|
||||
}
|
||||
};
|
||||
|
||||
const std::set<std::string> graphics_mod_user_directories =
|
||||
GetTextureDirectoriesWithGameId(File::GetUserPath(D_GRAPHICSMOD_IDX), m_game_id);
|
||||
|
||||
for (const auto& graphics_mod_directory : graphics_mod_user_directories)
|
||||
{
|
||||
try_add_mod(graphics_mod_directory, GraphicsModConfig::Source::User);
|
||||
}
|
||||
|
||||
const std::set<std::string> graphics_mod_system_directories = GetTextureDirectoriesWithGameId(
|
||||
File::GetSysDirectory() + DOLPHIN_SYSTEM_GRAPHICS_MOD_DIR, m_game_id);
|
||||
|
||||
for (const auto& graphics_mod_directory : graphics_mod_system_directories)
|
||||
{
|
||||
try_add_mod(graphics_mod_directory, GraphicsModConfig::Source::System);
|
||||
}
|
||||
|
||||
std::sort(m_graphics_mods.begin(), m_graphics_mods.end());
|
||||
for (auto& mod : m_graphics_mods)
|
||||
{
|
||||
m_path_to_graphics_mod[mod.GetAbsolutePath()] = &mod;
|
||||
}
|
||||
|
||||
m_change_count++;
|
||||
}
|
||||
|
||||
void GraphicsModGroupConfig::Save() const
|
||||
{
|
||||
const std::string file_path = GetPath();
|
||||
std::ofstream json_stream;
|
||||
File::OpenFStream(json_stream, file_path, std::ios_base::out);
|
||||
if (!json_stream.is_open())
|
||||
{
|
||||
ERROR_LOG_FMT(VIDEO, "Failed to open graphics mod group json file '{}' for writing", file_path);
|
||||
return;
|
||||
}
|
||||
|
||||
picojson::object serialized_root;
|
||||
picojson::array serialized_mods;
|
||||
for (const auto& mod : m_graphics_mods)
|
||||
{
|
||||
picojson::object serialized_mod;
|
||||
mod.SerializeToProfile(&serialized_mod);
|
||||
serialized_mods.push_back(picojson::value{serialized_mod});
|
||||
}
|
||||
serialized_root["mods"] = picojson::value{serialized_mods};
|
||||
|
||||
const auto output = picojson::value{serialized_root}.serialize(true);
|
||||
json_stream << output;
|
||||
}
|
||||
|
||||
void GraphicsModGroupConfig::SetChangeCount(u32 change_count)
|
||||
{
|
||||
m_change_count = change_count;
|
||||
}
|
||||
|
||||
u32 GraphicsModGroupConfig::GetChangeCount() const
|
||||
{
|
||||
return m_change_count;
|
||||
}
|
||||
|
||||
const std::vector<GraphicsModConfig>& GraphicsModGroupConfig::GetMods() const
|
||||
{
|
||||
return m_graphics_mods;
|
||||
}
|
||||
|
||||
GraphicsModConfig* GraphicsModGroupConfig::GetMod(const std::string& absolute_path) const
|
||||
{
|
||||
if (const auto iter = m_path_to_graphics_mod.find(absolute_path);
|
||||
iter != m_path_to_graphics_mod.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::string& GraphicsModGroupConfig::GetGameID() const
|
||||
{
|
||||
return m_game_id;
|
||||
}
|
||||
|
||||
std::string GraphicsModGroupConfig::GetPath() const
|
||||
{
|
||||
const std::string game_mod_root = File::GetUserPath(D_CONFIG_IDX) + GRAPHICSMOD_CONFIG_DIR;
|
||||
return fmt::format("{}/{}.json", game_mod_root, m_game_id);
|
||||
}
|
Reference in New Issue
Block a user