From 3e1627a4c505fa9109dd8d7d107a0b9946af8e5c Mon Sep 17 00:00:00 2001 From: Rezmason Date: Tue, 2 Mar 2021 19:11:59 -0800 Subject: [PATCH] Implementing the credits as just a slower splash, with fading in mixed in, and click-through links to the logos' corresponding sites. Added Aliceffekt logo and the secret logo. Updated the credit trigger to only show the secret if the player has an extra fuse *and* didn't use the walkthrough. --- TODO.txt | 12 +- media/data/data.txt | 2 +- media/graphics/logos/aliceffekt.svg | 14 ++ media/graphics/logos/hiversaires_source.svg | 12 ++ src/delays.c | 35 +++-- src/delays.h | 4 +- src/gui.c | 147 +++++++++++++------- src/gui.h | 3 +- src/play.c | 7 + src/stage.h | 13 +- src/stageregions.c | 20 +-- src/terminals.c | 7 +- src/walkthrough.c | 9 ++ src/walkthrough.h | 1 + 14 files changed, 179 insertions(+), 107 deletions(-) create mode 100644 media/graphics/logos/aliceffekt.svg create mode 100644 media/graphics/logos/hiversaires_source.svg diff --git a/TODO.txt b/TODO.txt index e0414b4..db54108 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,11 +1,3 @@ -- credits - Just rasterize them - Make an SVG, use libsvg to render it, put the command in a text file someplace, end of story -bug: audio loading hitch - - spin up a separate SDL in a thread for audio and mixer -profile - - any memory leaks? probably not? - deploy, test - Compile for multiple platforms - Give to testers @@ -13,6 +5,10 @@ deploy, test - test hacks especially, like the audio thread and resize event watcher - itch.io I guess +fix the audio loading hitch + - collect data on it first tho + - spin up a separate SDL in a thread for audio and mixer + mobile device support - Touch event support - Respond to device orientation diff --git a/media/data/data.txt b/media/data/data.txt index c7da66f..6111bbb 100644 --- a/media/data/data.txt +++ b/media/data/data.txt @@ -55,7 +55,7 @@ energyTerminal("nataniev_endgame_energy_terminal", 0); secretTerminal("rainre_secret_terminal", 0); energyTerminal("entente_energy_box", 1); energyTerminal("antechannel_energy_box", 1); -endgameCredit("endgame_credit", 0); +endgame("endgame_credit", 0); ententeProgressTerminal("entente_progress_terminal", 0); energyTerminal("capsule_nataniev_energy_terminal", 0); /*DOORS*/ diff --git a/media/graphics/logos/aliceffekt.svg b/media/graphics/logos/aliceffekt.svg new file mode 100644 index 0000000..3f05586 --- /dev/null +++ b/media/graphics/logos/aliceffekt.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/media/graphics/logos/hiversaires_source.svg b/media/graphics/logos/hiversaires_source.svg new file mode 100644 index 0000000..fae800a --- /dev/null +++ b/media/graphics/logos/hiversaires_source.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/src/delays.c b/src/delays.c index 4465cab..fcb3094 100644 --- a/src/delays.c +++ b/src/delays.c @@ -38,8 +38,8 @@ Delays_Quit() delays = NULL; } -int -Delays_Add(double duration, void (*onComplete)(void *data), void *data) +void +Delays_Add(int *uid, double duration, void (*onComplete)(void *data), void *data) { int i; for(i = 0; i < _numDelays; i++) { @@ -47,20 +47,30 @@ Delays_Add(double duration, void (*onComplete)(void *data), void *data) (*delays)[i].endTime = _totalTime + duration; (*delays)[i].onComplete = onComplete; (*delays)[i].data = data; - return i; + *uid = i; + return; } } - return -1; + *uid = -1; } void -Delays_Cancel(int uid, int complete) +Delays_Cancel(int *uid, int complete) { - void (*onComplete)() = (*delays)[uid].onComplete; - void *data = (*delays)[uid].data; - (*delays)[uid].onComplete = NULL; - (*delays)[uid].data = NULL; - (*delays)[uid].endTime = -1; + Delay *delay; + void (*onComplete)(); + void *data; + + if(*uid < 0 || *uid >= _numDelays) { + return; + } + delay = &(*delays)[*uid]; + onComplete = delay->onComplete; + data = delay->data; + delay->onComplete = NULL; + delay->data = NULL; + delay->endTime = -1; + *uid = -1; if(complete && onComplete != NULL) { onComplete(data); } @@ -69,11 +79,12 @@ Delays_Cancel(int uid, int complete) void Delays_Update(double totalTime) { - int i; + int i, uid; _totalTime = totalTime; for(i = 0; i < _numDelays; i++) { if((*delays)[i].endTime > 0 && (*delays)[i].endTime < _totalTime) { - Delays_Cancel(i, 1); + uid = i; + Delays_Cancel(&uid, 1); } } } diff --git a/src/delays.h b/src/delays.h index 7d0b654..e39ffae 100644 --- a/src/delays.h +++ b/src/delays.h @@ -26,6 +26,6 @@ typedef struct { void Delays_Init(int numDelays); void Delays_Quit(); -int Delays_Add(double duration, void (*onComplete)(), void *data); -void Delays_Cancel(int uid, int complete); +void Delays_Add(int *uid, double duration, void (*onComplete)(), void *data); +void Delays_Cancel(int *uid, int complete); void Delays_Update(double totalTime); diff --git a/src/gui.c b/src/gui.c index eec5b4e..b426aed 100644 --- a/src/gui.c +++ b/src/gui.c @@ -67,18 +67,22 @@ static Image *menuLogo; static Image *vignette; static Image *black; -static Image *hundredRabbitsLogo; -static Image *xxiivvLogo; -static Image *rezmasonLogo; +static Image *logos[5]; static int nodeImageIndex = 0; static Image *nodeImages[2]; static char nodeImagePaths[2][PATH_LENGTH]; -static int splash1Delay; -static int splash2Delay; -static int splash3Delay; -static int splash4Delay; +static int logoDelays[10]; + +static char *creditURLs[5] = { + "https://xxiivv.com", + "https://rezmason.net", + "https://aliceffekt.bandcamp.com", + "https://100r.co", + "https://git.sr.ht/~rabbits/hiversaires"}; +static int creditIndex; +static int showedURL = 0; int GUI_PreloadAssets() @@ -151,9 +155,11 @@ GUI_PreloadAssets() lazierLoadImage(menuLogo, "menu.logo.svg"); /* The splash screen images only show up once */ - loadLogo(hundredRabbitsLogo, "100R.svg"); - loadLogo(xxiivvLogo, "xxiivv.svg"); - loadLogo(rezmasonLogo, "rm.svg"); + loadLogo(logos[0], "100R.svg"); + loadLogo(logos[1], "xxiivv.svg"); + loadLogo(logos[2], "rm.svg"); + loadLogo(logos[3], "aliceffekt.svg"); + loadLogo(logos[4], "hiversaires_source.svg"); /* This one's interesting: the vignette is a full-screen @@ -178,9 +184,9 @@ GUI_Init() Stage_SetAlpha(BILLBOARD_HUD_SAVE, 0); Stage_SetAlpha(BILLBOARD_CLOCK_SHADOW, 0); Stage_SetAlpha(BILLBOARD_VIGNETTE, 0); - Stage_SetAlpha(BILLBOARD_MENU_LOGO, 0); - Stage_SetAlpha(BILLBOARD_MENU_CONTROLS, 0); - Stage_SetAlpha(BILLBOARD_SPLASH, 0); + Stage_SetAlpha(BILLBOARD_HIVERSAIRES_LOGO, 0); + Stage_SetAlpha(BILLBOARD_CONTROLS, 0); + Stage_SetAlpha(BILLBOARD_LOGO, 0); /* Most HUD elements occupy a Stage region for the whole game */ nodeImageIndex = 0; @@ -195,9 +201,9 @@ GUI_Init() Stage_SetImage(BILLBOARD_HUD_SAVE, iconsByType[ICONTYPE_SAVE]); Stage_SetImage(BILLBOARD_CLOCK_SHADOW, clocksByType[CLOCKTYPE_SHADOW]); Stage_SetImage(BILLBOARD_VIGNETTE, vignette); - Stage_SetImage(BILLBOARD_MENU_BLACK, black); - Stage_SetImage(BILLBOARD_MENU_LOGO, menuLogo); - Stage_SetImage(BILLBOARD_MENU_CONTROLS, menuControls); + Stage_SetImage(BILLBOARD_BLACK, black); + Stage_SetImage(BILLBOARD_HIVERSAIRES_LOGO, menuLogo); + Stage_SetImage(BILLBOARD_CONTROLS, menuControls); SDL_SetCursor(cursorsByType[currentCursorType][cursorPressed]); @@ -250,12 +256,10 @@ GUI_Quit() Loader_DestroyImage(black); black = NULL; - Loader_DestroyImage(hundredRabbitsLogo); - hundredRabbitsLogo = NULL; - Loader_DestroyImage(rezmasonLogo); - rezmasonLogo = NULL; - Loader_DestroyImage(xxiivvLogo); - xxiivvLogo = NULL; + for(i = 0; i < 5; i++) { + Loader_DestroyImage(logos[i]); + logos[i] = NULL; + } Loader_DestroyImage(nodeImages[0]); Loader_DestroyImage(nodeImages[1]); @@ -426,14 +430,10 @@ GUI_ShowAudio(int enabled) void GUI_HideMenu() { - Stage_SetAlpha(BILLBOARD_MENU_BLACK, 0.); - Stage_SetAlpha(BILLBOARD_MENU_CREDIT1, 0.); - Stage_SetAlpha(BILLBOARD_MENU_CREDIT2, 0.); - Stage_SetAlpha(BILLBOARD_MENU_CREDIT3, 0.); - Stage_SetAlpha(BILLBOARD_MENU_CREDIT4, 0.); - Stage_SetAlpha(BILLBOARD_MENU_LOGO, 0.); - Stage_SetAlpha(BILLBOARD_MENU_CONTROLS, 0.); - Stage_SetAlpha(BILLBOARD_SPLASH, 0.); + Stage_SetAlpha(BILLBOARD_BLACK, 0.); + Stage_SetAlpha(BILLBOARD_HIVERSAIRES_LOGO, 0.); + Stage_SetAlpha(BILLBOARD_CONTROLS, 0.); + Stage_SetAlpha(BILLBOARD_LOGO, 0.); } void @@ -445,9 +445,9 @@ GUI_ShowHomeMenu() Stage_SetAlpha(BILLBOARD_HUD_SAVE, 0); Stage_SetAlpha(BILLBOARD_NODE, 1); - Stage_Fade(BILLBOARD_MENU_BLACK, 1, 0, 2, 0); - Stage_Fade(BILLBOARD_MENU_LOGO, 1, 0, 2, 3); - Stage_Fade(BILLBOARD_MENU_CONTROLS, 1, 0, 1, 8); + Stage_Fade(BILLBOARD_BLACK, 1, 0, 2, 0); + Stage_Fade(BILLBOARD_HIVERSAIRES_LOGO, 1, 0, 2, 3); + Stage_Fade(BILLBOARD_CONTROLS, 1, 0, 1, 8); } void @@ -489,15 +489,15 @@ static void splashNext(void *data) { Image *image = data; - Stage_SetImage(BILLBOARD_SPLASH, image); - Stage_Fade(BILLBOARD_SPLASH, 1, 0, 0.125, 0.875); + Stage_SetImage(BILLBOARD_LOGO, image); + Stage_Fade(BILLBOARD_LOGO, 1, 0, 0.125, 0.675); } static void splashEnd(void *data) { FuncWrapper *wrapper = data; - Stage_SetAlpha(BILLBOARD_SPLASH, 0); + Stage_SetAlpha(BILLBOARD_LOGO, 0); wrapper->f(); free(wrapper); } @@ -505,37 +505,76 @@ splashEnd(void *data) void GUI_RunSplash(void (*onComplete)()) { - Stage_SetAlpha(BILLBOARD_MENU_BLACK, 1); - Stage_SetAlpha(BILLBOARD_SPLASH, 1); - splash1Delay = Delays_Add(0.5, splashNext, hundredRabbitsLogo); - splash2Delay = Delays_Add(1.5, splashNext, xxiivvLogo); - splash3Delay = Delays_Add(2.5, splashNext, rezmasonLogo); - splash4Delay = Delays_Add(3.5, splashEnd, wrapFunction(onComplete)); + Stage_SetAlpha(BILLBOARD_BLACK, 1); + Stage_SetAlpha(BILLBOARD_LOGO, 1); + Delays_Add(&logoDelays[0], 0.5 + 0.8 * 0, splashNext, logos[0]); + Delays_Add(&logoDelays[1], 0.5 + 0.8 * 1, splashNext, logos[1]); + Delays_Add(&logoDelays[2], 0.5 + 0.8 * 2, splashNext, logos[2]); + Delays_Add(&logoDelays[3], 0.5 + 0.8 * 3, splashNext, logos[3]); + Delays_Add(&logoDelays[4], 0.5 + 0.8 * 4, splashEnd, wrapFunction(onComplete)); } void GUI_SkipSplash() { - Stage_SetAlpha(BILLBOARD_MENU_BLACK, 1); - Stage_SetAlpha(BILLBOARD_SPLASH, 0); + Stage_SetAlpha(BILLBOARD_BLACK, 1); + Stage_SetAlpha(BILLBOARD_LOGO, 0); + + Delays_Cancel(&logoDelays[0], 0); + Delays_Cancel(&logoDelays[1], 0); + Delays_Cancel(&logoDelays[2], 0); + Delays_Cancel(&logoDelays[3], 0); + Delays_Cancel(&logoDelays[4], 1); +} - Delays_Cancel(splash1Delay, 0); - Delays_Cancel(splash2Delay, 0); - Delays_Cancel(splash3Delay, 0); - Delays_Cancel(splash4Delay, 1); +static void +creditIn(void *data) +{ + Image *image = data; + creditIndex++; + showedURL = 0; + Stage_SetImage(BILLBOARD_LOGO, image); + Stage_Fade(BILLBOARD_LOGO, 0, 1, 0.5, 0); +} + +static void +creditOut(void *data) +{ + (void)data; + Stage_Fade(BILLBOARD_LOGO, 1, 0, 0.5, 0); } void -GUI_ShowCreditsMenu(int showSecret) +GUI_ShowCredits(int showSecret) { - Stage_Fade(BILLBOARD_MENU_BLACK, 0, 1, 1, 1); - Stage_Fade(BILLBOARD_MENU_CREDIT1, 0, 1, 1, 6); - Stage_Fade(BILLBOARD_MENU_CREDIT2, 0, 1, 1, 10); - Stage_Fade(BILLBOARD_MENU_CREDIT3, 0, 1, 1, 16); + creditIndex = -1; + Stage_Fade(BILLBOARD_BLACK, 0, 1, 3, 0); + + Delays_Add(&logoDelays[0], 3 + (0.5 + 5) * 0 + 0.5 * 0, creditIn, logos[1]); + Delays_Add(&logoDelays[1], 3 + (0.5 + 5) * 1 + 0.5 * 0, creditOut, logos[1]); + + Delays_Add(&logoDelays[2], 3 + (0.5 + 5) * 1 + 0.5 * 1, creditIn, logos[2]); + Delays_Add(&logoDelays[3], 3 + (0.5 + 5) * 2 + 0.5 * 1, creditOut, logos[2]); + + Delays_Add(&logoDelays[4], 3 + (0.5 + 5) * 2 + 0.5 * 2, creditIn, logos[3]); + Delays_Add(&logoDelays[5], 3 + (0.5 + 5) * 3 + 0.5 * 2, creditOut, logos[3]); + + Delays_Add(&logoDelays[6], 3 + (0.5 + 5) * 3 + 0.5 * 3, creditIn, logos[0]); if(showSecret) { - Stage_Fade(BILLBOARD_MENU_CREDIT4, 0, 1, 1, 24); + Delays_Add(&logoDelays[7], 3 + (0.5 + 5) * 4 + 0.5 * 3, creditOut, logos[0]); + Delays_Add(&logoDelays[8], 3 + (0.5 + 5) * 4 + 0.5 * 4, creditIn, logos[4]); + } +} + +void +GUI_LaunchCreditURL() +{ + if(showedURL) { + return; } + showedURL = 1; + SDL_OpenURL(creditURLs[creditIndex]); } void diff --git a/src/gui.h b/src/gui.h index b8d2f63..612bbc1 100644 --- a/src/gui.h +++ b/src/gui.h @@ -105,7 +105,8 @@ void GUI_HideMenu(); void GUI_ShowHomeMenu(); void GUI_ShowMovement(int nudgeX, int nudgeY); void GUI_ShowNode(char *nodeName, Orientation orientation, NodeModifier modifier, double fadeDuration, double fadeDelay); -void GUI_ShowCreditsMenu(int showSecret); +void GUI_ShowCredits(int showSecret); +void GUI_LaunchCreditURL(); void GUI_RunSplash(void (*onComplete)()); void GUI_SkipSplash(); void GUI_FlashVignette(); diff --git a/src/play.c b/src/play.c index a5a3d0e..7a2ced2 100644 --- a/src/play.c +++ b/src/play.c @@ -119,6 +119,10 @@ action(int autoDoor) break; default: break; } + + if(_state->completed) { + GUI_ShowCredits(_state->energy > 0 && !Walkthrough_PlayerUsedWalkthrough()); + } } static void @@ -241,6 +245,9 @@ Play_ProcessInput(InputType type, int down) } if(_state->completed) { + if(down && (type == INPUTTYPE_ACTION || type == INPUTTYPE_CENTER || type == INPUTTYPE_FORWARD)) { + GUI_LaunchCreditURL(); + } return; } diff --git a/src/stage.h b/src/stage.h index bed58bf..2ee5b9e 100644 --- a/src/stage.h +++ b/src/stage.h @@ -72,15 +72,10 @@ typedef enum { BILLBOARD_HUD_STEP_LEFT, BILLBOARD_HUD_STEP_RIGHT, - BILLBOARD_MENU_BLACK, - BILLBOARD_MENU_CREDIT1, - BILLBOARD_MENU_CREDIT2, - BILLBOARD_MENU_CREDIT3, - BILLBOARD_MENU_CREDIT4, - BILLBOARD_MENU_LOGO, - BILLBOARD_MENU_CONTROLS, - - BILLBOARD_SPLASH, + BILLBOARD_BLACK, + BILLBOARD_HIVERSAIRES_LOGO, + BILLBOARD_CONTROLS, + BILLBOARD_LOGO, TRIGGER_ACTION, TRIGGER_MOVE_FORWARD, diff --git a/src/stageregions.c b/src/stageregions.c index a41f966..745a500 100644 --- a/src/stageregions.c +++ b/src/stageregions.c @@ -96,28 +96,16 @@ Region regions[] = /* BILLBOARD_HUD_STEP_RIGHT */ region(0.8, HUD_ALERT_Y, 0.2, HUD_HEIGHT, LAYOUTMODE_STRETCH), - /* BILLBOARD_MENU_BLACK */ + /* BILLBOARD_BLACK */ region(0., 0., 1., 1., LAYOUTMODE_STRETCH), - /* BILLBOARD_MENU_CREDIT1 */ + /* BILLBOARD_HIVERSAIRES_LOGO */ region(0., 0., 1., 1., LAYOUTMODE_CONTAIN), - /* BILLBOARD_MENU_CREDIT2 */ + /* BILLBOARD_CONTROLS */ region(0., 0., 1., 1., LAYOUTMODE_CONTAIN), - /* BILLBOARD_MENU_CREDIT3 */ - region(0., 0., 1., 1., LAYOUTMODE_CONTAIN), - - /* BILLBOARD_MENU_CREDIT4 */ - region(0., 0., 1., 1., LAYOUTMODE_CONTAIN), - - /* BILLBOARD_MENU_LOGO */ - region(0., 0., 1., 1., LAYOUTMODE_CONTAIN), - - /* BILLBOARD_MENU_CONTROLS */ - region(0., 0., 1., 1., LAYOUTMODE_CONTAIN), - - /* BILLBOARD_SPLASH */ + /* BILLBOARD_LOGO */ region(0.3, 0.3, 0.4, 0.4, LAYOUTMODE_CONTAIN), /* TRIGGER_ACTION */ diff --git a/src/terminals.c b/src/terminals.c index 30ed404..a2c8744 100644 --- a/src/terminals.c +++ b/src/terminals.c @@ -331,12 +331,11 @@ setupEntenteProgress(TerminalData *data, int *isOpen, GameState *state) } static int -changeEndgameCredit(TerminalData *data, int *isOpen, GameState *state) +changeEndgame(TerminalData *data, int *isOpen, GameState *state) { (void)data; (void)isOpen; state->completed = 1; - GUI_ShowCreditsMenu(state->energy > 0); return 1; } @@ -464,8 +463,8 @@ parseTerminal(Terminal *terminal, char *line, int lineNumber) } else if(strcmp(type, "secretTerminal") == 0) { terminal->setup = setupSecret; terminal->change = changeSecret; - } else if(strcmp(type, "endgameCredit") == 0) { - terminal->change = changeEndgameCredit; + } else if(strcmp(type, "endgame") == 0) { + terminal->change = changeEndgame; } else { printf("Terminal data error: unknown terminal type on line %d: %s\n", lineNumber, type); } diff --git a/src/walkthrough.c b/src/walkthrough.c index fd1c72e..5a8cdfb 100644 --- a/src/walkthrough.c +++ b/src/walkthrough.c @@ -63,6 +63,15 @@ Walkthrough_Reset() stepIndex = 0; } +int +Walkthrough_PlayerUsedWalkthrough() +{ +#ifdef DEBUG + return 0; +#endif + return stepIndex > 0; +} + InputType Walkthrough_Next() { diff --git a/src/walkthrough.h b/src/walkthrough.h index d2cc4cf..0ee742d 100644 --- a/src/walkthrough.h +++ b/src/walkthrough.h @@ -25,4 +25,5 @@ WITH REGARD TO THIS SOFTWARE. int Walkthrough_Init(char *data); void Walkthrough_Quit(); void Walkthrough_Reset(); +int Walkthrough_PlayerUsedWalkthrough(); InputType Walkthrough_Next(); -- 2.34.2