Implemented Reading/Writing keybindings using new parser object

dev
Shariq Shah 8 years ago
parent 4c5bb465b1
commit 5a60c94c76
  1. 3
      README.md
  2. 9
      src/common/log.c
  3. 2
      src/common/parser.c
  4. 1
      src/common/parser.h
  5. 4
      src/game/platform.c
  6. 507
      src/libsymmetry/input.c
  7. 20
      src/libsymmetry/input.h

@ -155,8 +155,6 @@
- ## TODO - ## TODO
- Add array support to variant
- Read/Write keybindings using new parser object
- Store Materials in new format supported by parser - Store Materials in new format supported by parser
- Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards - Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards
- Implement sound/listener loading from scene file - Implement sound/listener loading from scene file
@ -331,3 +329,4 @@
* Modify entity loading logic to use the new parsing code by parsing all entity properties into a hashmap first then recreating entity from that * Modify entity loading logic to use the new parsing code by parsing all entity properties into a hashmap first then recreating entity from that
* Implmented writing to file through the new Parser and Parser_Objects * Implmented writing to file through the new Parser and Parser_Objects
* Changed Config to read/write using new Parser and Parser_Objects * Changed Config to read/write using new Parser and Parser_Objects
* Implemented Reading/Writing keybindings using new parser object

@ -53,7 +53,14 @@ void log_init(const char* log_file_name, const char* user_directory)
void log_cleanup(void) void log_cleanup(void)
{ {
if(log_file) fclose(log_file); if(log_file)
{
time_t current_time;
time(&current_time);
fprintf(log_file, "\nLog closing at %s\n", ctime(&current_time));
fflush(log_file);
fclose(log_file);
}
} }

@ -242,6 +242,7 @@ int parser_object_type_from_str(const char* str)
else if(strncmp(str, "Model", HASH_MAX_KEY_LEN) == 0) object_type = PO_MODEL; else if(strncmp(str, "Model", HASH_MAX_KEY_LEN) == 0) object_type = PO_MODEL;
else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL; else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL;
else if(strncmp(str, "Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_CONFIG; else if(strncmp(str, "Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_CONFIG;
else if(strncmp(str, "Key", HASH_MAX_KEY_LEN) == 0) object_type = PO_KEY;
return object_type; return object_type;
} }
@ -254,6 +255,7 @@ const char* parser_object_type_to_str(int type)
case PO_MODEL: return "Model"; case PO_MODEL: return "Model";
case PO_MATERIAL: return "Material"; case PO_MATERIAL: return "Material";
case PO_CONFIG: return "Config"; case PO_CONFIG: return "Config";
case PO_KEY: return "Key";
case PO_UNKNOWN: return "Unknown"; case PO_UNKNOWN: return "Unknown";
default: return "Unknown"; default: return "Unknown";
} }

@ -9,6 +9,7 @@ enum Parser_Object_Type
PO_ENTITY, PO_ENTITY,
PO_MATERIAL, PO_MATERIAL,
PO_MODEL, PO_MODEL,
PO_KEY,
PO_UNKNOWN PO_UNKNOWN
}; };

@ -431,8 +431,8 @@ int platform_key_from_name(const char* key_name)
strncpy(trimmed_key_name, &key_name[start], (end - start) + 1); strncpy(trimmed_key_name, &key_name[start], (end - start) + 1);
int key = SDL_GetKeyFromName(trimmed_key_name); int key = SDL_GetKeyFromName(trimmed_key_name);
if(key == SDLK_UNKNOWN) /*if(key == SDLK_UNKNOWN)
log_error("platform:key_from_name", "Unrecognized key '%s', SDL (%s)", trimmed_key_name, SDL_GetError()); log_error("platform:key_from_name", "Unrecognized key '%s', SDL (%s)", trimmed_key_name, SDL_GetError());*/
return key; return key;
} }

@ -7,22 +7,16 @@
#include "gui.h" #include "gui.h"
#include "../common/string_utils.h" #include "../common/string_utils.h"
#include "../common/common.h" #include "../common/common.h"
#include "../common/hashmap.h"
#include "../common/variant.h"
#include "../common/parser.h" #include "../common/parser.h"
struct Input_Map
{
char* name;
struct Key_Combination* keys;
int state;
};
static void input_on_key(int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt); static void input_on_key(int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt);
static void input_on_mousebutton(int button, int state, int x, int y, int8 num_clicks); static void input_on_mousebutton(int button, int state, int x, int y, int8 num_clicks);
static void input_on_mousemotion(int x, int y, int xrel, int yrel); static void input_on_mousemotion(int x, int y, int xrel, int yrel);
static void input_on_mousewheel(int x, int y); static void input_on_mousewheel(int x, int y);
static int map_find(const char* name);
static void on_parser_assign(const char* key, const char* value, const char* filename, int current_line); static struct Hashmap* key_bindings = NULL;
static struct Input_Map* input_map_list = NULL;
void input_init(void) void input_init(void)
{ {
@ -31,192 +25,227 @@ void input_init(void)
platform->mousemotion_callback_set(&input_on_mousemotion); platform->mousemotion_callback_set(&input_on_mousemotion);
platform->mousewheel_callback_set(&input_on_mousewheel); platform->mousewheel_callback_set(&input_on_mousewheel);
input_map_list = array_new(struct Input_Map); key_bindings = hashmap_new();
if(!input_keybinds_load("keybindings.cfg", DIRT_USER))
/* Default keys for fallback */
struct Key_Binding forward_keys = {KEY_W, KMOD_NONE, KEY_UP, KMOD_NONE, KS_INACTIVE};
struct Key_Binding backward_keys = {KEY_S, KMOD_NONE, KEY_DOWN, KMOD_NONE, KS_INACTIVE};
struct Key_Binding up_keys = {KEY_Q, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding down_keys = {KEY_E, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding left_keys = {KEY_A, KMOD_NONE, KEY_LEFT, KMOD_NONE, KS_INACTIVE};
struct Key_Binding right_keys = {KEY_D, KMOD_NONE, KEY_RIGHT, KMOD_NONE, KS_INACTIVE};
struct Key_Binding turn_right_keys = {KEY_L, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding turn_left_keys = {KEY_J, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding turn_up_keys = {KEY_I, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding turn_down_keys = {KEY_K, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding sprint_keys = {KEY_LSHIFT, KMOD_NONE, KEY_RSHIFT, KMOD_NONE, KS_INACTIVE};
struct Key_Binding ed_toggle_keys = {KEY_F1, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding win_fullscr_keys = {KEY_F11, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding win_max_keys = {KEY_F12, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding reload_game_keys = {KEY_F5, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
input_map_create("Move_Forward", forward_keys);
input_map_create("Move_Backward", backward_keys);
input_map_create("Move_Up", up_keys);
input_map_create("Move_Down", down_keys);
input_map_create("Move_Left", left_keys);
input_map_create("Move_Right", right_keys);
input_map_create("Turn_Right", turn_right_keys);
input_map_create("Turn_Left", turn_left_keys);
input_map_create("Turn_Up", turn_up_keys);
input_map_create("Turn_Down", turn_down_keys);
input_map_create("Sprint", sprint_keys);
input_map_create("Editor_Toggle", ed_toggle_keys);
input_map_create("Window_Fullscreen", win_fullscr_keys);
input_map_create("Window_Maximize", win_max_keys);
input_map_create("Reload_Game_Lib", reload_game_keys);
if(!input_keybinds_load("keybindings.symtres", DIRT_USER))
{ {
log_error("input:init", "Failed to load keybindings"); log_error("input:init", "Failed to load keybindings");
log_message("Reverting to default keybindings"); log_message("Reverting to default keybindings");
if(!input_keybinds_load("keybindings.cfg", DIRT_INSTALL)) if(!input_keybinds_load("keybindings.symtres", DIRT_INSTALL))
{ {
log_error("input:init", "Failed to load default keybindings"); log_error("input:init", "Failed to load default keybindings");
input_keybinds_save("keybindings.symtres", DIRT_INSTALL);
} }
else
{
input_keybinds_save("keybindings.cfg");
}
}
/* Default keys for fallback */ input_keybinds_save("keybindings.symtres", DIRT_USER);
struct Key_Combination forward_keys[2] = {{KEY_W, KMD_NONE}, {KEY_UP, KMD_ALT | KMD_SHIFT}}; }
struct Key_Combination backward_keys[2] = {{KEY_S, KMD_NONE}, {KEY_DOWN, KMD_NONE}};
struct Key_Combination up_keys[2] = {{KEY_Q}};
struct Key_Combination down_keys[2] = {{KEY_E}};
struct Key_Combination left_keys[2] = {{KEY_A}, {KEY_LEFT}};
struct Key_Combination right_keys[2] = {{KEY_D}, {KEY_RIGHT}};
struct Key_Combination turn_right_keys[1] = {{KEY_L}};
struct Key_Combination turn_left_keys[1] = {{KEY_J}};
struct Key_Combination turn_up_keys[1] = {{KEY_I}};
struct Key_Combination turn_down_keys[1] = {{KEY_K}};
struct Key_Combination sprint_keys[2] = {{KEY_LSHIFT}, {KEY_RSHIFT}};
struct Key_Combination ed_toggle_keys[1] = {{KEY_F1}};
struct Key_Combination win_fullscr_keys[1] = {{KEY_F11}};
struct Key_Combination win_max_keys[1] = {{KEY_F12}};
struct Key_Combination reload_game_keys[1] = {{KEY_F5}};
input_map_create("Move_Forward", forward_keys, 2);
input_map_create("Move_Backward", backward_keys, 2);
input_map_create("Move_Up", up_keys, 1);
input_map_create("Move_Down", down_keys, 1);
input_map_create("Move_Left", left_keys, 2);
input_map_create("Move_Right", right_keys, 2);
input_map_create("Turn_Right", turn_right_keys, 1);
input_map_create("Turn_Left", turn_left_keys, 1);
input_map_create("Turn_Up", turn_up_keys, 1);
input_map_create("Turn_Down", turn_down_keys, 1);
input_map_create("Sprint", sprint_keys, 2);
input_map_create("Editor_Toggle", ed_toggle_keys, 1);
input_map_create("Window_Fullscreen", win_fullscr_keys, 1);
input_map_create("Window_Maximize", win_max_keys, 1);
input_map_create("Reload_Game_Lib", reload_game_keys, 1);
} }
void input_cleanup(void) void input_cleanup(void)
{ {
for(int i = 0; i < array_len(input_map_list); i++) char* key = NULL;
struct Variant* value = NULL;
HASHMAP_FOREACH(key_bindings, key, value)
{ {
struct Input_Map* map = &input_map_list[i]; free(value->val_voidptr);
if(map->name) free(map->name);
array_free(map->keys);
} }
array_free(input_map_list);
input_map_list = NULL; hashmap_free(key_bindings);
} }
void on_parser_assign(const char* key, const char* value, const char* filename, int current_line) bool input_keybinds_load(const char* filename, int directory_type)
{ {
char* value_copy = str_new(value); FILE* key_file = platform->file.open(directory_type, filename, "rb");
//value_copy[strlen(value_copy) - 1] = '\0'; if(!key_file)
char* val = strtok(value_copy, ",");
if(!val)
{ {
log_warning("Unable to parse keys for keybinding %s in file %s, line %d", key, filename, current_line); log_error("input:keybinds_load", "Could not open %s", filename);
free(value_copy); return false;
return;
} }
while(val) struct Parser* parser = parser_load_objects(key_file, filename);
if(!parser)
{ {
#define max_key_str_len 20 log_error("input:keybinds_load", "Failed to parse %s", filename);
/* Check if there are any Modifiers */ fclose(key_file);
int modifiers = KMD_NONE; return false;
char* keys = strstr(val, "-"); }
char* start_loc = val;
char key_name[max_key_str_len];
int skip_to_next = 0;
while(keys)
{
memset(key_name, '\0', max_key_str_len);
strncpy(key_name, start_loc, (keys - start_loc));
int key_modifier = platform->key_from_name(key_name); for(int i = 0; i < array_len(parser->objects); i++)
{
struct Parser_Object* object = &parser->objects[i];
if(key_modifier == KEY_UNKNOWN) const char* name_temp = NULL;
struct Key_Binding key_binding =
{
.state = KS_INACTIVE,
.key_primary = KEY_NONE,
.mods_primary = KMD_NONE,
.key_secondary = KEY_NONE,
.mods_secondary = KMD_NONE
};
if(hashmap_value_exists(object->data, "name")) name_temp = hashmap_str_get(object->data, "name");
if(hashmap_value_exists(object->data, "key_primary"))
{
int key = platform->key_from_name(hashmap_str_get(object->data, "key_primary"));
if(key != KEY_UNKNOWN)
{ {
log_warning("Unrecognized key %s in keybindings file %s, at line %d", key_name, filename, current_line); key_binding.key_primary = key;
skip_to_next = true;
break;
} }
}
switch(key_modifier) if(hashmap_value_exists(object->data, "key_secondary"))
{
int key = platform->key_from_name(hashmap_str_get(object->data, "key_secondary"));
if(key != KEY_UNKNOWN)
{ {
case KEY_LSHIFT: case KEY_RSHIFT: modifiers |= KMD_SHIFT; break; key_binding.key_secondary = key;
case KEY_LCTRL: case KEY_RCTRL: modifiers |= KMD_CTRL; break; }
case KEY_LALT: case KEY_RALT: modifiers |= KMD_ALT; break;
};
++keys;
start_loc = keys;
keys = strstr(keys, "-");
} }
if(skip_to_next) if(hashmap_value_exists(object->data, "mods_primary_ctrl"))
{ {
val = strtok(NULL, ","); if(hashmap_bool_get(object->data, "mods_primary_ctrl"))
continue; key_binding.mods_primary |= KMD_CTRL;
} }
/* Copy the last key after the hyphen */ if(hashmap_value_exists(object->data, "mods_primary_shift"))
strncpy(key_name, start_loc, max_key_str_len);
int key_code = platform->key_from_name(key_name);
if(key_code == KEY_UNKNOWN)
{ {
log_warning("Unrecognized key %s in keybindings file %s, at line %d", key_name, filename, current_line); if(hashmap_bool_get(object->data, "mods_primary_shift"))
val = strtok(NULL, ","); key_binding.mods_primary |= KMD_SHIFT;
continue; }
if(hashmap_value_exists(object->data, "mods_primary_alt"))
{
if(hashmap_bool_get(object->data, "mods_primary_alt"))
key_binding.mods_primary |= KMD_ALT;
} }
struct Key_Combination key_comb = { .key = key_code, .mods = modifiers}; if(hashmap_value_exists(object->data, "mods_secondary_ctrl"))
input_map_create(key, &key_comb, 1); {
if(hashmap_bool_get(object->data, "mods_secondary_ctrl"))
key_binding.mods_secondary |= KMD_CTRL;
}
val = strtok(NULL, ","); if(hashmap_value_exists(object->data, "mods_secondary_shift"))
{
if(hashmap_bool_get(object->data, "mods_secondary_shift"))
key_binding.mods_secondary = KMD_SHIFT;
}
if(hashmap_value_exists(object->data, "mods_secondary_alt"))
{
if(hashmap_bool_get(object->data, "mods_secondary_alt"))
key_binding.mods_secondary = KMD_ALT;
}
input_map_create(name_temp, key_binding);
} }
free(value_copy);
parser_free(parser);
fclose(key_file);
return true;
} }
bool input_keybinds_load(const char* filename, int directory_type) bool input_keybinds_save(const char* filename, int directory_type)
{ {
bool success = false; struct Parser* parser = parser_new();
FILE* config_file = platform->file.open(directory_type, filename, "r"); if(!parser)
if(!config_file)
{ {
log_error("input:keybinds_load", "Could not open %s", filename); log_error("input:keybinds_save", "Could not create Parser");
return success; return false;
} }
if(!parser_load(config_file, filename, &on_parser_assign, false, 0))
{ char* key = NULL;
log_error("input:keybinds_load", "Failed to parse file %s", filename); struct Variant* value = NULL;
}
else HASHMAP_FOREACH(key_bindings, key, value)
{ {
log_message("Loaded keybindings from %s", filename); struct Key_Binding* key_binding = (struct Key_Binding*)value->val_voidptr;
success = true; struct Parser_Object* object = parser_object_new(parser, PO_KEY);
if(!object)
{
log_error("input:keybinds_save", "Failed to create Parser_object for Map '%s'", key);
continue;
}
bool mods_primary_ctrl = ((key_binding->mods_primary & KMD_CTRL) == KMD_CTRL) ? true : false;
bool mods_primary_shift = ((key_binding->mods_primary & KMD_SHIFT) == KMD_SHIFT) ? true : false;
bool mods_primary_alt = ((key_binding->mods_primary & KMD_ALT) == KMD_ALT) ? true : false;
bool mods_secondary_ctrl = ((key_binding->mods_secondary & KMD_CTRL) == KMD_CTRL) ? true : false;
bool mods_secondary_shift = ((key_binding->mods_secondary & KMD_SHIFT) == KMD_SHIFT) ? true : false;
bool mods_secondary_alt = ((key_binding->mods_secondary & KMD_ALT) == KMD_ALT) ? true : false;
hashmap_str_set(object->data, "name", key);
hashmap_str_set(object->data, "key_primary", key_binding->key_primary == KEY_NONE ? "NONE" : platform->key_name_get(key_binding->key_primary));
hashmap_bool_set(object->data, "mods_primary_ctrl", mods_primary_ctrl);
hashmap_bool_set(object->data, "mods_primary_shift", mods_primary_shift);
hashmap_bool_set(object->data, "mods_primary_alt", mods_primary_alt);
hashmap_str_set(object->data, "key_secondary", key_binding->key_secondary == KEY_NONE ? "NONE" : platform->key_name_get(key_binding->key_secondary));
hashmap_bool_set(object->data, "mods_secondary_ctrl", mods_secondary_ctrl);
hashmap_bool_set(object->data, "mods_secondary_shift", mods_secondary_shift);
hashmap_bool_set(object->data, "mods_secondary_alt", mods_secondary_alt);
} }
fclose(config_file); log_message("Keybindings saved to %s", filename);
return success;
}
bool input_keybinds_save(const char* filename)
{
bool success = false;
FILE* config_file = platform->file.open(DIRT_USER, filename, "w"); bool write_success = false;
if(!config_file) FILE* key_file = platform->file.open(directory_type, filename, "w");
if(!key_file)
{ {
log_error("input:keybinds_save", "Could not open %s", filename); log_error("input:keybinds_save", "Could not open %s", filename);
return success;
} }
else
for(int i = 0; i < array_len(input_map_list); i++)
{ {
struct Input_Map* map = &input_map_list[i]; if(parser_write_objects(parser, key_file, filename))
fprintf(config_file, "%s : ", map->name);
for(int j = 0; j < array_len(map->keys); j++)
{ {
if(j != 0) fprintf(config_file, ", "); log_message("Input Maps written to %s", filename);
struct Key_Combination* key_comb = &map->keys[j]; write_success = true;
if((key_comb->mods & KMD_ALT) == KMD_ALT) fprintf(config_file, "%s-", platform->key_name_get(KEY_LALT)); }
if((key_comb->mods & KMD_SHIFT) == KMD_SHIFT) fprintf(config_file, "%s-", platform->key_name_get(KEY_LSHIFT)); else
if((key_comb->mods & KMD_CTRL) == KMD_CTRL) fprintf(config_file, "%s-", platform->key_name_get(KEY_LCTRL)); {
fprintf(config_file, "%s", platform->key_name_get(key_comb->key)); log_error("Failed to write Input Maps to %s", filename);
} }
fprintf(config_file, "\n");
} }
fprintf(config_file, "\n");
fclose(config_file); parser_free(parser);
log_message("Keybindings saved to %s", filename); fclose(key_file);
success = true; return write_success;
return success;
} }
void input_on_mousemotion(int x, int y, int xrel, int yrel) void input_on_mousemotion(int x, int y, int xrel, int yrel)
@ -248,31 +277,34 @@ void input_on_key(int key, int scancode, int state, int repeat, int mod_ctrl, in
if(mod_ctrl) mods |= KMD_CTRL; if(mod_ctrl) mods |= KMD_CTRL;
if(mod_shift) mods |= KMD_SHIFT; if(mod_shift) mods |= KMD_SHIFT;
if(mod_alt) mods |= KMD_ALT; if(mod_alt) mods |= KMD_ALT;
for(int i = 0; i < array_len(input_map_list); i++)
char* map_key = NULL;
struct Variant* value = NULL;
HASHMAP_FOREACH(key_bindings, map_key, value)
{ {
struct Input_Map* map = &input_map_list[i]; struct Key_Binding* key_binding = (struct Key_Binding*)value->val_voidptr;
for(int j = 0; j < array_len(map->keys); j++) //Check with primary key
if(key_binding->key_primary == key && (key_binding->mods_primary & mods) == key_binding->mods_primary)
{ {
/* if(map->state == KS_PRESSED && */ key_binding->state = state;
/* state == KS_RELEASED && */ break;
/* ((map->keys[j].mods & mods) == map->keys[j].mods)) */ }
/* { */
/* map->state = state; */ //If not, then check with secondary key
/* } */ if(key_binding->key_secondary == key && (key_binding->mods_secondary & mods) == key_binding->mods_secondary)
if(map->keys[j].key == key && ((map->keys[j].mods & mods) == map->keys[j].mods)) {
{ key_binding->state = state;
map->state = state; break;
break;
}
} }
} }
/* TODO: This is temporary. After proper event loop is added this code should not be here */ /* TODO: This is temporary. After proper event loop is added this code should not be here */
gui_handle_keyboard_event(key, state, mod_ctrl, mod_shift); gui_handle_keyboard_event(key, state, mod_ctrl, mod_shift);
} }
void input_on_mousebutton(int button, int state, int x, int y, int8 num_clicks) void input_on_mousebutton(int button, int state, int x, int y, int8 num_clicks)
{ {
/* Probably add 'mouse maps', same as input maps for keyboard but with buttons /* Probably add 'mouse maps', same as input maps for keyboard but with buttons.
Do we even need that? Do we even need that?
*/ */
/* TODO: This is temporary. After proper event loop is added this code should not be here */ /* TODO: This is temporary. After proper event loop is added this code should not be here */
@ -284,25 +316,38 @@ void input_mouse_mode_set(enum Mouse_Mode mode)
platform->mouse_relative_mode_set(mode == MM_NORMAL ? 0 : 1); platform->mouse_relative_mode_set(mode == MM_NORMAL ? 0 : 1);
} }
bool input_map_state_get(const char* map_name, int state) bool input_map_state_get(const char* name, int state)
{ {
int current_state = KS_INACTIVE; struct Key_Binding* key_binding = (struct Key_Binding*)hashmap_ptr_get(key_bindings, name);
for(int i = 0; i < array_len(input_map_list); i++) if(!key_binding)
{ {
struct Input_Map* map = &input_map_list[i]; log_error("input:map_state_get", "Map '%s' not found", name);
if(strcmp(map->name, map_name) == 0) return false;
{
current_state = map->state;
break;
}
} }
bool result = false; return (key_binding->state == state);
if(current_state == state) }
bool input_map_create(const char* name, struct Key_Binding key_combination)
{
//Check if a key map already exists
if(hashmap_value_exists(key_bindings, name))
{ {
result = true; log_warning("Removing existing Map '%s' and replacing with new one", name);
input_map_remove(name);
} }
return result;
struct Key_Binding* new_keybinding = malloc(sizeof(*new_keybinding));
if(!new_keybinding)
{
log_error("input:map_create", "Out of memory");
return false;
}
memcpy(new_keybinding, &key_combination, sizeof(key_combination));
hashmap_ptr_set(key_bindings, name, new_keybinding);
log_message("Created new input map '%s'", name);
return true;
} }
bool input_is_key_pressed(int key) bool input_is_key_pressed(int key)
@ -316,110 +361,66 @@ bool input_mousebutton_state_get(uint button, int state_type)
return state_type == current_state ? true : false; return state_type == current_state ? true : false;
} }
void input_map_create(const char* name, struct Key_Combination* keys, int num_keys)
{
assert(name && keys && num_keys > 0);
int index = map_find(name);
if(index > -1)
{
struct Input_Map* map = &input_map_list[index];
for(int i = 0; i < num_keys; i++)
{
struct Key_Combination* new_comb = array_grow(map->keys, struct Key_Combination);
new_comb->mods = KMD_NONE;
*new_comb = keys[i];
log_message("Added new Key combination to input map : %s", name);
}
}
else
{
struct Input_Map* new_map = array_grow(input_map_list, struct Input_Map);
new_map->name = str_new(name);
new_map->keys = array_new_cap(struct Key_Combination, num_keys);
new_map->state = KS_INACTIVE;
for(int i = 0; i < num_keys; i++)
{
new_map->keys[i].mods = KMD_NONE;
new_map->keys[i] = keys[i];
}
log_message("Created Input Map : %s", name);
}
}
void input_update(void) void input_update(void)
{ {
for(int i = 0; i < array_len(input_map_list); i++) struct Variant* value = NULL;
char* key = NULL;
HASHMAP_FOREACH(key_bindings, key, value)
{ {
struct Input_Map* map = &input_map_list[i]; struct Key_Binding* key_binding = (struct Key_Binding*)value->val_voidptr;
if(map->state == KS_RELEASED) if(key_binding->state == KS_RELEASED)
map->state = KS_INACTIVE; key_binding->state = KS_INACTIVE;
} }
} }
bool input_map_remove(const char* name) bool input_map_remove(const char* name)
{ {
assert(name); assert(name);
bool success = false;
int index = map_find(name); if(hashmap_value_exists(key_bindings, name))
if(index > -1)
{ {
array_remove_at(input_map_list, (int)index); struct Key_Binding* current_key = (struct Key_Binding*)hashmap_ptr_get(key_bindings, name);
success = true; free(current_key);
hashmap_value_remove(key_bindings, name);
} }
if(!success) log_error("input:map_remove", "Map %s not found", name); else
return success;
}
bool input_map_keys_set(const char* name, struct Key_Combination* keys, int num_keys)
{
assert(name && keys && num_keys > 0);
bool success = false;
int index = map_find(name);
if(index > -1)
{ {
struct Input_Map* map = &input_map_list[index]; log_error("input:map_remove", "Map '%s' not found", name);
if(array_len(map->keys) != num_keys) return false;
array_reset(map->keys, num_keys);
for(int i = 0; i < num_keys; i++)
map->keys[i] = keys[i];
map->state = KS_INACTIVE;
success = true;
} }
if(!success)
log_error("input:map_keys_set", "Map %s not found", name); return true;
return success;
} }
bool input_map_name_set(const char* name, const char* new_name) bool input_map_keys_set(const char* name, struct Key_Binding key_combination)
{ {
assert(name && new_name); assert(name);
bool success = false; struct Key_Binding* existing_combination = (struct Key_Binding*)hashmap_ptr_get(key_bindings, name);
int index = map_find(name); if(!existing_combination)
if(index > -1)
{ {
struct Input_Map* map = &input_map_list[index]; log_error("input:map_keys_set", "Map '%s' not found", name);
map->name = str_new(new_name); return false;
success = true;
} }
if(!success) log_error("input:map_name_set", "Map %s not found", name);
return success; memcpy(existing_combination, &key_combination, sizeof(key_combination));
existing_combination->state = KS_INACTIVE;
return true;
} }
int map_find(const char* name) bool input_map_name_set(const char* name, const char* new_name)
{ {
int index = -1; //assert(name && new_name);
for(int i = 0; i < array_len(input_map_list); i++) //bool success = false;
{ //int index = map_find(name);
struct Input_Map* map = &input_map_list[i]; //if(index > -1)
if(strcmp(name, map->name) == 0) //{
{ // struct Key_Binding* map = &key_bindings[index];
index = i; // map->name = str_new(new_name);
break; // success = true;
} //}
} //if(!success) log_error("input:map_name_set", "Map %s not found", name);
return index; //return success;
return false;
} }
int input_mouse_mode_get(void) int input_mouse_mode_get(void)

@ -6,10 +6,15 @@
#include <SDL.h> #include <SDL.h>
struct Key_Combination struct Key_Binding
{ {
int key; int key_primary;
int mods; int mods_primary;
int key_secondary;
int mods_secondary;
int state;
}; };
enum Key_Mod enum Key_Mod
@ -156,7 +161,8 @@ enum Keyboard_Key
KEY_RCTRL = SDLK_RCTRL, KEY_RCTRL = SDLK_RCTRL,
KEY_LALT = SDLK_LALT, KEY_LALT = SDLK_LALT,
KEY_RALT = SDLK_RALT, KEY_RALT = SDLK_RALT,
KEY_UNKNOWN = SDLK_UNKNOWN KEY_UNKNOWN = SDLK_UNKNOWN,
KEY_NONE = -1
}; };
enum Keyboard_Scancode enum Keyboard_Scancode
@ -410,7 +416,7 @@ enum Keyboard_Scancode
void input_init(void); void input_init(void);
bool input_keybinds_load(const char* filename, int directory_type); bool input_keybinds_load(const char* filename, int directory_type);
bool input_keybinds_save(const char* filename); bool input_keybinds_save(const char* filename, int directory_type);
void input_cleanup(void); void input_cleanup(void);
bool input_mousebutton_state_get(uint button, int state_type); bool input_mousebutton_state_get(uint button, int state_type);
bool input_is_key_pressed(int key); bool input_is_key_pressed(int key);
@ -421,8 +427,8 @@ void input_mouse_mode_set(enum Mouse_Mode mode);
int input_mouse_mode_get(void); int input_mouse_mode_get(void);
void input_update(void); void input_update(void);
bool input_map_state_get(const char* map_name, int state); bool input_map_state_get(const char* map_name, int state);
void input_map_create(const char* name, struct Key_Combination* keys, int num_keys); bool input_map_create(const char* name, struct Key_Binding key_combination);
bool input_map_keys_set(const char* name, struct Key_Combination* keys, int num_keys); bool input_map_keys_set(const char* name, struct Key_Binding key_combination);
bool input_map_remove(const char* name); bool input_map_remove(const char* name);
bool input_map_name_set(const char* name, const char* new_name); bool input_map_name_set(const char* name, const char* new_name);

Loading…
Cancel
Save