From 1ba89400d6c3a121ba09a6a631435cda4d315dfa Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Wed, 26 Sep 2012 20:00:11 +0200 Subject: [PATCH] revamp pause functionality --- src/level.c | 23 +++++++++++++++-------- src/level.h | 2 ++ src/levels/actions.c | 5 ++++- src/main.c | 26 +++++++++++++++++++++++++- src/main.h | 7 +++++++ src/menu.c | 2 ++ src/moonwalk.c | 2 +- src/pause.c | 23 +++++++++-------------- 8 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/level.c b/src/level.c index e49deda..b611e97 100644 --- a/src/level.c +++ b/src/level.c @@ -227,11 +227,17 @@ void Level_Logic(struct Game *game) { } } +void Level_Resume(struct Game *game) { + al_set_sample_instance_position(game->level.music, game->level.music_pos); + al_set_sample_instance_playing(game->level.music, true); +} + +void Level_Pause(struct Game *game) { + game->level.music_pos = al_get_sample_instance_position(game->level.music); + al_set_sample_instance_playing(game->level.music, false); +} + void Level_Draw(struct Game *game) { - if (!al_get_sample_instance_playing(game->level.music) && (game->loadstate==GAMESTATE_LEVEL)) { - al_set_sample_instance_playing(game->level.music, true); - al_set_sample_instance_position(game->level.music, game->level.music_pos); - } if (game->level.current_level!=1) Moonwalk_Draw(game); else { @@ -396,10 +402,7 @@ void Level_Load(struct Game *game) { } int Level_Keydown(struct Game *game, ALLEGRO_EVENT *ev) { - if (ev->keyboard.keycode==ALLEGRO_KEY_ESCAPE) { - game->level.music_pos = al_get_sample_instance_position(game->level.music); - al_set_sample_instance_playing(game->level.music, false); - } else if ((game->debug) && (ev->keyboard.keycode==ALLEGRO_KEY_F2)) { + if ((game->debug) && (ev->keyboard.keycode==ALLEGRO_KEY_F2)) { game->level.hp -= 0.1; if (game->level.hp <= 0) game->level.hp=0.001; } else if ((game->debug) && (ev->keyboard.keycode==ALLEGRO_KEY_F3)) { @@ -449,6 +452,7 @@ void Level_Preload(struct Game *game, void (*progress)(struct Game*, float)) { game->level.current_level = game->level.input.current_level; game->level.derpy_sheets = NULL; game->level.derpy = NULL; + game->level.unloading = false; Pause_Preload(game); RegisterDerpySpritesheet(game, "walk"); RegisterDerpySpritesheet(game, "fly"); @@ -470,7 +474,10 @@ void Level_Preload(struct Game *game, void (*progress)(struct Game*, float)) { } void Level_Unload(struct Game *game) { + if (game->level.unloading) return; + game->level.unloading = true; Pause_Unload_Real(game); + FadeGameState(game, false); if (game->level.current_level!=1) Moonwalk_Unload(game); else { TM_Destroy(); diff --git a/src/level.h b/src/level.h index 76a5110..e6efd5b 100644 --- a/src/level.h +++ b/src/level.h @@ -22,6 +22,8 @@ void SelectDerpySpritesheet(struct Game *game, char* name); void Level_Passed(struct Game *game); +void Level_Pause(struct Game *game); +void Level_Resume(struct Game *game); void Level_Draw(struct Game *game); void Level_Logic(struct Game *game); void Level_Preload(struct Game *game, void (*progress)(struct Game*, float)); diff --git a/src/levels/actions.c b/src/levels/actions.c index b7b90c8..8c57a6c 100644 --- a/src/levels/actions.c +++ b/src/levels/actions.c @@ -347,7 +347,10 @@ bool Welcome(struct Game *game, struct TM_Action *action, enum TM_ActionState st bool PassLevel(struct Game *game, struct TM_Action *action, enum TM_ActionState state) { if (state == TM_ACTIONSTATE_DESTROY) { Level_Passed(game); - TM_AddBackgroundAction(&FadeOut, NULL, 0, "fadeout"); + Level_Unload(game); + game->gamestate = GAMESTATE_LOADING; + game->loadstate = GAMESTATE_MAP; + //TM_AddBackgroundAction(&FadeOut, NULL, 0, "fadeout"); } return true; } diff --git a/src/main.c b/src/main.c index 305c9de..4a6562f 100644 --- a/src/main.c +++ b/src/main.c @@ -59,9 +59,15 @@ /*! \brief Macro for drawing active gamestate. */ #define DRAW_STATE(state, name) case state:\ name ## _Draw(game); break; -/*! \brief Macro for invocing logic function of active gamestate. */ +/*! \brief Macro for invoking logic function of active gamestate. */ #define LOGIC_STATE(state, name) case state:\ name ## _Logic(game); break; +/*! \brief Macro for invoking pause function of active gamestate. */ +#define PAUSE_STATE(state, name) case state:\ + PrintConsole(game, "Pause %s...", #state); name ## _Pause(game); break; +/*! \brief Macro for invoking resume function of active gamestate. */ +#define RESUME_STATE(state, name) case state:\ + PrintConsole(game, "Resume %s...", #state); name ## _Resume(game); break; double old_time = 0, fps; int frames_done = 0; @@ -242,6 +248,24 @@ void LogicGameState(struct Game *game) { } } +void PauseGameState(struct Game *game) { + switch (game->loadstate) { + PAUSE_STATE(GAMESTATE_LEVEL, Level) + default: + // not every gamestate needs to have pause function + break; + } +} + +void ResumeGameState(struct Game *game) { + switch (game->loadstate) { + RESUME_STATE(GAMESTATE_LEVEL, Level) + default: + // not every gamestate needs to have resume function + break; + } +} + void FadeGameState(struct Game *game, bool in) { ALLEGRO_BITMAP* bitmap = al_create_bitmap(game->viewportWidth, game->viewportHeight); al_set_target_bitmap(bitmap); diff --git a/src/main.h b/src/main.h index 1df8903..b34e35b 100644 --- a/src/main.h +++ b/src/main.h @@ -119,6 +119,7 @@ struct Level { float hp; /*!< Player health points (0-1). */ bool handle_input; /*!< When false, player looses control over Derpy. */ bool failed; /*!< Indicates if player failed level. */ + bool unloading; /*!< Indicated if level is already being unloaded. */ float meter_alpha; /*!< Alpha level of HP meter. */ int sheet_rows; /*!< Number of rows in current spritesheet. */ int sheet_cols; /*!< Number of cols in current spritesheet. */ @@ -315,6 +316,12 @@ void UnloadGameState(struct Game *game); /*! \brief Loads gamestate set in game->loadstate. */ void LoadGameState(struct Game *game); +/*! \brief Pauses gamestate set in game->loadstate. */ +void PauseGameState(struct Game *game); + +/*! \brief Resumes gamestate set in game->loadstate. */ +void ResumeGameState(struct Game *game); + /*! \brief Finds path for data file. */ char* GetDataFilePath(char* filename); diff --git a/src/menu.c b/src/menu.c index f01c9b8..243ef10 100644 --- a/src/menu.c +++ b/src/menu.c @@ -429,6 +429,7 @@ int Menu_Keydown(struct Game *game, ALLEGRO_EVENT *ev) { PrintConsole(game,"Game resumed."); al_destroy_bitmap(game->pause.bitmap); game->pause.bitmap = NULL; + ResumeGameState(game); game->gamestate = game->loadstate; break; case 1: @@ -499,6 +500,7 @@ int Menu_Keydown(struct Game *game, ALLEGRO_EVENT *ev) { PrintConsole(game,"Game resumed."); al_destroy_bitmap(game->pause.bitmap); game->pause.bitmap = NULL; + ResumeGameState(game); game->gamestate = game->loadstate; break; default: diff --git a/src/moonwalk.c b/src/moonwalk.c index c3ee12d..6117ed5 100644 --- a/src/moonwalk.c +++ b/src/moonwalk.c @@ -99,5 +99,5 @@ void Moonwalk_UnloadBitmaps(struct Game *game) { } void Moonwalk_Unload(struct Game *game) { - FadeGameState(game, false); + //FadeGameState(game, false); } diff --git a/src/pause.c b/src/pause.c index d450173..00c3010 100644 --- a/src/pause.c +++ b/src/pause.c @@ -71,32 +71,27 @@ void Pause_Preload(struct Game* game) { } void Pause_Load(struct Game* game) { - game->gamestate=game->loadstate; - game->loadstate=GAMESTATE_PAUSE; - DrawGameState(game); - game->loadstate=game->gamestate; - game->gamestate=GAMESTATE_PAUSE; + PauseGameState(game); ALLEGRO_BITMAP *fade = al_create_bitmap(game->viewportWidth, game->viewportHeight); al_set_target_bitmap(fade); al_clear_to_color(al_map_rgb(0,0,0)); al_set_target_bitmap(al_get_backbuffer(game->display)); - al_draw_tinted_bitmap(fade,al_map_rgba_f(1,1,1,0.75),0,0,0); - game->pause.bitmap = al_create_bitmap(game->viewportWidth, game->viewportHeight); - al_set_target_bitmap(game->pause.bitmap); - al_draw_bitmap(al_get_backbuffer(game->display), -1*(al_get_display_width(game->display)-game->viewportWidth)/2, -1*(al_get_display_height(game->display)-game->viewportHeight)/2, 0); - al_draw_bitmap(game->pause.derpy, 0.47*game->viewportWidth, game->viewportHeight*0.396, 0); - al_set_target_bitmap(al_get_backbuffer(game->display)); - al_destroy_bitmap(fade); + game->pause.bitmap = fade; ChangeMenuState(game,MENUSTATE_PAUSE); PrintConsole(game,"Game paused."); al_play_sample_instance(game->menu.click); } void Pause_Draw(struct Game* game) { - al_draw_bitmap(game->pause.bitmap, 0, 0, 0); + game->gamestate=game->loadstate; + game->loadstate=GAMESTATE_PAUSE; + DrawGameState(game); + game->loadstate=game->gamestate; + game->gamestate=GAMESTATE_PAUSE; + al_draw_tinted_bitmap(game->pause.bitmap,al_map_rgba_f(1,1,1,0.75),0,0,0); + al_draw_bitmap(game->pause.derpy, 0.47*game->viewportWidth, game->viewportHeight*0.396, 0); al_draw_text_with_shadow(game->menu.font_title, al_map_rgb(255,255,255), game->viewportWidth*0.5, game->viewportHeight*0.1, ALLEGRO_ALIGN_CENTRE, "Super Derpy"); al_draw_text_with_shadow(game->menu.font_subtitle, al_map_rgb(255,255,255), game->viewportWidth*0.5, game->viewportHeight*0.275, ALLEGRO_ALIGN_CENTRE, "Game paused."); - DrawMenuState(game); }