~rabbits/hiversaires

d9da5ec0b9118b5dc39cad5f5f8b07b3a2452b46 — Rezmason 11 months ago c016b5d
Added splash screen.
M build.sh => build.sh +1 -1
@@ 69,7 69,7 @@ then
    echo "Copying media..."
    cp -R media/audio media/fonts media/icons media/data bin
    mkdir bin/graphics
    cp -R media/graphics/cursor media/graphics/interface bin/graphics
    cp -R media/graphics/cursor media/graphics/interface media/graphics/logos bin/graphics
    mkdir bin/graphics/node_render
    while IFS= read -r line
    do

A media/graphics/interface/black.svg => media/graphics/interface/black.svg +3 -0
@@ 0,0 1,3 @@
<svg width="64" height="36" viewBox="0 0 16 9"  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink">
    <rect x="0" y="0" width="16" height="9" fill="black"/>
</svg>

M media/graphics/logos/100R.svg => media/graphics/logos/100R.svg +1 -2
@@ 1,5 1,4 @@
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="256" height="256">
  <!-- <rect x="0" y="0" width="200" height="200" fill="none" stroke="white" stroke-width="1"></rect> -->
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="512" height="512">
  <circle fill="white" cx="55"  cy="145" r="4"/>
  <circle fill="white" cx="65"  cy="145" r="4"/>
  <circle fill="white" cx="75"  cy="145" r="4"/>

M media/graphics/logos/rm.svg => media/graphics/logos/rm.svg +6 -4
@@ 1,6 1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 300" width="256" height="128">
<path fill="white" d="M408.75,0L243.51,237.7l-37.48-53.92c23.29-19.01,38.14-47.85,38.14-80.14C244.17,46.4,197.48,0,139.9,0H0
	v70.83h139.9c18.23,0,33.02,14.69,33.02,32.82s-14.78,32.82-33.02,32.82H0V300h71.25v-92.71h64.5L200.21,300h86.61l121.93-175.41
	V300H480V0H408.75z"/>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="384" height="384">
<g transform="translate(19,30) scale(0.125,0.125)">
	<path fill="white" d="M408.75,0L243.51,237.7l-37.48-53.92c23.29-19.01,38.14-47.85,38.14-80.14C244.17,46.4,197.48,0,139.9,0H0
		v70.83h139.9c18.23,0,33.02,14.69,33.02,32.82s-14.78,32.82-33.02,32.82H0V300h71.25v-92.71h64.5L200.21,300h86.61l121.93-175.41
		V300H480V0H408.75z"/>
</g>
</svg>

M media/graphics/logos/xxiivv.svg => media/graphics/logos/xxiivv.svg +13 -11
@@ 1,12 1,14 @@
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 138 32" width="256" height="128">
	<path d="
M 1,31
l 0,-22.5
a 7.5,7.5 0 1,1 15,0
l 0,15
a 7.5,7.5 0 0,0 15,0
l 0,-15
a 7.5,7.5 0 1,1 15,0
l 0,22.5 15,0 0,-30 15,0 0,30 15,0 0,-30 0.5,0 15,30 15,-30 15,30
" stroke="white" stroke-width="1.5" fill="none" stroke-linecap="round"/>
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="384" height="384">
	<g transform="translate(5,35) scale(0.65,0.65)">
		<path d="
		M 1,31
		l 0,-22.5
		a 7.5,7.5 0 1,1 15,0
		l 0,15
		a 7.5,7.5 0 0,0 15,0
		l 0,-15
		a 7.5,7.5 0 1,1 15,0
		l 0,22.5 15,0 0,-30 15,0 0,30 15,0 0,-30 0.5,0 15,30 15,-30 15,30
		" stroke="white" stroke-width="2" fill="none" stroke-linecap="round"/>
	</g>
</svg>

M src/gui.c => src/gui.c +75 -26
@@ 28,6 28,7 @@ WITH REGARD TO THIS SOFTWARE.
#define loadImage(asset, path) success &= Loader_LoadImage(Loader_CreateImage(&asset, LOADTYPE_MANUAL, "graphics/interface/" path))
#define lazyLoadImage(asset, path) Loader_CreateImage(&asset, LOADTYPE_LAZY, "graphics/interface/" path)
#define lazierLoadImage(asset, path) Loader_CreateImage(&asset, LOADTYPE_LAZIER, "graphics/interface/" path)
#define loadLogo(asset, path) Loader_CreateImage(&asset, LOADTYPE_LAZIER, "graphics/logos/" path)

static const char *modifierNames[] = {
	"",


@@ 62,6 63,11 @@ static Image *ententeProgressPane;
static Image *menuControls;
static Image *menuLogo;
static Image *vignette;
static Image *black;

static Image *hundredRabbitsLogo;
static Image *xxiivvLogo;
static Image *rezmasonLogo;

static int nodeImageIndex = 0;
static Image *nodeImages[2];


@@ 137,6 143,11 @@ GUI_PreloadAssets()
	lazierLoadImage(menuControls, "menu.controls.svg");
	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");

	/*
		This one's interesting: the vignette is a full-screen
		radial gradient that flashes almost every time the player


@@ 144,6 155,7 @@ GUI_PreloadAssets()
		but it's a very small SVG that's rendered very large.
	*/
	loadImage(vignette, "vignette.svg");
	loadImage(black, "black.svg");
	return success;
}



@@ 161,6 173,9 @@ GUI_Init()
	Stage_SetAlpha(BILLBOARD_VIGNETTE, 0);
	Stage_SetAlpha(BILLBOARD_MENU_LOGO, 0);
	Stage_SetAlpha(BILLBOARD_MENU_CONTROLS, 0);
	Stage_SetAlpha(BILLBOARD_SPLASH_TOP, 0);
	Stage_SetAlpha(BILLBOARD_SPLASH_LEFT, 0);
	Stage_SetAlpha(BILLBOARD_SPLASH_RIGHT, 0);

	/* Most HUD elements occupy a Stage region for the whole game */
	nodeImageIndex = 0;


@@ 175,8 190,12 @@ 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_SPLASH_TOP, hundredRabbitsLogo);
	Stage_SetImage(BILLBOARD_SPLASH_LEFT, xxiivvLogo);
	Stage_SetImage(BILLBOARD_SPLASH_RIGHT, rezmasonLogo);

	SDL_SetCursor(cursorsByType[currentCursorType][cursorPressed]);



@@ 226,6 245,15 @@ GUI_Quit()
	menuLogo = NULL;
	Loader_DestroyImage(vignette);
	vignette = NULL;
	Loader_DestroyImage(black);
	black = NULL;

	Loader_DestroyImage(hundredRabbitsLogo);
	hundredRabbitsLogo = NULL;
	Loader_DestroyImage(rezmasonLogo);
	rezmasonLogo = NULL;
	Loader_DestroyImage(xxiivvLogo);
	xxiivvLogo = NULL;

	Loader_DestroyImage(nodeImages[0]);
	Loader_DestroyImage(nodeImages[1]);


@@ 323,8 351,8 @@ GUI_ShowClockFace(int state, int refresh)
{
	Stage_SetImage(BILLBOARD_CLOCK, clocksByType[CLOCKTYPE_STATE_0 + state]);
	if(!refresh) {
		Stage_Fade(BILLBOARD_CLOCK_SHADOW, 0, 0.23, 1.5, 0.5);
		Stage_Fade(BILLBOARD_CLOCK, 0, 1, 0.5, 0.5);
		Stage_Fade(BILLBOARD_CLOCK_SHADOW, 0, 0.23, 1.5, 0.5, NULL);
		Stage_Fade(BILLBOARD_CLOCK, 0, 1, 0.5, 0.5, NULL);
	} else {
		Stage_SetAlpha(BILLBOARD_CLOCK_SHADOW, 0.23);
		Stage_SetAlpha(BILLBOARD_CLOCK, 1);


@@ 335,13 363,13 @@ void
GUI_ShowClock(int state)
{
	Stage_SetImage(BILLBOARD_HUD_CLOCK, iconsByType[ICONTYPE_CLOCK_0 + state]);
	Stage_Fade(BILLBOARD_HUD_CLOCK, 1, 0, 0.5, 3);
	Stage_Fade(BILLBOARD_HUD_CLOCK, 1, 0, 0.5, 3, NULL);
}

void
GUI_ShowClockAlert()
{
	Stage_Fade(BILLBOARD_HUD_CLOCK_ALERT, 1, 0, 0.5, 0.5);
	Stage_Fade(BILLBOARD_HUD_CLOCK_ALERT, 1, 0, 0.5, 0.5, NULL);
}

void


@@ 363,34 391,34 @@ GUI_ShowSeals(Zone zoneP, Zone zoneQ)
	Stage_SetImage(BILLBOARD_HUD_SEAL_1, sealsByZone[zone1]);
	Stage_SetImage(BILLBOARD_HUD_SEAL_2, sealsByZone[zone2]);

	Stage_Fade(BILLBOARD_HUD_SEAL_1, 1, 0, 0.5, 3);
	Stage_Fade(BILLBOARD_HUD_SEAL_2, 1, 0, 0.5, 3);
	Stage_Fade(BILLBOARD_HUD_SEAL_1, 1, 0, 0.5, 3, NULL);
	Stage_Fade(BILLBOARD_HUD_SEAL_2, 1, 0, 0.5, 3, NULL);
}

void
GUI_ShowSealAlert()
{
	Stage_Fade(BILLBOARD_HUD_SEAL_ALERT, 1, 0, 0.5, 0.5);
	Stage_Fade(BILLBOARD_HUD_SEAL_ALERT, 1, 0, 0.5, 0.5, NULL);
}

void
GUI_ShowEnergy(int level)
{
	Stage_SetImage(BILLBOARD_HUD_FUSE, iconsByType[ICONTYPE_FUSE_0 + level]);
	Stage_Fade(BILLBOARD_HUD_FUSE, 1, 0, 0.5, 3);
	Stage_Fade(BILLBOARD_HUD_FUSE, 1, 0, 0.5, 3, NULL);
}

void
GUI_ShowEnergyAlert()
{
	Stage_Fade(BILLBOARD_HUD_FUSE_ALERT, 1, 0, 1.5, 0.5);
	Stage_Fade(BILLBOARD_HUD_FUSE_ALERT, 1, 0, 1.5, 0.5, NULL);
}

void
GUI_ShowAudio(int enabled)
{
	Stage_SetImage(BILLBOARD_HUD_AUDIO, iconsByType[ICONTYPE_MUSIC_OFF + enabled]);
	Stage_Fade(BILLBOARD_HUD_AUDIO, 1, 0, 0.5, 3);
	Stage_Fade(BILLBOARD_HUD_AUDIO, 1, 0, 0.5, 3, NULL);
}

void


@@ 403,6 431,9 @@ GUI_HideMenu()
	Stage_SetAlpha(BILLBOARD_MENU_CREDIT4, 0.);
	Stage_SetAlpha(BILLBOARD_MENU_LOGO, 0.);
	Stage_SetAlpha(BILLBOARD_MENU_CONTROLS, 0.);
	Stage_SetAlpha(BILLBOARD_SPLASH_TOP, 0.);
	Stage_SetAlpha(BILLBOARD_SPLASH_LEFT, 0.);
	Stage_SetAlpha(BILLBOARD_SPLASH_RIGHT, 0.);
}

void


@@ 414,16 445,16 @@ 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_MENU_BLACK, 1, 0, 2, 0, NULL);
	Stage_Fade(BILLBOARD_MENU_LOGO, 1, 0, 2, 3, NULL);
	Stage_Fade(BILLBOARD_MENU_CONTROLS, 1, 0, 1, 8, NULL);
}

void
GUI_ShowMovement(int nudgeX, int nudgeY)
{
	Stage_Nudge(nudgeX * NUDGE_MULT, nudgeY * NUDGE_MULT, 0.2);
	Stage_Fade(BILLBOARD_NODE, 0.5, 1, 0.2, 0);
	Stage_Fade(BILLBOARD_NODE, 0.5, 1, 0.2, 0, NULL);
	Stage_SetAlpha(BILLBOARD_LAST_NODE_FADE, 0);
}



@@ 451,53 482,71 @@ GUI_ShowNode(char *nodeName, Orientation orientation, NodeModifier modifier, dou
	Stage_SwapImages(BILLBOARD_LAST_NODE_FADE, BILLBOARD_NODE);
	Stage_SetImage(BILLBOARD_NODE, nodeImages[nodeImageIndex]);
	Stage_SetAlpha(BILLBOARD_NODE, 1);
	Stage_Fade(BILLBOARD_LAST_NODE_FADE, 1, 0, fadeDuration, fadeDelay);
	Stage_Fade(BILLBOARD_LAST_NODE_FADE, 1, 0, fadeDuration, fadeDelay, NULL);
}

void
GUI_ShowSplash(void (*onComplete)())
{
	Stage_SetAlpha(BILLBOARD_MENU_BLACK, 1);
	Stage_Fade(BILLBOARD_SPLASH_TOP, 0, 1, 2, 0, NULL);
	Stage_Fade(BILLBOARD_SPLASH_LEFT, 0, 1, 1.5, 1, NULL);
	Stage_Fade(BILLBOARD_SPLASH_RIGHT, 0, 1, 1.5, 1.75, onComplete);
}

void
GUI_HideSplash(float delay, void (*onComplete)())
{
	Stage_SetAlpha(BILLBOARD_MENU_BLACK, 1);
	Stage_Fade(BILLBOARD_SPLASH_TOP, 1, 0, 2, 0. + delay, NULL);
	Stage_Fade(BILLBOARD_SPLASH_LEFT, 1, 0, 1.5, 1. + delay, NULL);
	Stage_Fade(BILLBOARD_SPLASH_RIGHT, 1, 0, 1.5, 1.75 + delay, onComplete);
}

void
GUI_ShowCreditsMenu(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);
	Stage_Fade(BILLBOARD_MENU_BLACK, 0, 1, 1, 1, NULL);
	Stage_Fade(BILLBOARD_MENU_CREDIT1, 0, 1, 1, 6, NULL);
	Stage_Fade(BILLBOARD_MENU_CREDIT2, 0, 1, 1, 10, NULL);
	Stage_Fade(BILLBOARD_MENU_CREDIT3, 0, 1, 1, 16, NULL);

	if(showSecret) {
		Stage_Fade(BILLBOARD_MENU_CREDIT4, 0, 1, 1, 24);
		Stage_Fade(BILLBOARD_MENU_CREDIT4, 0, 1, 1, 24, NULL);
	}
}

void
GUI_FlashVignette()
{
	Stage_Fade(BILLBOARD_VIGNETTE, 1., 0., 1., 0.);
	Stage_Fade(BILLBOARD_VIGNETTE, 1., 0., 1., 0., NULL);
}

void
GUI_ShowSave()
{
	Stage_Fade(BILLBOARD_HUD_SAVE, 1, 0, 0.5, 3);
	Stage_Fade(BILLBOARD_HUD_SAVE, 1, 0, 0.5, 3, NULL);
}

void
GUI_ShowProgressScreen(Chapter chapter)
{
	Stage_SetImage(BILLBOARD_PROGRESS_PANE, progressPanesByChapter[chapter]);
	Stage_Fade(BILLBOARD_PROGRESS_PANE, 0, 1, 0.5, 0.3);
	Stage_Fade(BILLBOARD_PROGRESS_PANE, 0, 1, 0.5, 0.3, NULL);
}

void
GUI_ShowEntenteScreen()
{
	Stage_SetImage(BILLBOARD_ENTENTE_SCREEN, ententeProgressPane);
	Stage_Fade(BILLBOARD_PROGRESS_PANE, 0, 1, 0.5, 0.3);
	Stage_Fade(BILLBOARD_PROGRESS_PANE, 0, 1, 0.5, 0.3, NULL);
}

void
GUI_ShowMazeInstruction(MazeAxis axis, MazeInstruction instruction)
{
	Stage_SetImage(BILLBOARD_ENTENTE_SCREEN, mazeIconsByAxisAndInstruction[axis][instruction]);
	Stage_Fade(BILLBOARD_ENTENTE_SCREEN, 0, 1, 1, 0);
	Stage_Fade(BILLBOARD_ENTENTE_SCREEN, 0, 1, 1, 0, NULL);
}

void


@@ 515,7 564,7 @@ GUI_ShowFootstep(Footstep step)
		name = BILLBOARD_HUD_STEP_FORWARD;
		break;
	}
	Stage_Fade(name, 1, 0, 0.5, 0);
	Stage_Fade(name, 1, 0, 0.5, 0, NULL);
}

void

M src/gui.h => src/gui.h +2 -0
@@ 106,6 106,8 @@ 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_ShowSplash(void (*onComplete)());
void GUI_HideSplash(float delay, void (*onComplete)());
void GUI_FlashVignette();
void GUI_ShowSave();
void GUI_ShowProgressScreen(Chapter chapter);

M src/play.c => src/play.c +8 -1
@@ 186,6 186,12 @@ reset()
	Prefs_Save();
}

static void
hideSplash()
{
	GUI_HideSplash(3, GUI_ShowHomeMenu);
}

void
Play_Init(GameState *state)
{


@@ 202,7 208,8 @@ Play_Init(GameState *state)
	Audio_SetActive(_state->audio);
	currentNode = Nodes_Get(_state->nodeName);
	refreshNode(0, 0);
	GUI_ShowHomeMenu();

	GUI_ShowSplash(hideSplash);

	printf(
		"		\n\n"

M src/stage.c => src/stage.c +4 -4
@@ 240,14 240,14 @@ Stage_SwapImages(RegionName name1, RegionName name2)
}

void
Stage_Fade(RegionName name, double startAlpha, double endAlpha, double duration, double delay)
Stage_Fade(RegionName name, double startAlpha, double endAlpha, double duration, double delay, void (*onComplete)())
{
	if(duration <= 0) {
		Stage_StopFade(name, 0);
		Stage_SetAlpha(name, endAlpha);
	} else {
		Region *region = &regions[name];
		Tween_Start(&region->alphaTween, startAlpha, endAlpha, _totalTime + delay, duration);
		Tween_Start(&region->alphaTween, startAlpha, endAlpha, _totalTime + delay, duration, onComplete);
		Tween_Update(&region->alphaTween, _totalTime);
		updateLazierImage(region);
	}


@@ 279,7 279,7 @@ Stage_Tint(SDL_Color color, double duration, double delay)
		Tween_Stop(&tintTween, 0);
		tintTween.value = 1;
	} else {
		Tween_Start(&tintTween, 0, 1, _totalTime + delay, duration);
		Tween_Start(&tintTween, 0, 1, _totalTime + delay, duration, NULL);
		Tween_Update(&tintTween, _totalTime);
	}
}


@@ 301,7 301,7 @@ Stage_Nudge(double x, double y, double duration)
	}
	nudgeX = x;
	nudgeY = y;
	Tween_Start(&nudgeTween, 0, 1, _totalTime, duration);
	Tween_Start(&nudgeTween, 0, 1, _totalTime, duration, NULL);
	Tween_Update(&nudgeTween, _totalTime);
}


M src/stage.h => src/stage.h +5 -1
@@ 78,6 78,10 @@ typedef enum {
	BILLBOARD_HUD_STEP_LEFT,
	BILLBOARD_HUD_STEP_RIGHT,

	BILLBOARD_SPLASH_TOP,
	BILLBOARD_SPLASH_LEFT,
	BILLBOARD_SPLASH_RIGHT,

	TRIGGER_ACTION,
	TRIGGER_MOVE_FORWARD,
	TRIGGER_MOVE_LEFT,


@@ 106,7 110,7 @@ void Stage_Init();
void Stage_Quit();
void Stage_SetImage(RegionName name, Image *image);
void Stage_SwapImages(RegionName name1, RegionName name2);
void Stage_Fade(RegionName name, double startAlpha, double endAlpha, double duration, double delay);
void Stage_Fade(RegionName name, double startAlpha, double endAlpha, double duration, double delay, void (*onComplete)());
void Stage_StopFade(RegionName name, int complete);
void Stage_SetAlpha(RegionName name, double alpha);
void Stage_Tint(SDL_Color color, double duration, double delay);

M src/stageregions.c => src/stageregions.c +8 -1
@@ 34,7 34,7 @@ WITH REGARD TO THIS SOFTWARE.

#define region(x, y, w, h, mode) \
	{ \
		__LINE__, {x, y, w, h}, mode, rect(), rect(), {0, 0, 0, 0, 0}, NULL, rect() \
		__LINE__, {x, y, w, h}, mode, rect(), rect(), {0, 0, 0, 0, 0, NULL}, NULL, rect() \
	}

Region regions[] =


@@ 117,6 117,13 @@ Region regions[] =
		/* BILLBOARD_HUD_STEP_RIGHT */
		region(0.8, HUD_ALERT_Y, 0.2, HUD_HEIGHT, LAYOUTMODE_STRETCH),

		/* BILLBOARD_SPLASH_TOP */
		region(0.2, 0.2, 0.6, 0.4, LAYOUTMODE_CONTAIN),
		/* BILLBOARD_SPLASH_LEFT */
		region(0.35, 0.7, 0.15, 0.3, LAYOUTMODE_CONTAIN),
		/* BILLBOARD_SPLASH_RIGHT */
		region(0.50, 0.7, 0.15, 0.3, LAYOUTMODE_CONTAIN),

		/* TRIGGER_ACTION */
		region(1. / 3., 1. / 3., 1. / 3., 1. / 3., LAYOUTMODE_STRETCH),


M src/tween.c => src/tween.c +9 -1
@@ 1,5 1,7 @@
#include "tween.h"

#include <string.h>

/*
Copyright (c) 2013-2021 Devine Lu Linvega
2018 web port by rezmason


@@ 26,17 28,23 @@ Tween_Update(Tween *tween, double now)
	} else if(t >= 1) {
		t = 1;
		tween->duration = -1;
		if(tween->onComplete != NULL) {
			void (*onComplete)() = tween->onComplete;
			tween->onComplete = NULL;
			onComplete();
		}
	}
	tween->value = t * tween->endValue + (1. - t) * tween->startValue;
}

void
Tween_Start(Tween *tween, double startValue, double endValue, double start, double duration)
Tween_Start(Tween *tween, double startValue, double endValue, double start, double duration, void (*onComplete)())
{
	tween->startValue = startValue;
	tween->endValue = endValue;
	tween->start = start;
	tween->duration = duration;
	tween->onComplete = onComplete;
}

void

M src/tween.h => src/tween.h +2 -1
@@ 22,8 22,9 @@ WITH REGARD TO THIS SOFTWARE.
typedef struct {
	double value, startValue, endValue;
	double start, duration;
	void (*onComplete)();
} Tween;

void Tween_Update(Tween *tween, double now);
void Tween_Start(Tween *tween, double startValue, double endValue, double start, double duration);
void Tween_Start(Tween *tween, double startValue, double endValue, double start, double duration, void (*onComplete)());
void Tween_Stop(Tween *tween, int complete);