diff --git a/src/credits.c b/src/credits.c index 37af14cd..16a0b018 100644 --- a/src/credits.c +++ b/src/credits.c @@ -265,6 +265,5 @@ void credits_loop(void) { SDL_GL_SwapBuffers(); frame_rate(&global.lasttime); } - global.whitefade = 1.0; credits_free(); } diff --git a/src/global.h b/src/global.h index 25004d22..b3eedb4d 100644 --- a/src/global.h +++ b/src/global.h @@ -121,8 +121,6 @@ typedef struct { RandomState rand_game; RandomState rand_visual; - - float whitefade; // hack for credits --> main transition } Global; extern Global global; diff --git a/src/menu/charselect.c b/src/menu/charselect.c index 09547864..88b0fe7c 100644 --- a/src/menu/charselect.c +++ b/src/menu/charselect.c @@ -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); } diff --git a/src/menu/difficulty.c b/src/menu/difficulty.c index 1df45b56..ded67451 100644 --- a/src/menu/difficulty.c +++ b/src/menu/difficulty.c @@ -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); } diff --git a/src/menu/gameovermenu.c b/src/menu/gameovermenu.c index 8a7775fb..98e544a4 100644 --- a/src/menu/gameovermenu.c +++ b/src/menu/gameovermenu.c @@ -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; diff --git a/src/menu/ingamemenu.c b/src/menu/ingamemenu.c index d24107eb..78be0a5a 100644 --- a/src/menu/ingamemenu.c +++ b/src/menu/ingamemenu.c @@ -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); diff --git a/src/menu/mainmenu.c b/src/menu/mainmenu.c index 52cc3a77..95c37744 100644 --- a/src/menu/mainmenu.c +++ b/src/menu/mainmenu.c @@ -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); } diff --git a/src/menu/menu.c b/src/menu/menu.c index 4775e4ab..7b23b33c 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -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); +} \ No newline at end of file diff --git a/src/menu/menu.h b/src/menu/menu.h index 488ed9f1..c65c460c 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -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 diff --git a/src/menu/options.c b/src/menu/options.c index bf60c342..cdd0852c 100644 --- a/src/menu/options.c +++ b/src/menu/options.c @@ -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); } diff --git a/src/menu/replayview.c b/src/menu/replayview.c index f3415acf..c2260710 100755 --- a/src/menu/replayview.c +++ b/src/menu/replayview.c @@ -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); } diff --git a/src/menu/savereplay.c b/src/menu/savereplay.c index e385e4f2..89cb0298 100755 --- a/src/menu/savereplay.c +++ b/src/menu/savereplay.c @@ -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); } diff --git a/src/menu/stageselect.c b/src/menu/stageselect.c index fc3ca6f7..ec36b951 100755 --- a/src/menu/stageselect.c +++ b/src/menu/stageselect.c @@ -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); } diff --git a/src/menu/stageselect.h b/src/menu/stageselect.h index 39475135..5b9ad5bb 100755 --- a/src/menu/stageselect.h +++ b/src/menu/stageselect.h @@ -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 diff --git a/src/stage.c b/src/stage.c index d3269d63..fba51ee0 100644 --- a/src/stage.c +++ b/src/stage.c @@ -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) {