From 235e2e0783709d4a6c5fef69b99da97ac8512226 Mon Sep 17 00:00:00 2001 From: Andrei Alexeyev <0x416b617269@gmail.com> Date: Sat, 5 Jan 2019 23:40:50 +0200 Subject: [PATCH] allow to skip credits if the game has been cleared at least once closes #154 --- src/credits.c | 12 +++++++++++- src/ending.h | 30 ++++++++++++++++++++++++++++-- src/progress.c | 20 ++++++++++++++++++++ src/progress.h | 3 +++ 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/credits.c b/src/credits.c index a17088f7..4d34b59e 100644 --- a/src/credits.c +++ b/src/credits.c @@ -26,6 +26,7 @@ static struct { int ecount; float panelalpha; int end; + bool skipable; } credits; #define CREDITS_ENTRY_FADEIN 200.0 @@ -218,8 +219,10 @@ static void credits_init(void) { stage_3d_context.crot[0] = 0; global.frames = 0; + credits_fill(); credits.end += 500 + CREDITS_ENTRY_FADEOUT; + credits.skipable = progress_times_any_good_ending_achieved() > 0; start_bgm("credits"); } @@ -424,7 +427,14 @@ static FrameAction credits_logic_frame(void *arg) { events_poll(NULL, 0); credits_process(); global.frames++; - return credits.end == 0 ? LFRAME_STOP : LFRAME_WAIT; + + if(credits.end == 0) { + return LFRAME_STOP; + } else if(credits.skipable && gamekeypressed(KEY_SKIP)) { + return LFRAME_SKIP; + } else { + return LFRAME_WAIT; + } } static FrameAction credits_render_frame(void *arg) { diff --git a/src/ending.h b/src/ending.h index 3872ec34..7dd7b267 100644 --- a/src/ending.h +++ b/src/ending.h @@ -16,7 +16,7 @@ enum { ENDING_FADE_TIME = 60, }; -enum { +typedef enum EndingID { // WARNING: Reordering this will break current progress files. ENDING_BAD_1, @@ -26,7 +26,33 @@ enum { ENDING_BAD_3, ENDING_GOOD_3, NUM_ENDINGS, -}; +} EndingID; + +#define GOOD_ENDINGS \ + ENDING(ENDING_GOOD_1) \ + ENDING(ENDING_GOOD_2) \ + ENDING(ENDING_GOOD_3) \ + +#define BAD_ENDINGS \ + ENDING(ENDING_BAD_1) \ + ENDING(ENDING_BAD_2) \ + ENDING(ENDING_BAD_3) \ + +static inline attr_must_inline bool ending_is_good(EndingID end) { + #define ENDING(e) (end == (e)) || + return ( + GOOD_ENDINGS + false); + #undef ENDING +} + +static inline attr_must_inline bool ending_is_bad(EndingID end) { + #define ENDING(e) (end == (e)) || + return ( + BAD_ENDINGS + false); + #undef ENDING +} typedef struct EndingEntry EndingEntry; typedef struct Ending Ending; diff --git a/src/progress.c b/src/progress.c index f8a5b5bf..8efb3c65 100644 --- a/src/progress.c +++ b/src/progress.c @@ -709,3 +709,23 @@ static void* delete_unknown_cmd(List **dest, List *elem, void *arg) { void progress_unload(void) { list_foreach(&progress.unknown, delete_unknown_cmd, NULL); } + +uint32_t progress_times_any_ending_achieved(void) { + uint x = 0; + + for(uint i = 0; i < NUM_ENDINGS; ++i) { + x += progress.achieved_endings[i]; + } + + return x; +} + +uint32_t progress_times_any_good_ending_achieved(void) { + uint x = 0; + + #define ENDING(e) x += progress.achieved_endings[e]; + GOOD_ENDINGS + #undef ENDING + + return x; +} diff --git a/src/progress.h b/src/progress.h index d118ab4d..9c63dbd3 100644 --- a/src/progress.h +++ b/src/progress.h @@ -60,3 +60,6 @@ extern GlobalProgress progress; void progress_load(void); void progress_save(void); void progress_unload(void); + +uint32_t progress_times_any_ending_achieved(void); +uint32_t progress_times_any_good_ending_achieved(void);