summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pavone <pavone@retrodev.com>2013-07-10 22:48:17 -0700
committerMike Pavone <pavone@retrodev.com>2013-07-10 22:48:17 -0700
commit122bf9de037f578cc4862b1dc775b6589d56057d (patch)
tree29777bacdb96d059f64f15b6749b876820600dfb
parent28b8256fddf53446898120f9b51a43f132d946bb (diff)
Read key bindings from config file
-rw-r--r--config.c2
-rw-r--r--default.cfg10
-rw-r--r--io.c100
-rw-r--r--tern.c17
-rw-r--r--tern.h1
5 files changed, 109 insertions, 21 deletions
diff --git a/config.c b/config.c
index 06e36cd..d106f27 100644
--- a/config.c
+++ b/config.c
@@ -122,7 +122,7 @@ tern_node * parse_config(char * config_data)
if (prefix) {
key = alloc_concat(prefix, key);
}
- head = tern_insert_ptr(head, key, val);
+ head = tern_insert_ptr(head, key, strdup(val));
if (prefix) {
free(key);
}
diff --git a/default.cfg b/default.cfg
index ac75505..d2cdde8 100644
--- a/default.cfg
+++ b/default.cfg
@@ -1,10 +1,10 @@
bindings {
keys {
- UP gamepads.1.up
- DOWN gamepads.1.down
- LEFT gamepads.1.left
- RIGHT gamepads.1.right
+ up gamepads.1.up
+ down gamepads.1.down
+ left gamepads.1.left
+ right gamepads.1.right
a gamepads.1.a
s gamepads.1.b
d gamepads.1.c
@@ -12,7 +12,7 @@ bindings {
w gamepads.1.y
e gamepads.1.z
f gamepads.1.mode
- ENTER gamepads.1.start
+ enter gamepads.1.start
[ ui.vdp_debug_mode
] ui.vdp_debug_pal
diff --git a/io.c b/io.c
index c951739..9fc3ad3 100644
--- a/io.c
+++ b/io.c
@@ -252,23 +252,93 @@ void handle_joy_dpad(int joystick, int dpadnum, uint8_t value)
}
}
+void process_keys(tern_node * cur, tern_node * special, tern_node * padbuttons, char * prefix)
+{
+ char * curstr;
+ int len;
+ if (!cur) {
+ return;
+ }
+ char onec[2];
+ if (prefix) {
+ len = strlen(prefix);
+ curstr = malloc(len + 2);
+ memcpy(curstr, prefix, len);
+ } else {
+ curstr = onec;
+ len = 0;
+ }
+ curstr[len] = cur->el;
+ if (cur->el) {
+ curstr[len+1] = 0;
+ process_keys(cur->straight.next, special, padbuttons, curstr);
+ } else {
+ int keycode = tern_find_int(special, curstr, 0);
+ if (!keycode) {
+ keycode = curstr[0];
+ if (curstr[1] != 0) {
+ fprintf(stderr, "%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]);
+ }
+ }
+ char * target = cur->straight.value.ptrval;
+ int gpadslen = strlen("gamepads.");
+ if (!memcmp(target, "gamepads.", gpadslen)) {
+ if (target[gpadslen] >= '1' && target[gpadslen] <= '8') {
+ int padnum = target[gpadslen] - '0';
+ int button = tern_find_int(padbuttons, target + gpadslen + 1, 0);
+ if (button) {
+ bind_gamepad(keycode, padnum, button);
+ } else {
+ if (target[gpadslen+1]) {
+ fprintf(stderr, "Gamepad mapping string '%s' refers to an invalid button '%s'\n", target, target + gpadslen + 1);
+ } else {
+ fprintf(stderr, "Gamepad mapping string '%s' has no button component\n", target);
+ }
+ }
+ } else {
+ fprintf(stderr, "Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]);
+ }
+ } else if(!memcmp(target, "ui.", strlen("ui."))) {
+ if (!strcmp(target + 3, "vdp_debug_mode")) {
+ bind_ui(keycode, UI_DEBUG_MODE_INC);
+ } else if(!strcmp(target + 3, "vdp_debug_pal")) {
+ bind_ui(keycode, UI_DEBUG_PAL_INC);
+ } else if(!strcmp(target + 3, "enter_debugger")) {
+ bind_ui(keycode, UI_ENTER_DEBUGGER);
+ } else {
+ fprintf(stderr, "Unreconized UI binding type %s for key %s\n", target, curstr);
+ }
+ } else {
+ fprintf(stderr, "Unrecognized binding type %s for key %s\n", target, curstr);
+ }
+ }
+ process_keys(cur->left, special, padbuttons, prefix);
+ process_keys(cur->right, special, padbuttons, prefix);
+}
+
void set_keybindings()
{
- bind_gamepad(RENDERKEY_UP, 1, DPAD_UP);
- bind_gamepad(RENDERKEY_DOWN, 1, DPAD_DOWN);
- bind_gamepad(RENDERKEY_LEFT, 1, DPAD_LEFT);
- bind_gamepad(RENDERKEY_RIGHT, 1, DPAD_RIGHT);
- bind_gamepad('a', 1, BUTTON_A);
- bind_gamepad('s', 1, BUTTON_B);
- bind_gamepad('d', 1, BUTTON_C);
- bind_gamepad('q', 1, BUTTON_X);
- bind_gamepad('w', 1, BUTTON_Y);
- bind_gamepad('e', 1, BUTTON_Z);
- bind_gamepad('\r', 1, BUTTON_START);
- bind_gamepad('f', 1, BUTTON_MODE);
- bind_ui('[', UI_DEBUG_MODE_INC);
- bind_ui(']', UI_DEBUG_PAL_INC);
- bind_ui('u', UI_ENTER_DEBUGGER);
+ tern_node * special = tern_insert_int(NULL, "up", RENDERKEY_UP);
+ special = tern_insert_int(special, "down", RENDERKEY_DOWN);
+ special = tern_insert_int(special, "left", RENDERKEY_LEFT);
+ special = tern_insert_int(special, "right", RENDERKEY_RIGHT);
+ special = tern_insert_int(special, "enter", '\r');
+
+ tern_node * padbuttons = tern_insert_int(NULL, ".up", DPAD_UP);
+ padbuttons = tern_insert_int(padbuttons, ".down", DPAD_DOWN);
+ padbuttons = tern_insert_int(padbuttons, ".left", DPAD_LEFT);
+ padbuttons = tern_insert_int(padbuttons, ".right", DPAD_RIGHT);
+ padbuttons = tern_insert_int(padbuttons, ".a", BUTTON_A);
+ padbuttons = tern_insert_int(padbuttons, ".b", BUTTON_B);
+ padbuttons = tern_insert_int(padbuttons, ".c", BUTTON_C);
+ padbuttons = tern_insert_int(padbuttons, ".x", BUTTON_X);
+ padbuttons = tern_insert_int(padbuttons, ".y", BUTTON_Y);
+ padbuttons = tern_insert_int(padbuttons, ".z", BUTTON_Z);
+ padbuttons = tern_insert_int(padbuttons, ".start", BUTTON_START);
+ padbuttons = tern_insert_int(padbuttons, ".mode", BUTTON_MODE);
+
+ tern_node * keys = tern_find_prefix(config, "bindingskeys");
+ process_keys(keys, special, padbuttons, NULL);
bind_dpad_gamepad(0, 0, RENDER_DPAD_UP, 2, DPAD_UP);
bind_dpad_gamepad(0, 0, RENDER_DPAD_DOWN, 2, DPAD_DOWN);
diff --git a/tern.c b/tern.c
index c0d3abf..7e60a22 100644
--- a/tern.c
+++ b/tern.c
@@ -63,6 +63,23 @@ int tern_find(tern_node * head, char * key, tern_val *ret)
return 0;
}
+tern_node * tern_find_prefix(tern_node * head, char * key)
+{
+ tern_node * cur = head;
+ while (cur && *key)
+ {
+ if (cur->el == *key) {
+ cur = cur->straight.next;
+ key++;
+ } else if (*key < cur->el) {
+ cur = cur->left;
+ } else {
+ cur = cur->right;
+ }
+ }
+ return cur;
+}
+
intptr_t tern_find_int(tern_node * head, char * key, intptr_t def)
{
tern_val ret;
diff --git a/tern.h b/tern.h
index 0c5935a..c731bf6 100644
--- a/tern.h
+++ b/tern.h
@@ -20,6 +20,7 @@ typedef struct tern_node {
tern_node * tern_insert(tern_node * head, char * key, tern_val value);
int tern_find(tern_node * head, char * key, tern_val *ret);
+tern_node * tern_find_prefix(tern_node * head, char * key);
intptr_t tern_find_int(tern_node * head, char * key, intptr_t def);
tern_node * tern_insert_int(tern_node * head, char * key, intptr_t value);
void * tern_find_ptr(tern_node * head, char * key);