mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-04 05:55:31 +02:00
Allow setting keybinding names from config
This commit is contained in:
parent
a833c96109
commit
4233d36b22
6 changed files with 138 additions and 19 deletions
|
@ -1240,6 +1240,7 @@
|
|||
3B10EC6C2568E5EA00372D13 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B3F7D1325B19C5A00EA5F1C /* MacOS */,
|
||||
3B10ED342568E95D00372D13 /* src */,
|
||||
3B1C236625A19B780075EF5D /* steamshim */,
|
||||
3B10EDD52568E96A00372D13 /* binding */,
|
||||
|
@ -1561,6 +1562,13 @@
|
|||
name = Steam;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3B3F7D1325B19C5A00EA5F1C /* MacOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = MacOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3B426F6A256B8AC0009EA00F /* ghc */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include <SDL_filesystem.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
@ -47,12 +48,42 @@ void fillStringVec(json::value &item, std::vector<std::string> &vector) {
|
|||
}
|
||||
}
|
||||
|
||||
bool copyObject(json::value &dest, json::value &src, const char *objectName = "") {
|
||||
assert(dest.is_object());
|
||||
if (src.is_null())
|
||||
return false;
|
||||
|
||||
if (!src.is_object())
|
||||
return false;
|
||||
|
||||
auto &srcVec = src.as_object();
|
||||
auto &destVec = dest.as_object();
|
||||
|
||||
for (auto it : srcVec) {
|
||||
// Specifically processs this object later.
|
||||
if (it.second.is_object() && destVec[it.first].is_object())
|
||||
continue;
|
||||
|
||||
if (it.second.is_array() && destVec[it.first].is_array() ||
|
||||
it.second.is_number() && destVec[it.first].is_number() ||
|
||||
it.second.is_string() && destVec[it.first].is_string() ||
|
||||
it.second.is_boolean() && destVec[it.first].is_boolean())
|
||||
{
|
||||
destVec[it.first] = it.second;
|
||||
}
|
||||
else {
|
||||
Debug() << "Invalid or unrecognized variable in configuration:" << objectName << it.first;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CONF_FILE "mkxp.json"
|
||||
|
||||
Config::Config() {}
|
||||
|
||||
void Config::read(int argc, char *argv[]) {
|
||||
auto opts = json::object({
|
||||
auto optsJ = json::object({
|
||||
{"rgssVersion", 0},
|
||||
{"debugMode", false},
|
||||
{"printFPS", false},
|
||||
|
@ -94,8 +125,20 @@ void Config::read(int argc, char *argv[]) {
|
|||
{"JITEnable", false},
|
||||
{"JITVerboseLevel", 0},
|
||||
{"JITMaxCache", 100},
|
||||
{"JITMinCalls", 10000}
|
||||
}).as_object();
|
||||
{"JITMinCalls", 10000},
|
||||
{"bindingNames", json::object({
|
||||
{"a", "A"},
|
||||
{"b", "B"},
|
||||
{"c", "C"},
|
||||
{"x", "X"},
|
||||
{"y", "Y"},
|
||||
{"z", "Z"},
|
||||
{"l", "L"},
|
||||
{"r", "R"}
|
||||
})}
|
||||
});
|
||||
|
||||
auto &opts = optsJ.as_object();
|
||||
|
||||
#define GUARD(exp) \
|
||||
try { exp } catch (...) {}
|
||||
|
@ -122,20 +165,8 @@ try { exp } catch (...) {}
|
|||
if (!confData.is_object())
|
||||
confData = json::object({});
|
||||
|
||||
auto &cdObject = confData.as_object();
|
||||
|
||||
for (auto it : cdObject) {
|
||||
if (it.second.is_array() && opts[it.first].is_array() ||
|
||||
it.second.is_number() && opts[it.first].is_number() ||
|
||||
it.second.is_string() && opts[it.first].is_string() ||
|
||||
it.second.is_boolean() && opts[it.first].is_boolean())
|
||||
{
|
||||
opts[it.first] = it.second;
|
||||
}
|
||||
else {
|
||||
Debug() << "Invalid or unrecognized variable in configuration:" << it.first;
|
||||
}
|
||||
}
|
||||
copyObject(optsJ, confData);
|
||||
copyObject(opts["bindingNames"], confData.as_object()["bindingNames"], "bindingNames .");
|
||||
}
|
||||
|
||||
#define SET_OPT_CUSTOMKEY(var, key, type) GUARD(var = opts[#key].as_##type();)
|
||||
|
@ -185,6 +216,19 @@ try { exp } catch (...) {}
|
|||
fillStringVec(opts["RTP"], rtps);
|
||||
fillStringVec(opts["fontSub"], fontSubs);
|
||||
fillStringVec(opts["rubyLoadpath"], rubyLoadpaths);
|
||||
|
||||
auto &bnames = opts["bindingNames"].as_object();
|
||||
|
||||
#define BINDING_NAME(btn) kbActionNames.btn = bnames[#btn].as_string()
|
||||
BINDING_NAME(a);
|
||||
BINDING_NAME(b);
|
||||
BINDING_NAME(c);
|
||||
BINDING_NAME(x);
|
||||
BINDING_NAME(y);
|
||||
BINDING_NAME(z);
|
||||
BINDING_NAME(l);
|
||||
BINDING_NAME(r);
|
||||
|
||||
rgssVersion = clamp(rgssVersion, 0, 3);
|
||||
SE.sourceCount = clamp(SE.sourceCount, 1, 64);
|
||||
|
||||
|
|
14
src/config.h
14
src/config.h
|
@ -106,6 +106,20 @@ struct Config {
|
|||
int minCalls;
|
||||
} jit;
|
||||
|
||||
// Keybinding action name mappings
|
||||
struct {
|
||||
std::string a;
|
||||
std::string b;
|
||||
std::string c;
|
||||
|
||||
std::string x;
|
||||
std::string y;
|
||||
std::string z;
|
||||
|
||||
std::string l;
|
||||
std::string r;
|
||||
} kbActionNames;
|
||||
|
||||
/* Internal */
|
||||
std::string customDataPath;
|
||||
std::string commonDataPath;
|
||||
|
|
|
@ -1125,6 +1125,37 @@ void Input::update()
|
|||
p->repeating = None;
|
||||
}
|
||||
|
||||
std::vector<std::string> Input::getBindings(ButtonCode code) {
|
||||
std::vector<std::string> ret;
|
||||
for (const auto &b : p->kbBindings) {
|
||||
if (b.target != code) continue;
|
||||
ret.push_back(SDL_GetScancodeName(b.source));
|
||||
}
|
||||
|
||||
for (const auto &b : p->jsBBindings) {
|
||||
if (b.target != code) continue;
|
||||
ret.push_back(std::string("JSBUTTON") + std::to_string(b.source));
|
||||
}
|
||||
|
||||
for (const auto &b : p->jsABindings) {
|
||||
if (b.target != code) continue;
|
||||
ret.push_back(std::string("JSAXIS") + std::to_string(b.source));
|
||||
}
|
||||
|
||||
for (const auto &b : p->jsHBindings) {
|
||||
if (b.target != code) continue;
|
||||
ret.push_back(std::string("JSHAT") + std::to_string(b.source));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string &Input::getActionName(int button) {
|
||||
for (const auto &b : p->kbBindings) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool Input::isPressed(int button)
|
||||
{
|
||||
return p->getStateCheck(button).pressed;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern std::unordered_map<int, int> vKeyToScancode;
|
||||
extern std::unordered_map<std::string, int> strToScancode;
|
||||
|
@ -54,6 +55,11 @@ public:
|
|||
|
||||
void update();
|
||||
|
||||
std::vector<std::string> getBindings(ButtonCode code);
|
||||
|
||||
std::string &getActionName(int button);
|
||||
void setActionName(int button, const char *name);
|
||||
|
||||
bool isPressed(int button);
|
||||
bool isTriggered(int button);
|
||||
bool isRepeated(int button);
|
||||
|
|
|
@ -60,7 +60,7 @@ struct VButton
|
|||
{
|
||||
Input::ButtonCode code;
|
||||
const char *str;
|
||||
} static const vButtons[] =
|
||||
} static vButtons[] =
|
||||
{
|
||||
BTN_STRING(Up),
|
||||
BTN_STRING(Down),
|
||||
|
@ -181,7 +181,9 @@ struct BindingWidget : Widget
|
|||
: Widget(p, rect),
|
||||
vb(vButtons[vbIndex]),
|
||||
hoveredCell(-1)
|
||||
{}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void appendBindings(BDescVec &d) const;
|
||||
|
||||
|
@ -949,6 +951,20 @@ void Label::drawHandler(SDL_Surface *surf)
|
|||
|
||||
SettingsMenu::SettingsMenu(RGSSThreadData &rtData)
|
||||
{
|
||||
// Set names to be shown in the menu
|
||||
{
|
||||
#define SET_BUTTON_NAME(n, b) vButtons[n].str = rtData.config.kbActionNames.b.c_str();
|
||||
SET_BUTTON_NAME(2, l);
|
||||
SET_BUTTON_NAME(5, r);
|
||||
SET_BUTTON_NAME(6, a);
|
||||
SET_BUTTON_NAME(7, b);
|
||||
SET_BUTTON_NAME(8, c);
|
||||
SET_BUTTON_NAME(9, x);
|
||||
SET_BUTTON_NAME(10, y);
|
||||
SET_BUTTON_NAME(11, z);
|
||||
#undef SET_BUTTON_NAME
|
||||
}
|
||||
|
||||
p = new SettingsMenuPrivate(rtData);
|
||||
p->state = Idle;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue