mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Core / DolphinQt / InputCommon: reduce the number disk writes when using DynamicInputTextures
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ public:
|
||||
void UnregisterHotplugCallback();
|
||||
|
||||
void GenerateControllerTextures(const Common::IniFile& file);
|
||||
void GenerateControllerTextures();
|
||||
|
||||
private:
|
||||
ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle;
|
||||
|
Reference in New Issue
Block a user