improved the no-stage-bg feature, and extended the options menu functionality while I was at it
This commit is contained in:
parent
c25566346e
commit
7fb8b25732
8 changed files with 105 additions and 44 deletions
|
@ -34,7 +34,8 @@ enum {
|
|||
NO_SHADER,
|
||||
NO_AUDIO,
|
||||
|
||||
NO_STAGEBG
|
||||
NO_STAGEBG,
|
||||
NO_STAGEBG_FPSLIMIT
|
||||
};
|
||||
|
||||
void parse_config(char *filename);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
"disable_shader" { yylval = NO_SHADER; return tNO_SHADER; }
|
||||
"disable_audio" {yylval = NO_AUDIO; return tNO_AUDIO; }
|
||||
"disable_stagebg" { yylval = NO_STAGEBG; return tNO_STAGEBG; }
|
||||
"disable_stagebg_auto_fpslimit" { yylval = NO_STAGEBG_FPSLIMIT; return tNO_STAGEBG_FPSLIMIT; }
|
||||
|
||||
"shift" { yylval = SDLK_LSHIFT; return SKEY; }
|
||||
"ctrl" { yylval = SDLK_LCTRL; return SKEY; }
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
%token tNO_SHADER
|
||||
%token tNO_AUDIO
|
||||
%token tNO_STAGEBG
|
||||
%token tNO_STAGEBG_FPSLIMIT
|
||||
|
||||
%token SKEY
|
||||
|
||||
|
@ -86,7 +87,8 @@ key_key : tKEY_UP
|
|||
| tNO_SHADER
|
||||
| tNO_AUDIO
|
||||
| tFULLSCREEN
|
||||
| tNO_STAGEBG;
|
||||
| tNO_STAGEBG
|
||||
| tNO_STAGEBG_FPSLIMIT;
|
||||
|
||||
nl : LB { lineno++; };
|
||||
%%
|
||||
|
@ -137,4 +139,5 @@ void config_preset() {
|
|||
tconfig.intval[NO_AUDIO] = 0;
|
||||
|
||||
tconfig.intval[NO_STAGEBG] = 0;
|
||||
tconfig.intval[NO_STAGEBG_FPSLIMIT] = 40;
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ typedef struct {
|
|||
|
||||
FPSCounter fps;
|
||||
|
||||
int nostagebg; // I don't want the automatic stagebg handling to mess with the config, and I don't want that longass if in more than one place either.
|
||||
} Global;
|
||||
|
||||
extern Global global;
|
||||
|
|
|
@ -103,7 +103,6 @@ int main(int argc, char** argv) {
|
|||
|
||||
atexit(taisei_shutdown);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("** Compiled with DEBUG flag!\n");
|
||||
if(argc >= 2 && argv[1]) {
|
||||
|
|
|
@ -111,37 +111,60 @@ int bind_addvalue(OptionBinding *b, char *val)
|
|||
return b->valcount-1;
|
||||
}
|
||||
|
||||
void bind_setvaluerange(OptionBinding *b, int vmin, int vmax) {
|
||||
b->valrange_min = vmin;
|
||||
b->valrange_max = vmax;
|
||||
}
|
||||
|
||||
// Called to select a value of a BT_IntValue type binding by index
|
||||
int binding_setvalue(OptionBinding *b, int v)
|
||||
int bind_setvalue(OptionBinding *b, int v)
|
||||
{
|
||||
return b->selected = b->setter(b, v);
|
||||
}
|
||||
|
||||
// Called to get the selected value of a BT_IntValue type binding by index
|
||||
int binding_getvalue(OptionBinding *b)
|
||||
int bind_getvalue(OptionBinding *b)
|
||||
{
|
||||
// query AND update
|
||||
return b->selected = b->getter(b);
|
||||
}
|
||||
|
||||
// Selects the next to current value of a BT_IntValue type binding
|
||||
int binding_setnext(OptionBinding *b)
|
||||
int bind_setnext(OptionBinding *b)
|
||||
{
|
||||
int s = b->selected + 1;
|
||||
if(s >= b->valcount)
|
||||
int s = b->selected +1;
|
||||
|
||||
if(b->valrange_max) {
|
||||
if(s > b->valrange_max)
|
||||
s = b->valrange_min;
|
||||
} else if(s >= b->valcount)
|
||||
s = 0;
|
||||
|
||||
return binding_setvalue(b, s);
|
||||
|
||||
return bind_setvalue(b, s);
|
||||
}
|
||||
|
||||
// Selects the previous to current value of a BT_IntValue type binding
|
||||
int binding_setprev(OptionBinding *b)
|
||||
int bind_setprev(OptionBinding *b)
|
||||
{
|
||||
int s = b->selected - 1;
|
||||
if(s < 0)
|
||||
|
||||
if(b->valrange_max) {
|
||||
if(s < b->valrange_min)
|
||||
s = b->valrange_max;
|
||||
} else if(s < 0)
|
||||
s = b->valcount - 1;
|
||||
|
||||
return binding_setvalue(b, s);
|
||||
return bind_setvalue(b, s);
|
||||
}
|
||||
|
||||
void bind_setdependence(OptionBinding *b, BindingDependence dep) {
|
||||
b->dependence = dep;
|
||||
}
|
||||
|
||||
int bind_isactive(OptionBinding *b) {
|
||||
if(!b->dependence)
|
||||
return True;
|
||||
return b->dependence();
|
||||
}
|
||||
|
||||
// Initializes selection for all BT_IntValue type bindings
|
||||
|
@ -152,7 +175,7 @@ void bindings_initvalues(MenuData *m)
|
|||
int i;
|
||||
for(i = 0; i < m->ecount; ++i)
|
||||
if(binds[i].enabled && binds[i].type == BT_IntValue)
|
||||
binding_getvalue(&(binds[i]));
|
||||
bind_getvalue(&(binds[i]));
|
||||
}
|
||||
|
||||
// --- Shared binding callbacks --- //
|
||||
|
@ -177,6 +200,9 @@ int bind_common_onoffset_inverted(void *b, int v)
|
|||
return tconfig.intval[((OptionBinding*)b)->configentry] = v;
|
||||
}
|
||||
|
||||
#define bind_common_intget bind_common_onoffget_inverted
|
||||
#define bind_common_intset bind_common_onoffset_inverted
|
||||
|
||||
// --- Binding callbacks for individual options --- //
|
||||
|
||||
int bind_fullscreen_set(void *b, int v)
|
||||
|
@ -227,6 +253,10 @@ int bind_noshader_set(void *b, int v)
|
|||
return i;
|
||||
}
|
||||
|
||||
int bind_stagebg_fpslimit_dependence() {
|
||||
return tconfig.intval[NO_STAGEBG] == 2;
|
||||
}
|
||||
|
||||
// --- Config saving --- //
|
||||
|
||||
void menu_save_config(MenuData *m, char *filename)
|
||||
|
@ -293,7 +323,7 @@ void backtomain(void *arg)
|
|||
}
|
||||
|
||||
void create_options_menu(MenuData *m) {
|
||||
OptionBinding* b;
|
||||
OptionBinding *b;
|
||||
|
||||
create_menu(m);
|
||||
m->type = MT_Persistent;
|
||||
|
@ -317,10 +347,18 @@ void create_options_menu(MenuData *m) {
|
|||
bind_onoff(b);
|
||||
|
||||
add_menu_entry(m, "Stage Background", do_nothing, NULL);
|
||||
b = bind_option(m, "disable_stagebg", NO_STAGEBG, bind_common_onoffget_inverted,
|
||||
bind_common_onoffset_inverted);
|
||||
bind_onoff(b);
|
||||
|
||||
b = bind_option(m, "disable_stagebg", NO_STAGEBG, bind_common_intget,
|
||||
bind_common_intset);
|
||||
bind_addvalue(b, "on");
|
||||
bind_addvalue(b, "off");
|
||||
bind_addvalue(b, "auto");
|
||||
|
||||
add_menu_entry(m, "Minimum FPS", do_nothing, NULL);
|
||||
b = bind_option(m, "disable_stagebg_auto_fpslimit", NO_STAGEBG_FPSLIMIT, bind_common_intget,
|
||||
bind_common_intset);
|
||||
bind_setvaluerange(b, 20, 60);
|
||||
bind_setdependence(b, bind_stagebg_fpslimit_dependence);
|
||||
|
||||
add_menu_entry(m, " ", NULL, NULL);
|
||||
allocate_binding(m);
|
||||
|
||||
|
@ -403,37 +441,46 @@ void draw_options_menu(MenuData *menu) {
|
|||
for(i = 0; i < menu->ecount; i++) {
|
||||
menu->entries[i].drawdata += 0.2 * (10*(i == menu->cursor) - menu->entries[i].drawdata);
|
||||
|
||||
bind = &(binds[i]);
|
||||
int hasbind = bind->enabled;
|
||||
float alpha = (!hasbind || bind_isactive(bind))? 1 : 0.5;
|
||||
|
||||
if(menu->entries[i].action == NULL && clr != 0) {
|
||||
clr = 0;
|
||||
glColor4f(0.5, 0.5, 0.5, 0.7);
|
||||
glColor4f(0.5, 0.5, 0.5, 0.7 * alpha);
|
||||
} else if(i == menu->cursor && clr != 1) {
|
||||
clr = 1;
|
||||
glColor4f(1,1,0,0.7);
|
||||
glColor4f(1,1,0,0.7 * alpha);
|
||||
} else if(clr != 2) {
|
||||
clr = 2;
|
||||
glColor4f(1, 1, 1, 0.7);
|
||||
glColor4f(1, 1, 1, 0.7 * alpha);
|
||||
}
|
||||
|
||||
draw_text(AL_Left, 20 - menu->entries[i].drawdata, 20*i, menu->entries[i].name, _fonts.standard);
|
||||
draw_text(AL_Left,
|
||||
((hasbind && bind->dependence)? 20 : 0) // hack hack hack
|
||||
+ 20 - menu->entries[i].drawdata, 20*i, menu->entries[i].name, _fonts.standard);
|
||||
|
||||
bind = &(binds[i]);
|
||||
if(bind->enabled)
|
||||
if(hasbind)
|
||||
{
|
||||
int j, origin = SCREEN_W - 220;
|
||||
|
||||
switch(bind->type)
|
||||
{
|
||||
case BT_IntValue:
|
||||
for(j = bind->valcount-1; j+1; --j)
|
||||
{
|
||||
if(bind->valrange_max) {
|
||||
char tmp[16]; // who'd use a 16-digit number here anyway?
|
||||
snprintf(tmp, 16, "%d", bind_getvalue(bind));
|
||||
draw_text(AL_Right, origin, 20*i, tmp, _fonts.standard);
|
||||
} else for(j = bind->valcount-1; j+1; --j) {
|
||||
if(j != bind->valcount-1)
|
||||
origin -= strlen(bind->values[j+1])/2.0 * 20;
|
||||
|
||||
if(binding_getvalue(bind) == j && clr != 1) {
|
||||
if(bind_getvalue(bind) == j) {
|
||||
clr = 1;
|
||||
glColor4f(1,1,0,0.7);
|
||||
glColor4f(1,1,0,0.7 * alpha);
|
||||
} else if(clr != 0) {
|
||||
clr = 0;
|
||||
glColor4f(0.5,0.5,0.5,0.7);
|
||||
glColor4f(0.5,0.5,0.5,0.7 * alpha);
|
||||
}
|
||||
|
||||
draw_text(AL_Right, origin, 20*i, bind->values[j], _fonts.standard);
|
||||
|
@ -473,7 +520,7 @@ void draw_options_menu(MenuData *menu) {
|
|||
|
||||
// --- Input processing --- //
|
||||
|
||||
void binding_input(MenuData *menu, OptionBinding *b)
|
||||
void bind_input(MenuData *menu, OptionBinding *b)
|
||||
{
|
||||
// yes, no global_input() here.
|
||||
|
||||
|
@ -499,20 +546,22 @@ void binding_input(MenuData *menu, OptionBinding *b)
|
|||
}
|
||||
|
||||
static void options_key_action(MenuData *menu, int sym) {
|
||||
#define SHOULD_SKIP (!menu->entries[menu->cursor].action || (((OptionBinding*)menu->context)[menu->cursor].enabled && !bind_isactive(&(((OptionBinding*)menu->context)[menu->cursor]))))
|
||||
|
||||
if(sym == tconfig.intval[KEY_DOWN] || sym == SDLK_DOWN) {
|
||||
menu->drawdata[3] = 10;
|
||||
do {
|
||||
menu->cursor++;
|
||||
if(menu->cursor >= menu->ecount)
|
||||
menu->cursor = 0;
|
||||
} while(!menu->entries[menu->cursor].action);
|
||||
} while SHOULD_SKIP;
|
||||
} else if(sym == tconfig.intval[KEY_UP] || sym == SDLK_UP) {
|
||||
menu->drawdata[3] = 10;
|
||||
do {
|
||||
menu->cursor--;
|
||||
if(menu->cursor < 0)
|
||||
menu->cursor = menu->ecount - 1;
|
||||
} while(!menu->entries[menu->cursor].action);
|
||||
} while SHOULD_SKIP;
|
||||
} else if((sym == tconfig.intval[KEY_SHOT] || sym == SDLK_RETURN) && menu->entries[menu->cursor].action) {
|
||||
menu->selected = menu->cursor;
|
||||
|
||||
|
@ -521,7 +570,7 @@ static void options_key_action(MenuData *menu, int sym) {
|
|||
|
||||
if(bind->enabled) switch(bind->type)
|
||||
{
|
||||
case BT_IntValue: binding_setnext(bind); break;
|
||||
case BT_IntValue: bind_setnext(bind); break;
|
||||
case BT_KeyBinding: bind->blockinput = True; break;
|
||||
}
|
||||
else
|
||||
|
@ -532,14 +581,14 @@ static void options_key_action(MenuData *menu, int sym) {
|
|||
OptionBinding *bind = &(binds[menu->selected]);
|
||||
|
||||
if(bind->enabled && bind->type == BT_IntValue)
|
||||
binding_setprev(bind);
|
||||
bind_setprev(bind);
|
||||
} else if(sym == tconfig.intval[KEY_RIGHT] || sym == SDLK_RIGHT) {
|
||||
menu->selected = menu->cursor;
|
||||
OptionBinding *binds = (OptionBinding*)menu->context;
|
||||
OptionBinding *bind = &(binds[menu->selected]);
|
||||
|
||||
if(bind->enabled && bind->type == BT_IntValue)
|
||||
binding_setnext(bind);
|
||||
bind_setnext(bind);
|
||||
} else if(sym == SDLK_ESCAPE) {
|
||||
menu->quit = 2;
|
||||
}
|
||||
|
@ -553,7 +602,7 @@ void options_menu_input(MenuData *menu) {
|
|||
|
||||
if((b = get_input_blocking_binding(menu)) != NULL)
|
||||
{
|
||||
binding_input(menu, b);
|
||||
bind_input(menu, b);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ int options_menu_loop(MenuData *m);
|
|||
|
||||
typedef int (*BindingGetter)(void*);
|
||||
typedef int (*BindingSetter)(void*, int);
|
||||
typedef int (*BindingDependence)();
|
||||
|
||||
typedef enum BindingType {
|
||||
BT_IntValue,
|
||||
|
@ -27,8 +28,11 @@ typedef enum BindingType {
|
|||
typedef struct OptionBinding {
|
||||
char **values;
|
||||
int valcount;
|
||||
int valrange_min;
|
||||
int valrange_max;
|
||||
BindingGetter getter;
|
||||
BindingSetter setter;
|
||||
BindingDependence dependence;
|
||||
int selected;
|
||||
int configentry;
|
||||
int enabled;
|
||||
|
|
17
src/stage.c
17
src/stage.c
|
@ -16,6 +16,7 @@ void stage_start() {
|
|||
global.frames = 0;
|
||||
global.game_over = 0;
|
||||
global.points = 0;
|
||||
global.nostagebg = False;
|
||||
}
|
||||
|
||||
void stage_input() {
|
||||
|
@ -129,9 +130,14 @@ void stage_draw(StageRule bgdraw, ShaderRule *shaderrules, int time) {
|
|||
glTranslatef(-(VIEWPORT_X+VIEWPORT_W/2.0), -(VIEWPORT_Y+VIEWPORT_H/2.0),0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
if(!global.menu && !tconfig.intval[NO_STAGEBG])
|
||||
// NO_STAGEBG == 2 means "automatic mode". Do we need a derpenum for this?
|
||||
// global.fps.fps is unreliable here, show_fps is better
|
||||
|
||||
if(!global.nostagebg && ((!global.menu && !tconfig.intval[NO_STAGEBG]) ||
|
||||
(tconfig.intval[NO_STAGEBG] == 2 && (global.fps.show_fps == 0 || global.fps.show_fps > tconfig.intval[NO_STAGEBG_FPSLIMIT]))))
|
||||
bgdraw();
|
||||
|
||||
else global.nostagebg = True;
|
||||
|
||||
glPopMatrix();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
|
@ -234,7 +240,7 @@ void apply_bg_shaders(ShaderRule *shaderrules) {
|
|||
glPopMatrix();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
} else if(!tconfig.intval[NO_STAGEBG]) {
|
||||
} else if(!global.nostagebg) {
|
||||
for(i = 0; shaderrules != NULL && shaderrules[i] != NULL; i++) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[!fbonum].fbo);
|
||||
shaderrules[i](fbonum);
|
||||
|
@ -357,9 +363,6 @@ void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event,
|
|||
|
||||
SDL_GL_SwapBuffers();
|
||||
frame_rate(&global.lasttime);
|
||||
|
||||
if(global.fps.fps <= 40)
|
||||
tconfig.intval[NO_STAGEBG] = 1;
|
||||
}
|
||||
|
||||
end();
|
||||
|
@ -371,4 +374,4 @@ void draw_stage_title(int t, int dur, char *stage, char *subtitle) {
|
|||
return;
|
||||
|
||||
draw_text(AL_Center, VIEWPORT_W/2, VIEWPORT_H/2, stage, _fonts.mainmenu);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue