mirror of https://github.com/mgba-emu/mgba.git
Qt: Keymap saving
This commit is contained in:
parent
0f2c4e5baf
commit
26a087d24e
|
@ -2,8 +2,11 @@
|
||||||
|
|
||||||
#include "util/configuration.h"
|
#include "util/configuration.h"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#define SECTION_NAME_MAX 128
|
#define SECTION_NAME_MAX 128
|
||||||
#define KEY_NAME_MAX 32
|
#define KEY_NAME_MAX 32
|
||||||
|
#define KEY_VALUE_MAX 16
|
||||||
|
|
||||||
struct GBAInputMapImpl {
|
struct GBAInputMapImpl {
|
||||||
int* map;
|
int* map;
|
||||||
|
@ -17,6 +20,7 @@ static void _loadKey(struct GBAInputMap* map, uint32_t type, const struct Config
|
||||||
|
|
||||||
char keyKey[KEY_NAME_MAX];
|
char keyKey[KEY_NAME_MAX];
|
||||||
snprintf(keyKey, KEY_NAME_MAX, "key%s", keyName);
|
snprintf(keyKey, KEY_NAME_MAX, "key%s", keyName);
|
||||||
|
keyKey[KEY_NAME_MAX - 1] = '\0';
|
||||||
|
|
||||||
const char* value = ConfigurationGetValue(config, sectionName, keyKey);
|
const char* value = ConfigurationGetValue(config, sectionName, keyKey);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
@ -30,6 +34,22 @@ static void _loadKey(struct GBAInputMap* map, uint32_t type, const struct Config
|
||||||
GBAInputBindKey(map, type, intValue, key);
|
GBAInputBindKey(map, type, intValue, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _saveKey(const struct GBAInputMap* map, uint32_t type, struct Configuration* config, enum GBAKey key, const char* keyName) {
|
||||||
|
char sectionName[SECTION_NAME_MAX];
|
||||||
|
snprintf(sectionName, SECTION_NAME_MAX, "input.%c%c%c%c", type >> 24, type >> 16, type >> 8, type);
|
||||||
|
sectionName[SECTION_NAME_MAX - 1] = '\0';
|
||||||
|
|
||||||
|
char keyKey[KEY_NAME_MAX];
|
||||||
|
snprintf(keyKey, KEY_NAME_MAX, "key%s", keyName);
|
||||||
|
keyKey[KEY_NAME_MAX - 1] = '\0';
|
||||||
|
|
||||||
|
int value = GBAInputQueryBinding(map, type, key);
|
||||||
|
char keyValue[KEY_VALUE_MAX];
|
||||||
|
snprintf(keyValue, KEY_VALUE_MAX, "%" PRIi32, value);
|
||||||
|
|
||||||
|
ConfigurationSetValue(config, sectionName, keyKey, keyValue);
|
||||||
|
}
|
||||||
|
|
||||||
void GBAInputMapInit(struct GBAInputMap* map) {
|
void GBAInputMapInit(struct GBAInputMap* map) {
|
||||||
map->maps = 0;
|
map->maps = 0;
|
||||||
map->numMaps = 0;
|
map->numMaps = 0;
|
||||||
|
@ -129,7 +149,6 @@ int GBAInputQueryBinding(const struct GBAInputMap* map, uint32_t type, enum GBAK
|
||||||
return impl->map[input];
|
return impl->map[input];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GBAInputMapLoad(struct GBAInputMap* map, uint32_t type, const struct Configuration* config) {
|
void GBAInputMapLoad(struct GBAInputMap* map, uint32_t type, const struct Configuration* config) {
|
||||||
_loadKey(map, type, config, GBA_KEY_A, "A");
|
_loadKey(map, type, config, GBA_KEY_A, "A");
|
||||||
_loadKey(map, type, config, GBA_KEY_B, "B");
|
_loadKey(map, type, config, GBA_KEY_B, "B");
|
||||||
|
@ -142,3 +161,16 @@ void GBAInputMapLoad(struct GBAInputMap* map, uint32_t type, const struct Config
|
||||||
_loadKey(map, type, config, GBA_KEY_LEFT, "Left");
|
_loadKey(map, type, config, GBA_KEY_LEFT, "Left");
|
||||||
_loadKey(map, type, config, GBA_KEY_RIGHT, "Right");
|
_loadKey(map, type, config, GBA_KEY_RIGHT, "Right");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GBAInputMapSave(const struct GBAInputMap* map, uint32_t type, struct Configuration* config) {
|
||||||
|
_saveKey(map, type, config, GBA_KEY_A, "A");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_B, "B");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_L, "L");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_R, "R");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_START, "Start");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_SELECT, "Select");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_UP, "Up");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_DOWN, "Down");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_LEFT, "Left");
|
||||||
|
_saveKey(map, type, config, GBA_KEY_RIGHT, "Right");
|
||||||
|
}
|
||||||
|
|
|
@ -18,5 +18,6 @@ void GBAInputBindKey(struct GBAInputMap*, uint32_t type, int key, enum GBAKey in
|
||||||
int GBAInputQueryBinding(const struct GBAInputMap*, uint32_t type, enum GBAKey input);
|
int GBAInputQueryBinding(const struct GBAInputMap*, uint32_t type, enum GBAKey input);
|
||||||
|
|
||||||
void GBAInputMapLoad(struct GBAInputMap*, uint32_t type, const struct Configuration*);
|
void GBAInputMapLoad(struct GBAInputMap*, uint32_t type, const struct Configuration*);
|
||||||
|
void GBAInputMapSave(const struct GBAInputMap*, uint32_t type, struct Configuration*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,9 +57,6 @@ public:
|
||||||
const GBAOptions* options() const { return &m_opts; }
|
const GBAOptions* options() const { return &m_opts; }
|
||||||
bool parseArguments(GBAArguments* args, int argc, char* argv[]);
|
bool parseArguments(GBAArguments* args, int argc, char* argv[]);
|
||||||
|
|
||||||
const Configuration* configuration() const { return &m_config.configTable; }
|
|
||||||
const Configuration* defaults() const { return &m_config.defaultsTable; }
|
|
||||||
|
|
||||||
ConfigOption* addOption(const char* key);
|
ConfigOption* addOption(const char* key);
|
||||||
void updateOption(const char* key);
|
void updateOption(const char* key);
|
||||||
|
|
||||||
|
@ -73,6 +70,11 @@ public slots:
|
||||||
void write();
|
void write();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Configuration* configuration() { return &m_config.configTable; }
|
||||||
|
Configuration* defaults() { return &m_config.defaultsTable; }
|
||||||
|
|
||||||
|
friend class InputController; // TODO: Do this without friends
|
||||||
|
|
||||||
GBAConfig m_config;
|
GBAConfig m_config;
|
||||||
GBAOptions m_opts;
|
GBAOptions m_opts;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <QPaintEvent>
|
#include <QPaintEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include "InputController.h"
|
#include "InputController.h"
|
||||||
#include "KeyEditor.h"
|
#include "KeyEditor.h"
|
||||||
|
@ -20,6 +21,8 @@ const qreal GBAKeyEditor::DPAD_HEIGHT = 0.1;
|
||||||
|
|
||||||
GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, QWidget* parent)
|
GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
, m_type(type)
|
||||||
|
, m_controller(controller)
|
||||||
{
|
{
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowFullscreenButtonHint);
|
setWindowFlags(windowFlags() & ~Qt::WindowFullscreenButtonHint);
|
||||||
setMinimumSize(300, 300);
|
setMinimumSize(300, 300);
|
||||||
|
@ -47,58 +50,29 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, QWidget* paren
|
||||||
m_keyL->setValue(GBAInputQueryBinding(map, type, GBA_KEY_L));
|
m_keyL->setValue(GBAInputQueryBinding(map, type, GBA_KEY_L));
|
||||||
m_keyR->setValue(GBAInputQueryBinding(map, type, GBA_KEY_R));
|
m_keyR->setValue(GBAInputQueryBinding(map, type, GBA_KEY_R));
|
||||||
|
|
||||||
connect(m_keyDU, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
connect(m_keyDU, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
controller->bindKey(type, key, GBA_KEY_UP);
|
connect(m_keyDD, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
setNext();
|
connect(m_keyDL, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
});
|
connect(m_keyDR, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
|
connect(m_keySelect, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
|
connect(m_keyStart, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
|
connect(m_keyA, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
|
connect(m_keyB, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
|
connect(m_keyL, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
|
connect(m_keyR, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
|
||||||
|
|
||||||
connect(m_keyDD, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
m_buttons = new QWidget(this);
|
||||||
controller->bindKey(type, key, GBA_KEY_DOWN);
|
QVBoxLayout* layout = new QVBoxLayout;
|
||||||
setNext();
|
m_buttons->setLayout(layout);
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_keyDL, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
QPushButton* setAll = new QPushButton(tr("Set all"));
|
||||||
controller->bindKey(type, key, GBA_KEY_LEFT);
|
connect(setAll, SIGNAL(pressed()), this, SLOT(setAll()));
|
||||||
setNext();
|
layout->addWidget(setAll);
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_keyDR, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
QPushButton* save = new QPushButton(tr("Save"));
|
||||||
controller->bindKey(type, key, GBA_KEY_RIGHT);
|
connect(save, SIGNAL(pressed()), this, SLOT(save()));
|
||||||
setNext();
|
layout->addWidget(save);
|
||||||
});
|
layout->setSpacing(6);
|
||||||
|
|
||||||
connect(m_keySelect, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
|
||||||
controller->bindKey(type, key, GBA_KEY_SELECT);
|
|
||||||
setNext();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_keyStart, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
|
||||||
controller->bindKey(type, key, GBA_KEY_START);
|
|
||||||
setNext();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_keyA, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
|
||||||
controller->bindKey(type, key, GBA_KEY_A);
|
|
||||||
setNext();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_keyB, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
|
||||||
controller->bindKey(type, key, GBA_KEY_B);
|
|
||||||
setNext();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_keyL, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
|
||||||
controller->bindKey(type, key, GBA_KEY_L);
|
|
||||||
setNext();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_keyR, &KeyEditor::valueChanged, [this, type, controller](int key) {
|
|
||||||
controller->bindKey(type, key, GBA_KEY_R);
|
|
||||||
setNext();
|
|
||||||
});
|
|
||||||
|
|
||||||
m_setAll = new QPushButton(tr("Set all"), this);
|
|
||||||
connect(m_setAll, SIGNAL(pressed()), this, SLOT(setAll()));
|
|
||||||
|
|
||||||
m_keyOrder = QList<KeyEditor*>{
|
m_keyOrder = QList<KeyEditor*>{
|
||||||
m_keyDU,
|
m_keyDU,
|
||||||
|
@ -116,6 +90,8 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, QWidget* paren
|
||||||
m_currentKey = m_keyOrder.end();
|
m_currentKey = m_keyOrder.end();
|
||||||
|
|
||||||
m_background.load(":/res/keymap.qpic");
|
m_background.load(":/res/keymap.qpic");
|
||||||
|
|
||||||
|
setAll->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAKeyEditor::setAll() {
|
void GBAKeyEditor::setAll() {
|
||||||
|
@ -124,7 +100,7 @@ void GBAKeyEditor::setAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAKeyEditor::resizeEvent(QResizeEvent* event) {
|
void GBAKeyEditor::resizeEvent(QResizeEvent* event) {
|
||||||
setLocation(m_setAll, 0.5, 0.2);
|
setLocation(m_buttons, 0.5, 0.2);
|
||||||
setLocation(m_keyDU, DPAD_CENTER_X, DPAD_CENTER_Y - DPAD_HEIGHT);
|
setLocation(m_keyDU, DPAD_CENTER_X, DPAD_CENTER_Y - DPAD_HEIGHT);
|
||||||
setLocation(m_keyDD, DPAD_CENTER_X, DPAD_CENTER_Y + DPAD_HEIGHT);
|
setLocation(m_keyDD, DPAD_CENTER_X, DPAD_CENTER_Y + DPAD_HEIGHT);
|
||||||
setLocation(m_keyDL, DPAD_CENTER_X - DPAD_WIDTH, DPAD_CENTER_Y);
|
setLocation(m_keyDL, DPAD_CENTER_X - DPAD_WIDTH, DPAD_CENTER_Y);
|
||||||
|
@ -160,6 +136,20 @@ void GBAKeyEditor::setNext() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GBAKeyEditor::save() {
|
||||||
|
m_controller->bindKey(m_type, m_keyDU->value(), GBA_KEY_UP);
|
||||||
|
m_controller->bindKey(m_type, m_keyDD->value(), GBA_KEY_DOWN);
|
||||||
|
m_controller->bindKey(m_type, m_keyDL->value(), GBA_KEY_LEFT);
|
||||||
|
m_controller->bindKey(m_type, m_keyDR->value(), GBA_KEY_RIGHT);
|
||||||
|
m_controller->bindKey(m_type, m_keySelect->value(), GBA_KEY_SELECT);
|
||||||
|
m_controller->bindKey(m_type, m_keyStart->value(), GBA_KEY_START);
|
||||||
|
m_controller->bindKey(m_type, m_keyA->value(), GBA_KEY_A);
|
||||||
|
m_controller->bindKey(m_type, m_keyB->value(), GBA_KEY_B);
|
||||||
|
m_controller->bindKey(m_type, m_keyL->value(), GBA_KEY_L);
|
||||||
|
m_controller->bindKey(m_type, m_keyR->value(), GBA_KEY_R);
|
||||||
|
m_controller->saveConfiguration(m_type);
|
||||||
|
}
|
||||||
|
|
||||||
void GBAKeyEditor::setLocation(QWidget* widget, qreal x, qreal y) {
|
void GBAKeyEditor::setLocation(QWidget* widget, qreal x, qreal y) {
|
||||||
QSize s = size();
|
QSize s = size();
|
||||||
QSize hint = widget->sizeHint();
|
QSize hint = widget->sizeHint();
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#include <QPicture>
|
#include <QPicture>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class QPushButton;
|
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
class InputController;
|
class InputController;
|
||||||
|
@ -25,17 +23,19 @@ protected:
|
||||||
virtual void resizeEvent(QResizeEvent*) override;
|
virtual void resizeEvent(QResizeEvent*) override;
|
||||||
virtual void paintEvent(QPaintEvent*) override;
|
virtual void paintEvent(QPaintEvent*) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void setNext();
|
||||||
|
void save();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const qreal DPAD_CENTER_X;
|
static const qreal DPAD_CENTER_X;
|
||||||
static const qreal DPAD_CENTER_Y;
|
static const qreal DPAD_CENTER_Y;
|
||||||
static const qreal DPAD_WIDTH;
|
static const qreal DPAD_WIDTH;
|
||||||
static const qreal DPAD_HEIGHT;
|
static const qreal DPAD_HEIGHT;
|
||||||
|
|
||||||
void setNext();
|
|
||||||
|
|
||||||
void setLocation(QWidget* widget, qreal x, qreal y);
|
void setLocation(QWidget* widget, qreal x, qreal y);
|
||||||
|
|
||||||
QPushButton* m_setAll;
|
QWidget* m_buttons;
|
||||||
KeyEditor* m_keyDU;
|
KeyEditor* m_keyDU;
|
||||||
KeyEditor* m_keyDD;
|
KeyEditor* m_keyDD;
|
||||||
KeyEditor* m_keyDL;
|
KeyEditor* m_keyDL;
|
||||||
|
@ -49,6 +49,7 @@ private:
|
||||||
QList<KeyEditor*> m_keyOrder;
|
QList<KeyEditor*> m_keyOrder;
|
||||||
QList<KeyEditor*>::iterator m_currentKey;
|
QList<KeyEditor*>::iterator m_currentKey;
|
||||||
|
|
||||||
|
uint32_t m_type;
|
||||||
InputController* m_controller;
|
InputController* m_controller;
|
||||||
|
|
||||||
QPicture m_background;
|
QPicture m_background;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "InputController.h"
|
#include "InputController.h"
|
||||||
|
|
||||||
#include <Qt>
|
#include "ConfigController.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "util/configuration.h"
|
#include "util/configuration.h"
|
||||||
|
@ -37,15 +37,21 @@ InputController::~InputController() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::loadDefaultConfiguration(const Configuration* config) {
|
void InputController::setConfiguration(ConfigController* config) {
|
||||||
loadConfiguration(KEYBOARD, config);
|
m_config = config;
|
||||||
|
loadConfiguration(KEYBOARD);
|
||||||
#ifdef BUILD_SDL
|
#ifdef BUILD_SDL
|
||||||
loadConfiguration(SDL_BINDING_BUTTON, config);
|
loadConfiguration(SDL_BINDING_BUTTON);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::loadConfiguration(uint32_t type, const Configuration* config) {
|
void InputController::loadConfiguration(uint32_t type) {
|
||||||
GBAInputMapLoad(&m_inputMap, type, config);
|
GBAInputMapLoad(&m_inputMap, type, m_config->configuration());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputController::saveConfiguration(uint32_t type) {
|
||||||
|
GBAInputMapSave(&m_inputMap, type, m_config->configuration());
|
||||||
|
m_config->write();
|
||||||
}
|
}
|
||||||
|
|
||||||
GBAKey InputController::mapKeyboard(int key) const {
|
GBAKey InputController::mapKeyboard(int key) const {
|
||||||
|
|
|
@ -9,10 +9,10 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Configuration;
|
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
|
class ConfigController;
|
||||||
|
|
||||||
class InputController {
|
class InputController {
|
||||||
public:
|
public:
|
||||||
static const uint32_t KEYBOARD = 0x51545F4B;
|
static const uint32_t KEYBOARD = 0x51545F4B;
|
||||||
|
@ -20,8 +20,9 @@ public:
|
||||||
InputController();
|
InputController();
|
||||||
~InputController();
|
~InputController();
|
||||||
|
|
||||||
void loadDefaultConfiguration(const Configuration* config);
|
void setConfiguration(ConfigController* config);
|
||||||
void loadConfiguration(uint32_t type, const Configuration* config);
|
void loadConfiguration(uint32_t type);
|
||||||
|
void saveConfiguration(uint32_t type = KEYBOARD);
|
||||||
|
|
||||||
GBAKey mapKeyboard(int key) const;
|
GBAKey mapKeyboard(int key) const;
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GBAInputMap m_inputMap;
|
GBAInputMap m_inputMap;
|
||||||
|
ConfigController* m_config;
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
#ifdef BUILD_SDL
|
||||||
GBASDLEvents m_sdlEvents;
|
GBASDLEvents m_sdlEvents;
|
||||||
|
|
|
@ -109,7 +109,7 @@ void Window::loadConfig() {
|
||||||
m_screenWidget->setSizeHint(QSize(opts->width, opts->height));
|
m_screenWidget->setSizeHint(QSize(opts->width, opts->height));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inputController.loadDefaultConfiguration(m_config->configuration());
|
m_inputController.setConfiguration(m_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::saveConfig() {
|
void Window::saveConfig() {
|
||||||
|
|
Loading…
Reference in New Issue