Added keybinds and config saving (TODO: allow the user to actually customize the keys)
This commit is contained in:
parent
3e4413ca1c
commit
9e35feadad
2 changed files with 137 additions and 22 deletions
|
@ -6,6 +6,7 @@
|
|||
* Copyright (C) 2011, Alexeyew Andrew <https://github.com/nexAkari>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "menu.h"
|
||||
#include "options.h"
|
||||
#include "global.h"
|
||||
|
@ -36,9 +37,8 @@ void allocate_bindings(MenuData *m)
|
|||
m->context = (void*)binds;
|
||||
}
|
||||
|
||||
void free_bindings(void *menu)
|
||||
void free_bindings(MenuData *m)
|
||||
{
|
||||
MenuData *m = (MenuData*)menu;
|
||||
OptionBinding *binds = (OptionBinding*)m->context;
|
||||
|
||||
int i, j;
|
||||
|
@ -55,6 +55,60 @@ void free_bindings(void *menu)
|
|||
free(binds);
|
||||
}
|
||||
|
||||
void menu_save_config(MenuData *m, char *filename)
|
||||
{
|
||||
char *buf;
|
||||
buf = malloc(strlen((char*)filename)+strlen((char*)get_config_path())+3);
|
||||
strcpy(buf, (char*)get_config_path());
|
||||
strcat(buf, "/");
|
||||
strcat(buf, filename);
|
||||
|
||||
FILE *out = fopen(buf, "w");
|
||||
free(buf);
|
||||
|
||||
if(!out)
|
||||
{
|
||||
perror("fopen");
|
||||
return;
|
||||
}
|
||||
|
||||
fputs("# Generated by taisei\n", out);
|
||||
|
||||
int i;
|
||||
for(i = 0; i < m->ecount; ++i)
|
||||
{
|
||||
OptionBinding *binds = (OptionBinding*)m->context;
|
||||
OptionBinding *bind = &(binds[i]);
|
||||
|
||||
if(!bind->enabled)
|
||||
continue;
|
||||
|
||||
switch(bind->type)
|
||||
{
|
||||
case BT_IntValue:
|
||||
fprintf(out, "%s = %i\n", bind->optname, tconfig.intval[bind->configentry]);
|
||||
break;
|
||||
|
||||
case BT_KeyBinding:
|
||||
fprintf(out, "%s = K%i # SDL key name: %s\n", bind->optname, tconfig.intval[bind->configentry],
|
||||
SDL_GetKeyName(tconfig.intval[bind->configentry]));
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("FIXME: unhandled BindingType %i, option '%s' will NOT be saved!\n", bind->type, bind->optname);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Saved config '%s'\n", filename);
|
||||
}
|
||||
|
||||
void options_menu_destroy(void *menu)
|
||||
{
|
||||
MenuData *m = (MenuData*)menu;
|
||||
menu_save_config(m, CONFIG_FILE);
|
||||
free_bindings(menu);
|
||||
}
|
||||
|
||||
OptionBinding* bind_option_to_entry(MenuData *m, int entry, char *optname, int cfgentry, BindingGetter getter, BindingSetter setter)
|
||||
{
|
||||
OptionBinding *binds = (OptionBinding*)m->context;
|
||||
|
@ -66,6 +120,21 @@ OptionBinding* bind_option_to_entry(MenuData *m, int entry, char *optname, int c
|
|||
bind->optname = malloc((strlen(optname) + 1) * sizeof(char));
|
||||
strcpy(bind->optname, optname);
|
||||
bind->enabled = True;
|
||||
bind->type = BT_IntValue;
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
||||
OptionBinding* bind_keybinding_to_entry(MenuData *m, int entry, char *optname, int cfgentry)
|
||||
{
|
||||
OptionBinding *binds = (OptionBinding*)m->context;
|
||||
OptionBinding *bind = &(binds[entry]);
|
||||
|
||||
bind->configentry = cfgentry;
|
||||
bind->optname = malloc((strlen(optname) + 1) * sizeof(char));
|
||||
strcpy(bind->optname, optname);
|
||||
bind->enabled = True;
|
||||
bind->type = BT_KeyBinding;
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
@ -111,7 +180,7 @@ void bindings_initvalues(MenuData *m)
|
|||
|
||||
int i;
|
||||
for(i = 0; i < m->ecount; ++i)
|
||||
if(binds[i].enabled)
|
||||
if(binds[i].enabled && binds[i].type == BT_IntValue)
|
||||
binds[i].selected = binds[i].getter(&(binds[i]));
|
||||
}
|
||||
|
||||
|
@ -174,17 +243,32 @@ void create_options_menu(MenuData *m) {
|
|||
|
||||
create_menu(m);
|
||||
m->type = MT_Persistent;
|
||||
m->ondestroy = free_bindings;
|
||||
m->ondestroy = options_menu_destroy;
|
||||
|
||||
add_menu_entry(m, "Fullscreen", do_nothing, NULL);
|
||||
add_menu_entry(m, "Fullscreen", do_nothing, NULL); // entry 0
|
||||
add_menu_entry(m, "Audio", do_nothing, NULL);
|
||||
add_menu_entry(m, "Shader", do_nothing, NULL);
|
||||
add_menu_entry(m, " ", NULL, NULL);
|
||||
add_menu_entry(m, "Customize controls", NULL, NULL);
|
||||
add_menu_entry(m, "Back", backtomain, m);
|
||||
add_menu_entry(m, "Move up", do_nothing, NULL); // entry 4
|
||||
add_menu_entry(m, "Move down", do_nothing, NULL);
|
||||
add_menu_entry(m, "Move left", do_nothing, NULL);
|
||||
add_menu_entry(m, "Move right", do_nothing, NULL);
|
||||
add_menu_entry(m, " ", NULL, NULL);
|
||||
add_menu_entry(m, "Fire", do_nothing, NULL); // entry 9
|
||||
add_menu_entry(m, "Focus", do_nothing, NULL);
|
||||
add_menu_entry(m, "Bomb", do_nothing, NULL);
|
||||
add_menu_entry(m, " ", NULL, NULL);
|
||||
add_menu_entry(m, "Toggle fullscreen", do_nothing, NULL); // entry 13
|
||||
// UNCOMMENT after akari/screenshot is merged
|
||||
//add_menu_entry(m, "Take a screenshot", do_nothing, NULL);
|
||||
add_menu_entry(m, " ", NULL, NULL);
|
||||
//add_menu_entry(m, "Customize controls", NULL, NULL);
|
||||
add_menu_entry(m, "Return to the main menu", backtomain, m);
|
||||
|
||||
allocate_bindings(m);
|
||||
|
||||
// this sucks but you have to specify the positional number of the menu entry as the second argument to bind_option_to_entry or bind_keybinding_to_entry
|
||||
|
||||
b = bind_option_to_entry(m, 0, "fullscreen", FULLSCREEN, bind_common_onoffget, bind_fullscreen_set);
|
||||
bind_onoff(b);
|
||||
|
||||
|
@ -196,6 +280,19 @@ void create_options_menu(MenuData *m) {
|
|||
bind_noshader_set);
|
||||
bind_onoff(b);
|
||||
|
||||
bind_keybinding_to_entry(m, 4, "key_up", KEY_UP);
|
||||
bind_keybinding_to_entry(m, 5, "key_down", KEY_DOWN);
|
||||
bind_keybinding_to_entry(m, 6, "key_left", KEY_LEFT);
|
||||
bind_keybinding_to_entry(m, 7, "key_right", KEY_RIGHT);
|
||||
|
||||
bind_keybinding_to_entry(m, 9, "key_shot", KEY_SHOT);
|
||||
bind_keybinding_to_entry(m, 10, "key_focus", KEY_FOCUS);
|
||||
bind_keybinding_to_entry(m, 11, "key_bomb", KEY_BOMB);
|
||||
|
||||
bind_keybinding_to_entry(m, 13, "key_fullscreen", KEY_FULLSCREEN);
|
||||
// UNCOMMENT after akari/screeenshot is merged
|
||||
//bind_keybinding_to_entry(m, 14, "key_screenshot", KEY_SCREENSHOT);
|
||||
|
||||
bindings_initvalues(m);
|
||||
}
|
||||
|
||||
|
@ -249,19 +346,29 @@ void draw_options_menu(MenuData *menu) {
|
|||
|
||||
bind = &(binds[i]);
|
||||
|
||||
if(bind->enabled && bind->valcount > 0)
|
||||
if(bind->enabled)
|
||||
{
|
||||
int len = 0, j;
|
||||
for(j = bind->valcount - 1; j+1; --j)
|
||||
int j, origin = SCREEN_W - 220;
|
||||
switch(bind->type)
|
||||
{
|
||||
len += strlen(bind->values[j]);
|
||||
|
||||
if(bind->selected == j)
|
||||
glColor4f(1,1,0,0.7);
|
||||
else
|
||||
glColor4f(0.5,0.5,0.5,0.7);
|
||||
|
||||
draw_text(AL_Right, SCREEN_W - 200 - (len*20), 20*i, bind->values[j], _fonts.standard);
|
||||
case BT_IntValue:
|
||||
for(j = bind->valcount-1; j+1; --j)
|
||||
{
|
||||
if(j != bind->valcount-1)
|
||||
origin -= strlen(bind->values[j+1])/2.0 * 20;
|
||||
|
||||
if(bind->selected == j)
|
||||
glColor4f(1,1,0,0.7);
|
||||
else
|
||||
glColor4f(0.5,0.5,0.5,0.7);
|
||||
|
||||
draw_text(AL_Right, origin, 20*i, bind->values[j], _fonts.standard);
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_KeyBinding:
|
||||
draw_text(AL_Right, origin, 20*i, SDL_GetKeyName(tconfig.intval[bind->configentry]), _fonts.standard);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,8 +414,10 @@ void options_menu_input(MenuData *menu) {
|
|||
OptionBinding *binds = (OptionBinding*)menu->context;
|
||||
OptionBinding *bind = &(binds[menu->selected]);
|
||||
|
||||
if(bind->enabled)
|
||||
binding_setnext(bind);
|
||||
if(bind->enabled) switch(bind->type)
|
||||
{
|
||||
case BT_IntValue: binding_setnext(bind); break;
|
||||
}
|
||||
else
|
||||
menu->quit = 1;
|
||||
} else if(sym == tconfig.intval[KEY_LEFT]) {
|
||||
|
@ -316,14 +425,14 @@ void options_menu_input(MenuData *menu) {
|
|||
OptionBinding *binds = (OptionBinding*)menu->context;
|
||||
OptionBinding *bind = &(binds[menu->selected]);
|
||||
|
||||
if(bind->enabled)
|
||||
if(bind->enabled && bind->type == BT_IntValue)
|
||||
binding_setprev(bind);
|
||||
} else if(sym == tconfig.intval[KEY_RIGHT]) {
|
||||
menu->selected = menu->cursor;
|
||||
OptionBinding *binds = (OptionBinding*)menu->context;
|
||||
OptionBinding *bind = &(binds[menu->selected]);
|
||||
|
||||
if(bind->enabled)
|
||||
if(bind->enabled && bind->type == BT_IntValue)
|
||||
binding_setnext(bind);
|
||||
} else if(sym == SDLK_ESCAPE) {
|
||||
menu->quit = 2;
|
||||
|
|
|
@ -19,6 +19,11 @@ int options_menu_loop(MenuData *m);
|
|||
typedef int (*BindingGetter)(void*);
|
||||
typedef int (*BindingSetter)(void*, int);
|
||||
|
||||
typedef enum BindingType {
|
||||
BT_IntValue,
|
||||
BT_KeyBinding
|
||||
} BindingType;
|
||||
|
||||
typedef struct OptionBinding {
|
||||
char **values;
|
||||
int valcount;
|
||||
|
@ -28,6 +33,7 @@ typedef struct OptionBinding {
|
|||
int configentry;
|
||||
int enabled;
|
||||
char *optname;
|
||||
BindingType type;
|
||||
} OptionBinding;
|
||||
|
||||
void draw_options_menu_bg(MenuData*);
|
||||
|
|
Loading…
Reference in a new issue