mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-25 06:44:59 +00:00
Merge pull request #13311 from iwubcode/dynamic_input_textures_reduce_image_writes
Core / DolphinQt / InputCommon: reduce the number disk writes when using DynamicInputTextures
This commit is contained in:
commit
2da255d8cd
21 changed files with 155 additions and 59 deletions
|
@ -88,8 +88,10 @@ JNIEXPORT void JNICALL
|
||||||
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_updateSingleControlReference(
|
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_updateSingleControlReference(
|
||||||
JNIEnv* env, jobject obj, jobject control_reference)
|
JNIEnv* env, jobject obj, jobject control_reference)
|
||||||
{
|
{
|
||||||
return EmulatedControllerFromJava(env, obj)->UpdateSingleControlReference(
|
ControllerEmu::EmulatedController* controller = EmulatedControllerFromJava(env, obj);
|
||||||
g_controller_interface, ControlReferenceFromJava(env, control_reference));
|
controller->GetConfig()->GenerateControllerTextures();
|
||||||
|
return controller->UpdateSingleControlReference(g_controller_interface,
|
||||||
|
ControlReferenceFromJava(env, control_reference));
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
|
@ -100,6 +102,7 @@ Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedContro
|
||||||
|
|
||||||
controller->LoadDefaults(g_controller_interface);
|
controller->LoadDefaults(g_controller_interface);
|
||||||
controller->UpdateReferences(g_controller_interface);
|
controller->UpdateReferences(g_controller_interface);
|
||||||
|
controller->GetConfig()->GenerateControllerTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
|
@ -113,6 +116,7 @@ Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedContro
|
||||||
|
|
||||||
controller->LoadConfig(§ion);
|
controller->LoadConfig(§ion);
|
||||||
controller->UpdateReferences(g_controller_interface);
|
controller->UpdateReferences(g_controller_interface);
|
||||||
|
controller->GetConfig()->GenerateControllerTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
|
@ -126,6 +130,7 @@ Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedContro
|
||||||
|
|
||||||
controller->LoadConfig(ini.GetOrCreateSection("Profile"));
|
controller->LoadConfig(ini.GetOrCreateSection("Profile"));
|
||||||
controller->UpdateReferences(g_controller_interface);
|
controller->UpdateReferences(g_controller_interface);
|
||||||
|
controller->GetConfig()->GenerateControllerTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
|
|
|
@ -550,7 +550,7 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
|
||||||
if (!EmulatedBS2(system, guard, system.IsWii(), *volume, riivolution_patches))
|
if (!EmulatedBS2(system, guard, system.IsWii(), *volume, riivolution_patches))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SConfig::OnNewTitleLoad(guard);
|
SConfig::OnTitleDirectlyBooted(guard);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,7 +601,7 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SConfig::OnNewTitleLoad(guard);
|
SConfig::OnTitleDirectlyBooted(guard);
|
||||||
|
|
||||||
ppc_state.pc = executable.reader->GetEntryPoint();
|
ppc_state.pc = executable.reader->GetEntryPoint();
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
|
||||||
if (!Boot_WiiWAD(system, wad))
|
if (!Boot_WiiWAD(system, wad))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SConfig::OnNewTitleLoad(guard);
|
SConfig::OnTitleDirectlyBooted(guard);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +631,7 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
|
||||||
if (!BootNANDTitle(system, nand_title.id))
|
if (!BootNANDTitle(system, nand_title.id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SConfig::OnNewTitleLoad(guard);
|
SConfig::OnTitleDirectlyBooted(guard);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,7 +657,7 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
|
||||||
ipl.disc->auto_disc_change_paths);
|
ipl.disc->auto_disc_change_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
SConfig::OnNewTitleLoad(guard);
|
SConfig::OnTitleDirectlyBooted(guard);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,11 @@
|
||||||
#include "Core/HLE/HLE.h"
|
#include "Core/HLE/HLE.h"
|
||||||
#include "Core/HW/DVD/DVDInterface.h"
|
#include "Core/HW/DVD/DVDInterface.h"
|
||||||
#include "Core/HW/EXI/EXI_Device.h"
|
#include "Core/HW/EXI/EXI_Device.h"
|
||||||
|
#include "Core/HW/GCKeyboard.h"
|
||||||
|
#include "Core/HW/GCPad.h"
|
||||||
#include "Core/HW/SI/SI.h"
|
#include "Core/HW/SI/SI.h"
|
||||||
#include "Core/HW/SI/SI_Device.h"
|
#include "Core/HW/SI/SI_Device.h"
|
||||||
|
#include "Core/HW/Wiimote.h"
|
||||||
#include "Core/Host.h"
|
#include "Core/Host.h"
|
||||||
#include "Core/IOS/ES/ES.h"
|
#include "Core/IOS/ES/ES.h"
|
||||||
#include "Core/IOS/ES/Formats.h"
|
#include "Core/IOS/ES/Formats.h"
|
||||||
|
@ -239,7 +242,20 @@ void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::stri
|
||||||
DolphinAnalytics::Instance().ReportGameStart();
|
DolphinAnalytics::Instance().ReportGameStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SConfig::OnNewTitleLoad(const Core::CPUThreadGuard& guard)
|
void SConfig::OnESTitleChanged()
|
||||||
|
{
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
Pad::LoadConfig();
|
||||||
|
Keyboard::LoadConfig();
|
||||||
|
if (system.IsWii() && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
|
||||||
|
{
|
||||||
|
Wiimote::LoadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReloadTextures(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SConfig::OnTitleDirectlyBooted(const Core::CPUThreadGuard& guard)
|
||||||
{
|
{
|
||||||
auto& system = guard.GetSystem();
|
auto& system = guard.GetSystem();
|
||||||
if (!Core::IsRunningOrStarting(system))
|
if (!Core::IsRunningOrStarting(system))
|
||||||
|
@ -253,9 +269,27 @@ void SConfig::OnNewTitleLoad(const Core::CPUThreadGuard& guard)
|
||||||
}
|
}
|
||||||
CBoot::LoadMapFromFilename(guard, ppc_symbol_db);
|
CBoot::LoadMapFromFilename(guard, ppc_symbol_db);
|
||||||
HLE::Reload(system);
|
HLE::Reload(system);
|
||||||
|
|
||||||
PatchEngine::Reload(system);
|
PatchEngine::Reload(system);
|
||||||
HiresTexture::Update();
|
|
||||||
WC24PatchEngine::Reload();
|
WC24PatchEngine::Reload();
|
||||||
|
|
||||||
|
// Note: Wii is handled by ES title change
|
||||||
|
if (!system.IsWii())
|
||||||
|
{
|
||||||
|
ReloadTextures(system);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SConfig::ReloadTextures(Core::System& system)
|
||||||
|
{
|
||||||
|
Pad::GenerateDynamicInputTextures();
|
||||||
|
Keyboard::GenerateDynamicInputTextures();
|
||||||
|
if (system.IsWii() && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
|
||||||
|
{
|
||||||
|
Wiimote::GenerateDynamicInputTextures();
|
||||||
|
}
|
||||||
|
|
||||||
|
HiresTexture::Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SConfig::LoadDefaults()
|
void SConfig::LoadDefaults()
|
||||||
|
|
|
@ -73,9 +73,15 @@ struct SConfig
|
||||||
void SetRunningGameMetadata(const DiscIO::Volume& volume, const DiscIO::Partition& partition);
|
void SetRunningGameMetadata(const DiscIO::Volume& volume, const DiscIO::Partition& partition);
|
||||||
void SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Platform platform);
|
void SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Platform platform);
|
||||||
void SetRunningGameMetadata(const std::string& game_id);
|
void SetRunningGameMetadata(const std::string& game_id);
|
||||||
// Reloads title-specific map files, patches, custom textures, etc.
|
|
||||||
// This should only be called after the new title has been loaded into memory.
|
// Triggered when Dolphin loads a title directly
|
||||||
static void OnNewTitleLoad(const Core::CPUThreadGuard& guard);
|
// Reloads title-specific map files, patches, etc.
|
||||||
|
static void OnTitleDirectlyBooted(const Core::CPUThreadGuard& guard);
|
||||||
|
|
||||||
|
// Direct title change from ES (Wii system)
|
||||||
|
// Wii titles will still hit OnTitleDirectlyBooted
|
||||||
|
// but GC titles will never see this call
|
||||||
|
static void OnESTitleChanged();
|
||||||
|
|
||||||
void LoadDefaults();
|
void LoadDefaults();
|
||||||
static std::string MakeGameID(std::string_view file_name);
|
static std::string MakeGameID(std::string_view file_name);
|
||||||
|
@ -112,6 +118,8 @@ private:
|
||||||
SConfig();
|
SConfig();
|
||||||
~SConfig();
|
~SConfig();
|
||||||
|
|
||||||
|
static void ReloadTextures(Core::System& system);
|
||||||
|
|
||||||
void SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id,
|
void SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id,
|
||||||
u64 title_id, u16 revision, DiscIO::Region region);
|
u64 title_id, u16 revision, DiscIO::Region region);
|
||||||
|
|
||||||
|
|
|
@ -524,11 +524,7 @@ static void EmuThread(Core::System& system, std::unique_ptr<BootParameters> boot
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// Load Wiimotes - only if we are booting in Wii mode
|
// Wiimote input config is loaded in OnESTitleChanged
|
||||||
if (system.IsWii() && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
|
|
||||||
{
|
|
||||||
Wiimote::LoadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeLook::LoadInputConfig();
|
FreeLook::LoadInputConfig();
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,11 @@ void LoadConfig()
|
||||||
s_config.LoadConfig();
|
s_config.LoadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateDynamicInputTextures()
|
||||||
|
{
|
||||||
|
s_config.GenerateControllerTextures();
|
||||||
|
}
|
||||||
|
|
||||||
ControllerEmu::ControlGroup* GetGroup(int port, KeyboardGroup group)
|
ControllerEmu::ControlGroup* GetGroup(int port, KeyboardGroup group)
|
||||||
{
|
{
|
||||||
return static_cast<GCKeyboard*>(s_config.GetController(port))->GetGroup(group);
|
return static_cast<GCKeyboard*>(s_config.GetController(port))->GetGroup(group);
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace Keyboard
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void LoadConfig();
|
void LoadConfig();
|
||||||
|
void GenerateDynamicInputTextures();
|
||||||
|
|
||||||
InputConfig* GetConfig();
|
InputConfig* GetConfig();
|
||||||
ControllerEmu::ControlGroup* GetGroup(int port, KeyboardGroup group);
|
ControllerEmu::ControlGroup* GetGroup(int port, KeyboardGroup group);
|
||||||
|
|
|
@ -46,6 +46,11 @@ void LoadConfig()
|
||||||
s_config.LoadConfig();
|
s_config.LoadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateDynamicInputTextures()
|
||||||
|
{
|
||||||
|
s_config.GenerateControllerTextures();
|
||||||
|
}
|
||||||
|
|
||||||
bool IsInitialized()
|
bool IsInitialized()
|
||||||
{
|
{
|
||||||
return !s_config.ControllersNeedToBeCreated();
|
return !s_config.ControllersNeedToBeCreated();
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace Pad
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void LoadConfig();
|
void LoadConfig();
|
||||||
|
void GenerateDynamicInputTextures();
|
||||||
bool IsInitialized();
|
bool IsInitialized();
|
||||||
|
|
||||||
InputConfig* GetConfig();
|
InputConfig* GetConfig();
|
||||||
|
|
|
@ -211,6 +211,11 @@ void LoadConfig()
|
||||||
s_last_connect_request_counter.fill(0);
|
s_last_connect_request_counter.fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateDynamicInputTextures()
|
||||||
|
{
|
||||||
|
s_config.GenerateControllerTextures();
|
||||||
|
}
|
||||||
|
|
||||||
void Resume()
|
void Resume()
|
||||||
{
|
{
|
||||||
WiimoteReal::Resume();
|
WiimoteReal::Resume();
|
||||||
|
|
|
@ -78,6 +78,7 @@ void Shutdown();
|
||||||
void Initialize(InitializeMode init_mode);
|
void Initialize(InitializeMode init_mode);
|
||||||
void ResetAllWiimotes();
|
void ResetAllWiimotes();
|
||||||
void LoadConfig();
|
void LoadConfig();
|
||||||
|
void GenerateDynamicInputTextures();
|
||||||
void Resume();
|
void Resume();
|
||||||
void Pause();
|
void Pause();
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,7 @@ void TitleContext::Update(const ES::TMDReader& tmd_, const ES::TicketReader& tic
|
||||||
if (first_change)
|
if (first_change)
|
||||||
{
|
{
|
||||||
SConfig::GetInstance().SetRunningGameMetadata(tmd, platform);
|
SConfig::GetInstance().SetRunningGameMetadata(tmd, platform);
|
||||||
|
SConfig::GetInstance().OnESTitleChanged();
|
||||||
first_change = false;
|
first_change = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -952,7 +952,7 @@ static void FinishPPCBootstrap(Core::System& system, u64 userdata, s64 cycles_la
|
||||||
|
|
||||||
ASSERT(Core::IsCPUThread());
|
ASSERT(Core::IsCPUThread());
|
||||||
Core::CPUThreadGuard guard(system);
|
Core::CPUThreadGuard guard(system);
|
||||||
SConfig::OnNewTitleLoad(guard);
|
SConfig::OnTitleDirectlyBooted(guard);
|
||||||
|
|
||||||
INFO_LOG_FMT(IOS, "Bootstrapping done.");
|
INFO_LOG_FMT(IOS, "Bootstrapping done.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ bool Load(Core::System& system)
|
||||||
NOTICE_LOG_FMT(IOS, "IPL ready.");
|
NOTICE_LOG_FMT(IOS, "IPL ready.");
|
||||||
system.SetIsMIOS(true);
|
system.SetIsMIOS(true);
|
||||||
system.GetDVDInterface().UpdateRunningGameMetadata();
|
system.GetDVDInterface().UpdateRunningGameMetadata();
|
||||||
SConfig::OnNewTitleLoad(guard);
|
SConfig::OnTitleDirectlyBooted(guard);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // namespace IOS::HLE::MIOS
|
} // namespace IOS::HLE::MIOS
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "InputCommon/ControllerEmu/ControllerEmu.h"
|
#include "InputCommon/ControllerEmu/ControllerEmu.h"
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
#include "InputCommon/ControllerInterface/MappingCommon.h"
|
#include "InputCommon/ControllerInterface/MappingCommon.h"
|
||||||
|
#include "InputCommon/InputConfig.h"
|
||||||
|
|
||||||
namespace MappingCommon
|
namespace MappingCommon
|
||||||
{
|
{
|
||||||
|
@ -135,6 +136,7 @@ public:
|
||||||
m_parent->Save();
|
m_parent->Save();
|
||||||
m_parent->GetController()->UpdateSingleControlReference(g_controller_interface,
|
m_parent->GetController()->UpdateSingleControlReference(g_controller_interface,
|
||||||
control_reference);
|
control_reference);
|
||||||
|
m_parent->GetController()->GetConfig()->GenerateControllerTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateInputDetectionStartTimer()
|
void UpdateInputDetectionStartTimer()
|
||||||
|
|
|
@ -322,6 +322,7 @@ void MappingWindow::OnLoadProfilePressed()
|
||||||
|
|
||||||
m_controller->LoadConfig(ini.GetOrCreateSection("Profile"));
|
m_controller->LoadConfig(ini.GetOrCreateSection("Profile"));
|
||||||
m_controller->UpdateReferences(g_controller_interface);
|
m_controller->UpdateReferences(g_controller_interface);
|
||||||
|
m_controller->GetConfig()->GenerateControllerTextures();
|
||||||
|
|
||||||
const auto lock = GetController()->GetStateLock();
|
const auto lock = GetController()->GetStateLock();
|
||||||
emit ConfigChanged();
|
emit ConfigChanged();
|
||||||
|
@ -561,6 +562,7 @@ void MappingWindow::OnDefaultFieldsPressed()
|
||||||
{
|
{
|
||||||
m_controller->LoadDefaults(g_controller_interface);
|
m_controller->LoadDefaults(g_controller_interface);
|
||||||
m_controller->UpdateReferences(g_controller_interface);
|
m_controller->UpdateReferences(g_controller_interface);
|
||||||
|
m_controller->GetConfig()->GenerateControllerTextures();
|
||||||
|
|
||||||
const auto lock = GetController()->GetStateLock();
|
const auto lock = GetController()->GetStateLock();
|
||||||
emit ConfigChanged();
|
emit ConfigChanged();
|
||||||
|
@ -578,6 +580,7 @@ void MappingWindow::OnClearFieldsPressed()
|
||||||
m_controller->SetDefaultDevice(default_device);
|
m_controller->SetDefaultDevice(default_device);
|
||||||
|
|
||||||
m_controller->UpdateReferences(g_controller_interface);
|
m_controller->UpdateReferences(g_controller_interface);
|
||||||
|
m_controller->GetConfig()->GenerateControllerTextures();
|
||||||
|
|
||||||
const auto lock = GetController()->GetStateLock();
|
const auto lock = GetController()->GetStateLock();
|
||||||
emit ConfigChanged();
|
emit ConfigChanged();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
|
|
||||||
#include "InputCommon/DynamicInputTextures/DITConfiguration.h"
|
#include "InputCommon/DynamicInputTextures/DITConfiguration.h"
|
||||||
|
#include "InputCommon/ImageOperations.h"
|
||||||
#include "VideoCommon/HiresTextures.h"
|
#include "VideoCommon/HiresTextures.h"
|
||||||
#include "VideoCommon/TextureCacheBase.h"
|
#include "VideoCommon/TextureCacheBase.h"
|
||||||
|
|
||||||
|
@ -42,9 +43,34 @@ void DynamicInputTextureManager::Load()
|
||||||
void DynamicInputTextureManager::GenerateTextures(const Common::IniFile& file,
|
void DynamicInputTextureManager::GenerateTextures(const Common::IniFile& file,
|
||||||
const std::vector<std::string>& controller_names)
|
const std::vector<std::string>& controller_names)
|
||||||
{
|
{
|
||||||
|
DynamicInputTextures::OutputDetails output;
|
||||||
for (const auto& configuration : m_configuration)
|
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
|
} // namespace InputCommon
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <picojson.h>
|
#include <picojson.h>
|
||||||
|
|
||||||
#include "Common/CommonPaths.h"
|
#include "Common/CommonPaths.h"
|
||||||
#include "Common/FileUtil.h"
|
|
||||||
#include "Common/IniFile.h"
|
#include "Common/IniFile.h"
|
||||||
#include "Common/JsonUtil.h"
|
#include "Common/JsonUtil.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
@ -68,26 +67,30 @@ Configuration::Configuration(const std::string& json_path)
|
||||||
|
|
||||||
Configuration::~Configuration() = default;
|
Configuration::~Configuration() = default;
|
||||||
|
|
||||||
bool Configuration::GenerateTextures(const Common::IniFile& file,
|
void Configuration::GenerateTextures(const Common::IniFile& file,
|
||||||
const std::vector<std::string>& controller_names) const
|
const std::vector<std::string>& controller_names,
|
||||||
|
OutputDetails* output) const
|
||||||
{
|
{
|
||||||
bool any_dirty = false;
|
|
||||||
for (const auto& texture_data : m_dynamic_input_textures)
|
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;
|
void Configuration::GenerateTexture(const Common::IniFile& file,
|
||||||
}
|
|
||||||
|
|
||||||
bool Configuration::GenerateTexture(const Common::IniFile& file,
|
|
||||||
const std::vector<std::string>& controller_names,
|
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
|
// Two copies of the loaded texture
|
||||||
// The first one is used as a fallback if a key or device isn't mapped
|
// 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
|
// 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);
|
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;
|
auto image_to_write = original_image;
|
||||||
|
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
@ -179,25 +182,8 @@ bool Configuration::GenerateTexture(const Common::IniFile& file,
|
||||||
|
|
||||||
if (dirty)
|
if (dirty)
|
||||||
{
|
{
|
||||||
const std::string& game_id = SConfig::GetInstance().GetGameID();
|
(*output)[texture_data.m_generated_folder_name][texture_data.m_hires_texture_name] =
|
||||||
const auto hi_res_folder =
|
std::move(*image_to_write);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} // namespace InputCommon::DynamicInputTextures
|
} // namespace InputCommon::DynamicInputTextures
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "InputCommon/DynamicInputTextures/DITData.h"
|
#include "InputCommon/DynamicInputTextures/DITData.h"
|
||||||
|
#include "InputCommon/ImageOperations.h"
|
||||||
|
|
||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
|
@ -16,18 +18,21 @@ class IniFile;
|
||||||
|
|
||||||
namespace InputCommon::DynamicInputTextures
|
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
|
class Configuration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Configuration(const std::string& json_path);
|
explicit Configuration(const std::string& json_path);
|
||||||
~Configuration();
|
~Configuration();
|
||||||
bool GenerateTextures(const Common::IniFile& file,
|
void GenerateTextures(const Common::IniFile& file,
|
||||||
const std::vector<std::string>& controller_names) const;
|
const std::vector<std::string>& controller_names,
|
||||||
|
OutputDetails* output) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool GenerateTexture(const Common::IniFile& file,
|
void GenerateTexture(const Common::IniFile& file,
|
||||||
const std::vector<std::string>& controller_names,
|
const std::vector<std::string>& controller_names, const Data& texture_data,
|
||||||
const Data& texture_data) const;
|
OutputDetails* output) const;
|
||||||
|
|
||||||
std::vector<Data> m_dynamic_input_textures;
|
std::vector<Data> m_dynamic_input_textures;
|
||||||
std::string m_base_path;
|
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"};
|
static constexpr std::array<std::string_view, MAX_BBMOTES> num = {"1", "2", "3", "4", "BB"};
|
||||||
std::string profile[MAX_BBMOTES];
|
std::string profile[MAX_BBMOTES];
|
||||||
|
|
||||||
m_dynamic_input_tex_config_manager.Load();
|
|
||||||
|
|
||||||
if (SConfig::GetInstance().GetGameID() != "00000000")
|
if (SConfig::GetInstance().GetGameID() != "00000000")
|
||||||
{
|
{
|
||||||
const std::string profile_directory = GetUserProfileDirectoryPath();
|
const std::string profile_directory = GetUserProfileDirectoryPath();
|
||||||
|
@ -102,8 +100,6 @@ bool InputConfig::LoadConfig()
|
||||||
// Next profile
|
// Next profile
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dynamic_input_tex_config_manager.GenerateTextures(inifile, controller_names);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -139,8 +135,6 @@ void InputConfig::SaveConfig()
|
||||||
controller_names.push_back(controller->GetName());
|
controller_names.push_back(controller->GetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dynamic_input_tex_config_manager.GenerateTextures(inifile, controller_names);
|
|
||||||
|
|
||||||
inifile.Save(ini_filename);
|
inifile.Save(ini_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +204,8 @@ bool InputConfig::IsControllerControlledByGamepadDevice(int index) const
|
||||||
|
|
||||||
void InputConfig::GenerateControllerTextures(const Common::IniFile& file)
|
void InputConfig::GenerateControllerTextures(const Common::IniFile& file)
|
||||||
{
|
{
|
||||||
|
m_dynamic_input_tex_config_manager.Load();
|
||||||
|
|
||||||
std::vector<std::string> controller_names;
|
std::vector<std::string> controller_names;
|
||||||
for (auto& controller : m_controllers)
|
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);
|
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 UnregisterHotplugCallback();
|
||||||
|
|
||||||
void GenerateControllerTextures(const Common::IniFile& file);
|
void GenerateControllerTextures(const Common::IniFile& file);
|
||||||
|
void GenerateControllerTextures();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle;
|
ControllerInterface::HotplugCallbackHandle m_hotplug_callback_handle;
|
||||||
|
|
Loading…
Add table
Reference in a new issue