M TODO.txt => TODO.txt +4 -8
@@ 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
M media/data/data.txt => media/data/data.txt +1 -1
@@ 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*/
A media/graphics/logos/aliceffekt.svg => media/graphics/logos/aliceffekt.svg +14 -0
@@ 0,0 1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="512" height="512">
+ <g transform="translate(0,40) scale(0.032625,0.032625)">
+ <polygon fill="white" points="0,330.9 0,483.5 277,206 277,268 225,268 135,376 277,376 277,430 385,430 385,54 277,54"/>
+ <polygon fill="white" points="393,54 393,376 715,376 715,268 501,268 501,54"/>
+ <polygon fill="white" points="724,54 832,54 832,376 724,376"/>
+ <polygon fill="white" points="841,54 841,376 1108.8,376 1162,321.6 1162,168.5 1063.5,268 949,268 949,162 1162,162 1162,54"/>
+ <polygon fill="white" points="2161,376 2161,54 2482,54 2482,204 2443,244 2269,268 2374,162 2269,162 2269,268 2482,268 2482,376"/>
+ <polygon fill="white" points="1831,54 1831,268 1609,268 1609,162 1714,162 1609,268 1783,244 1822,204 1822,54 1501,54 1501,268 1279,268 1279,162 1384,162 1279,268 1453,244 1492,204 1492,54 1171,54 1171,376 1501,376 1501,527 1609,419 1609,376 1831,376 1831,527 1939,419 1939,376 1981,376 2089,268 1939,268 1939,162 2044,162 1939,268 2113,244 2152,204 2152,54"/>
+ <polygon fill="white" points="2934,0 2907.3,0 2724.5,162 2826,162 2826,273 2845,376 2947.8,376 3054.5,268 2934,268 2934,162 3063,162 3063,54 2934,54"/>
+ <polygon fill="white" points="2712.6,171.4 2800,260 2874,485 2632,244"/>
+ <polygon fill="white" points="2491,54 2491,376 2599,376 2599,268 2812,54 2661,54 2599,116 2599,54"/>
+ </g>
+</svg>
A media/graphics/logos/hiversaires_source.svg => media/graphics/logos/hiversaires_source.svg +12 -0
@@ 0,0 1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="512" height="512">
+ <g transform="translate(0,25) scale(0.3425,0.3425)">
+ <path fill="white" d="M203.1,10.9v99h-14.5V67.7h-27.8v42.2h-14.5V67.7h-27.8v42.2h-14.5v-99h14.5v42.2h27.8V10.9h14.5v42.2h27.8
+ V10.9H203.1z M32.2,96.8c-2.4-9.4-3.5-19.2-3.5-29.3c0-10.1,1.2-19.8,3.5-29.3c2.4-9.4,5.6-18.6,9.9-27.3h-5.6
+ C29.1,19.1,23.6,28.2,20,38.2S14.5,58,14.5,67.6c0,9.6,1.8,19.3,5.5,29.4s9.1,19.1,16.5,27.2H42C37.8,115.4,34.5,106.3,32.2,96.8z
+ M73.5,52.1V38.6L84.6,45l4.2-6.4l-11.6-7.1l11.6-7.1L84.6,18l-11.1,6.4V10.9h-8.4v13.5L54,18l-4.2,6.4l11.6,7.1l-11.6,7.1L54,45
+ l11.1-6.4v13.5H73.5z M226.1,38.3c2.4,9.4,3.6,19.2,3.6,29.3c0,10.1-1.2,19.9-3.6,29.3s-5.6,18.5-9.8,27.3h5.6
+ c7.3-8.2,12.8-17.2,16.4-27.2c3.7-10,5.5-19.8,5.5-29.4c0-9.5-1.8-19.3-5.5-29.3c-3.7-10-9.2-19.1-16.4-27.3h-5.6
+ C220.5,19.7,223.7,28.9,226.1,38.3z M276,78.4V64.2h-14.2v14.2H276z M276,109.9V95.8h-14.2v24.4L276,109.9z"/>
+ </g>
+</svg>
M src/delays.c => src/delays.c +23 -12
@@ 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);
}
}
}
M src/delays.h => src/delays.h +2 -2
@@ 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);
M src/gui.c => src/gui.c +93 -54
@@ 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
M src/gui.h => src/gui.h +2 -1
@@ 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();
M src/play.c => src/play.c +7 -0
@@ 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;
}
M src/stage.h => src/stage.h +4 -9
@@ 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,
M src/stageregions.c => src/stageregions.c +4 -16
@@ 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 */
M src/terminals.c => src/terminals.c +3 -4
@@ 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);
}
M src/walkthrough.c => src/walkthrough.c +9 -0
@@ 63,6 63,15 @@ Walkthrough_Reset()
stepIndex = 0;
}
+int
+Walkthrough_PlayerUsedWalkthrough()
+{
+#ifdef DEBUG
+ return 0;
+#endif
+ return stepIndex > 0;
+}
+
InputType
Walkthrough_Next()
{
M src/walkthrough.h => src/walkthrough.h +1 -0
@@ 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();