diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsMod.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsMod.cpp index b04190ad67..6a62f5768d 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsMod.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsMod.cpp @@ -112,6 +112,42 @@ std::string GraphicsModConfig::GetAbsolutePath() const } } +void GraphicsModConfig::SerializeToConfig(picojson::object& json_obj) const +{ + picojson::object serialized_metadata; + serialized_metadata["title"] = picojson::value{m_title}; + serialized_metadata["author"] = picojson::value{m_author}; + serialized_metadata["description"] = picojson::value{m_description}; + json_obj["meta"] = picojson::value{serialized_metadata}; + + picojson::array serialized_groups; + for (const auto& group : m_groups) + { + picojson::object serialized_group; + group.SerializeToConfig(serialized_group); + serialized_groups.push_back(picojson::value{serialized_group}); + } + json_obj["groups"] = picojson::value{serialized_groups}; + + picojson::array serialized_features; + for (const auto& feature : m_features) + { + picojson::object serialized_feature; + feature.SerializeToConfig(serialized_feature); + serialized_features.push_back(picojson::value{serialized_feature}); + } + json_obj["features"] = picojson::value{serialized_features}; + + picojson::array serialized_assets; + for (const auto& asset : m_assets) + { + picojson::object serialized_asset; + asset.SerializeToConfig(serialized_asset); + serialized_assets.push_back(picojson::value{serialized_asset}); + } + json_obj["assets"] = picojson::value{serialized_assets}; +} + bool GraphicsModConfig::DeserializeFromConfig(const picojson::value& value) { const auto& meta = value.get("meta"); diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsMod.h b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsMod.h index 953af6201b..fd35b963dd 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsMod.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsMod.h @@ -38,6 +38,7 @@ struct GraphicsModConfig std::string GetAbsolutePath() const; + void SerializeToConfig(picojson::object& json_obj) const; bool DeserializeFromConfig(const picojson::value& value); void SerializeToProfile(picojson::object* value) const; diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.cpp index 5b3141a283..4b51c1c367 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.cpp @@ -4,6 +4,19 @@ #include "VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h" #include "Common/Logging/Log.h" +#include "Common/StringUtil.h" + +void GraphicsModAssetConfig::SerializeToConfig(picojson::object& json_obj) const +{ + json_obj["name"] = picojson::value{m_asset_id}; + + picojson::object serialized_data; + for (const auto& [name, path] : m_map) + { + serialized_data[name] = picojson::value{PathToString(path)}; + } + json_obj["data"] = picojson::value{serialized_data}; +} bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj) { @@ -19,13 +32,13 @@ bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj) "that is not a string"); return false; } - m_name = name_iter->second.to_str(); + m_asset_id = name_iter->second.to_str(); auto data_iter = obj.find("data"); if (data_iter == obj.end()) { ERROR_LOG_FMT(VIDEO, "Failed to load mod configuration file, specified asset '{}' has no data", - m_name); + m_asset_id); return false; } if (!data_iter->second.is()) @@ -33,7 +46,7 @@ bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj) ERROR_LOG_FMT(VIDEO, "Failed to load mod configuration file, specified asset '{}' has data " "that is not an object", - m_name); + m_asset_id); return false; } for (const auto& [key, value] : data_iter->second.get()) @@ -43,7 +56,7 @@ bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj) ERROR_LOG_FMT(VIDEO, "Failed to load mod configuration file, specified asset '{}' has data " "with a value for key '{}' that is not a string", - m_name, key); + m_asset_id, key); return false; } m_map[key] = value.to_str(); diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h index b38ba792cc..53d8d71892 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h @@ -11,8 +11,9 @@ struct GraphicsModAssetConfig { - std::string m_name; + VideoCommon::CustomAssetLibrary::AssetID m_asset_id; VideoCommon::DirectFilesystemAssetLibrary::AssetMap m_map; + void SerializeToConfig(picojson::object& json_obj) const; bool DeserializeFromConfig(const picojson::object& obj); }; diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.cpp index 3fa75eceba..cc889f70cb 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.cpp @@ -5,6 +5,13 @@ #include "Common/Logging/Log.h" +void GraphicsModFeatureConfig::SerializeToConfig(picojson::object& json_obj) const +{ + json_obj["group"] = picojson::value{m_group}; + json_obj["action"] = picojson::value{m_action}; + json_obj["action_data"] = m_action_data; +} + bool GraphicsModFeatureConfig::DeserializeFromConfig(const picojson::object& obj) { if (auto group_iter = obj.find("group"); group_iter != obj.end()) diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.h b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.h index af71bf35a7..5204eaef57 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsModFeature.h @@ -13,6 +13,7 @@ struct GraphicsModFeatureConfig std::string m_action; picojson::value m_action_data; + void SerializeToConfig(picojson::object& json_obj) const; bool DeserializeFromConfig(const picojson::object& value); void SerializeToProfile(picojson::object* value) const; diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTarget.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTarget.cpp index 374b138571..575a318484 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTarget.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTarget.cpp @@ -5,6 +5,7 @@ #include "Common/Logging/Log.h" #include "Common/StringUtil.h" +#include "Common/VariantUtil.h" #include "VideoCommon/TextureCacheBase.h" namespace @@ -152,6 +153,53 @@ std::optional ExtractTextureFilenameForConfig(const picojson::objec } } // namespace +void SerializeTargetToConfig(picojson::object& json_obj, const GraphicsTargetConfig& target) +{ + std::visit( + overloaded{ + [&](const DrawStartedTextureTarget& the_target) { + json_obj["type"] = picojson::value{"draw_started"}; + json_obj["texture_filename"] = picojson::value{the_target.m_texture_info_string}; + }, + [&](const LoadTextureTarget& the_target) { + json_obj["type"] = picojson::value{"load_texture"}; + json_obj["texture_filename"] = picojson::value{the_target.m_texture_info_string}; + }, + [&](const CreateTextureTarget& the_target) { + json_obj["type"] = picojson::value{"create_texture"}; + json_obj["texture_filename"] = picojson::value{the_target.m_texture_info_string}; + }, + [&](const EFBTarget& the_target) { + json_obj["type"] = picojson::value{"efb"}; + json_obj["texture_filename"] = picojson::value{ + fmt::format("{}_{}x{}_{}", EFB_DUMP_PREFIX, the_target.m_width, the_target.m_height, + static_cast(the_target.m_texture_format))}; + }, + [&](const XFBTarget& the_target) { + json_obj["type"] = picojson::value{"xfb"}; + json_obj["texture_filename"] = picojson::value{ + fmt::format("{}_{}x{}_{}", XFB_DUMP_PREFIX, the_target.m_width, the_target.m_height, + static_cast(the_target.m_texture_format))}; + }, + [&](const ProjectionTarget& the_target) { + json_obj["type"] = picojson::value{"projection"}; + if (the_target.m_projection_type == ProjectionType::Orthographic) + { + json_obj["type"] = picojson::value{"2d"}; + } + else + { + json_obj["type"] = picojson::value{"3d"}; + } + if (the_target.m_texture_info_string) + { + json_obj["texture_filename"] = picojson::value{*the_target.m_texture_info_string}; + } + }, + }, + target); +} + std::optional DeserializeTargetFromConfig(const picojson::object& obj) { const auto type_iter = obj.find("type"); diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTarget.h b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTarget.h index bde445258c..740da00727 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTarget.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTarget.h @@ -55,6 +55,7 @@ using GraphicsTargetConfig = std::variant; +void SerializeTargetToConfig(picojson::object& json_obj, const GraphicsTargetConfig& target); std::optional DeserializeTargetFromConfig(const picojson::object& obj); void SerializeTargetToProfile(picojson::object* obj, const GraphicsTargetConfig& target); diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.cpp index 753f304cb5..f02a047339 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.cpp @@ -5,6 +5,19 @@ #include "Common/Logging/Log.h" +void GraphicsTargetGroupConfig::SerializeToConfig(picojson::object& json_obj) const +{ + picojson::array serialized_targets; + for (const auto& target : m_targets) + { + picojson::object serialized_target; + SerializeTargetToConfig(serialized_target, target); + serialized_targets.push_back(picojson::value{serialized_target}); + } + json_obj["targets"] = picojson::value{serialized_targets}; + json_obj["name"] = picojson::value{m_name}; +} + bool GraphicsTargetGroupConfig::DeserializeFromConfig(const picojson::object& obj) { if (auto name_iter = obj.find("name"); name_iter != obj.end()) diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.h b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.h index 2db2517175..d0034ef30b 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Config/GraphicsTargetGroup.h @@ -15,6 +15,7 @@ struct GraphicsTargetGroupConfig std::string m_name; std::vector m_targets; + void SerializeToConfig(picojson::object& json_obj) const; bool DeserializeFromConfig(const picojson::object& obj); void SerializeToProfile(picojson::object* obj) const; diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.cpp index 0d2f0fe347..01e7a07033 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.cpp @@ -225,7 +225,7 @@ void GraphicsModManager::Load(const GraphicsModGroupConfig& config) WARN_LOG_FMT(VIDEO, "Specified graphics mod asset '{}' for mod '{}' has an absolute path, you " "shouldn't release this to users.", - asset.m_name, mod.m_title); + asset.m_asset_id, mod.m_title); } else { @@ -233,7 +233,7 @@ void GraphicsModManager::Load(const GraphicsModGroupConfig& config) } } - filesystem_library->SetAssetIDMapData(asset.m_name, std::move(asset_map)); + filesystem_library->SetAssetIDMapData(asset.m_asset_id, std::move(asset_map)); } }