Skip to content

Commit

Permalink
Core / DolphinQt / InputCommon: reduce the number disk writes when us…
Browse files Browse the repository at this point in the history
…ing DynamicInputTextures
  • Loading branch information
iwubcode committed Jan 26, 2025
1 parent 56b7b0a commit 56bef66
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 40 deletions.
3 changes: 3 additions & 0 deletions Source/Core/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,10 @@ static void EmuThread(Core::System& system, std::unique_ptr<BootParameters> boot
g_controller_interface.ChangeWindow(wsi.render_window);

Pad::LoadConfig();
Pad::GenerateDynamicInputTextures();
Pad::LoadGBAConfig();
Keyboard::LoadConfig();
Keyboard::GenerateDynamicInputTextures();

BootSessionData boot_session_data = std::move(boot->boot_session_data);
const std::optional<std::string>& savestate_path = boot_session_data.GetSavestatePath();
Expand Down Expand Up @@ -546,6 +548,7 @@ static void EmuThread(Core::System& system, std::unique_ptr<BootParameters> boot
if (system.IsWii() && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
{
Wiimote::LoadConfig();
Wiimote::GenerateDynamicInputTextures();
}

FreeLook::LoadInputConfig();
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/Core/HW/GCKeyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ void LoadConfig()
s_config.LoadConfig();
}

void GenerateDynamicInputTextures()
{
s_config.GenerateControllerTextures();
}

ControllerEmu::ControlGroup* GetGroup(int port, KeyboardGroup group)
{
return static_cast<GCKeyboard*>(s_config.GetController(port))->GetGroup(group);
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/HW/GCKeyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace Keyboard
void Shutdown();
void Initialize();
void LoadConfig();
void GenerateDynamicInputTextures();

InputConfig* GetConfig();
ControllerEmu::ControlGroup* GetGroup(int port, KeyboardGroup group);
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/Core/HW/GCPad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ void LoadConfig()
s_config.LoadConfig();
}

void GenerateDynamicInputTextures()
{
s_config.GenerateControllerTextures();
}

bool IsInitialized()
{
return !s_config.ControllersNeedToBeCreated();
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/HW/GCPad.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Pad
void Shutdown();
void Initialize();
void LoadConfig();
void GenerateDynamicInputTextures();
bool IsInitialized();

InputConfig* GetConfig();
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/Core/HW/Wiimote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ void LoadConfig()
s_last_connect_request_counter.fill(0);
}

void GenerateDynamicInputTextures()
{
s_config.GenerateControllerTextures();
}

void Resume()
{
WiimoteReal::Resume();
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/HW/Wiimote.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void Shutdown();
void Initialize(InitializeMode init_mode);
void ResetAllWiimotes();
void LoadConfig();
void GenerateDynamicInputTextures();
void Resume();
void Pause();

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/Config/Mapping/MappingCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "InputCommon/ControllerEmu/ControllerEmu.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "InputCommon/ControllerInterface/MappingCommon.h"
#include "InputCommon/InputConfig.h"

namespace MappingCommon
{
Expand Down Expand Up @@ -88,6 +89,7 @@ class MappingProcessor : public QWidget

m_parent->GetController()->UpdateSingleControlReference(g_controller_interface,
control_reference);
m_parent->GetController()->GetConfig()->GenerateControllerTextures();
UnQueueInputDetection(button);
}
}
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ void MappingWindow::OnLoadProfilePressed()

m_controller->LoadConfig(ini.GetOrCreateSection("Profile"));
m_controller->UpdateReferences(g_controller_interface);
m_controller->GetConfig()->GenerateControllerTextures();

const auto lock = GetController()->GetStateLock();
emit ConfigChanged();
Expand Down Expand Up @@ -543,6 +544,7 @@ void MappingWindow::OnDefaultFieldsPressed()
{
m_controller->LoadDefaults(g_controller_interface);
m_controller->UpdateReferences(g_controller_interface);
m_controller->GetConfig()->GenerateControllerTextures();

const auto lock = GetController()->GetStateLock();
emit ConfigChanged();
Expand All @@ -560,6 +562,7 @@ void MappingWindow::OnClearFieldsPressed()
m_controller->SetDefaultDevice(default_device);

m_controller->UpdateReferences(g_controller_interface);
m_controller->GetConfig()->GenerateControllerTextures();

const auto lock = GetController()->GetStateLock();
emit ConfigChanged();
Expand Down
28 changes: 27 additions & 1 deletion Source/Core/InputCommon/DynamicInputTextureManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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);
(void)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
42 changes: 14 additions & 28 deletions Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
15 changes: 10 additions & 5 deletions Source/Core/InputCommon/DynamicInputTextures/DITConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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;
Expand Down
25 changes: 19 additions & 6 deletions Source/Core/InputCommon/InputConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -102,8 +100,6 @@ bool InputConfig::LoadConfig()
// Next profile
n++;
}

m_dynamic_input_tex_config_manager.GenerateTextures(inifile, controller_names);
return true;
}
else
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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)
{
Expand All @@ -218,3 +214,20 @@ void InputConfig::GenerateControllerTextures(const Common::IniFile& file)

m_dynamic_input_tex_config_manager.GenerateTextures(file, controller_names);
}

void InputConfig::GenerateControllerTextures()
{
std::string ini_filename = File::GetUserPath(D_CONFIG_IDX) + m_ini_name + ".ini";

Common::IniFile inifile;
inifile.Load(ini_filename);

std::vector<std::string> controller_names;
for (auto& controller : m_controllers)
{
controller->SaveConfig(inifile.GetOrCreateSection(controller->GetName()));
controller_names.push_back(controller->GetName());
}

GenerateControllerTextures(inifile);
}
1 change: 1 addition & 0 deletions Source/Core/InputCommon/InputConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class InputConfig
void UnregisterHotplugCallback();

void GenerateControllerTextures(const Common::IniFile& file);
void GenerateControllerTextures();

private:
ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle;
Expand Down

0 comments on commit 56bef66

Please sign in to comment.