diff --git a/assets/Auf_FerienReisen.wav b/assets/Auf_FerienReisen.wav new file mode 100644 index 0000000..67a2938 Binary files /dev/null and b/assets/Auf_FerienReisen.wav differ diff --git a/assets/Dynamiden.wav b/assets/Dynamiden.wav new file mode 100644 index 0000000..8fa8184 Binary files /dev/null and b/assets/Dynamiden.wav differ diff --git a/assets/Freikugeln.wav b/assets/Freikugeln.wav index 55794cf..d01cfc9 100644 Binary files a/assets/Freikugeln.wav and b/assets/Freikugeln.wav differ diff --git a/assets/Ohne_Sorgen!.wav b/assets/Ohne_Sorgen!.wav new file mode 100644 index 0000000..e3c42d9 Binary files /dev/null and b/assets/Ohne_Sorgen!.wav differ diff --git a/assets/Perpetuum_Mobile.wav b/assets/Perpetuum_Mobile.wav new file mode 100644 index 0000000..33c99c3 Binary files /dev/null and b/assets/Perpetuum_Mobile.wav differ diff --git a/src/main.cpp b/src/main.cpp index 0d28b3f..e15a4df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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) { s.push_back({ "WAIT_CLICK", [&interp]() -> bool { @@ -302,6 +312,8 @@ static void cmd_end(Script& s, Interpreter& interp) // --------------------------------------------------------------------------- int main() { + srand((unsigned int)time(NULL)); + const int WIDTH = 1280; const int HEIGHT = 720; const int CHAR_WIDTH = 400; @@ -327,9 +339,26 @@ int main() { 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; AudioDataHandle music_data(audio_load_madpcm( - "assets/Freikugeln.wav", + track->file, &music_size, &music_channels, &music_rate, &music_total_samples)); 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) { 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_anim_all = [&]() { cmd_wait_anim_all(S, interp); }; 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 // ------------------------------------------------------------------ - // 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, 1.5f, EASE_OUT_CUBIC, true); 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."); 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(maksw_happy_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC); speaker("maksw"); - line("Oh Wiktor, what a nice surprise!"); + line(greetings[greeting_idx]); wait_click(); 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(wikor_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC); speaker("wikor"); - line("No, I was just walking by."); + line(responses[response_idx]); wait_click(); line("Cool engine though."); 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(); show(mask_id); 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); show(maksw_neutral_id); scale(maksw_neutral_id, 1.0f); scale(wikor_id, 1.05f); - // Phase 3 - uncover hide(mask_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); - // Dialogue fires immediately - text appears as the wipe reveals the scene speaker("wikor"); + clear(); + wait_anim(mask2_id); line("Anyways, how's your day going?"); wait_click(); @@ -542,7 +564,10 @@ int main() { 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); 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(); finish_all(); @@ -632,4 +657,4 @@ int main() { audio_stop(audio, music_id); return 0; -} \ No newline at end of file +}