summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon
diff options
context:
space:
mode:
authoriwubcode <iwubcode@users.noreply.github.com>2025-01-25 21:49:32 -0600
committeriwubcode <iwubcode@users.noreply.github.com>2025-03-22 14:53:02 -0500
commitd03f9032c129e440e4f07d319be8b52500798e07 (patch)
tree8be51b82db6cde8050f55bbb35287d83b4de0c85 /Source/Core/InputCommon
parent18979129f35f56de9f87e2a7919788679337abfa (diff)
Core / DolphinQt / InputCommon: reduce the number disk writes when using DynamicInputTextures
Diffstat (limited to 'Source/Core/InputCommon')
-rw-r--r--Source/Core/InputCommon/DynamicInputTextureManager.cpp28
-rw-r--r--Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.cpp42
-rw-r--r--Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.h15
-rw-r--r--Source/Core/InputCommon/InputConfig.cpp23
-rw-r--r--Source/Core/InputCommon/InputConfig.h1
5 files changed, 69 insertions, 40 deletions
diff --git a/Source/Core/InputCommon/DynamicInputTextureManager.cpp b/Source/Core/InputCommon/DynamicInputTextureManager.cpp
index fade2c05d4..af5214bd37 100644
--- a/Source/Core/InputCommon/DynamicInputTextureManager.cpp
+++ b/Source/Core/InputCommon/DynamicInputTextureManager.cpp
@@ -12,6 +12,7 @@
#include "Core/Core.h"
#include "InputCommon/DynamicInputTextures/DITConfiguration.h"
+#include "InputCommon/ImageOperations.h"
#include "VideoCommon/HiresTextures.h"
#include "VideoCommon/TextureCacheBase.h"
@@ -42,9 +43,34 @@ void DynamicInputTextureManager::Load()
void DynamicInputTextureManager::GenerateTextures(const Common::IniFile& file,
const std::vector<std::string>& controller_names)
{
+ DynamicInputTextures::OutputDetails output;
for (const auto& configuration : m_configuration)
{
- (void)configuration.GenerateTextures(file, controller_names);
+ configuration.GenerateTextures(file, controller_names, &output);
+ }
+
+ const std::string& game_id = SConfig::GetInstance().GetGameID();
+ for (const auto& [generated_folder_name, images] : output)
+ {
+ const auto hi_res_folder = File::GetUserPath(D_HIRESTEXTURES_IDX) + generated_folder_name;
+
+ if (!File::IsDirectory(hi_res_folder))
+ {
+ File::CreateDir(hi_res_folder);
+ }
+
+ const auto game_id_folder = hi_res_folder + DIR_SEP + "gameids";
+ if (!File::IsDirectory(game_id_folder))
+ {
+ File::CreateDir(game_id_folder);
+ }
+
+ File::CreateEmptyFile(game_id_folder + DIR_SEP + game_id + ".txt");
+
+ for (const auto& [image_name, image] : images)
+ {
+ WriteImage(hi_res_folder + DIR_SEP + image_name, image);
+ }
}
}
} // namespace InputCommon
diff --git a/Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.cpp b/Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.cpp
index 870dbf9bba..cced429e81 100644
--- a/Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.cpp
+++ b/Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.cpp
@@ -10,7 +10,6 @@
#include <picojson.h>
#include "Common/CommonPaths.h"
-#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Common/JsonUtil.h"
#include "Common/Logging/Log.h"
@@ -68,26 +67,30 @@ Configuration::Configuration(const std::string& json_path)
Configuration::~Configuration() = default;
-bool Configuration::GenerateTextures(const Common::IniFile& file,
- const std::vector<std::string>& controller_names) const
+void Configuration::GenerateTextures(const Common::IniFile& file,
+ const std::vector<std::string>& controller_names,
+ OutputDetails* output) const
{
- bool any_dirty = false;
for (const auto& texture_data : m_dynamic_input_textures)
{
- any_dirty |= GenerateTexture(file, controller_names, texture_data);
+ GenerateTexture(file, controller_names, texture_data, output);
}
-
- return any_dirty;
}
-bool Configuration::GenerateTexture(const Common::IniFile& file,
+void Configuration::GenerateTexture(const Common::IniFile& file,
const std::vector<std::string>& controller_names,
- const Data& texture_data) const
+ const Data& texture_data, OutputDetails* output) const
{
// Two copies of the loaded texture
// The first one is used as a fallback if a key or device isn't mapped
// the second one is used as the final image to write to the textures directory
const auto original_image = LoadImage(m_base_path + texture_data.m_image_name);
+ if (!original_image)
+ {
+ ERROR_LOG_FMT(VIDEO, "Failed to load image '{}' needed for dynamic input texture generation",
+ texture_data.m_image_name);
+ return;
+ }
auto image_to_write = original_image;
bool dirty = false;
@@ -179,25 +182,8 @@ bool Configuration::GenerateTexture(const Common::IniFile& file,
if (dirty)
{
- const std::string& game_id = SConfig::GetInstance().GetGameID();
- const auto hi_res_folder =
- File::GetUserPath(D_HIRESTEXTURES_IDX) + texture_data.m_generated_folder_name;
- if (!File::IsDirectory(hi_res_folder))
- {
- File::CreateDir(hi_res_folder);
- }
- WriteImage(hi_res_folder + DIR_SEP + texture_data.m_hires_texture_name, *image_to_write);
-
- const auto game_id_folder = hi_res_folder + DIR_SEP + "gameids";
- if (!File::IsDirectory(game_id_folder))
- {
- File::CreateDir(game_id_folder);
- }
- File::CreateEmptyFile(game_id_folder + DIR_SEP + game_id + ".txt");
-
- return true;
+ (*output)[texture_data.m_generated_folder_name][texture_data.m_hires_texture_name] =
+ std::move(*image_to_write);
}
-
- return false;
}
} // namespace InputCommon::DynamicInputTextures
diff --git a/Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.h b/Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.h
index 145099ea27..68a55c2af4 100644
--- a/Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.h
+++ b/Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.h
@@ -3,11 +3,13 @@
#pragma once
+#include <map>
#include <string>
#include <vector>
#include "Common/CommonTypes.h"
#include "InputCommon/DynamicInputTextures/DITData.h"
+#include "InputCommon/ImageOperations.h"
namespace Common
{
@@ -16,18 +18,21 @@ class IniFile;
namespace InputCommon::DynamicInputTextures
{
+// Output folder name to image name to image data
+using OutputDetails = std::map<std::string, std::map<std::string, ImagePixelData>>;
class Configuration
{
public:
explicit Configuration(const std::string& json_path);
~Configuration();
- bool GenerateTextures(const Common::IniFile& file,
- const std::vector<std::string>& controller_names) const;
+ void GenerateTextures(const Common::IniFile& file,
+ const std::vector<std::string>& controller_names,
+ OutputDetails* output) const;
private:
- bool GenerateTexture(const Common::IniFile& file,
- const std::vector<std::string>& controller_names,
- const Data& texture_data) const;
+ void GenerateTexture(const Common::IniFile& file,
+ const std::vector<std::string>& controller_names, const Data& texture_data,
+ OutputDetails* output) const;
std::vector<Data> m_dynamic_input_textures;
std::string m_base_path;
diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp
index ff3f68acd0..2dd39f945b 100644
--- a/Source/Core/InputCommon/InputConfig.cpp
+++ b/Source/Core/InputCommon/InputConfig.cpp
@@ -35,8 +35,6 @@ bool InputConfig::LoadConfig()
static constexpr std::array<std::string_view, MAX_BBMOTES> num = {"1", "2", "3", "4", "BB"};
std::string profile[MAX_BBMOTES];
- m_dynamic_input_tex_config_manager.Load();
-
if (SConfig::GetInstance().GetGameID() != "00000000")
{
const std::string profile_directory = GetUserProfileDirectoryPath();
@@ -102,8 +100,6 @@ bool InputConfig::LoadConfig()
// Next profile
n++;
}
-
- m_dynamic_input_tex_config_manager.GenerateTextures(inifile, controller_names);
return true;
}
else
@@ -139,8 +135,6 @@ void InputConfig::SaveConfig()
controller_names.push_back(controller->GetName());
}
- m_dynamic_input_tex_config_manager.GenerateTextures(inifile, controller_names);
-
inifile.Save(ini_filename);
}
@@ -210,6 +204,8 @@ bool InputConfig::IsControllerControlledByGamepadDevice(int index) const
void InputConfig::GenerateControllerTextures(const Common::IniFile& file)
{
+ m_dynamic_input_tex_config_manager.Load();
+
std::vector<std::string> controller_names;
for (auto& controller : m_controllers)
{
@@ -218,3 +214,18 @@ void InputConfig::GenerateControllerTextures(const Common::IniFile& file)
m_dynamic_input_tex_config_manager.GenerateTextures(file, controller_names);
}
+
+void InputConfig::GenerateControllerTextures()
+{
+ const std::string ini_filename = File::GetUserPath(D_CONFIG_IDX) + m_ini_name + ".ini";
+
+ Common::IniFile inifile;
+ inifile.Load(ini_filename);
+
+ for (auto& controller : m_controllers)
+ {
+ controller->SaveConfig(inifile.GetOrCreateSection(controller->GetName()));
+ }
+
+ GenerateControllerTextures(inifile);
+}
diff --git a/Source/Core/InputCommon/InputConfig.h b/Source/Core/InputCommon/InputConfig.h
index 09b9f6c182..6cd428a8d8 100644
--- a/Source/Core/InputCommon/InputConfig.h
+++ b/Source/Core/InputCommon/InputConfig.h
@@ -55,6 +55,7 @@ public:
void UnregisterHotplugCallback();
void GenerateControllerTextures(const Common::IniFile& file);
+ void GenerateControllerTextures();
private:
ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle;