Added a basic options menu. Doesn't save to the config yet.

This commit is contained in:
Akari 2011-07-03 16:11:18 +03:00
parent 056e3bdae8
commit 599d5a8d82
11 changed files with 457 additions and 36 deletions

View file

@ -32,6 +32,7 @@ set(SRCs
fbo.c
menu/menu.c
menu/mainmenu.c
menu/options.c
menu/ingamemenu.c
menu/gameovermenu.c
menu/difficulty.c

View file

@ -11,22 +11,55 @@
Global global;
void init_global() {
memset(&global, 0, sizeof(global));
srand(time(0));
load_resources();
printf("- fonts:\n");
init_fonts();
if(!tconfig.intval[NO_SHADER]) {
void _init_fbo()
{
if(!tconfig.intval[NO_SHADER] && !global.fbo_initialized) {
printf("init_fbo():\n");
init_fbo(&global.fbg);
init_fbo(&global.fsec);
printf("-- finished\n");
global.fbo_initialized = True;
}
}
void init_alut()
{
if(!tconfig.intval[NO_AUDIO] && !global.alut_initialized)
{
if(!alutInit(&global.argc, global.argv))
{
warnx("Error initializing audio: %s", alutGetErrorString(alutGetError()));
tconfig.intval[NO_AUDIO] = 1;
printf("-- ALUT\n");
global.alut_initialized = False;
return;
}
tconfig.intval[NO_AUDIO] = 0;
global.alut_initialized = True;
}
}
void init_global(int argc, char **argv) {
memset(&global, 0, sizeof(global));
srand(time(0));
global.fbo_initialized = False;
global.textures_loaded = False;
global.shaders_loaded = False;
global.sounds_loaded = False;
global.alut_initialized = False;
global.argc = argc;
global.argv = argv;
load_resources();
printf("- fonts:\n");
init_fonts();
_init_fbo();
init_alut();
}
void game_over() {
global.game_over = GAMEOVER_DEFEAT;
printf("Game Over!\n");

View file

@ -101,6 +101,12 @@ typedef struct {
FBO fbg;
FBO fsec;
int fbo_initialized;
int alut_initialized;
int sounds_loaded;
int textures_loaded;
int shaders_loaded;
Boss *boss;
MenuData *menu;
Dialog *dialog;
@ -114,6 +120,9 @@ typedef struct {
int fullscreenhotkey_state;
int argc;
char **argv;
FPSCounter fps;
} Global;

View file

@ -79,16 +79,9 @@ int main(int argc, char** argv) {
printf("-- GLEW\n");
init_gl();
printf("-- GL\n");
if(!tconfig.intval[NO_AUDIO] && !alutInit(&argc, argv)) {
warnx("Error initializing audio: %s", alutGetErrorString(alutGetError()));
tconfig.intval[NO_AUDIO] = 1;
printf("-- ALUT\n");
}
init_global();
init_global(argc, argv);
printf("initialization complete.\n");
MenuData menu;
create_main_menu(&menu);
@ -99,4 +92,4 @@ int main(int argc, char** argv) {
shutdown();
return 1;
}
}

View file

@ -36,6 +36,13 @@ troll:
stage0_loop();
}
void enter_options(void *arg)
{
MenuData m;
create_options_menu(&m);
options_menu_loop();
}
void create_main_menu(MenuData *m) {
create_menu(m);
@ -43,7 +50,8 @@ void create_main_menu(MenuData *m) {
add_menu_entry(m, "Start Story", start_story, NULL);
add_menu_entry(m, "Start Extra", NULL, NULL);
add_menu_entry(m, "Options", NULL, NULL);
//add_menu_entry(m, "Options", NULL, NULL);
add_menu_entry(m, "Options", enter_options, NULL);
add_menu_entry(m, "Quit", quit_menu, m);
}
@ -99,4 +107,4 @@ void draw_main_menu(MenuData *menu) {
void main_menu_loop(MenuData *menu) {
menu_loop(menu, NULL, draw_main_menu);
}
}

View file

@ -17,4 +17,4 @@ void draw_main_menu_bg(MenuData *m);
void draw_main_menu(MenuData *m);
void main_menu_loop(MenuData *m);
#endif
#endif

View file

@ -20,6 +20,9 @@ void add_menu_entry(MenuData *menu, char *name, void (*action)(void *), void *ar
void destroy_menu(MenuData *menu) {
int i;
if(menu->ondestroy)
menu->ondestroy(menu);
for(i = 0; i < menu->ecount; i++)
free(menu->entries[i].name);
@ -31,6 +34,7 @@ void create_menu(MenuData *menu) {
menu->fade = 1;
menu->selected = -1;
menu->ondestroy = NULL;
}
void menu_input(MenuData *menu) {

View file

@ -39,6 +39,9 @@ typedef struct MenuData{
float fade;
float drawdata[4];
void *context;
void (*ondestroy)(void*);
} MenuData;
void add_menu_entry(MenuData *menu, char *name, void (*action)(void *), void *arg);
@ -51,4 +54,4 @@ void menu_input(MenuData *menu);
int menu_loop(MenuData *menu, void (*input)(MenuData*), void (*draw)(MenuData*));
void fade_out(float f);
#endif
#endif

329
src/menu/options.c Normal file
View file

@ -0,0 +1,329 @@
#include "menu.h"
#include "options.h"
#include "global.h"
void do_nothing(void *arg)
{
printf("NOTHING happened!\n");
}
void backtomain(void *arg)
{
MenuData *m = arg;
m->quit = 2;
}
void allocate_bindings(MenuData *m)
{
OptionBinding *binds = malloc(m->ecount * sizeof(OptionBinding));
int i;
for(i = 0; i < m->ecount; ++i)
{
binds[i].values = NULL;
binds[i].getter = NULL;
binds[i].setter = NULL;
binds[i].selected = -1;
binds[i].valcount = 0;
binds[i].configentry = -1;
binds[i].enabled = False;
}
m->context = (void*)binds;
}
void free_bindings(void *menu)
{
MenuData *m = (MenuData*)menu;
OptionBinding *binds = (OptionBinding*)m->context;
int i, j;
for(i = 0; i < m->ecount; ++i)
{
OptionBinding *bind = &(binds[i]);
if(!bind->enabled)
continue;
if(bind->values) for(j = 0; j < bind->valcount; ++j)
free(bind->values[j]);
free(bind->optname);
}
free(binds);
}
OptionBinding* bind_option_to_entry(MenuData *m, int entry, char *optname, int cfgentry, BindingGetter getter, BindingSetter setter)
{
OptionBinding *binds = (OptionBinding*)m->context;
OptionBinding *bind = &(binds[entry]);
bind->getter = getter;
bind->setter = setter;
bind->configentry = cfgentry;
bind->optname = malloc((strlen(optname) + 1) * sizeof(char));
strcpy(bind->optname, optname);
bind->enabled = True;
return bind;
}
int bind_addvalue(OptionBinding *b, char *val)
{
if(!b->values)
b->values = malloc(++b->valcount * sizeof(char));
else
b->values = realloc(b->values, ++b->valcount * sizeof(char));
b->values[b->valcount-1] = malloc((strlen(val) + 1) * sizeof(char));
strcpy(b->values[b->valcount-1], val);
return b->valcount-1;
}
int binding_setvalue(OptionBinding *b, int v)
{
return b->selected = b->setter(b, v);
}
int binding_setnext(OptionBinding *b)
{
int s = b->selected + 1;
if(s >= b->valcount)
s = 0;
return binding_setvalue(b, s);
}
int binding_setprev(OptionBinding *b)
{
int s = b->selected - 1;
if(s < 0)
s = b->valcount - 1;
return binding_setvalue(b, s);
}
void bindings_initvalues(MenuData *m)
{
OptionBinding *binds = (OptionBinding*)m->context;
int i;
for(i = 0; i < m->ecount; ++i)
if(binds[i].enabled)
binds[i].selected = binds[i].getter(&(binds[i]));
}
int bind_common_onoffget(void *b)
{
return !tconfig.intval[((OptionBinding*)b)->configentry];
}
int bind_common_onoffset(void *b, int v)
{
return !(tconfig.intval[((OptionBinding*)b)->configentry] = !v);
}
int bind_common_onoffget_inverted(void *b)
{
return tconfig.intval[((OptionBinding*)b)->configentry];
}
int bind_common_onoffset_inverted(void *b, int v)
{
return tconfig.intval[((OptionBinding*)b)->configentry] = v;
}
int bind_fullscreen_set(void *b, int v)
{
toggle_fullscreen();
return bind_common_onoffset(b, v);
}
int bind_noaudio_set(void *b, int v)
{
int i = bind_common_onoffset_inverted(b, v);
if(!v)
{
init_alut();
load_resources();
}
return i;
}
int bind_noshader_set(void *b, int v)
{
int i = bind_common_onoffset_inverted(b, v);
if(!v)
{
_init_fbo();
load_resources();
}
return i;
}
void create_options_menu(MenuData *m) {
OptionBinding* b;
create_menu(m);
m->type = MT_Persistent;
m->ondestroy = free_bindings;
add_menu_entry(m, "Fullscreen", do_nothing, NULL);
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);
allocate_bindings(m);
b = bind_option_to_entry(m, 0, "fullscreen", FULLSCREEN, bind_common_onoffget, bind_fullscreen_set);
bind_addvalue(b, "on");
bind_addvalue(b, "off");
b = bind_option_to_entry(m, 1, "disable_audio", NO_AUDIO, bind_common_onoffget_inverted,
bind_noaudio_set);
bind_addvalue(b, "on");
bind_addvalue(b, "off");
b = bind_option_to_entry(m, 2, "disable_shader", NO_SHADER, bind_common_onoffget_inverted,
bind_noshader_set);
bind_addvalue(b, "on");
bind_addvalue(b, "off");
bindings_initvalues(m);
}
void draw_options_menu(MenuData *menu) {
glColor4f(0.3, 0.3, 0.3, 1);
draw_texture(SCREEN_W/2, SCREEN_H/2, "mainmenu/mainmenubgbg");
glColor4f(1,0.6,0.5,0.6 + 0.1*sin(menu->frames/100.0));
draw_texture(SCREEN_W/2, SCREEN_H/2, "mainmenu/mainmenubg");
glColor4f(1,1,1,1);
draw_text(AL_Right, 140*(1-menu->fade), 30, "Options", _fonts.mainmenu);
//glColor4f(1,1,1,0.7);
//draw_texture(SCREEN_W/2+40, SCREEN_H/2, "mainmenu/gate");
glPushMatrix();
glTranslatef(100, 100, 0);
glPushMatrix();
glTranslatef(0, menu->drawdata[2], 0);
glColor4f(0,0,0,0.5);
glBegin(GL_QUADS);
glVertex3f(0, -10, 0);
glVertex3f(0, 10, 0);
glVertex3f(SCREEN_W - 200, 10, 0);
glVertex3f(SCREEN_W - 200, -10, 0);
glEnd();
glPopMatrix();
OptionBinding *binds = (OptionBinding*)menu->context;
OptionBinding *bind;
int i;
for(i = 0; i < menu->ecount; i++) {
float s = 0;
float grey = 1;
if(menu->entries[i].action == NULL)
grey = 0.5;
if(i == menu->cursor)
{
glColor4f(1,1,0,0.7);
s = 5*sin(menu->frames/80.0 + 20*i);
}
else
glColor4f(grey,grey,grey,0.7);
draw_text(AL_Left, 20 + s, 20*i, menu->entries[i].name, _fonts.standard);
bind = &(binds[i]);
if(bind->enabled && bind->valcount > 0)
{
int len = 0, j;
for(j = bind->valcount - 1; j+1; --j)
{
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);
}
}
}
glPopMatrix();
menu->drawdata[2] += (20*menu->cursor - menu->drawdata[2])/10.0;
fade_out(menu->fade);
glColor4f(1,1,1,1);
}
void options_menu_input(MenuData *menu) {
SDL_Event event;
global_input();
while(SDL_PollEvent(&event)) {
int sym = event.key.keysym.sym;
if(event.type == SDL_KEYDOWN) {
if(sym == tconfig.intval[KEY_DOWN]) {
menu->drawdata[3] = 10;
while(!(menu->entries[++menu->cursor].action));
} else if(sym == tconfig.intval[KEY_UP]) {
menu->drawdata[3] = 10;
while(!(menu->entries[--menu->cursor].action));
} else if((sym == tconfig.intval[KEY_SHOT] || sym == SDLK_RETURN) && menu->entries[menu->cursor].action) {
menu->selected = menu->cursor;
// hack hack
if(menu->entries[menu->selected].action == backtomain)
menu->quit = 1;
OptionBinding *binds = (OptionBinding*)menu->context;
OptionBinding *bind = &(binds[menu->selected]);
if(bind->enabled)
binding_setnext(bind);
} else if(sym == tconfig.intval[KEY_LEFT]) {
menu->selected = menu->cursor;
OptionBinding *binds = (OptionBinding*)menu->context;
OptionBinding *bind = &(binds[menu->selected]);
if(bind->enabled)
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)
binding_setnext(bind);
} else if(sym == SDLK_ESCAPE) {
menu->quit = 2;
}
menu->cursor = (menu->cursor % menu->ecount) + menu->ecount*(menu->cursor < 0);
} else if(event.type == SDL_QUIT) {
exit(1);
}
}
}
int options_menu_loop(MenuData *menu) {
return menu_loop(menu, options_menu_input, draw_options_menu);
}

27
src/menu/options.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef OPTMENU_H
#define OPTMENU_H
#include "menu.h"
void create_options_menu(MenuData *m);
void draw_options_menu(MenuData *m);
int options_menu_loop(MenuData *m);
typedef int (*BindingGetter)(void*);
typedef int (*BindingSetter)(void*, int);
typedef struct OptionBinding {
char **values;
int valcount;
BindingGetter getter;
BindingSetter setter;
int selected;
int configentry;
int enabled;
char *optname;
} OptionBinding;
#endif

View file

@ -52,28 +52,42 @@ void recurse_dir(char *path) {
void load_resources() {
printf("load_resources():\n");
char *path = malloc(strlen(get_prefix())+7);
printf("- textures:\n");
strcpy(path, get_prefix());
strcat(path, "gfx");
recurse_dir(path);
if(!tconfig.intval[NO_AUDIO]) {
if(!global.textures_loaded)
{
printf("- textures:\n");
strcpy(path, get_prefix());
strcat(path, "gfx");
recurse_dir(path);
global.textures_loaded = True;
}
if(!global.sounds_loaded && !tconfig.intval[NO_AUDIO]) {
printf("- sounds:\n");
alGenSources(SNDSRC_COUNT, global.sndsrc);
strcpy(path, get_prefix());
strcat(path, "sfx");
recurse_dir(path);
global.sounds_loaded = True;
}
if(!tconfig.intval[NO_SHADER]) {
printf("- shader:\n");
strcpy(path, get_prefix());
strcat(path, "shader");
recurse_dir(path);
} else {
printf("- shader: disabled.\n");
if(!global.shaders_loaded)
{
if(!tconfig.intval[NO_SHADER]) {
printf("- shader:\n");
strcpy(path, get_prefix());
strcat(path, "shader");
recurse_dir(path);
global.shaders_loaded = True;
} else {
printf("- shader: disabled.\n");
}
}
free(path);
}
Texture *get_tex(char *name) {
@ -307,4 +321,4 @@ void fill_screen_p(float xoff, float yoff, float ratio, Texture *tex) {
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}
}