mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-15 22:21:25 +00:00
Qt: Add custom pad configs
Add a custom pad config for every game.
This commit is contained in:
parent
cb78522620
commit
9aa08313e3
@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/types.h"
|
||||
#include "Utilities/mutex.h"
|
||||
@ -633,8 +633,8 @@ public:
|
||||
}
|
||||
|
||||
// Emplace the object returned by provider() and return it if no object exists
|
||||
template <typename T, typename F>
|
||||
static auto import(F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider()))
|
||||
template <typename T, typename F, typename... Args>
|
||||
static auto import(F&& provider, Args&&... args) -> decltype(static_cast<std::shared_ptr<T>>(provider(std::forward<Args>(args)...)))
|
||||
{
|
||||
std::shared_ptr<T> ptr;
|
||||
{
|
||||
@ -644,7 +644,7 @@ public:
|
||||
|
||||
if (!cur)
|
||||
{
|
||||
ptr = provider();
|
||||
ptr = provider(std::forward<Args>(args)...);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
@ -662,8 +662,8 @@ public:
|
||||
}
|
||||
|
||||
// Emplace the object return by provider() (old object will be removed if it exists)
|
||||
template <typename T, typename F>
|
||||
static auto import_always(F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider()))
|
||||
template <typename T, typename F, typename... Args>
|
||||
static auto import_always(F&& provider, Args&&... args) -> decltype(static_cast<std::shared_ptr<T>>(provider(std::forward<Args>(args)...)))
|
||||
{
|
||||
std::shared_ptr<T> ptr;
|
||||
std::shared_ptr<void> old;
|
||||
@ -672,7 +672,7 @@ public:
|
||||
|
||||
auto& cur = g_vec[get_type<T>()];
|
||||
|
||||
ptr = provider();
|
||||
ptr = provider(std::forward<Args>(args)...);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "PadHandler.h"
|
||||
#include "pad_thread.h"
|
||||
|
||||
cfg_input g_cfg_input;
|
||||
|
||||
@ -268,13 +269,25 @@ bool PadHandlerBase::has_led()
|
||||
return b_has_led;
|
||||
}
|
||||
|
||||
std::string PadHandlerBase::get_config_dir(pad_handler type)
|
||||
std::string PadHandlerBase::get_config_dir(pad_handler type, const std::string& title_id)
|
||||
{
|
||||
if (!title_id.empty())
|
||||
{
|
||||
return Emu.GetCustomInputConfigDir(title_id) + fmt::format("%s", type) + "/";
|
||||
}
|
||||
return fs::get_config_dir() + "/InputConfigs/" + fmt::format("%s", type) + "/";
|
||||
}
|
||||
|
||||
std::string PadHandlerBase::get_config_filename(int i)
|
||||
std::string PadHandlerBase::get_config_filename(int i, const std::string& title_id)
|
||||
{
|
||||
if (!title_id.empty() && fs::is_file(Emu.GetCustomInputConfigPath(title_id)))
|
||||
{
|
||||
const std::string path = Emu.GetCustomInputConfigDir(title_id) + g_cfg_input.player[i]->handler.to_string() + "/" + g_cfg_input.player[i]->profile.to_string() + ".yml";
|
||||
if (fs::is_file(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return fs::get_config_dir() + "/InputConfigs/" + g_cfg_input.player[i]->handler.to_string() + "/" + g_cfg_input.player[i]->profile.to_string() + ".yml";
|
||||
}
|
||||
|
||||
@ -286,7 +299,7 @@ void PadHandlerBase::init_configs()
|
||||
{
|
||||
if (g_cfg_input.player[i]->handler == m_type)
|
||||
{
|
||||
init_config(&m_pad_configs[index], get_config_filename(i));
|
||||
init_config(&m_pad_configs[index], get_config_filename(i, pad::g_title_id));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "Utilities/Config.h"
|
||||
#include "Utilities/types.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/GameInfo.h"
|
||||
|
||||
// TODO: HLE info (constants, structs, etc.) should not be available here
|
||||
|
||||
@ -268,7 +269,7 @@ struct cfg_player final : cfg::node
|
||||
|
||||
struct cfg_input final : cfg::node
|
||||
{
|
||||
const std::string cfg_name = fs::get_config_dir() + "/config_input.yml";
|
||||
std::string cfg_name = fs::get_config_dir() + "/config_input.yml";
|
||||
|
||||
cfg_player player1{ this, "Player 1 Input", pad_handler::keyboard };
|
||||
cfg_player player2{ this, "Player 2 Input", pad_handler::null };
|
||||
@ -280,18 +281,32 @@ struct cfg_input final : cfg::node
|
||||
|
||||
cfg_player *player[7]{ &player1, &player2, &player3, &player4, &player5, &player6, &player7 }; // Thanks gcc!
|
||||
|
||||
bool load()
|
||||
bool load(const std::string& title_id = "")
|
||||
{
|
||||
if (fs::file cfg_file{ cfg_name, fs::read })
|
||||
cfg_name = Emu.GetCustomInputConfigPath(title_id);
|
||||
|
||||
if (!fs::is_file(cfg_name))
|
||||
{
|
||||
cfg_name = fs::get_config_dir() + "/config_input.yml";
|
||||
}
|
||||
|
||||
if (fs::file cfg_file{cfg_name, fs::read})
|
||||
{
|
||||
return from_string(cfg_file.to_string());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void save()
|
||||
void save(const std::string& title_id = "")
|
||||
{
|
||||
if (title_id.empty())
|
||||
{
|
||||
cfg_name = fs::get_config_dir() + "/config_input.yml";
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg_name = Emu.GetCustomInputConfigPath(title_id);
|
||||
}
|
||||
fs::file(cfg_name, fs::rewrite).write(to_string());
|
||||
}
|
||||
};
|
||||
@ -460,8 +475,8 @@ public:
|
||||
bool has_deadzones();
|
||||
bool has_led();
|
||||
|
||||
static std::string get_config_dir(pad_handler type);
|
||||
static std::string get_config_filename(int i);
|
||||
static std::string get_config_dir(pad_handler type, const std::string& title_id = "");
|
||||
static std::string get_config_filename(int i, const std::string& title_id = "");
|
||||
|
||||
virtual bool Init() { return true; }
|
||||
PadHandlerBase(pad_handler type = pad_handler::null);
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
#include "Utilities/GDBDebugServer.h"
|
||||
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Utilities/JIT.h"
|
||||
|
||||
#if defined(_WIN32) || defined(HAVE_VULKAN)
|
||||
@ -303,31 +302,31 @@ void Emulator::Init()
|
||||
|
||||
if (g_cfg.vfs.init_dirs)
|
||||
{
|
||||
fs::create_path(dev_hdd0);
|
||||
fs::create_path(dev_hdd1);
|
||||
fs::create_path(dev_usb);
|
||||
fs::create_dir(dev_hdd0 + "game/");
|
||||
fs::create_dir(dev_hdd0 + "game/TEST12345/");
|
||||
fs::create_dir(dev_hdd0 + "game/TEST12345/USRDIR/");
|
||||
fs::create_dir(dev_hdd0 + "game/.locks/");
|
||||
fs::create_dir(dev_hdd0 + "home/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/exdata/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/savedata/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/trophy/");
|
||||
fs::write_file(dev_hdd0 + "home/" + m_usr + "/localusername", fs::create + fs::excl + fs::write, "User"s);
|
||||
fs::create_dir(dev_hdd0 + "disc/");
|
||||
fs::create_dir(dev_hdd0 + "savedata/");
|
||||
fs::create_dir(dev_hdd0 + "savedata/vmc/");
|
||||
fs::create_dir(dev_hdd1 + "cache/");
|
||||
fs::create_dir(dev_hdd1 + "game/");
|
||||
fs::create_path(dev_hdd0);
|
||||
fs::create_path(dev_hdd1);
|
||||
fs::create_path(dev_usb);
|
||||
fs::create_dir(dev_hdd0 + "game/");
|
||||
fs::create_dir(dev_hdd0 + "game/TEST12345/");
|
||||
fs::create_dir(dev_hdd0 + "game/TEST12345/USRDIR/");
|
||||
fs::create_dir(dev_hdd0 + "game/.locks/");
|
||||
fs::create_dir(dev_hdd0 + "home/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/exdata/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/savedata/");
|
||||
fs::create_dir(dev_hdd0 + "home/" + m_usr + "/trophy/");
|
||||
fs::write_file(dev_hdd0 + "home/" + m_usr + "/localusername", fs::create + fs::excl + fs::write, "User"s);
|
||||
fs::create_dir(dev_hdd0 + "disc/");
|
||||
fs::create_dir(dev_hdd0 + "savedata/");
|
||||
fs::create_dir(dev_hdd0 + "savedata/vmc/");
|
||||
fs::create_dir(dev_hdd1 + "cache/");
|
||||
fs::create_dir(dev_hdd1 + "game/");
|
||||
}
|
||||
|
||||
fs::create_path(fs::get_cache_dir() + "shaderlog/");
|
||||
fs::create_path(fs::get_config_dir() + "captures/");
|
||||
|
||||
#ifdef WITH_GDB_DEBUGGER
|
||||
LOG_SUCCESS(GENERAL, "GDB debug server will be started and listening on %d upon emulator boot", (int) g_cfg.misc.gdb_server_port);
|
||||
LOG_SUCCESS(GENERAL, "GDB debug server will be started and listening on %d upon emulator boot", (int)g_cfg.misc.gdb_server_port);
|
||||
#endif
|
||||
|
||||
// Initialize patch engine
|
||||
@ -506,7 +505,7 @@ bool Emulator::BootRsxCapture(const std::string& path)
|
||||
GetCallbacks().on_ready();
|
||||
|
||||
auto gsrender = fxm::import<GSRender>(Emu.GetCallbacks().get_gs_render);
|
||||
auto padhandler = fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler);
|
||||
auto padhandler = fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler, "");
|
||||
|
||||
if (gsrender.get() == nullptr || padhandler.get() == nullptr)
|
||||
return false;
|
||||
@ -727,6 +726,22 @@ std::string Emulator::GetCustomConfigPath(const std::string& title_id, bool get_
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string Emulator::GetCustomInputConfigDir(const std::string& title_id)
|
||||
{
|
||||
// Notice: the extra folder for each title id may be removed at a later stage
|
||||
// Warning: make sure to change any function that removes this directory as well
|
||||
#ifdef _WIN32
|
||||
return fs::get_config_dir() + "config/custom_input_configs/" + title_id + "/";
|
||||
#else
|
||||
return fs::get_config_dir() + "custom_input_configs/" + title_id + "/";
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string Emulator::GetCustomInputConfigPath(const std::string& title_id)
|
||||
{
|
||||
return GetCustomInputConfigDir(title_id) + "/config_input_" + title_id + ".yml";
|
||||
}
|
||||
|
||||
void Emulator::SetForceBoot(bool force_boot)
|
||||
{
|
||||
m_force_boot = force_boot;
|
||||
@ -1343,7 +1358,7 @@ void Emulator::Load(bool add_only, bool force_global_config)
|
||||
}
|
||||
|
||||
fxm::import<GSRender>(Emu.GetCallbacks().get_gs_render); // TODO: must be created in appropriate sys_rsx syscall
|
||||
fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler);
|
||||
fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler, m_title_id);
|
||||
network_thread_init();
|
||||
}
|
||||
else if (ppu_prx.open(elf_file) == elf_error::ok)
|
||||
|
@ -189,12 +189,12 @@ struct EmuCallbacks
|
||||
std::function<void()> on_stop;
|
||||
std::function<void()> on_ready;
|
||||
std::function<void()> exit;
|
||||
std::function<void()> reset_pads;
|
||||
std::function<void(const std::string&)> reset_pads;
|
||||
std::function<void(bool)> enable_pads;
|
||||
std::function<void(s32, s32)> handle_taskbar_progress; // (type, value) type: 0 for reset, 1 for increment, 2 for set_limit
|
||||
std::function<std::shared_ptr<class KeyboardHandlerBase>()> get_kb_handler;
|
||||
std::function<std::shared_ptr<class MouseHandlerBase>()> get_mouse_handler;
|
||||
std::function<std::shared_ptr<class pad_thread>()> get_pad_handler;
|
||||
std::function<std::shared_ptr<class pad_thread>(const std::string&)> get_pad_handler;
|
||||
std::function<std::unique_ptr<class GSFrameBase>()> get_gs_frame;
|
||||
std::function<std::shared_ptr<class GSRender>()> get_gs_render;
|
||||
std::function<std::shared_ptr<class AudioBackend>()> get_audio;
|
||||
@ -326,6 +326,8 @@ public:
|
||||
|
||||
static std::string GetCustomConfigDir();
|
||||
static std::string GetCustomConfigPath(const std::string& title_id, bool get_deprecated_path = false);
|
||||
static std::string GetCustomInputConfigDir(const std::string& title_id);
|
||||
static std::string GetCustomInputConfigPath(const std::string& title_id);
|
||||
|
||||
void SetForceBoot(bool force_boot);
|
||||
|
||||
|
BIN
rpcs3/Icons/combo_config_bordered.png
Normal file
BIN
rpcs3/Icons/combo_config_bordered.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
BIN
rpcs3/Icons/controllers_2.png
Normal file
BIN
rpcs3/Icons/controllers_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -14,6 +14,7 @@ namespace pad
|
||||
{
|
||||
atomic_t<pad_thread*> g_current = nullptr;
|
||||
std::recursive_mutex g_pad_mutex;
|
||||
std::string g_title_id;
|
||||
}
|
||||
|
||||
struct pad_setting
|
||||
@ -23,8 +24,9 @@ struct pad_setting
|
||||
u32 device_type;
|
||||
};
|
||||
|
||||
pad_thread::pad_thread(void *_curthread, void *_curwindow) : curthread(_curthread), curwindow(_curwindow)
|
||||
pad_thread::pad_thread(void *_curthread, void *_curwindow, const std::string& title_id) : curthread(_curthread), curwindow(_curwindow)
|
||||
{
|
||||
pad::g_title_id = title_id;
|
||||
Init();
|
||||
|
||||
thread = std::make_shared<std::thread>(&pad_thread::ThreadFunc, this);
|
||||
@ -65,7 +67,7 @@ void pad_thread::Init()
|
||||
|
||||
handlers.clear();
|
||||
|
||||
g_cfg_input.load();
|
||||
g_cfg_input.load(pad::g_title_id);
|
||||
|
||||
std::shared_ptr<keyboard_pad_handler> keyptr;
|
||||
|
||||
@ -142,8 +144,9 @@ void pad_thread::SetRumble(const u32 pad, u8 largeMotor, bool smallMotor)
|
||||
}
|
||||
}
|
||||
|
||||
void pad_thread::Reset()
|
||||
void pad_thread::Reset(const std::string& title_id)
|
||||
{
|
||||
pad::g_title_id = title_id;
|
||||
reset = active.load();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <thread>
|
||||
@ -16,14 +16,14 @@ struct PadInfo
|
||||
class pad_thread
|
||||
{
|
||||
public:
|
||||
pad_thread(void *_curthread, void *_curwindow); // void * instead of QThread * and QWindow * because of include in emucore
|
||||
pad_thread(void* _curthread, void* _curwindow, const std::string& title_id = ""); // void * instead of QThread * and QWindow * because of include in emucore
|
||||
~pad_thread();
|
||||
|
||||
PadInfo& GetInfo() { return m_info; }
|
||||
auto& GetPads() { return m_pads; }
|
||||
void SetRumble(const u32 pad, u8 largeMotor, bool smallMotor);
|
||||
void Init();
|
||||
void Reset();
|
||||
void Reset(const std::string& title_id = "");
|
||||
void SetEnabled(bool enabled);
|
||||
void SetIntercepted(bool intercepted);
|
||||
|
||||
@ -50,6 +50,7 @@ namespace pad
|
||||
{
|
||||
extern atomic_t<pad_thread*> g_current;
|
||||
extern std::recursive_mutex g_pad_mutex;
|
||||
extern std::string g_title_id;
|
||||
|
||||
static inline class pad_thread* get_current_handler()
|
||||
{
|
||||
|
@ -18,5 +18,7 @@
|
||||
<file>Icons/open.png</file>
|
||||
<file>Icons/custom_config.png</file>
|
||||
<file>Icons/custom_config_2.png</file>
|
||||
<file>Icons/controllers_2.png</file>
|
||||
<file>Icons/combo_config_bordered.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -142,9 +142,9 @@ void rpcs3_app::InitializeCallbacks()
|
||||
RequestCallAfter(std::move(func));
|
||||
};
|
||||
|
||||
callbacks.reset_pads = [this]()
|
||||
callbacks.reset_pads = [this](const std::string& title_id = "")
|
||||
{
|
||||
pad::get_current_handler()->Reset();
|
||||
pad::get_current_handler()->Reset(title_id);
|
||||
};
|
||||
callbacks.enable_pads = [this](bool enable)
|
||||
{
|
||||
@ -183,9 +183,9 @@ void rpcs3_app::InitializeCallbacks()
|
||||
}
|
||||
};
|
||||
|
||||
callbacks.get_pad_handler = [this]() -> std::shared_ptr<pad_thread>
|
||||
callbacks.get_pad_handler = [this](const std::string& title_id) -> std::shared_ptr<pad_thread>
|
||||
{
|
||||
return std::make_shared<pad_thread>(thread(), gameWindow);
|
||||
return std::make_shared<pad_thread>(thread(), gameWindow, title_id);
|
||||
};
|
||||
|
||||
callbacks.get_gs_frame = [this]() -> std::unique_ptr<GSFrameBase>
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "game_list_frame.h"
|
||||
#include "qt_utils.h"
|
||||
#include "settings_dialog.h"
|
||||
#include "pad_settings_dialog.h"
|
||||
#include "table_item_delegate.h"
|
||||
#include "custom_table_widget_item.h"
|
||||
#include "input_dialog.h"
|
||||
@ -114,6 +115,10 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
|
||||
QMenu* configure = new QMenu(this);
|
||||
configure->addActions(m_columnActs);
|
||||
configure->exec(mapToGlobal(pos));
|
||||
|
||||
QMenu* pad_configure = new QMenu(this);
|
||||
pad_configure->addActions(m_columnActs);
|
||||
pad_configure->exec(mapToGlobal(pos));
|
||||
});
|
||||
|
||||
connect(m_xgrid, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot);
|
||||
@ -471,12 +476,14 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
|
||||
}
|
||||
|
||||
const auto compat = m_game_compat->GetCompatibility(game.serial);
|
||||
|
||||
const bool hasCustomConfig = fs::is_file(Emu.GetCustomConfigPath(game.serial)) || fs::is_file(Emu.GetCustomConfigPath(game.serial, true));
|
||||
const bool hasCustomPadConfig = fs::is_file(Emu.GetCustomInputConfigPath(game.serial));
|
||||
|
||||
const QColor color = getGridCompatibilityColor(compat.color);
|
||||
const QPixmap pxmap = PaintedPixmap(img, hasCustomConfig, color);
|
||||
const QPixmap pxmap = PaintedPixmap(img, hasCustomConfig, hasCustomPadConfig, color);
|
||||
|
||||
m_game_data.push_back(game_info(new gui_game_info{ game, compat, img, pxmap, hasCustomConfig }));
|
||||
m_game_data.push_back(game_info(new gui_game_info{game, compat, img, pxmap, hasCustomConfig, hasCustomPadConfig}));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@ -695,6 +702,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||
}
|
||||
myMenu.addAction(boot);
|
||||
QAction* configure = myMenu.addAction(tr("&Configure"));
|
||||
QAction* pad_configure = myMenu.addAction(tr("&Configure pads"));
|
||||
QAction* createPPUCache = myMenu.addAction(tr("&Create PPU Cache"));
|
||||
myMenu.addSeparator();
|
||||
QAction* renameTitle = myMenu.addAction(tr("&Rename In Game List"));
|
||||
@ -709,9 +717,20 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||
QAction* remove_custom_config = remove_menu->addAction(tr("&Remove Custom Configuration"));
|
||||
connect(remove_custom_config, &QAction::triggered, [=]()
|
||||
{
|
||||
if (RemoveCustomConfiguration(currGame.serial, true))
|
||||
if (RemoveCustomConfiguration(currGame.serial, gameinfo, true))
|
||||
{
|
||||
ShowCustomConfigIcon(item, false);
|
||||
ShowCustomConfigIcon(item, config::type::emu);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (gameinfo->hasCustomPadConfig)
|
||||
{
|
||||
QAction* remove_custom_pad_config = remove_menu->addAction(tr("&Remove Custom Pad Configuration"));
|
||||
connect(remove_custom_pad_config, &QAction::triggered, [=]()
|
||||
{
|
||||
if (RemoveCustomPadConfiguration(currGame.serial, gameinfo, true))
|
||||
{
|
||||
ShowCustomConfigIcon(item, config::type::pad);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -775,7 +794,33 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||
settings_dialog dlg(m_gui_settings, m_emu_settings, 0, this, &currGame);
|
||||
if (dlg.exec() == QDialog::Accepted && !gameinfo->hasCustomConfig)
|
||||
{
|
||||
ShowCustomConfigIcon(item, true);
|
||||
gameinfo->hasCustomConfig = true;
|
||||
ShowCustomConfigIcon(item, config::type::emu);
|
||||
}
|
||||
});
|
||||
connect(pad_configure, &QAction::triggered, [=]
|
||||
{
|
||||
if (!Emu.IsStopped())
|
||||
{
|
||||
Emu.GetCallbacks().enable_pads(false);
|
||||
}
|
||||
pad_settings_dialog dlg(this, &currGame);
|
||||
connect(&dlg, &QDialog::finished, [this](int/* result*/)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Emu.GetCallbacks().reset_pads(Emu.GetTitleID());
|
||||
});
|
||||
if (dlg.exec() == QDialog::Accepted && !gameinfo->hasCustomPadConfig)
|
||||
{
|
||||
gameinfo->hasCustomPadConfig = true;
|
||||
ShowCustomConfigIcon(item, config::type::pad);
|
||||
}
|
||||
if (!Emu.IsStopped())
|
||||
{
|
||||
Emu.GetCallbacks().enable_pads(true);
|
||||
}
|
||||
});
|
||||
connect(hide_serial, &QAction::triggered, [=](bool checked)
|
||||
@ -801,7 +846,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||
}
|
||||
|
||||
QMessageBox* mb = new QMessageBox(QMessageBox::Question, tr("Confirm %1 Removal").arg(qstr(currGame.category)), tr("Permanently remove %0 from drive?\nPath: %1").arg(name).arg(qstr(currGame.path)), QMessageBox::Yes | QMessageBox::No, this);
|
||||
mb->setCheckBox(new QCheckBox(tr("Remove caches and custom config")));
|
||||
mb->setCheckBox(new QCheckBox(tr("Remove caches and custom configs")));
|
||||
mb->deleteLater();
|
||||
if (mb->exec() == QMessageBox::Yes)
|
||||
{
|
||||
@ -811,6 +856,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
||||
RemovePPUCache(cache_base_dir);
|
||||
RemoveSPUCache(cache_base_dir);
|
||||
RemoveCustomConfiguration(currGame.serial);
|
||||
RemoveCustomPadConfiguration(currGame.serial);
|
||||
}
|
||||
fs::remove_all(currGame.path);
|
||||
m_game_data.erase(std::remove(m_game_data.begin(), m_game_data.end(), gameinfo), m_game_data.end());
|
||||
@ -933,7 +979,7 @@ bool game_list_frame::CreatePPUCache(const std::string& path)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool game_list_frame::RemoveCustomConfiguration(const std::string& title_id, bool is_interactive)
|
||||
bool game_list_frame::RemoveCustomConfiguration(const std::string& title_id, game_info game, bool is_interactive)
|
||||
{
|
||||
const std::string config_path_new = Emu.GetCustomConfigPath(title_id);
|
||||
const std::string config_path_old = Emu.GetCustomConfigPath(title_id, true);
|
||||
@ -954,6 +1000,10 @@ bool game_list_frame::RemoveCustomConfiguration(const std::string& title_id, boo
|
||||
}
|
||||
if (fs::remove_file(path))
|
||||
{
|
||||
if (game)
|
||||
{
|
||||
game->hasCustomConfig = false;
|
||||
}
|
||||
LOG_SUCCESS(GENERAL, "Removed configuration file: %s", path);
|
||||
}
|
||||
else
|
||||
@ -971,6 +1021,41 @@ bool game_list_frame::RemoveCustomConfiguration(const std::string& title_id, boo
|
||||
return result;
|
||||
}
|
||||
|
||||
bool game_list_frame::RemoveCustomPadConfiguration(const std::string& title_id, game_info game, bool is_interactive)
|
||||
{
|
||||
const std::string config_dir = Emu.GetCustomInputConfigDir(title_id);
|
||||
|
||||
if (!fs::is_dir(config_dir))
|
||||
return true;
|
||||
|
||||
if (is_interactive && QMessageBox::question(this, tr("Confirm Removal"), (!Emu.IsStopped() && Emu.GetTitleID() == title_id)
|
||||
? tr("Remove custom pad configuration?\nYour configuration will revert to the global pad settings.")
|
||||
: tr("Remove custom pad configuration?")) != QMessageBox::Yes)
|
||||
return true;
|
||||
|
||||
if (QDir(qstr(config_dir)).removeRecursively())
|
||||
{
|
||||
if (game)
|
||||
{
|
||||
game->hasCustomPadConfig = false;
|
||||
}
|
||||
if (!Emu.IsStopped() && Emu.GetTitleID() == title_id)
|
||||
{
|
||||
Emu.GetCallbacks().enable_pads(false);
|
||||
Emu.GetCallbacks().reset_pads(title_id);
|
||||
Emu.GetCallbacks().enable_pads(true);
|
||||
}
|
||||
LOG_NOTICE(GENERAL, "Removed pad configuration directory: %s", config_dir);
|
||||
return true;
|
||||
}
|
||||
else if (is_interactive)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Warning!"), tr("Failed to completely remove pad configuration directory!"));
|
||||
LOG_FATAL(GENERAL, "Failed to completely remove pad configuration directory: %s\nError: %s", config_dir, fs::g_tls_error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_list_frame::RemoveShadersCache(const std::string& base_dir, bool is_interactive)
|
||||
{
|
||||
if (!fs::is_dir(base_dir))
|
||||
@ -1260,6 +1345,52 @@ void game_list_frame::BatchRemoveCustomConfigurations()
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
void game_list_frame::BatchRemoveCustomPadConfigurations()
|
||||
{
|
||||
std::set<std::string> serials;
|
||||
for (const auto& game : m_game_data)
|
||||
{
|
||||
if (game->hasCustomPadConfig && !serials.count(game->info.serial))
|
||||
{
|
||||
serials.emplace(game->info.serial);
|
||||
}
|
||||
}
|
||||
const u32 total = serials.size();
|
||||
|
||||
if (total == 0)
|
||||
{
|
||||
QMessageBox::information(this, tr("Custom Pad Configuration Batch Removal"), tr("No files found"), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
progress_dialog* pdlg = new progress_dialog(tr("Removing all custom pad configurations"), tr("Cancel"), 0, total, this);
|
||||
pdlg->setWindowTitle(tr("Custom Pad Configuration Batch Removal"));
|
||||
pdlg->setAutoClose(false);
|
||||
pdlg->setAutoReset(false);
|
||||
pdlg->show();
|
||||
|
||||
u32 removed = 0;
|
||||
for (const auto& serial : serials)
|
||||
{
|
||||
if (pdlg->wasCanceled())
|
||||
{
|
||||
LOG_NOTICE(GENERAL, "Custom Pad Configuration Batch Removal was canceled. %d/%d custom pad configurations cleared", removed, total);
|
||||
break;
|
||||
}
|
||||
QApplication::processEvents();
|
||||
|
||||
if (RemoveCustomPadConfiguration(serial))
|
||||
{
|
||||
pdlg->SetValue(++removed);
|
||||
}
|
||||
}
|
||||
|
||||
pdlg->setLabelText(tr("%0/%1 custom pad configurations cleared").arg(removed).arg(total));
|
||||
pdlg->setCancelButtonText(tr("OK"));
|
||||
QApplication::beep();
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
void game_list_frame::BatchRemoveShaderCaches()
|
||||
{
|
||||
std::set<std::string> serials;
|
||||
@ -1302,7 +1433,7 @@ void game_list_frame::BatchRemoveShaderCaches()
|
||||
QApplication::beep();
|
||||
}
|
||||
|
||||
QPixmap game_list_frame::PaintedPixmap(const QImage& img, bool paint_config_icon, const QColor& compatibility_color)
|
||||
QPixmap game_list_frame::PaintedPixmap(const QImage& img, bool paint_config_icon, bool paint_pad_config_icon, const QColor& compatibility_color)
|
||||
{
|
||||
const int device_pixel_ratio = devicePixelRatio();
|
||||
const QSize original_size = img.size();
|
||||
@ -1318,11 +1449,26 @@ QPixmap game_list_frame::PaintedPixmap(const QImage& img, bool paint_config_icon
|
||||
painter.drawImage(QPoint(0, 0), img);
|
||||
}
|
||||
|
||||
if (paint_config_icon && !m_isListLayout)
|
||||
if (!m_isListLayout && (paint_config_icon || paint_pad_config_icon))
|
||||
{
|
||||
const int width = original_size.width() * 0.2;
|
||||
const QPoint origin = QPoint(original_size.width() - width, 0);
|
||||
QImage custom_config_icon(":/Icons/custom_config_2.png");
|
||||
QString icon_path;
|
||||
|
||||
if (paint_config_icon && paint_pad_config_icon)
|
||||
{
|
||||
icon_path = ":/Icons/combo_config_bordered.png";
|
||||
}
|
||||
else if (paint_config_icon)
|
||||
{
|
||||
icon_path = ":/Icons/custom_config_2.png";
|
||||
}
|
||||
else if (paint_pad_config_icon)
|
||||
{
|
||||
icon_path = ":/Icons/controllers_2.png";
|
||||
}
|
||||
|
||||
QImage custom_config_icon(icon_path);
|
||||
custom_config_icon.setDevicePixelRatio(device_pixel_ratio);
|
||||
painter.drawImage(origin, custom_config_icon.scaled(QSize(width, width) * device_pixel_ratio, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation));
|
||||
}
|
||||
@ -1342,7 +1488,7 @@ QPixmap game_list_frame::PaintedPixmap(const QImage& img, bool paint_config_icon
|
||||
return QPixmap::fromImage(image.scaled(m_Icon_Size * device_pixel_ratio, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation));
|
||||
}
|
||||
|
||||
void game_list_frame::ShowCustomConfigIcon(QTableWidgetItem* item, bool enabled)
|
||||
void game_list_frame::ShowCustomConfigIcon(QTableWidgetItem* item, config::type type)
|
||||
{
|
||||
auto game = GetGameInfoFromItem(item);
|
||||
if (game == nullptr)
|
||||
@ -1350,24 +1496,22 @@ void game_list_frame::ShowCustomConfigIcon(QTableWidgetItem* item, bool enabled)
|
||||
return;
|
||||
}
|
||||
|
||||
game->hasCustomConfig = enabled;
|
||||
const QColor color = getGridCompatibilityColor(game->compat.color);
|
||||
game->pxmap = PaintedPixmap(game->icon, enabled, color);
|
||||
|
||||
if (!m_isListLayout)
|
||||
{
|
||||
const QColor color = getGridCompatibilityColor(game->compat.color);
|
||||
game->pxmap = PaintedPixmap(game->icon, game->hasCustomConfig, game->hasCustomPadConfig, color);
|
||||
int r = m_xgrid->currentItem()->row(), c = m_xgrid->currentItem()->column();
|
||||
m_xgrid->addItem(game->pxmap, qstr(game->info.name).simplified(), r, c);
|
||||
m_xgrid->item(r, c)->setData(gui::game_role, QVariant::fromValue(game));
|
||||
}
|
||||
else if (enabled)
|
||||
{
|
||||
else if (game->hasCustomConfig && game->hasCustomPadConfig)
|
||||
m_gameList->item(item->row(), gui::column_name)->setIcon(QIcon(":/Icons/combo_config_bordered.png"));
|
||||
else if (game->hasCustomConfig)
|
||||
m_gameList->item(item->row(), gui::column_name)->setIcon(QIcon(":/Icons/custom_config.png"));
|
||||
}
|
||||
else if (game->hasCustomPadConfig)
|
||||
m_gameList->item(item->row(), gui::column_name)->setIcon(QIcon(":/Icons/controllers.png"));
|
||||
else
|
||||
{
|
||||
m_gameList->setItem(item->row(), gui::column_name, new custom_table_widget_item(game->info.name));
|
||||
}
|
||||
}
|
||||
|
||||
void game_list_frame::ResizeIcons(const int& sliderPos)
|
||||
@ -1395,7 +1539,7 @@ void game_list_frame::RepaintIcons(const bool& fromSettings)
|
||||
for (auto& game : m_game_data)
|
||||
{
|
||||
QColor color = getGridCompatibilityColor(game->compat.color);
|
||||
game->pxmap = PaintedPixmap(game->icon, game->hasCustomConfig, color);
|
||||
game->pxmap = PaintedPixmap(game->icon, game->hasCustomConfig, game->hasCustomPadConfig, color);
|
||||
}
|
||||
|
||||
Refresh();
|
||||
@ -1560,10 +1704,18 @@ int game_list_frame::PopulateGameList()
|
||||
|
||||
// Title
|
||||
custom_table_widget_item* title_item = new custom_table_widget_item(title);
|
||||
if (game->hasCustomConfig)
|
||||
if (game->hasCustomConfig && game->hasCustomPadConfig)
|
||||
{
|
||||
title_item->setIcon(QIcon(":/Icons/combo_config_bordered.png"));
|
||||
}
|
||||
else if (game->hasCustomConfig)
|
||||
{
|
||||
title_item->setIcon(QIcon(":/Icons/custom_config.png"));
|
||||
}
|
||||
else if (game->hasCustomPadConfig)
|
||||
{
|
||||
title_item->setIcon(QIcon(":/Icons/controllers.png"));
|
||||
}
|
||||
|
||||
// Serial
|
||||
custom_table_widget_item* serial_item = new custom_table_widget_item(game->info.serial);
|
||||
|
@ -31,6 +31,15 @@ enum Category
|
||||
Others,
|
||||
};
|
||||
|
||||
namespace config
|
||||
{
|
||||
enum class type
|
||||
{
|
||||
emu,
|
||||
pad
|
||||
};
|
||||
}
|
||||
|
||||
namespace category // (see PARAM.SFO in psdevwiki.com) TODO: Disc Categories
|
||||
{
|
||||
// PS3 bootable
|
||||
@ -171,6 +180,7 @@ struct gui_game_info
|
||||
QImage icon;
|
||||
QPixmap pxmap;
|
||||
bool hasCustomConfig;
|
||||
bool hasCustomPadConfig;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<gui_game_info> game_info;
|
||||
@ -215,6 +225,7 @@ public Q_SLOTS:
|
||||
void BatchRemovePPUCaches();
|
||||
void BatchRemoveSPUCaches();
|
||||
void BatchRemoveCustomConfigurations();
|
||||
void BatchRemoveCustomPadConfigurations();
|
||||
void BatchRemoveShaderCaches();
|
||||
void SetListMode(const bool& isList);
|
||||
void SetSearchText(const QString& text);
|
||||
@ -234,9 +245,9 @@ protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
private:
|
||||
QPixmap PaintedPixmap(const QImage& img, bool paint_config_icon = false, const QColor& color = QColor());
|
||||
QPixmap PaintedPixmap(const QImage& img, bool paint_config_icon = false, bool paint_pad_config_icon = false, const QColor& color = QColor());
|
||||
QColor getGridCompatibilityColor(const QString& string);
|
||||
void ShowCustomConfigIcon(QTableWidgetItem* item, bool enabled);
|
||||
void ShowCustomConfigIcon(QTableWidgetItem* item, config::type type);
|
||||
void PopulateGameGrid(int maxCols, const QSize& image_size, const QColor& image_color);
|
||||
bool IsEntryVisible(const game_info& game);
|
||||
void SortGameList();
|
||||
@ -244,7 +255,8 @@ private:
|
||||
int PopulateGameList();
|
||||
bool SearchMatchesApp(const std::string& name, const std::string& serial);
|
||||
|
||||
bool RemoveCustomConfiguration(const std::string& base_dir, bool is_interactive = false);
|
||||
bool RemoveCustomConfiguration(const std::string& title_id, game_info game = nullptr, bool is_interactive = false);
|
||||
bool RemoveCustomPadConfiguration(const std::string& title_id, game_info game = nullptr, bool is_interactive = false);
|
||||
bool RemoveShadersCache(const std::string& base_dir, bool is_interactive = false);
|
||||
bool RemovePPUCache(const std::string& base_dir, bool is_interactive = false);
|
||||
bool RemoveSPUCache(const std::string& base_dir, bool is_interactive = false);
|
||||
|
@ -1247,6 +1247,7 @@ void main_window::CreateConnects()
|
||||
connect(ui->batchRemoveSPUCachesAct, &QAction::triggered, m_gameListFrame, &game_list_frame::BatchRemoveSPUCaches);
|
||||
connect(ui->batchRemoveShaderCachesAct, &QAction::triggered, m_gameListFrame, &game_list_frame::BatchRemoveShaderCaches);
|
||||
connect(ui->batchRemoveCustomConfigurationsAct, &QAction::triggered, m_gameListFrame, &game_list_frame::BatchRemoveCustomConfigurations);
|
||||
connect(ui->batchRemoveCustomPadConfigurationsAct, &QAction::triggered, m_gameListFrame, &game_list_frame::BatchRemoveCustomPadConfigurations);
|
||||
|
||||
connect(ui->sysPauseAct, &QAction::triggered, this, &main_window::OnPlayOrPause);
|
||||
connect(ui->sysStopAct, &QAction::triggered, [=]() { Emu.Stop(); });
|
||||
@ -1282,20 +1283,19 @@ void main_window::CreateConnects()
|
||||
|
||||
auto openPadSettings = [this]
|
||||
{
|
||||
auto resetPadHandlers = [this](int/* result*/)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Emu.GetCallbacks().reset_pads();
|
||||
};
|
||||
if (!Emu.IsStopped())
|
||||
{
|
||||
Emu.GetCallbacks().enable_pads(false);
|
||||
}
|
||||
pad_settings_dialog dlg(this);
|
||||
connect(&dlg, &QDialog::finished, resetPadHandlers);
|
||||
connect(&dlg, &QDialog::finished, [this](int/* result*/)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Emu.GetCallbacks().reset_pads(Emu.GetTitleID());
|
||||
});
|
||||
dlg.exec();
|
||||
if (!Emu.IsStopped())
|
||||
{
|
||||
|
@ -141,7 +141,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1058</width>
|
||||
<height>21</height>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
@ -172,6 +172,7 @@
|
||||
<addaction name="batchCreatePPUCachesAct"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="batchRemoveCustomConfigurationsAct"/>
|
||||
<addaction name="batchRemoveCustomPadConfigurationsAct"/>
|
||||
<addaction name="batchRemovePPUCachesAct"/>
|
||||
<addaction name="batchRemoveSPUCachesAct"/>
|
||||
<addaction name="batchRemoveShaderCachesAct"/>
|
||||
@ -995,6 +996,11 @@
|
||||
<string>Remove Shader Caches</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="batchRemoveCustomPadConfigurationsAct">
|
||||
<property name="text">
|
||||
<string>Remove Custom Pad Configurations</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <QCheckBox>
|
||||
#include <QCheckBox>
|
||||
#include <QGroupBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
@ -29,19 +29,13 @@ constexpr auto qstr = QString::fromStdString;
|
||||
|
||||
inline bool CreateConfigFile(const QString& dir, const QString& name)
|
||||
{
|
||||
QString input_dir = qstr(fs::get_config_dir()) + "/InputConfigs/";
|
||||
if (!QDir().mkdir(input_dir) && !QDir().exists(input_dir))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "Failed to create dir %s", sstr(input_dir));
|
||||
return false;
|
||||
}
|
||||
if (!QDir().mkdir(dir) && !QDir().exists(dir))
|
||||
if (!QDir().mkpath(dir))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "Failed to create dir %s", sstr(dir));
|
||||
return false;
|
||||
}
|
||||
|
||||
QString filename = dir + name + ".yml";
|
||||
const QString filename = dir + name + ".yml";
|
||||
QFile new_file(filename);
|
||||
|
||||
if (!new_file.open(QIODevice::WriteOnly))
|
||||
@ -54,16 +48,25 @@ inline bool CreateConfigFile(const QString& dir, const QString& name)
|
||||
return true;
|
||||
};
|
||||
|
||||
pad_settings_dialog::pad_settings_dialog(QWidget *parent)
|
||||
pad_settings_dialog::pad_settings_dialog(QWidget *parent, const GameInfo *game)
|
||||
: QDialog(parent), ui(new Ui::pad_settings_dialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowTitle(tr("Gamepads Settings"));
|
||||
|
||||
// load input config
|
||||
g_cfg_input.from_default();
|
||||
g_cfg_input.load();
|
||||
|
||||
if (game)
|
||||
{
|
||||
m_title_id = game->serial;
|
||||
g_cfg_input.load(game->serial);
|
||||
setWindowTitle(tr("Gamepads Settings: [%0] %1").arg(qstr(game->serial)).arg(qstr(game->name).simplified()));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_cfg_input.load();
|
||||
setWindowTitle(tr("Gamepads Settings"));
|
||||
}
|
||||
|
||||
// Create tab widget for 7 players
|
||||
m_tabs = new QTabWidget;
|
||||
@ -153,7 +156,7 @@ pad_settings_dialog::pad_settings_dialog(QWidget *parent)
|
||||
QMessageBox::warning(this, tr("Error"), tr("Please choose a non-existing name"));
|
||||
continue;
|
||||
}
|
||||
if (CreateConfigFile(qstr(PadHandlerBase::get_config_dir(g_cfg_input.player[i]->handler)), friendlyName))
|
||||
if (CreateConfigFile(qstr(PadHandlerBase::get_config_dir(g_cfg_input.player[i]->handler, m_title_id)), friendlyName))
|
||||
{
|
||||
ui->chooseProfile->addItem(friendlyName);
|
||||
ui->chooseProfile->setCurrentText(friendlyName);
|
||||
@ -839,6 +842,7 @@ void pad_settings_dialog::OnPadButtonClicked(int id)
|
||||
|
||||
void pad_settings_dialog::OnTabChanged(int index)
|
||||
{
|
||||
// TODO: Do not save yet! But keep all profile changes until the dialog was saved.
|
||||
// Save old profile
|
||||
SaveProfile();
|
||||
|
||||
@ -898,7 +902,7 @@ void pad_settings_dialog::ChangeInputType()
|
||||
if (!g_cfg_input.player[player]->handler.from_string(handler))
|
||||
{
|
||||
// Something went wrong
|
||||
LOG_ERROR(GENERAL, "Failed to convert input string:%s", handler);
|
||||
LOG_ERROR(GENERAL, "Failed to convert input string: %s", handler);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -963,7 +967,7 @@ void pad_settings_dialog::ChangeInputType()
|
||||
}
|
||||
}
|
||||
|
||||
QString profile_dir = qstr(PadHandlerBase::get_config_dir(m_handler->m_type));
|
||||
QString profile_dir = qstr(PadHandlerBase::get_config_dir(m_handler->m_type, m_title_id));
|
||||
QStringList profiles = gui::utils::get_dir_entries(QDir(profile_dir), QStringList() << "*.yml");
|
||||
|
||||
if (profiles.isEmpty())
|
||||
@ -1021,7 +1025,7 @@ void pad_settings_dialog::ChangeProfile()
|
||||
}
|
||||
|
||||
// Change handler
|
||||
const std::string cfg_name = PadHandlerBase::get_config_dir(m_handler->m_type) + m_profile + ".yml";
|
||||
const std::string cfg_name = PadHandlerBase::get_config_dir(m_handler->m_type, m_title_id) + m_profile + ".yml";
|
||||
|
||||
// Adjust to the different pad handlers
|
||||
switch (m_handler->m_type)
|
||||
@ -1145,7 +1149,7 @@ void pad_settings_dialog::SaveExit()
|
||||
g_cfg_input.player[i]->profile.from_default();
|
||||
}
|
||||
|
||||
g_cfg_input.save();
|
||||
g_cfg_input.save(m_title_id);
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
#include "Emu/Io/PadHandler.h"
|
||||
#include "Emu/GameInfo.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -85,7 +86,7 @@ class pad_settings_dialog : public QDialog
|
||||
const QString Disconnected_suffix = tr(" (disconnected)");
|
||||
|
||||
public:
|
||||
explicit pad_settings_dialog(QWidget *parent = nullptr);
|
||||
explicit pad_settings_dialog(QWidget *parent = nullptr, const GameInfo *game = nullptr);
|
||||
~pad_settings_dialog();
|
||||
|
||||
private Q_SLOTS:
|
||||
@ -100,6 +101,7 @@ private Q_SLOTS:
|
||||
|
||||
private:
|
||||
Ui::pad_settings_dialog *ui;
|
||||
std::string m_title_id;
|
||||
|
||||
// TabWidget
|
||||
QTabWidget* m_tabs;
|
||||
|
Loading…
x
Reference in New Issue
Block a user