music! random dialogue!
This commit is contained in:
1 parent
02b5bc8b52
commit
469f0db39c
6 files changed
+55
-30
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+55
-30
@@ -187,6 +187,16 @@ static void cmd_line(Script& s, text_t* dialogue,
|
|||||||
} });
|
} });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cmd_clear(Script& s, text_t* dialogue,
|
||||||
|
element_handle_t dialogue_id, compositor_t* comp)
|
||||||
|
{
|
||||||
|
s.push_back({ "CLEAR", [=]() -> bool {
|
||||||
|
text_clear(dialogue);
|
||||||
|
compositor_mark_content_dirty(comp, dialogue_id);
|
||||||
|
return false;
|
||||||
|
} });
|
||||||
|
}
|
||||||
|
|
||||||
static void cmd_wait_click(Script& s, Interpreter& interp)
|
static void cmd_wait_click(Script& s, Interpreter& interp)
|
||||||
{
|
{
|
||||||
s.push_back({ "WAIT_CLICK", [&interp]() -> bool {
|
s.push_back({ "WAIT_CLICK", [&interp]() -> bool {
|
||||||
@@ -302,6 +312,8 @@ static void cmd_end(Script& s, Interpreter& interp)
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
const int WIDTH = 1280;
|
const int WIDTH = 1280;
|
||||||
const int HEIGHT = 720;
|
const int HEIGHT = 720;
|
||||||
const int CHAR_WIDTH = 400;
|
const int CHAR_WIDTH = 400;
|
||||||
@@ -327,9 +339,26 @@ int main() {
|
|||||||
|
|
||||||
audio_set_global_volume(audio, 1.0f);
|
audio_set_global_volume(audio, 1.0f);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* title;
|
||||||
|
const char* composer;
|
||||||
|
const char* file;
|
||||||
|
} music_track_t;
|
||||||
|
|
||||||
|
static const music_track_t strauss_tracks[] = {
|
||||||
|
{"Freikugeln", "Johann Strauss II", "assets/Freikugeln.wav"},
|
||||||
|
{"Perpetuum Mobile", "Johann Strauss II", "assets/Perpetuum_Mobile.wav"},
|
||||||
|
{"Ohne Sorgen!", "Josef Strauss", "assets/Ohne_Sorgen!.wav"},
|
||||||
|
{"Auf Ferienreisen", "Josef Strauss", "assets/Auf_Ferienreisen.wav"},
|
||||||
|
{"Dynamiden", "Josef Strauss", "assets/Dynamiden.wav"}
|
||||||
|
};
|
||||||
|
|
||||||
|
int track_idx = rand() % (sizeof(strauss_tracks) / sizeof(strauss_tracks[0]));
|
||||||
|
const music_track_t* track = &strauss_tracks[track_idx];
|
||||||
|
|
||||||
int music_size, music_channels, music_rate, music_total_samples;
|
int music_size, music_channels, music_rate, music_total_samples;
|
||||||
AudioDataHandle music_data(audio_load_madpcm(
|
AudioDataHandle music_data(audio_load_madpcm(
|
||||||
"assets/Freikugeln.wav",
|
track->file,
|
||||||
&music_size, &music_channels, &music_rate, &music_total_samples));
|
&music_size, &music_channels, &music_rate, &music_total_samples));
|
||||||
if (!music_data) { printf("Failed to load audio\n"); return 1; }
|
if (!music_data) { printf("Failed to load audio\n"); return 1; }
|
||||||
|
|
||||||
@@ -415,6 +444,7 @@ int main() {
|
|||||||
auto line = [&](const char* text, float speed = 30.0f) {
|
auto line = [&](const char* text, float speed = 30.0f) {
|
||||||
cmd_line(S, dlg, dlg_id, comp, text, speed);
|
cmd_line(S, dlg, dlg_id, comp, text, speed);
|
||||||
};
|
};
|
||||||
|
auto clear = [&]() { cmd_clear(S, dlg, dlg_id, comp); };
|
||||||
auto wait_click = [&]() { cmd_wait_click(S, interp); };
|
auto wait_click = [&]() { cmd_wait_click(S, interp); };
|
||||||
auto wait_anim_all = [&]() { cmd_wait_anim_all(S, interp); };
|
auto wait_anim_all = [&]() { cmd_wait_anim_all(S, interp); };
|
||||||
auto wait_anim = [&](element_handle_t e) { cmd_wait_anim_elem(S, interp, e); };
|
auto wait_anim = [&](element_handle_t e) { cmd_wait_anim_elem(S, interp, e); };
|
||||||
@@ -440,9 +470,6 @@ int main() {
|
|||||||
// Scene 1 - maksw slides in, introduces the engine
|
// Scene 1 - maksw slides in, introduces the engine
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
// Slide maksw_happy in from off-screen, bob on arrival, scale up as
|
|
||||||
// "active speaker". No WAIT_ANIM here - dialogue starts immediately
|
|
||||||
// and the animation plays alongside the typewriter, which feels natural.
|
|
||||||
anim_move(maksw_happy_id, CENTER_X, CHAR_BASELINE_Y,
|
anim_move(maksw_happy_id, CENTER_X, CHAR_BASELINE_Y,
|
||||||
1.5f, EASE_OUT_CUBIC, true);
|
1.5f, EASE_OUT_CUBIC, true);
|
||||||
anim_scale(maksw_happy_id, 1.1f, 0.3f, EASE_IN_OUT_CUBIC, /*queue=*/true, /*parallel=*/false);
|
anim_scale(maksw_happy_id, 1.1f, 0.3f, EASE_IN_OUT_CUBIC, /*queue=*/true, /*parallel=*/false);
|
||||||
@@ -463,10 +490,25 @@ int main() {
|
|||||||
line("Yeah, hello to you too.");
|
line("Yeah, hello to you too.");
|
||||||
wait_click();
|
wait_click();
|
||||||
|
|
||||||
|
const char* greetings[] = {
|
||||||
|
"Oh Wiktor, what a nice surprise!",
|
||||||
|
"Oh hey Wiktor, didn't expect to see you!",
|
||||||
|
"Wiktor! What brings you here?"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* responses[] = {
|
||||||
|
"No, I was just walking by.",
|
||||||
|
"Nah, just passing through.",
|
||||||
|
"Not really, just wandering."
|
||||||
|
};
|
||||||
|
|
||||||
|
int greeting_idx = rand() % 3;
|
||||||
|
int response_idx = rand() % 3;
|
||||||
|
|
||||||
anim_scale(wikor_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
|
anim_scale(wikor_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
|
||||||
anim_scale(maksw_happy_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
|
anim_scale(maksw_happy_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
|
||||||
speaker("maksw");
|
speaker("maksw");
|
||||||
line("Oh Wiktor, what a nice surprise!");
|
line(greetings[greeting_idx]);
|
||||||
wait_click();
|
wait_click();
|
||||||
|
|
||||||
line("...Do you need anything?");
|
line("...Do you need anything?");
|
||||||
@@ -475,48 +517,28 @@ int main() {
|
|||||||
anim_scale(maksw_happy_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
|
anim_scale(maksw_happy_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
|
||||||
anim_scale(wikor_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
|
anim_scale(wikor_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
|
||||||
speaker("wikor");
|
speaker("wikor");
|
||||||
line("No, I was just walking by.");
|
line(responses[response_idx]);
|
||||||
wait_click();
|
wait_click();
|
||||||
|
|
||||||
line("Cool engine though.");
|
line("Cool engine though.");
|
||||||
wait_click();
|
wait_click();
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
// Transition - wipe in, swap scene, wipe out
|
|
||||||
//
|
|
||||||
// Phase 1: mask slides down from above to cover the screen.
|
|
||||||
// We WAIT on that specific element so we know exactly when
|
|
||||||
// the screen is fully hidden - no guessing, no hack cases.
|
|
||||||
//
|
|
||||||
// Phase 2: while hidden, swap sprites and set up the new scene state.
|
|
||||||
// All of this is instant (no animation), which is fine because
|
|
||||||
// the mask is covering everything.
|
|
||||||
//
|
|
||||||
// Phase 3: hide mask, show mask2 (already covering screen at y=0),
|
|
||||||
// slide mask2 downward to reveal the new scene.
|
|
||||||
// We don't WAIT here - dialogue runs alongside the wipe-out,
|
|
||||||
// which looks intentional and cinematic.
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Phase 1 - cover
|
|
||||||
finish_all();
|
finish_all();
|
||||||
show(mask_id);
|
show(mask_id);
|
||||||
anim_move(mask_id, 0, 0, 0.5f, EASE_OUT_CUBIC);
|
anim_move(mask_id, 0, 0, 0.5f, EASE_OUT_CUBIC);
|
||||||
wait_anim(mask_id); // block until mask fully covers the screen
|
wait_anim(mask_id);
|
||||||
|
|
||||||
// Phase 2 - swap (mask is covering, player sees nothing)
|
|
||||||
hide(maksw_happy_id);
|
hide(maksw_happy_id);
|
||||||
show(maksw_neutral_id);
|
show(maksw_neutral_id);
|
||||||
scale(maksw_neutral_id, 1.0f);
|
scale(maksw_neutral_id, 1.0f);
|
||||||
scale(wikor_id, 1.05f);
|
scale(wikor_id, 1.05f);
|
||||||
|
|
||||||
// Phase 3 - uncover
|
|
||||||
hide(mask_id);
|
hide(mask_id);
|
||||||
show(mask2_id);
|
show(mask2_id);
|
||||||
// mask2 starts at y=0 (covering screen), animate it off downward
|
|
||||||
anim_move(mask2_id, 0, HEIGHT, 0.5f, EASE_OUT_CUBIC);
|
anim_move(mask2_id, 0, HEIGHT, 0.5f, EASE_OUT_CUBIC);
|
||||||
// Dialogue fires immediately - text appears as the wipe reveals the scene
|
|
||||||
speaker("wikor");
|
speaker("wikor");
|
||||||
|
clear();
|
||||||
|
wait_anim(mask2_id);
|
||||||
line("Anyways, how's your day going?");
|
line("Anyways, how's your day going?");
|
||||||
wait_click();
|
wait_click();
|
||||||
|
|
||||||
@@ -542,7 +564,10 @@ int main() {
|
|||||||
anim_scale(wikor_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
|
anim_scale(wikor_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
|
||||||
anim_scale(maksw_neutral_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
|
anim_scale(maksw_neutral_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
|
||||||
speaker("maksw");
|
speaker("maksw");
|
||||||
line("Yep! Freikugeln by Johann Strauss II!");
|
char music_line[256];
|
||||||
|
snprintf(music_line, sizeof(music_line),
|
||||||
|
"Yep! %s by %s!", track->title, track->composer);
|
||||||
|
line(music_line);
|
||||||
wait_click();
|
wait_click();
|
||||||
|
|
||||||
finish_all();
|
finish_all();
|
||||||
|
|||||||
Reference in new issue
Block a user