diff --git a/Common/IniFile.cpp b/Common/IniFile.cpp index ff867a01b..40abe0280 100644 --- a/Common/IniFile.cpp +++ b/Common/IniFile.cpp @@ -148,7 +148,7 @@ void IniFile::Section::Set(const char* key, const std::vector& newV std::vector::const_iterator it; for (it = newValues.begin(); it != newValues.end(); ++it) { - temp = (*it) + ","; + temp += (*it) + ","; } // remove last , if (temp.length()) diff --git a/Common/IniFile.h b/Common/IniFile.h index 14c3bfeb3..09ce6ca0d 100644 --- a/Common/IniFile.h +++ b/Common/IniFile.h @@ -20,6 +20,7 @@ #include #include +#include #include "StringUtil.h" @@ -68,12 +69,48 @@ public: } void Set(const char* key, const std::vector& newValues); + template + void Set(const char* key, const std::map& newValues) + { + std::vector temp; + for(typename std::map::const_iterator it = newValues.begin(); it != newValues.end(); it++) + { + temp.push_back(ValueToString(it->first)+"_"+ValueToString(it->second)); + } + Set(key,temp); + } + bool Get(const char* key, int* value, int defaultValue = 0); bool Get(const char* key, u32* value, u32 defaultValue = 0); bool Get(const char* key, bool* value, bool defaultValue = false); bool Get(const char* key, float* value, float defaultValue = false); bool Get(const char* key, double* value, double defaultValue = false); bool Get(const char* key, std::vector& values); + template + bool Get(const char* key, std::map& values) + { + std::vector temp; + if(!Get(key,temp)) + { + return false; + } + values.clear(); + for(int i = 0; i < temp.size(); i++) + { + std::vector key_val; + SplitString(temp[i],'_',key_val); + if(key_val.size() < 2) + continue; + U mapKey; + V mapValue; + if(!TryParse(key_val[0],&mapKey)) + continue; + if(!TryParse(key_val[1],&mapValue)) + continue; + values[mapKey] = mapValue; + } + return true; + } bool operator < (const Section& other) const { return name < other.name; diff --git a/Common/StringUtil.h b/Common/StringUtil.h index 0b2ca1bd0..f27678ebf 100644 --- a/Common/StringUtil.h +++ b/Common/StringUtil.h @@ -118,6 +118,14 @@ static bool TryParse(const std::string &str, N *const output) return false; } +template +static std::string ValueToString(const N value) +{ + std::stringstream string; + string << value; + return string.str(); +} + // TODO: kill this bool AsciiToHex(const char* _szValue, u32& result); diff --git a/Core/Config.cpp b/Core/Config.cpp index 270cdbb4a..08ceab4dd 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -83,6 +83,7 @@ void CConfig::Load(const char *iniFileName) false); #endif control->Get("LargeControls", &bLargeControls, false); + control->Get("KeyMapping",iMappingMap); IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam"); pspConfig->Get("Language", &ilanguage, PSP_SYSTEMPARAM_LANGUAGE_ENGLISH); @@ -133,6 +134,7 @@ void CConfig::Save() control->Set("ShowStick", bShowAnalogStick); control->Set("ShowTouchControls", bShowTouchControls); control->Set("LargeControls", bLargeControls); + control->Set("KeyMapping",iMappingMap); IniFile::Section *pspConfig = iniFile.GetOrCreateSection("SystemParam"); pspConfig->Set("Language", ilanguage); diff --git a/Core/Config.h b/Core/Config.h index 6ff3b7513..5eeebf1b4 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -18,6 +18,7 @@ #pragma once #include +#include #define PPSSPP_VERSION_STR "0.6.1" @@ -73,6 +74,9 @@ public: bool bShowDebugStats; bool bLargeControls; + // Control + std::map iMappingMap; // Can be used differently depending on systems + // SystemParam int ilanguage; int itimeformat; diff --git a/Qt/EmuThread.cpp b/Qt/EmuThread.cpp index 4ffd52b3a..935766b81 100644 --- a/Qt/EmuThread.cpp +++ b/Qt/EmuThread.cpp @@ -109,27 +109,12 @@ void EmuThread::run() UpdateInputState(input_state); - static const int mapping[12][2] = { - {PAD_BUTTON_A, CTRL_CROSS}, - {PAD_BUTTON_B, CTRL_CIRCLE}, - {PAD_BUTTON_X, CTRL_SQUARE}, - {PAD_BUTTON_Y, CTRL_TRIANGLE}, - {PAD_BUTTON_UP, CTRL_UP}, - {PAD_BUTTON_DOWN, CTRL_DOWN}, - {PAD_BUTTON_LEFT, CTRL_LEFT}, - {PAD_BUTTON_RIGHT, CTRL_RIGHT}, - {PAD_BUTTON_LBUMPER, CTRL_LTRIGGER}, - {PAD_BUTTON_RBUMPER, CTRL_RTRIGGER}, - {PAD_BUTTON_START, CTRL_START}, - {PAD_BUTTON_SELECT, CTRL_SELECT}, - }; - - for (int i = 0; i < 12; i++) { - if (input_state->pad_buttons_down & mapping[i][0]) { - __CtrlButtonDown(mapping[i][1]); + for (int i = 0; i < controllistCount; i++) { + if (input_state->pad_buttons_down & controllist[i].emu_id) { + __CtrlButtonDown(controllist[i].psp_id); } - if (input_state->pad_buttons_up & mapping[i][0]) { - __CtrlButtonUp(mapping[i][1]); + if (input_state->pad_buttons_up & controllist[i].emu_id) { + __CtrlButtonUp(controllist[i].psp_id); } } __CtrlSetAnalog(input_state->pad_lstick_x, input_state->pad_lstick_y); diff --git a/Qt/PPSSPP.pro b/Qt/PPSSPP.pro index 4f018883c..c60866afb 100755 --- a/Qt/PPSSPP.pro +++ b/Qt/PPSSPP.pro @@ -21,8 +21,10 @@ linux: LIBS += -L. -lCore -lCommon -lNative linux: PRE_TARGETDEPS += ./libCommon.a ./libCore.a ./libNative.a # Main -SOURCES += ../native/base/QtMain.cpp -HEADERS += ../native/base/QtMain.h +SOURCES += ../native/base/QtMain.cpp \ + qkeyedit.cpp +HEADERS += ../native/base/QtMain.h \ + qkeyedit.h # Native SOURCES += ../android/jni/EmuScreen.cpp \ @@ -73,4 +75,7 @@ linux:!mobile_platform { FORMS += mainwindow.ui \ debugger_disasm.ui \ controls.ui + + RESOURCES += \ + resources.qrc } diff --git a/Qt/controls.cpp b/Qt/controls.cpp index 82993f791..ad1fa8356 100644 --- a/Qt/controls.cpp +++ b/Qt/controls.cpp @@ -1,29 +1,24 @@ #include "controls.h" #include "ui_controls.h" +#include "Core/Config.h" -struct Controls_ -{ - char* command; - char* key; -}; - -const Controls_ controllist[] = { - {"Start","1"}, - {"Select","2"}, - {"Square","Z"}, - {"Triangle","A"}, - {"Circle","S"}, - {"Cross","X"}, - {"Left Trigger","Q"}, - {"Right Trigger","W"}, - {"Up","Arrow Up"}, - {"Down","Arrow Down"}, - {"Left","Arrow Left"}, - {"Right","Arrow Right"}, - {"Analog Up","I"}, - {"Analog Down","K"}, - {"Analog Left","J"}, - {"Analog Right","L"}, +Controls_ controllist[] = { + {"Edit_Start", "Start", Qt::Key_1, PAD_BUTTON_START, CTRL_START}, + {"Edit_Select", "Select", Qt::Key_2, PAD_BUTTON_SELECT, CTRL_SELECT}, + {"Edit_S", "Square", Qt::Key_Z, PAD_BUTTON_X, CTRL_SQUARE}, + {"Edit_T", "Triangle", Qt::Key_A, PAD_BUTTON_Y, CTRL_TRIANGLE}, + {"Edit_O", "Circle", Qt::Key_S, PAD_BUTTON_B, CTRL_CIRCLE}, + {"Edit_X", "Cross", Qt::Key_X, PAD_BUTTON_A, CTRL_CROSS}, + {"Edit_LT", "Left Trigger", Qt::Key_Q, PAD_BUTTON_LBUMPER, CTRL_LTRIGGER}, + {"Edit_RT", "Right Trigger", Qt::Key_W, PAD_BUTTON_RBUMPER, CTRL_RTRIGGER}, + {"Edit_Up", "Up", Qt::Key_Up, PAD_BUTTON_UP, CTRL_UP}, + {"Edit_Down", "Down", Qt::Key_Down, PAD_BUTTON_DOWN, CTRL_DOWN}, + {"Edit_Left", "Left", Qt::Key_Left, PAD_BUTTON_LEFT, CTRL_LEFT}, + {"Edit_Right", "Right", Qt::Key_Right, PAD_BUTTON_RIGHT, CTRL_RIGHT}, + {"", "Analog Up", Qt::Key_I, PAD_BUTTON_JOY_UP, 0}, + {"", "Analog Down", Qt::Key_K, PAD_BUTTON_JOY_DOWN,0}, + {"", "Analog Left", Qt::Key_J, PAD_BUTTON_JOY_LEFT,0}, + {"", "Analog Right", Qt::Key_L, PAD_BUTTON_JOY_RIGHT,0}, }; Controls::Controls(QWidget *parent) : @@ -31,25 +26,47 @@ Controls::Controls(QWidget *parent) : ui(new Ui::Controls) { ui->setupUi(this); - - int numRows = sizeof(controllist)/sizeof(Controls_); - - ui->listControls->setRowCount(numRows); - - for(int i = 0; i < numRows; i++) - { - QTableWidgetItem* item = new QTableWidgetItem(); - item->setText(controllist[i].command); - ui->listControls->setItem(i,0,item); - - item = new QTableWidgetItem(); - item->setText(controllist[i].key); - ui->listControls->setItem(i,1,item); - ui->listControls->setRowHeight(i,15); - } } Controls::~Controls() { delete ui; } + +void Controls::showEvent(QShowEvent*) +{ + for(int i = 0; i < controllistCount; i++) + { + if(g_Config.iMappingMap.find(i) != g_Config.iMappingMap.end()) + { + controllist[i].key = (Qt::Key)g_Config.iMappingMap[i]; + } + + if(controllist[i].editName != "") + { + QLineEdit* edit = findChild(controllist[i].editName); + if(edit) + { + QKeySequence sec(controllist[i].key); + edit->setText(sec.toString()); + } + } + } +} + +void Controls::on_buttonBox_accepted() +{ + for(int i = 0; i < controllistCount; i++) + { + if(controllist[i].editName != "") + { + QLineEdit* edit = findChild(controllist[i].editName); + if(edit) + { + QKeySequence sec(edit->text()); + controllist[i].key = (Qt::Key)sec[0]; + g_Config.iMappingMap[i] = sec[0]; + } + } + } +} diff --git a/Qt/controls.h b/Qt/controls.h index fb5d1ad3a..347fd8b25 100644 --- a/Qt/controls.h +++ b/Qt/controls.h @@ -2,11 +2,26 @@ #define CONTROLS_H #include +#include "native/input/input_state.h" +#include "Core/HLE/sceCtrl.h" namespace Ui { class Controls; } +struct Controls_ +{ +public: + QString editName; + QString command; + Qt::Key key; + int emu_id; + int psp_id; +}; + +const int controllistCount = 16; +extern Controls_ controllist[]; + class Controls : public QDialog { Q_OBJECT @@ -14,7 +29,11 @@ class Controls : public QDialog public: explicit Controls(QWidget *parent = 0); ~Controls(); - + + void showEvent(QShowEvent *); +private slots: + void on_buttonBox_accepted(); + private: Ui::Controls *ui; }; diff --git a/Qt/controls.ui b/Qt/controls.ui index 9215adf9f..77de1e830 100644 --- a/Qt/controls.ui +++ b/Qt/controls.ui @@ -6,43 +6,180 @@ 0 0 - 400 - 300 + 618 + 351 + + + 0 + 0 + + Dialog - - - Note : Currently controls are NOT configurable. + + + + 600 + 300 + - - - - - - QAbstractItemView::SingleSelection + + + 600 + 300 + - - QAbstractItemView::SelectRows - - - false - - - 2 - - - false - - - false - - - + + + + 50 + 50 + 501 + 191 + + + + + + + :/images/resources/psp.png + + + + + + 50 + 100 + 41 + 25 + + + + + + + 30 + 130 + 41 + 25 + + + + + + + 80 + 130 + 41 + 25 + + + + + + + 50 + 160 + 41 + 25 + + + + + + + 150 + 240 + 41 + 25 + + + + + + + 410 + 240 + 41 + 25 + + + + + + + 360 + 240 + 41 + 25 + + + + + + + 510 + 160 + 41 + 25 + + + + + + + 480 + 130 + 41 + 25 + + + + + + + 530 + 130 + 41 + 25 + + + + + + + 510 + 100 + 41 + 25 + + + + + + + 440 + 20 + 41 + 25 + + + + + + + 120 + 20 + 41 + 25 + + + @@ -57,7 +194,16 @@ - + + + QKeyEdit + QLineEdit +
qkeyedit.h
+
+
+ + + buttonBox diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index 4456555cb..497a8178c 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -20,28 +20,6 @@ #include "QtHost.h" #include "EmuThread.h" -// Input -const int buttonMappings[18] = { - Qt::Key_X, //A - Qt::Key_S, //B - Qt::Key_Z, //X - Qt::Key_A, //Y - Qt::Key_W, //LBUMPER - Qt::Key_Q, //RBUMPER - Qt::Key_1, //START - Qt::Key_2, //SELECT - Qt::Key_Up, //UP - Qt::Key_Down, //DOWN - Qt::Key_Left, //LEFT - Qt::Key_Right, //RIGHT - 0, //MENU (event) - Qt::Key_Backspace, //BACK - Qt::Key_I, //JOY UP - Qt::Key_K, //JOY DOWN - Qt::Key_J, //JOY LEFT - Qt::Key_L, //JOY RIGHT -}; - const char *stateToLoad = NULL; MainWindow::MainWindow(QWidget *parent) : @@ -673,20 +651,20 @@ void MainWindow::keyPressEvent(QKeyEvent *e) return; } - for (int b = 0; b < 14; b++) { - if (e->key() == buttonMappings[b]) + for (int b = 0; b < controllistCount; b++) { + if (e->key() == controllist[b].key) { - input_state.pad_buttons |= (1<key() == buttonMappings[b]) + for (int b = 0; b < controllistCount; b++) { + if (e->key() == controllist[b].key) { - input_state.pad_buttons &= ~(1< +#include + +QKeyEdit::QKeyEdit(QWidget *parent) : + QLineEdit(parent) +{ +} + +bool QKeyEdit::event(QEvent *e) +{ + if(e->type() == QEvent::KeyPress) + { + QKeyEvent *ke = static_cast(e); + QKeySequence seq(ke->key()); + setText(seq.toString()); + return true; + } + + return QLineEdit::event(e); +} diff --git a/Qt/qkeyedit.h b/Qt/qkeyedit.h new file mode 100644 index 000000000..1beb9ac35 --- /dev/null +++ b/Qt/qkeyedit.h @@ -0,0 +1,20 @@ +#ifndef QKEYEDIT_H +#define QKEYEDIT_H + +#include + +class QKeyEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit QKeyEdit(QWidget *parent = 0); + +protected: + bool event(QEvent *e); +signals: + +public slots: + +}; + +#endif // QKEYEDIT_H diff --git a/Qt/resources.qrc b/Qt/resources.qrc new file mode 100644 index 000000000..b99c51d7c --- /dev/null +++ b/Qt/resources.qrc @@ -0,0 +1,5 @@ + + + resources/psp.png + + diff --git a/Qt/resources/psp.png b/Qt/resources/psp.png new file mode 100644 index 000000000..aa6330b1b Binary files /dev/null and b/Qt/resources/psp.png differ