4coder/4ed_command.cpp

164 lines
4.2 KiB
C++
Raw Normal View History

2015-09-28 23:34:55 +00:00
/*
* Mr. 4th Dimention - Allen Webster
*
* 19.08.2015
*
* Command management functions for 4coder
*
*/
// TOP
2015-12-01 02:51:53 +00:00
#define Command_Function_Sig(name) void (name)( \
System_Functions *system, \
struct Command_Data *command, \
struct Command_Binding binding)
typedef Command_Function_Sig(*Command_Function);
2015-09-28 23:34:55 +00:00
struct Command_Binding{
Command_Function function;
Custom_Command_Function *custom;
i64 hash;
};
struct Command_Map{
2015-10-16 20:31:04 +00:00
Command_Map *parent;
2015-09-28 23:34:55 +00:00
Command_Binding vanilla_keyboard_default;
2015-10-16 20:31:04 +00:00
Command_Binding *commands;
2015-09-28 23:34:55 +00:00
i32 count, max;
};
internal void command_null(Command_Data *command);
internal i64
map_hash(u16 event_code, u8 modifiers){
2015-12-01 02:51:53 +00:00
i64 result = (event_code << 8) | modifiers;
2015-09-28 23:34:55 +00:00
return result;
}
2015-11-16 16:15:45 +00:00
internal b32
2016-01-06 15:39:15 +00:00
map_add(Command_Map *map, u16 event_code, u8 modifiers,
Command_Function function, Custom_Command_Function *custom = 0){
2015-09-28 23:34:55 +00:00
Assert(map->count * 8 < map->max * 7);
Command_Binding bind;
bind.function = function;
bind.custom = custom;
bind.hash = map_hash(event_code, modifiers);
i32 max = map->max;
i32 index = bind.hash % max;
Command_Binding entry;
while ((entry = map->commands[index]).function && entry.hash != -1){
if (entry.hash == bind.hash){
return 1;
}
index = (index + 1) % max;
}
map->commands[index] = bind;
++map->count;
return 0;
}
2015-11-16 16:15:45 +00:00
internal b32
2016-01-06 15:39:15 +00:00
map_find_entry(Command_Map *map, u16 event_code, u8 modifiers,
i32 *index_out){
2015-09-28 23:34:55 +00:00
i64 hash = map_hash(event_code, modifiers);
i32 max = map->max;
i32 index = hash % map->max;
Command_Binding entry;
while ((entry = map->commands[index]).function){
if (entry.hash == hash){
*index_out = index;
return 1;
}
index = (index + 1) % max;
}
return 0;
}
2015-11-16 16:15:45 +00:00
internal b32
2016-01-06 15:39:15 +00:00
map_find(Command_Map *map, u16 event_code, u8 modifiers,
Command_Binding *bind_out){
2015-11-16 16:15:45 +00:00
b32 result;
2015-09-28 23:34:55 +00:00
i32 index;
result = map_find_entry(map, event_code, modifiers, &index);
if (result){
*bind_out = map->commands[index];
}
return result;
}
2015-11-16 16:15:45 +00:00
internal b32
2015-09-28 23:34:55 +00:00
map_drop(Command_Map *map, u16 event_code, u8 modifiers){
2015-11-16 16:15:45 +00:00
b32 result;
2015-09-28 23:34:55 +00:00
i32 index;
result = map_find_entry(map, event_code, modifiers, &index);
if (result){
map->commands[index].function = 0;
map->commands[index].hash = -1;
}
return result;
}
internal void
2016-01-06 15:39:15 +00:00
map_init(Command_Map *commands, Partition *part, i32 max,
Command_Map *parent){
2015-10-16 20:31:04 +00:00
commands->parent = parent;
commands->commands = push_array(part, Command_Binding, max);
memset(commands->commands, 0, max*sizeof(*commands->commands));
2015-09-28 23:34:55 +00:00
commands->vanilla_keyboard_default = {};
2015-10-16 20:31:04 +00:00
commands->max = max;
2015-09-28 23:34:55 +00:00
commands->count = 0;
}
internal void
2016-01-06 15:39:15 +00:00
map_get_vanilla_keyboard_default(Command_Map *map, u8 command,
Command_Binding *bind_out){
2015-09-28 23:34:55 +00:00
if (command == MDFR_NONE){
*bind_out = map->vanilla_keyboard_default;
}
}
2016-01-06 15:39:15 +00:00
inline u8
apply_shift_to_code(u8 keycode){
return !(keycode >= 0x20 && keycode < 0x7F && keycode != ' ');
}
2015-09-28 23:34:55 +00:00
internal Command_Binding
2016-01-17 01:34:48 +00:00
map_extract(Command_Map *map, Key_Event_Data key){
2015-09-28 23:34:55 +00:00
Command_Binding bind = {};
2015-10-28 01:45:03 +00:00
b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL];
b32 alt = key.modifiers[CONTROL_KEY_ALT];
2016-01-06 15:39:15 +00:00
b32 shift = key.modifiers[CONTROL_KEY_SHIFT];
2015-12-01 02:51:53 +00:00
u16 code;
u8 command = MDFR_NONE;
2015-09-28 23:34:55 +00:00
2016-01-17 01:34:48 +00:00
if (key.character_no_caps_lock != 0 &&
key.character_no_caps_lock != ' ') shift = 0;
2016-01-06 15:39:15 +00:00
2015-09-28 23:34:55 +00:00
if (shift) command |= MDFR_SHIFT;
if (ctrl) command |= MDFR_CTRL;
if (alt) command |= MDFR_ALT;
2016-01-06 15:39:15 +00:00
2016-01-17 01:34:48 +00:00
code = key.character_no_caps_lock;
2015-12-01 02:51:53 +00:00
if (code == 0){
2016-01-17 01:34:48 +00:00
code = key.keycode;
2015-12-01 02:51:53 +00:00
map_find(map, code, command, &bind);
}
else{
command &= ~(MDFR_SHIFT);
map_find(map, code, command, &bind);
if (bind.function == 0){
map_get_vanilla_keyboard_default(map, command, &bind);
}
2015-09-28 23:34:55 +00:00
}
return bind;
}
// BOTTOM