mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 13:47:57 +03:00
initial Gamepad profiles support
This commit is contained in:
parent
8b21aca123
commit
cce77fc4ab
10 changed files with 238 additions and 45 deletions
|
@ -198,6 +198,8 @@ set(COMMON_SRC_FILES
|
|||
FpUtils.h
|
||||
FrameDump.cpp
|
||||
FrameDump.h
|
||||
InputConfig.cpp
|
||||
InputConfig.h
|
||||
GenericMipsExecutor.h
|
||||
gs/GsCachedArea.cpp
|
||||
gs/GsCachedArea.h
|
||||
|
|
46
Source/InputConfig.cpp
Normal file
46
Source/InputConfig.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include "AppConfig.h"
|
||||
#include "InputConfig.h"
|
||||
#include "PathUtils.h"
|
||||
|
||||
#define PROFILE_PATH ("inputprofiles")
|
||||
|
||||
CInputConfig::CInputConfig(const Framework::CConfig::PathType& path)
|
||||
: CConfig(path)
|
||||
{
|
||||
}
|
||||
|
||||
bool CInputConfig::IsValidProfileName(std::string name)
|
||||
{
|
||||
static const std::string valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-";
|
||||
for(auto c : name)
|
||||
{
|
||||
if(valid_chars.find(c) == std::string::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<CInputConfig> CInputConfig::LoadProfile(std::string name)
|
||||
{
|
||||
auto path = GetProfilePath() / name;
|
||||
path.replace_extension(".xml");
|
||||
return std::make_unique<CInputConfig>(path);
|
||||
}
|
||||
|
||||
Framework::CConfig::PathType CInputConfig::GetProfilePath()
|
||||
{
|
||||
auto profile_path = CAppConfig::GetBasePath() / PROFILE_PATH;
|
||||
Framework::PathUtils::EnsurePathExists(profile_path);
|
||||
return profile_path;
|
||||
}
|
||||
|
||||
Framework::CConfig::PathType CInputConfig::GetProfile(std::string name)
|
||||
{
|
||||
auto profile_path = CAppConfig::GetBasePath() / PROFILE_PATH;
|
||||
Framework::PathUtils::EnsurePathExists(profile_path);
|
||||
profile_path /= name;
|
||||
profile_path.replace_extension(".xml");
|
||||
return profile_path;
|
||||
}
|
17
Source/InputConfig.h
Normal file
17
Source/InputConfig.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#define DEFAULT_PROFILE ("default")
|
||||
|
||||
class CInputConfig : public Framework::CConfig
|
||||
{
|
||||
public:
|
||||
CInputConfig(const Framework::CConfig::PathType& path);
|
||||
virtual ~CInputConfig() = default;
|
||||
|
||||
static bool IsValidProfileName(std::string);
|
||||
static CConfig::PathType GetProfilePath();
|
||||
static CConfig::PathType GetProfile(std::string = DEFAULT_PROFILE);
|
||||
static std::unique_ptr<CInputConfig> LoadProfile(std::string = DEFAULT_PROFILE);
|
||||
};
|
|
@ -98,23 +98,9 @@ static void SaveBindingTargetPreference(Framework::CConfig& config, const char*
|
|||
}
|
||||
|
||||
CInputBindingManager::CInputBindingManager()
|
||||
: m_config(CAppConfig::GetInstance())
|
||||
{
|
||||
for(unsigned int pad = 0; pad < MAX_PADS; pad++)
|
||||
{
|
||||
for(unsigned int button = 0; button < PS2::CControllerInfo::MAX_BUTTONS; button++)
|
||||
{
|
||||
auto prefBase = Framework::CConfig::MakePreferenceName(CONFIG_PREFIX, m_padPreferenceName[pad], PS2::CControllerInfo::m_buttonName[button]);
|
||||
m_config.RegisterPreferenceInteger(Framework::CConfig::MakePreferenceName(prefBase, CONFIG_BINDING_TYPE).c_str(), 0);
|
||||
RegisterBindingTargetPreference(m_config, Framework::CConfig::MakePreferenceName(prefBase, CONFIG_BINDINGTARGET1).c_str());
|
||||
if(PS2::CControllerInfo::IsAxis(static_cast<PS2::CControllerInfo::BUTTON>(button)))
|
||||
{
|
||||
RegisterBindingTargetPreference(m_config, Framework::CConfig::MakePreferenceName(prefBase, CONFIG_BINDINGTARGET2).c_str());
|
||||
}
|
||||
CPovHatBinding::RegisterPreferences(m_config, prefBase.c_str());
|
||||
}
|
||||
}
|
||||
Load();
|
||||
m_config = CInputConfig::LoadProfile();
|
||||
Reload();
|
||||
}
|
||||
|
||||
bool CInputBindingManager::HasBindings() const
|
||||
|
@ -174,15 +160,31 @@ void CInputBindingManager::OnInputEventReceived(const BINDINGTARGET& target, uin
|
|||
}
|
||||
}
|
||||
|
||||
void CInputBindingManager::Load()
|
||||
void CInputBindingManager::Reload()
|
||||
{
|
||||
|
||||
for(unsigned int pad = 0; pad < MAX_PADS; pad++)
|
||||
{
|
||||
for(unsigned int button = 0; button < PS2::CControllerInfo::MAX_BUTTONS; button++)
|
||||
{
|
||||
auto prefBase = Framework::CConfig::MakePreferenceName(CONFIG_PREFIX, m_padPreferenceName[pad], PS2::CControllerInfo::m_buttonName[button]);
|
||||
m_config->RegisterPreferenceInteger(Framework::CConfig::MakePreferenceName(prefBase, CONFIG_BINDING_TYPE).c_str(), 0);
|
||||
RegisterBindingTargetPreference(*m_config, Framework::CConfig::MakePreferenceName(prefBase, CONFIG_BINDINGTARGET1).c_str());
|
||||
if(PS2::CControllerInfo::IsAxis(static_cast<PS2::CControllerInfo::BUTTON>(button)))
|
||||
{
|
||||
RegisterBindingTargetPreference(*m_config, Framework::CConfig::MakePreferenceName(prefBase, CONFIG_BINDINGTARGET2).c_str());
|
||||
}
|
||||
CPovHatBinding::RegisterPreferences(*m_config, prefBase.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int pad = 0; pad < MAX_PADS; pad++)
|
||||
{
|
||||
for(unsigned int button = 0; button < PS2::CControllerInfo::MAX_BUTTONS; button++)
|
||||
{
|
||||
BINDINGTYPE bindingType = BINDING_UNBOUND;
|
||||
auto prefBase = Framework::CConfig::MakePreferenceName(CONFIG_PREFIX, m_padPreferenceName[pad], PS2::CControllerInfo::m_buttonName[button]);
|
||||
bindingType = static_cast<BINDINGTYPE>(m_config.GetPreferenceInteger((prefBase + "." + std::string(CONFIG_BINDING_TYPE)).c_str()));
|
||||
bindingType = static_cast<BINDINGTYPE>(m_config->GetPreferenceInteger((prefBase + "." + std::string(CONFIG_BINDING_TYPE)).c_str()));
|
||||
if(bindingType == BINDING_UNBOUND) continue;
|
||||
BindingPtr binding;
|
||||
switch(bindingType)
|
||||
|
@ -199,7 +201,7 @@ void CInputBindingManager::Load()
|
|||
}
|
||||
if(binding)
|
||||
{
|
||||
binding->Load(m_config, prefBase.c_str());
|
||||
binding->Load(*m_config, prefBase.c_str());
|
||||
}
|
||||
m_bindings[pad][button] = binding;
|
||||
}
|
||||
|
@ -207,6 +209,12 @@ void CInputBindingManager::Load()
|
|||
ResetBindingValues();
|
||||
}
|
||||
|
||||
void CInputBindingManager::Load(std::string profile)
|
||||
{
|
||||
m_config = CInputConfig::LoadProfile(profile);
|
||||
Reload();
|
||||
}
|
||||
|
||||
void CInputBindingManager::Save()
|
||||
{
|
||||
for(unsigned int pad = 0; pad < MAX_PADS; pad++)
|
||||
|
@ -216,11 +224,11 @@ void CInputBindingManager::Save()
|
|||
const auto& binding = m_bindings[pad][button];
|
||||
if(!binding) continue;
|
||||
auto prefBase = Framework::CConfig::MakePreferenceName(CONFIG_PREFIX, m_padPreferenceName[pad], PS2::CControllerInfo::m_buttonName[button]);
|
||||
m_config.SetPreferenceInteger(Framework::CConfig::MakePreferenceName(prefBase, CONFIG_BINDING_TYPE).c_str(), binding->GetBindingType());
|
||||
binding->Save(m_config, prefBase.c_str());
|
||||
m_config->SetPreferenceInteger(Framework::CConfig::MakePreferenceName(prefBase, CONFIG_BINDING_TYPE).c_str(), binding->GetBindingType());
|
||||
binding->Save(*m_config, prefBase.c_str());
|
||||
}
|
||||
}
|
||||
m_config.Save();
|
||||
m_config->Save();
|
||||
}
|
||||
|
||||
const CInputBindingManager::CBinding* CInputBindingManager::GetBinding(uint32 pad, PS2::CControllerInfo::BUTTON button) const
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "Config.h"
|
||||
#include "InputConfig.h"
|
||||
#include "ControllerInfo.h"
|
||||
#include "InputProvider.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
class CInputBindingManager
|
||||
{
|
||||
|
@ -60,7 +62,8 @@ public:
|
|||
void SetPovHatBinding(uint32, PS2::CControllerInfo::BUTTON, const BINDINGTARGET&, uint32);
|
||||
void SetSimulatedAxisBinding(uint32, PS2::CControllerInfo::BUTTON, const BINDINGTARGET&, const BINDINGTARGET&);
|
||||
|
||||
void Load();
|
||||
void Reload();
|
||||
void Load(std::string);
|
||||
void Save();
|
||||
|
||||
private:
|
||||
|
@ -149,6 +152,6 @@ private:
|
|||
static uint32 m_buttonDefaultValue[PS2::CControllerInfo::MAX_BUTTONS];
|
||||
static const char* m_padPreferenceName[MAX_PADS];
|
||||
|
||||
Framework::CConfig& m_config;
|
||||
std::unique_ptr<CInputConfig> m_config;
|
||||
ProviderMap m_providers;
|
||||
};
|
||||
|
|
|
@ -6,10 +6,18 @@
|
|||
#include <QFile>
|
||||
#include <QAbstractButton>
|
||||
#include <QPushButton>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include "PreferenceDefs.h"
|
||||
#include "PathUtils.h"
|
||||
#include "bindingmodel.h"
|
||||
#include "ControllerInfo.h"
|
||||
#include "inputeventselectiondialog.h"
|
||||
#include "QStringUtils.h"
|
||||
|
||||
#include "filesystem_def.h"
|
||||
#include <iostream>
|
||||
|
||||
ControllerConfigDialog::ControllerConfigDialog(CInputBindingManager* inputBindingManager, CInputProviderQtKey* qtKeyInputProvider, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
|
@ -18,7 +26,23 @@ ControllerConfigDialog::ControllerConfigDialog(CInputBindingManager* inputBindin
|
|||
, m_qtKeyInputProvider(qtKeyInputProvider)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
std::string profile = CAppConfig::GetInstance().GetPreferenceString(PREF_INPUT_PAD1_PROFILE);
|
||||
|
||||
PrepareBindingsView();
|
||||
|
||||
auto path = CInputConfig::GetProfilePath();
|
||||
if(fs::is_directory(path))
|
||||
{
|
||||
for(auto& entry : fs::directory_iterator(path))
|
||||
{
|
||||
auto profile = Framework::PathUtils::GetNativeStringFromPath(entry.path().stem());
|
||||
ui->comboBox->addItem(profile.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
auto index = ui->comboBox->findText(profile.c_str());
|
||||
if(index >= 0)
|
||||
ui->comboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
ControllerConfigDialog::~ControllerConfigDialog()
|
||||
|
@ -43,10 +67,12 @@ void ControllerConfigDialog::on_buttonBox_clicked(QAbstractButton* button)
|
|||
if(button == ui->buttonBox->button(QDialogButtonBox::Ok))
|
||||
{
|
||||
m_inputManager->Save();
|
||||
CAppConfig::GetInstance().Save();
|
||||
}
|
||||
else if(button == ui->buttonBox->button(QDialogButtonBox::Apply))
|
||||
{
|
||||
m_inputManager->Save();
|
||||
CAppConfig::GetInstance().Save();
|
||||
}
|
||||
else if(button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults))
|
||||
{
|
||||
|
@ -60,7 +86,7 @@ void ControllerConfigDialog::on_buttonBox_clicked(QAbstractButton* button)
|
|||
}
|
||||
else if(button == ui->buttonBox->button(QDialogButtonBox::Cancel))
|
||||
{
|
||||
m_inputManager->Load();
|
||||
m_inputManager->Reload();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,3 +150,58 @@ int ControllerConfigDialog::OpenBindConfigDialog(int index)
|
|||
auto res = IESD.exec();
|
||||
return res;
|
||||
}
|
||||
|
||||
void ControllerConfigDialog::on_comboBox_currentIndexChanged(int index)
|
||||
{
|
||||
ui->delProfileButton->setEnabled(index > 0);
|
||||
|
||||
auto profile = ui->comboBox->itemText(index).toStdString();
|
||||
m_inputManager->Load(profile.c_str());
|
||||
CAppConfig::GetInstance().SetPreferenceString(PREF_INPUT_PAD1_PROFILE, profile.c_str());
|
||||
|
||||
static_cast<CBindingModel*>(ui->tableView->model())->Refresh();
|
||||
}
|
||||
|
||||
void ControllerConfigDialog::on_addProfileButton_clicked()
|
||||
{
|
||||
std::string profile_name;
|
||||
while(profile_name.empty())
|
||||
{
|
||||
bool ok_pressed = false;
|
||||
QString name = QInputDialog::getText(this, tr("Enter Profile Name"), tr("Only letters, numbers and dash characters allowed.\nProfile name:"),
|
||||
QLineEdit::Normal, "", &ok_pressed);
|
||||
|
||||
if(!ok_pressed)
|
||||
return;
|
||||
|
||||
if(!name.isEmpty() && CInputConfig::IsValidProfileName(name.toStdString()))
|
||||
profile_name = name.toStdString();
|
||||
}
|
||||
|
||||
{
|
||||
auto profile_path = CInputConfig::GetProfile(profile_name);
|
||||
if(!fs::exists(profile_path))
|
||||
{
|
||||
ui->comboBox->addItem(profile_name.c_str());
|
||||
}
|
||||
|
||||
auto index = ui->comboBox->findText(profile_name.c_str());
|
||||
if(index >= 0)
|
||||
ui->comboBox->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerConfigDialog::on_delProfileButton_clicked()
|
||||
{
|
||||
auto name = ui->comboBox->currentText();
|
||||
std::string profile_name = name.toStdString();
|
||||
{
|
||||
auto profile_path = CInputConfig::GetProfile(profile_name);
|
||||
if(fs::exists(profile_path))
|
||||
{
|
||||
fs::remove(profile_path);
|
||||
int index = ui->comboBox->currentIndex();
|
||||
ui->comboBox->removeItem(index);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,6 +27,10 @@ private slots:
|
|||
void on_tableView_doubleClicked(const QModelIndex& index);
|
||||
void on_ConfigAllButton_clicked();
|
||||
|
||||
void on_comboBox_currentIndexChanged(int index);
|
||||
void on_addProfileButton_clicked();
|
||||
void on_delProfileButton_clicked();
|
||||
|
||||
private:
|
||||
void PrepareBindingsView();
|
||||
int OpenBindConfigDialog(int index);
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
#define PREFERENCE_AUDIO_ENABLEOUTPUT "audio.enableoutput"
|
||||
#define PREF_UI_PAUSEWHENFOCUSLOST "ui.pausewhenfocuslost"
|
||||
#define PREF_VIDEO_GS_HANDLER "video.gshandler"
|
||||
#define PREF_INPUT_PAD1_PROFILE "input.pad1.profile"
|
||||
|
|
|
@ -26,26 +26,6 @@
|
|||
<string>Controller Manager</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="ConfigAllButton">
|
||||
<property name="text">
|
||||
<string>Config All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="enabled">
|
||||
|
@ -83,6 +63,53 @@ QGroupBox::title {
|
|||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="ConfigAllButton">
|
||||
<property name="text">
|
||||
<string>Config All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Profile(s)</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox">
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addProfileButton">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="delProfileButton">
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
|
|
|
@ -150,7 +150,10 @@ void MainWindow::InitVirtualMachine()
|
|||
{
|
||||
m_virtualMachine->CreatePadHandler(CPH_GenericInput::GetFactoryFunction());
|
||||
auto padHandler = static_cast<CPH_GenericInput*>(m_virtualMachine->GetPadHandler());
|
||||
auto profile = CAppConfig::GetInstance().GetPreferenceString(PREF_INPUT_PAD1_PROFILE);
|
||||
|
||||
auto& bindingManager = padHandler->GetBindingManager();
|
||||
bindingManager.Load(profile);
|
||||
|
||||
//Create QtKeyInputProvider
|
||||
m_qtKeyInputProvider = std::make_shared<CInputProviderQtKey>();
|
||||
|
@ -642,6 +645,7 @@ void MainWindow::RegisterPreferences()
|
|||
CAppConfig::GetInstance().RegisterPreferenceBoolean(PREFERENCE_AUDIO_ENABLEOUTPUT, true);
|
||||
CAppConfig::GetInstance().RegisterPreferenceBoolean(PREF_UI_PAUSEWHENFOCUSLOST, true);
|
||||
CAppConfig::GetInstance().RegisterPreferenceInteger(PREF_VIDEO_GS_HANDLER, SettingsDialog::GS_HANDLERS::OPENGL);
|
||||
CAppConfig::GetInstance().RegisterPreferenceString(PREF_INPUT_PAD1_PROFILE, "default");
|
||||
}
|
||||
|
||||
void MainWindow::focusOutEvent(QFocusEvent* event)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue