revisited menus

This commit is contained in:
laochailan 2012-08-12 16:54:48 +02:00
parent 6cac793550
commit d3bea2f52b
15 changed files with 222 additions and 289 deletions

View file

@ -265,6 +265,5 @@ void credits_loop(void) {
SDL_GL_SwapBuffers();
frame_rate(&global.lasttime);
}
global.whitefade = 1.0;
credits_free();
}

View file

@ -121,8 +121,6 @@ typedef struct {
RandomState rand_game;
RandomState rand_visual;
float whitefade; // hack for credits --> main transition
} Global;
extern Global global;

View file

@ -17,13 +17,6 @@ void set_shotmode(void *p) {
global.plr.shot = (ShotMode) p;
}
void create_char_menu(MenuData *m) {
create_menu(m);
add_menu_entry(m, "dialog/marisa|Kirisame Marisa|Black Magician", set_player, (void *)Marisa);
add_menu_entry(m, "dialog/youmu|Konpaku Youmu|Half Ghost Girl", set_player, (void *)Youmu);
}
void create_shottype_menu(MenuData *m) {
create_menu(m);
@ -31,9 +24,21 @@ void create_shottype_menu(MenuData *m) {
add_menu_entry(m, "Star Sign|Haunting Sign", set_shotmode, (void *) YoumuHoming);
}
void draw_char_menu(MenuData *menu, MenuData *mod) {
void create_char_menu(MenuData *m) {
create_menu(m);
m->context = malloc(sizeof(MenuData));
create_shottype_menu(m->context);
add_menu_entry(m, "dialog/marisa|Kirisame Marisa|Black Magician", set_player, (void *)Marisa);
add_menu_entry(m, "dialog/youmu|Konpaku Youmu|Half Ghost Girl", set_player, (void *)Youmu);
}
void draw_char_menu(MenuData *menu) {
MenuData *mod = ((MenuData *)menu->context);
draw_options_menu_bg(menu);
draw_text(AL_Right, 220*(1-menu->fade), 30, "Player Select", _fonts.mainmenu);
draw_text(AL_Right, 220*(1-menu_fade(menu)), 30, "Player Select", _fonts.mainmenu);
glPushMatrix();
glColor4f(0,0,0,0.7);
@ -115,13 +120,13 @@ void draw_char_menu(MenuData *menu, MenuData *mod) {
}
glColor3f(1,1,1);
fade_out(menu->fade);
}
void char_menu_input(MenuData *menu, MenuData *mod) {
void char_menu_input(MenuData *menu) {
SDL_Event event;
MenuData *mod = menu->context;
while(SDL_PollEvent(&event)) {
int sym = event.key.keysym.sym;
Uint8 *keys = SDL_GetKeyState(NULL);
@ -137,40 +142,24 @@ void char_menu_input(MenuData *menu, MenuData *mod) {
} else if(sym == tconfig.intval[KEY_UP] || sym == SDLK_UP) {
mod->cursor--;
} else if((sym == tconfig.intval[KEY_SHOT] || (sym == SDLK_RETURN && !keys[SDLK_LALT] && !keys[SDLK_RALT])) && menu->entries[menu->cursor].action) {
menu->quit = 1;
close_menu(menu);
menu->selected = menu->cursor;
mod->quit = 1;
close_menu(mod);
mod->selected = mod->cursor;
mod->fade = 1;
} else if(sym == SDLK_ESCAPE && menu->type == MT_Transient) {
menu->quit = 1;
} else if(sym == SDLK_ESCAPE) {
close_menu(menu);
}
menu->cursor = (menu->cursor % menu->ecount) + menu->ecount*(menu->cursor < 0);
mod->cursor = (mod->cursor % mod->ecount) + mod->ecount*(mod->cursor < 0);
} else if(event.type == SDL_QUIT) {
exit(1);
}
}
}
int char_menu_loop(MenuData *menu) {
set_ortho();
MenuData mod;
create_shottype_menu(&mod);
while(menu->quit != 2) {
menu_logic(menu);
menu_logic(&mod);
char_menu_input(menu, &mod);
draw_char_menu(menu, &mod);
SDL_GL_SwapBuffers();
frame_rate(&menu->lasttime);
}
destroy_menu(menu);
return menu->selected;
void free_char_menu(MenuData *menu) {
free(menu->context);
}
int char_menu_loop(MenuData *menu) {
return menu_loop(menu, char_menu_input, draw_char_menu, free_char_menu);
}

View file

@ -16,6 +16,8 @@ void set_difficulty(void *d) {
void create_difficulty_menu(MenuData *m) {
create_menu(m);
m->flags = MF_Transient | MF_Abortable;
add_menu_entry(m, "Easy\nfor fearful fairies", set_difficulty, (void *)D_Easy);
add_menu_entry(m, "Normal\nfor confident kappa", set_difficulty, (void *)D_Normal);
add_menu_entry(m, "Hard\nfor omnipotent oni", set_difficulty, (void *)D_Hard);
@ -25,7 +27,7 @@ void create_difficulty_menu(MenuData *m) {
void draw_difficulty_menu(MenuData *menu) {
draw_options_menu_bg(menu);
draw_text(AL_Right, 210*(1-menu->fade), 30, "Rank Select", _fonts.mainmenu);
draw_text(AL_Right, 210*(1-menu_fade(menu)), 30, "Rank Select", _fonts.mainmenu);
int i;
for(i = 0; i < menu->ecount; i++) {
@ -50,10 +52,8 @@ void draw_difficulty_menu(MenuData *menu) {
glColor3f(1,1,1);
glPopMatrix();
}
fade_out(menu->fade);
}
int difficulty_menu_loop(MenuData *menu) {
return menu_loop(menu, NULL, draw_difficulty_menu);
return menu_loop(menu, NULL, draw_difficulty_menu, NULL);
}

View file

@ -33,8 +33,6 @@ void give_up(void *arg) {
MenuData *create_gameover_menu(void) {
MenuData *m = malloc(sizeof(MenuData));
create_menu(m);
m->abortable = -1;
m->title = "Game over!";
char s[64];
int c = MAX_CONTINUES - global.plr.continues;

View file

@ -18,7 +18,9 @@ void return_to_title(void *arg) {
MenuData *create_ingame_menu(void) {
MenuData *m = malloc(sizeof(MenuData));
create_menu(m);
m->flags = MF_Abortable | MF_Transient;
add_menu_entry(m, "Return to Game", return_to_game, NULL);
add_menu_entry(m, "Return to Title", return_to_title, NULL);
@ -28,7 +30,7 @@ MenuData *create_ingame_menu(void) {
void ingame_menu_logic(MenuData **menu) {
menu_logic(*menu);
if((*menu)->quit == 2 && (*menu)->selected != 1) { // let the stage clean up when returning to title
if((*menu)->state == MS_FadeOut && (*menu)->selected != 1) { // let the stage clean up when returning to title
destroy_menu(*menu);
free(*menu);
*menu = NULL;
@ -36,11 +38,8 @@ void ingame_menu_logic(MenuData **menu) {
}
void draw_ingame_menu(MenuData *menu) {
float rad = IMENU_BLUR;
float fade = menu->fade;
float rad = (1.0-menu_fade(menu))*IMENU_BLUR;
if(menu->selected != 1) // hardly hardcoded. 1 -> "Return to Title"
rad = IMENU_BLUR * (1.0-fade);
if(!tconfig.intval[NO_SHADER]) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -54,25 +53,18 @@ void draw_ingame_menu(MenuData *menu) {
glPushMatrix();
glTranslatef(VIEWPORT_W/2, VIEWPORT_H/4, 0);
glColor4f(0.6,0.6,0.8,0.23*rad/IMENU_BLUR);
glPushMatrix();
glTranslatef(0, menu->drawdata[0], 0);
glScalef(menu->drawdata[1]/45.0,0.25,1);
glRotatef(menu->frames*2,0,0,1);
draw_texture(0,0,"part/smoke");
glPopMatrix();
draw_menu_selector(0, menu->drawdata[0], menu->drawdata[1]/45.0, 0.25, menu->frames);
// cirno's perfect math class #2: Euler Sign ~ Differential Fun
menu->drawdata[0] += (menu->cursor*35 - menu->drawdata[0])/7.0;
menu->drawdata[1] += (strlen(menu->entries[menu->cursor].name)*5 - menu->drawdata[1])/10.0;
if(menu->title) {
float s = 0.3 + 0.2 * sin(menu->frames/10.0);
glColor4f(1-s/2, 1-s/2, 1-s, 1.0 - menu->fade);
draw_text(AL_Center, 0, -2 * 35, menu->title, _fonts.standard);
}
// if(menu->title) {
// float s = 0.3 + 0.2 * sin(menu->frames/10.0);
// glColor4f(1-s/2, 1-s/2, 1-s, 1-menu_fade(menu));
// draw_text(AL_Center, 0, -2 * 35, menu->title, _fonts.standard);
// }
int i;
for(i = 0; i < menu->ecount; i++) {
@ -83,7 +75,7 @@ void draw_ingame_menu(MenuData *menu) {
s = 0.3 + 0.2*sin(menu->frames/7.0);
}
glColor4f(t-s,t-s,t-s/2, 1.0 - menu->fade);
glColor4f(t-s,t-s,t-s/2, 1-menu_fade(menu));
} else
glColor4f(0.5, 0.5, 0.5, 0.5);

View file

@ -21,11 +21,6 @@
#include "credits.h"
#include "paths/native.h"
void quit_menu(void *arg) {
MenuData *m = arg;
m->quit = 2;
}
void start_story(void *arg) {
MenuData m;
@ -97,9 +92,7 @@ void enter_replayview(void *arg) {
void create_main_menu(MenuData *m) {
create_menu(m);
m->type = MT_Persistent;
add_menu_entry(m, "Start Story", start_story, NULL);
add_menu_entry(m, "Start Extra", NULL, NULL);
#ifdef DEBUG
@ -107,7 +100,7 @@ void create_main_menu(MenuData *m) {
#endif
add_menu_entry(m, "Replays", enter_replayview, NULL);
add_menu_entry(m, "Options", enter_options, NULL);
add_menu_entry(m, "Quit", quit_menu, m);
add_menu_entry(m, "Quit", (MenuAction)kill_menu, m);
}
@ -159,15 +152,8 @@ void draw_main_menu(MenuData *menu) {
}
glPopMatrix();
fade_out(menu->fade);
if(global.whitefade > 0) {
colorfill(1, 1, 1, global.whitefade);
global.whitefade -= 1 / 300.0;
} else global.whitefade = 0;
}
void main_menu_loop(MenuData *menu) {
menu_loop(menu, NULL, draw_main_menu);
menu_loop(menu, NULL, draw_main_menu, NULL);
}

View file

@ -26,16 +26,11 @@ void add_menu_separator(MenuData *menu) {
void destroy_menu(MenuData *menu) {
int i;
if(menu->ondestroy)
menu->ondestroy(menu);
for(i = 0; i < menu->ecount; i++) {
MenuEntry *e = &(menu->entries[i]);
free(e->name);
if(e->freearg)
e->freearg(e->arg);
}
free(menu->entries);
@ -44,33 +39,48 @@ void destroy_menu(MenuData *menu) {
void create_menu(MenuData *menu) {
memset(menu, 0, sizeof(MenuData));
menu->fade = 1;
menu->selected = -1;
menu->quitdelay = FADE_TIME;
}
void close_menu(MenuData *menu) {
menu->quitframe = menu->frames;
}
void kill_menu(MenuData *menu) {
menu->state = MS_Dead;
}
float menu_fade(MenuData *menu) {
if(menu->frames < menu->quitdelay)
return 1.0 - menu->frames/(float)menu->quitdelay;
if(menu->quitframe && menu->frames >= menu->quitframe)
return (menu->frames - menu->quitframe)/(float)menu->quitdelay;
return 0.0;
}
static void key_action(MenuData *menu, int sym) {
Uint8 *keys = SDL_GetKeyState(NULL);
int look_i_can_hardcode_annoying_menu_hacks_too = menu->title && !strcmp(menu->title, "Save replay?");
if(sym == tconfig.intval[KEY_DOWN] || sym == SDLK_DOWN || look_i_can_hardcode_annoying_menu_hacks_too &&
(sym == tconfig.intval[KEY_RIGHT] || sym == SDLK_RIGHT)) {
if(sym == tconfig.intval[KEY_DOWN] || sym == SDLK_DOWN) {
do {
if(++menu->cursor >= menu->ecount)
menu->cursor = 0;
} while(menu->entries[menu->cursor].action == NULL);
} else if(sym == tconfig.intval[KEY_UP] || sym == SDLK_UP || look_i_can_hardcode_annoying_menu_hacks_too &&
(sym == tconfig.intval[KEY_LEFT] || sym == SDLK_LEFT)) {
} else if(sym == tconfig.intval[KEY_UP] || sym == SDLK_UP) {
do {
if(--menu->cursor < 0)
menu->cursor = menu->ecount - 1;
} while(menu->entries[menu->cursor].action == NULL);
} else if((sym == tconfig.intval[KEY_SHOT] || (sym == SDLK_RETURN && !keys[SDLK_LALT] && !keys[SDLK_RALT])) && menu->entries[menu->cursor].action) {
menu->quit = 1;
menu->selected = menu->cursor;
} else if(sym == SDLK_ESCAPE && (menu->type == MT_Transient || menu->abortable) && menu->abortable >= 0) {
menu->quit = 1;
menu->abort = 1;
close_menu(menu);
} else if(sym == SDLK_ESCAPE && menu->flags & MF_Abortable) {
close_menu(menu);
menu->selected = -1;
}
}
@ -87,46 +97,56 @@ void menu_input(MenuData *menu) {
}
void menu_logic(MenuData *menu) {
int hax = 0;
menu->frames++;
if(menu->quit == 1 && menu->fade < 1.0)
menu->fade += 1.0/FADE_TIME;
if(menu->quit == 0 && menu->fade > 0)
menu->fade -= 1.0/FADE_TIME;
if(menu->fade < 0)
menu->fade = 0;
if(menu->fade > 1)
menu->fade = 1;
if(menu->quit == 1 && (menu->fade >= 1.0 || (hax = (!menu->abort && menu->instantselect)))) {
if(hax)
menu->fade = 0;
global.whitefade = 0;
menu->quit = menu->type == MT_Transient ? 2 : 0;
if(menu->quitframe && menu->frames >= menu->quitframe)
menu->state = MS_FadeOut;
if(menu->abort && menu->abortaction)
menu->abortaction(menu->abortarg);
else if(menu->selected != -1 && menu->entries[menu->selected].action != NULL)
menu->entries[menu->selected].action(menu->entries[menu->selected].arg);
if(menu->quitframe && menu->frames >= menu->quitframe + menu->quitdelay) {
menu->state = MS_Dead;
if(!(menu->flags & MF_Transient) && menu->selected != -1 && menu->entries[menu->selected].action != NULL) {
menu->state = MS_Normal;
menu->quitframe = 0;
menu->entries[menu->selected].action(menu->entries[menu->selected].arg);
}
}
}
int menu_loop(MenuData *menu, void (*input)(MenuData*), void (*draw)(MenuData*)) {
int menu_loop(MenuData *menu, void (*input)(MenuData*), void (*draw)(MenuData*), void (*end)(MenuData*)) {
set_ortho();
while(menu->quit != 2) {
while(menu->state != MS_Dead) {
menu_logic(menu);
if(input)
input(menu);
else
menu_input(menu);
if(menu->state != MS_FadeOut) {
if(input)
input(menu);
else
menu_input(menu);
}
draw(menu);
SDL_GL_SwapBuffers();
frame_rate(&menu->lasttime);
}
destroy_menu(menu);
if(end)
end(menu);
destroy_menu(menu);
return menu->selected;
}
void draw_menu_selector(float x, float y, float w, float h, float t) {
Texture *bg = get_tex("part/smoke");
glPushMatrix();
glTranslatef(x, y, 0);
glScalef(w, h, 1);
glRotatef(t*2,0,0,1);
glColor4f(0,0,0,0.5);
draw_texture_p(0,0,bg);
glPopMatrix();
}
void draw_menu_title(MenuData *m, char *title) {
draw_text(AL_Right, (stringwidth(title, _fonts.mainmenu) + 10) * (1.0-menu_fade(m)), 30, title, _fonts.mainmenu);
}

View file

@ -9,26 +9,35 @@
#define MENU_H
#define IMENU_BLUR 0.05
#define FADE_TIME 15
#define TS_KR_DELAY SDL_DEFAULT_REPEAT_DELAY
#define TS_KR_INTERVAL (SDL_DEFAULT_REPEAT_INTERVAL*2)
enum {
FADE_TIME = 15
};
typedef struct {
char *name;
void (*action)(void *arg);
void *arg;
float drawdata;
void (*freearg)(void *arg);
void (*draw)(void *e, int i, int cnt);
} MenuEntry;
typedef enum MenuType { // whether to close on selection or not.
MT_Transient, // ingame menus are for the transient people.
MT_Persistent
typedef enum MenuFlag {
MF_Transient = 1, // whether to close on selection or not.
MF_Abortable = 2
} MenuType;
enum MenuState{
MS_Normal = 0,
MS_FadeOut,
MS_Dead
};
typedef void (*MenuAction)(void*);
typedef struct MenuData{
MenuType type;
int flags;
int cursor;
int selected;
@ -39,22 +48,16 @@ typedef struct MenuData{
int frames;
int lasttime;
int quit;
float fade;
int abort;
int abortable;
void (*abortaction)(void *arg);
void *abortarg;
int instantselect;
int state;
int quitframe;
int quitdelay;
float drawdata[4];
float drawdata[4];
char *title;
void *context;
void (*ondestroy)(void*);
} MenuData;
void add_menu_entry(MenuData *menu, char *name, void (*action)(void *), void *arg);
void add_menu_entry(MenuData *menu, char *name, MenuAction action, void *arg);
void add_menu_separator(MenuData *menu);
void create_menu(MenuData *menu);
void destroy_menu(MenuData *menu);
@ -62,7 +65,14 @@ void destroy_menu(MenuData *menu);
void menu_logic(MenuData *menu);
void menu_input(MenuData *menu);
int menu_loop(MenuData *menu, void (*input)(MenuData*), void (*draw)(MenuData*));
void close_menu(MenuData *menu); // softly close menu (should be used in most cases)
void kill_menu(MenuData *menu); // quit action for persistent menus
int menu_loop(MenuData *menu, void (*input)(MenuData*), void (*draw)(MenuData*), void (*end)(MenuData*));
float menu_fade(MenuData *menu);
void draw_menu_selector(float x, float y, float w, float h, float t);
void draw_menu_title(MenuData *m, char *title);
#endif

View file

@ -321,9 +321,8 @@ int bind_saverpy_set(void *b, int v)
// --- Creating, destroying, filling the menu --- //
void destroy_options_menu(void *menu)
void destroy_options_menu(MenuData *m)
{
MenuData *m = (MenuData*)menu;
OptionBinding *binds = (OptionBinding*)m->context;
int i;
@ -343,22 +342,16 @@ void destroy_options_menu(void *menu)
}
config_save(CONFIG_FILE);
free_bindings(menu);
free_bindings(m);
}
void do_nothing(void *arg) { }
void backtomain(void *arg)
{
MenuData *m = arg;
m->quit = 2;
}
void create_options_menu(MenuData *m) {
OptionBinding *b;
create_menu(m);
m->type = MT_Transient;
m->ondestroy = destroy_options_menu;
m->flags = MF_Abortable;
m->context = NULL;
#define bind_onoff(b) bind_addvalue(b, "on"); bind_addvalue(b, "off")
@ -448,7 +441,7 @@ void create_options_menu(MenuData *m) {
add_menu_separator(m);
allocate_binding(m);
add_menu_entry(m, "Return to the main menu", backtomain, m);
add_menu_entry(m, "Return to the main menu", (MenuAction)close_menu, m);
allocate_binding(m);
}
@ -464,20 +457,11 @@ void draw_options_menu_bg(MenuData* menu) {
void draw_options_menu(MenuData *menu) {
draw_options_menu_bg(menu);
draw_text(AL_Right, 140*(1-menu->fade), 30, "Options", _fonts.mainmenu);
draw_text(AL_Right, 140*(1-menu_fade(menu)), 30, "Options", _fonts.mainmenu);
glPushMatrix();
glTranslatef(100, 100, 0);
/*
glPushMatrix();
glTranslatef(SCREEN_W/2 - 100, menu->drawdata[2], 0);
glScalef(SCREEN_W - 200, 20, 1);
glColor4f(0,0,0,0.5);
draw_quad();
glPopMatrix();
*/
Texture *bg = get_tex("part/smoke");
glPushMatrix();
glTranslatef(menu->drawdata[0], menu->drawdata[2], 0);
@ -590,8 +574,6 @@ void draw_options_menu(MenuData *menu) {
glPopMatrix();
fade_out(menu->fade);
}
// --- Input processing --- //
@ -683,7 +665,7 @@ static void options_key_action(MenuData *menu, int sym) {
break;
default:
break;
} else menu->quit = 1;
} else close_menu(menu);
} else if(sym == tconfig.intval[KEY_LEFT] || sym == SDLK_LEFT) {
menu->selected = menu->cursor;
OptionBinding *binds = (OptionBinding*)menu->context;
@ -699,7 +681,7 @@ static void options_key_action(MenuData *menu, int sym) {
if(bind->enabled && (bind->type == BT_IntValue || bind->type == BT_Resolution))
bind_setnext(bind);
} else if(sym == SDLK_ESCAPE) {
menu->quit = 1;
close_menu(menu);
}
menu->cursor = (menu->cursor % menu->ecount) + menu->ecount*(menu->cursor < 0);
@ -725,6 +707,6 @@ void options_menu_input(MenuData *menu) {
}
int options_menu_loop(MenuData *menu) {
return menu_loop(menu, options_menu_input, draw_options_menu);
return menu_loop(menu, options_menu_input, draw_options_menu, destroy_options_menu);
}

View file

@ -54,8 +54,6 @@ void start_replay(void *arg) {
global.game_over = 0;
global.replaymode = REPLAY_RECORD;
replay_destroy(&global.replay);
replayview->instantselect = False;
}
MenuData* replayview_stageselect(Replay *rpy) {
@ -102,7 +100,7 @@ static void shorten(char *s, int width) {
}
static void replayview_draw_stagemenu(MenuData *m) {
float alpha = 1 - m->fade;
float alpha = min(1, m->frames/40.0);
int i;
float height = (1+m->ecount) * 20;
@ -138,31 +136,16 @@ static void replayview_draw_stagemenu(MenuData *m) {
glPopMatrix();
}
static void replayview_draw(MenuData *m) {
draw_stage_menu(m);
if(m->context) {
MenuData *sm = m->context;
menu_logic(sm);
if(sm->quit == 2) {
destroy_menu(sm);
m->context = NULL;
} else {
fade_out(0.3 * (1 - sm->fade));
replayview_draw_stagemenu(sm);
if(!sm->abort && sm->quit == 1)
m->fade = sm->fade;
}
}
}
static void replayview_drawitem(void *n, int item, int cnt) {
MenuEntry *e = (MenuEntry*)n;
Replay *rpy = (Replay*)e->arg;
float sizes[] = {1.2, 1.45, 0.8, 0.8, 0.65};
int columns = 5, i, j;
if(!rpy)
return;
for(i = 0; i < columns; ++i) {
char tmp[128];
int csize = sizes[i] * (SCREEN_W - 210)/columns;
@ -216,6 +199,29 @@ static void replayview_drawitem(void *n, int item, int cnt) {
}
}
static void replayview_draw(MenuData *m) {
draw_options_menu_bg(m);
draw_menu_title(m, "Replays");
m->drawdata[0] = SCREEN_W/2 - 100;
m->drawdata[1] = (SCREEN_W - 200)*0.85;
m->drawdata[2] += (20*m->cursor - m->drawdata[2])/10.0;
draw_menu_list(m, 100, 100, replayview_drawitem);
if(m->context) {
MenuData *sm = m->context;
menu_logic(sm);
if(sm->state == MS_Dead) {
destroy_menu(sm);
m->context = NULL;
} else {
replayview_draw_stagemenu(sm);
}
}
}
int replayview_cmp(const void *a, const void *b) {
return ((Replay*)(((MenuEntry*)b)->arg))->stages[0].seed - ((Replay*)(((MenuEntry*)a)->arg))->stages[0].seed;
}
@ -244,8 +250,6 @@ int fill_replayview_menu(MenuData *m) {
}
add_menu_entry(m, " ", replayview_run, rpy);
m->entries[m->ecount-1].freearg = replayview_freearg;
m->entries[m->ecount-1].draw = replayview_drawitem;
++rpys;
}
@ -257,7 +261,7 @@ int fill_replayview_menu(MenuData *m) {
void replayview_abort(void *a) {
MenuData *m = a;
m->quit = 2;
close_menu(m);
if(m->context) { // will unlikely get here
MenuData *sm = m->context;
@ -268,13 +272,10 @@ void replayview_abort(void *a) {
void create_replayview_menu(MenuData *m) {
create_menu(m);
m->type = MT_Persistent;
m->abortable = True;
m->abortaction = replayview_abort;
m->abortarg = m;
m->title = "Replays";
replayview = m;
m->flags = MF_Abortable;
int r = fill_replayview_menu(m);
if(!r) {
@ -295,11 +296,17 @@ void replayview_menu_input(MenuData *m) {
else
menu_input(m);
if(m->selected >= 0)
m->instantselect = m->selected != m->ecount-1 && (((Replay*)m->entries[m->selected].arg)->stgcount > 1);
}
void free_replayview(MenuData *m) {
int i;
for(i = 0; i < m->ecount; i++)
if(m->entries[i].action == replayview_run)
replayview_freearg(m->entries[i].arg);
}
int replayview_menu_loop(MenuData *m) {
return menu_loop(m, replayview_menu_input, replayview_draw);
return menu_loop(m, replayview_menu_input, replayview_draw, free_replayview);
}

View file

@ -35,43 +35,32 @@ void save_rpy(void *a) {
snprintf(name, 128, "taisei_%s_stg%d_%s_%s", strtime, rpy->stages[0].stage, prepr, drepr);
replay_save(rpy, name);
if(a) ((MenuData*)a)->quit = 2;
}
void dont_save_rpy(void *a) {
((MenuData*)a)->quit = 2;
if(a) close_menu(a);
}
void create_saverpy_menu(MenuData *m) {
create_menu(m);
m->type = MT_Persistent;
m->title = "Save replay?";
add_menu_entry(m, "Yes", save_rpy, m);
add_menu_entry(m, "No", dont_save_rpy, m);
add_menu_entry(m, "No", (MenuAction) close_menu, m);
}
void draw_saverpy_menu(MenuData *m) {
draw_options_menu_bg(m);
int i;
Texture *bg = get_tex("part/smoke");
glPushMatrix();
glTranslatef(SCREEN_W/2 + 100 * m->drawdata[0] - 50, SCREEN_H/2, 0); // 135
glScalef(1, 0.5, 1);
glRotatef(m->frames*2,0,0,1);
glColor4f(0,0,0,0.5);
draw_texture_p(0,0,bg);
glPopMatrix();
draw_options_menu_bg(m);
draw_menu_selector(SCREEN_W/2 + 100 * m->drawdata[0] - 50, SCREEN_H/2, 1, 0.5, m->frames);
glPushMatrix();
glColor4f(1, 1, 1, 1);
glTranslatef(SCREEN_W/2, SCREEN_H/2 - 100, 0);
draw_text(AL_Center, 0, 0, m->title, _fonts.mainmenu);
draw_text(AL_Center, 0, 0, "Save Replay?", _fonts.mainmenu);
glTranslatef(0, 100, 0);
m->drawdata[0] += (m->cursor - m->drawdata[0])/10.0;
int i; for(i = 0; i < m->ecount; i++) {
for(i = 0; i < m->ecount; i++) {
MenuEntry *e = &(m->entries[i]);
e->drawdata += 0.2 * (10*(i == m->cursor) - e->drawdata);
@ -89,10 +78,8 @@ void draw_saverpy_menu(MenuData *m) {
}
glPopMatrix();
fade_out(m->fade);
}
int saverpy_menu_loop(MenuData *m) {
return menu_loop(m, NULL, draw_saverpy_menu);
return menu_loop(m, NULL, draw_saverpy_menu, NULL);
}

View file

@ -13,19 +13,12 @@
#include "stageselect.h"
#include "mainmenu.h"
void backtomain(void*);
void create_stage_menu(MenuData *m) {
char title[STGMENU_MAX_TITLE_LENGTH];
int i;
create_menu(m);
m->type = MT_Persistent;
m->abortable = True;
m->abortaction = backtomain;
m->abortarg = m;
// TODO: I think ALL menus should use the title field, but I don't want to screw with it right now.
m->title = "Stage Select";
m->flags = MF_Abortable;
for(i = 0; stages[i].loop; ++i) if(!stages[i].hidden) {
snprintf(title, STGMENU_MAX_TITLE_LENGTH, "%s", stages[i].title);
@ -33,38 +26,14 @@ void create_stage_menu(MenuData *m) {
}
add_menu_separator(m);
add_menu_entry(m, "Back", backtomain, m);
add_menu_entry(m, "Back", (MenuAction)close_menu, m);
}
void draw_stage_menu(MenuData *m) {
draw_options_menu_bg(m);
draw_text(AL_Right, (stringwidth(m->title, _fonts.mainmenu) + 10) * (1-m->fade), 30, m->title, _fonts.mainmenu);
void draw_menu_list(MenuData *m, float x, float y, void (*draw)(void *, int, int)) {
glPushMatrix();
glTranslatef(100, 100 + (((m->ecount * 20 + 290) > SCREEN_W)? min(0, SCREEN_H * 0.7 - 100 - m->drawdata[2]) : 0), 0);
glTranslatef(x, y + (((m->ecount * 20 + 290) > SCREEN_W)? min(0, SCREEN_H * 0.7 - 100 - m->drawdata[2]) : 0), 0);
/*
glPushMatrix();
glTranslatef(SCREEN_W/2 - 100, m->drawdata[2], 0);
glScalef(SCREEN_W - 200, 20, 1);
glColor4f(0,0,0,0.5);
draw_quad();
glPopMatrix();
*/
Texture *bg = get_tex("part/smoke");
glPushMatrix();
glTranslatef(m->drawdata[0], m->drawdata[2], 0);
glScalef(m->drawdata[1]/100.0, 0.2, 1);
glRotatef(m->frames*2,0,0,1);
glColor4f(0,0,0,0.5);
draw_texture_p(0,0,bg);
glPopMatrix();
MenuEntry *s = &(m->entries[m->cursor]);
m->drawdata[0] += ((s->draw? SCREEN_W/2 - 100 : (stringwidth(s->name, _fonts.mainmenu)/2 - s->drawdata*1.5)) - m->drawdata[0])/10.0;
m->drawdata[1] += ((s->draw? (SCREEN_W - 200)*0.85 : stringwidth(s->name, _fonts.mainmenu)) - m->drawdata[1])/10.0;
m->drawdata[2] += (20*m->cursor - m->drawdata[2])/10.0;
draw_menu_selector(m->drawdata[0], m->drawdata[2], m->drawdata[1]/100.0, 0.2, m->frames);
int i;
for(i = 0; i < m->ecount; i++) {
@ -76,22 +45,32 @@ void draw_stage_menu(MenuData *m) {
if(e->action == NULL)
glColor4f(0.5, 0.5, 0.5, 0.5);
else {
//glColor4f(0.7 + 0.3 * (1-a), 1, 1, 0.7 + 0.3 * a);
float ia = 1-a;
glColor4f(0.9 + ia * 0.1, 0.6 + ia * 0.4, 0.2 + ia * 0.8, 0.7 + 0.3 * a);
}
if(e->draw)
e->draw(e, i, m->ecount);
if(draw && i < m->ecount-1)
draw(e, i, m->ecount);
else if(e->name)
draw_text(AL_Left, 20 - e->drawdata, 20*i, e->name, _fonts.standard);
draw_text(AL_Left, 20 - e->drawdata, 20*i, e->name, _fonts.standard);
}
glPopMatrix();
}
fade_out(m->fade);
void draw_stage_menu(MenuData *m) {
MenuEntry *s = &(m->entries[m->cursor]);
draw_options_menu_bg(m);
draw_menu_title(m, "Stage Select");
m->drawdata[0] += (stringwidth(s->name, _fonts.mainmenu)/2.0 - s->drawdata*1.5 - m->drawdata[0])/10.0;
m->drawdata[1] += (stringwidth(s->name, _fonts.mainmenu) - m->drawdata[1])/10.0;
m->drawdata[2] += (20*m->cursor - m->drawdata[2])/10.0;
draw_menu_list(m, 100, 100, NULL);
}
int stage_menu_loop(MenuData *m) {
return menu_loop(m, NULL, draw_stage_menu);
return menu_loop(m, NULL, draw_stage_menu, NULL);
}

View file

@ -12,7 +12,7 @@
#define STGMENU_MAX_TITLE_LENGTH 128
void create_stage_menu(MenuData *m);
void draw_stage_menu(MenuData *m);
void draw_menu_list(MenuData *m, float x, float y, void (*draw)(void *, int, int));
int stage_menu_loop(MenuData *m);
#endif

View file

@ -55,7 +55,7 @@ void stage_ingamemenu(void) {
if(!global.menu)
global.menu = create_ingame_menu();
else
global.menu->quit = 1;
close_menu(global.menu);
}
void replay_input(void) {
@ -305,12 +305,6 @@ void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int
glPopMatrix();
}
if(global.frames < 4*FADE_TIME)
fade_out(1.0 - global.frames/(float)(4*FADE_TIME));
if(global.timer > time - 4*FADE_TIME) {
fade_out((global.timer - time + 4*FADE_TIME)/(float)(4*FADE_TIME));
}
if(global.menu) {
glPushMatrix();
glTranslatef(VIEWPORT_X,VIEWPORT_Y,0);
@ -319,14 +313,6 @@ void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int
}
draw_hud();
// I don't remember how did it work before the massive transition hacking - and neither do I want to.
// So I'll just leave these new hacks here. At least they are not AS horrible as the old ones.
// They are still horrible, though. I hate them. HATE HATE HATE HATE HATE HATE HATE HATE HATE.
if(global.menu && !global.menu->abort && global.menu->quit == 1 && global.menu->selected == 1)
fade_out(global.menu->fade);
else if(global.game_over == GAMEOVER_ABORT || global.game_over == GAMEOVER_DEFEAT)
fade_out(1);
}
int apply_shaderrules(ShaderRule *shaderrules, int fbonum) {