diff --git a/src/main.cpp b/src/main.cpp index 8e3d213..4fa803e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -120,6 +120,54 @@ struct Scene { } }; +constexpr Command Show(const char* character, const char* sprite, int x, int y, int z, + TransitionType trans = TRANS_NONE, float duration = 0.0f, bool blocking = true) +{ + return Command{ + .type = CMD_SHOW, + .blocking = blocking, + .show = CmdShow{character, sprite, x, y, z, trans, duration} + }; +} + +constexpr Command Hide(const char* character, TransitionType trans = TRANS_NONE, float duration = 0.0f, bool blocking = true) +{ + return Command{ + .type = CMD_HIDE, + .blocking = blocking, + .hide = CmdHide{character, trans, duration} + }; +} + +constexpr Command Speak(const char* speaker, const char* text, float text_speed = 30.0f, bool blocking = true) +{ + return Command{ + .type = CMD_SPEAK, + .blocking = blocking, + .speak = CmdSpeak{speaker, text, text_speed} + }; +} + +constexpr Command Wait(bool blocking = true) +{ + return Command{ .type = CMD_WAIT, .blocking = blocking, .wait = {} }; +} + +constexpr Command Clear(bool blocking = true) +{ + return Command{ .type = CMD_CLEAR, .blocking = blocking, .clear = {} }; +} + +constexpr Command SetZ(const char* character, int z, bool blocking = false) +{ + return Command{ .type = CMD_SET_Z, .blocking = blocking, .set_z = CmdSetZ{character, z} }; +} + +constexpr Command SetScale(const char* character, float scale, TransitionType trans = TRANS_NONE, float duration = 0.0f, bool blocking = false) +{ + return Command{ .type = CMD_SET_SCALE, .blocking = blocking, .set_scale = CmdSetScale{character, scale, trans, duration} }; +} + // ============================================================================ // ANIMATION TRACKER // ============================================================================ @@ -532,29 +580,154 @@ int main() { // --- Scene Script --- Command scene_commands[] = { - {.type = CMD_SHOW, .blocking = false, .show = {.character = "maksw", .sprite = "neutral", .x = 100, .y = POS_Y, .z = 2, .transition = TRANS_SLIDE_LEFT, .duration_ms = 500.0f } }, - {.type = CMD_SHOW, .blocking = true, .show = {.character = "wikor", .sprite = "neutral", .x = 800, .y = POS_Y, .z = 1, .transition = TRANS_SLIDE_RIGHT, .duration_ms = 500.0f } }, + // entrances + Show("maksw", "neutral", 100, POS_Y, 2, TRANS_SLIDE_LEFT, 500.0f, false), + Show("wikor", "neutral", 800, POS_Y, 1, TRANS_SLIDE_RIGHT, 500.0f, true), - {.type = CMD_SPEAK, .blocking = true, .speak = {.speaker = "Maksw", .text = "Wow, it's been a really long week, hasn't it? The sky looks different today.", .text_speed = 30.0f } }, - {.type = CMD_SPEAK, .blocking = true, .speak = {.speaker = "", .text = "\nline 2", .text_speed = 0.0f } }, - {.type = CMD_WAIT, .blocking = true, .wait = {} }, - {.type = CMD_CLEAR, .blocking = true, .clear = {} }, + // wilczur starts (maksw) + SetScale("maksw", 1.05f, TRANS_FADE, 200.0f), + SetZ("maksw", 3), + SetScale("wikor", 1.0f, TRANS_FADE, 200.0f), + SetZ("wikor", 1), - {.type = CMD_SPEAK, .blocking = true, .speak = {.speaker = "Maksw", .text = "I mean, just look at how the clouds are stretching all the way to the horizon. Feels almost cinematic.", .text_speed = 30.0f } }, - {.type = CMD_WAIT, .blocking = true, .wait = {} }, - {.type = CMD_CLEAR, .blocking = true, .clear = {} }, + Speak(u8"wilczur", u8"Long day, huh? Feels like we ran a marathon we didn't sign up for."), + Wait(), + Clear(), - {.type = CMD_SET_SCALE, .blocking = false, .set_scale = {.character = "maksw", .scale = 1.0f, .transition = TRANS_FADE, .duration_ms = 200.0f } }, - {.type = CMD_SET_Z, .blocking = false, .set_z = {.character = "maksw", .z = 1 } }, - {.type = CMD_SET_Z, .blocking = false, .set_z = {.character = "wikor", .z = 3 } }, - {.type = CMD_SET_SCALE, .blocking = false, .set_scale = {.character = "wikor", .scale = 1.05f, .transition = TRANS_FADE, .duration_ms = 200.0f } }, + Speak(u8"wilczur", u8"I thought the report would close this morning. Guess not."), + Wait(), + Clear(), - {.type = CMD_SPEAK, .blocking = true, .speak = {.speaker = u8"admirał wiktorov", .text = "I see what you mean. It's almost like the clouds are in slow motion today. Peaceful, but a bit eerie too.", .text_speed = 30.0f } }, - {.type = CMD_WAIT, .blocking = true, .wait = {} }, - {.type = CMD_CLEAR, .blocking = true, .clear = {} }, + // wiktor responds (wikor) + SetScale("wikor", 1.05f, TRANS_FADE, 200.0f), + SetZ("wikor", 3), + SetScale("maksw", 1.0f, TRANS_FADE, 200.0f), + SetZ("maksw", 1), - {.type = CMD_HIDE, .blocking = false, .hide = {.character = "maksw", .transition = TRANS_FADE, .duration_ms = 500.0f } }, - {.type = CMD_HIDE, .blocking = true, .hide = {.character = "wikor", .transition = TRANS_FADE, .duration_ms = 500.0f } }, + Speak(u8"admirał wiktorov", u8"You always underestimate bureaucracy's appetite for time."), + Wait(), + Clear(), + + Speak(u8"admirał wiktorov", u8"It eats minutes like some folks eat sweets."), + Wait(), + Clear(), + + // narrator (reset both scales) + //SetScale("maksw", 1.0f, TRANS_FADE, 150.0f), + //SetZ("maksw", 1), + SetScale("wikor", 1.0f, TRANS_FADE, 150.0f), + SetZ("wikor", 1), + + Speak(u8"", u8"The lights in the corridor hummed, steady and indifferent."), + Wait(), + Clear(), + + // wilczur again + SetScale("maksw", 1.05f, TRANS_FADE, 200.0f), + SetZ("maksw", 3), + //SetScale("wikor", 1.0f, TRANS_FADE, 200.0f), + //SetZ("wikor", 1), + + Speak(u8"wilczur", u8"I keep telling myself 'five minutes' and then three episodes later it's midnight."), + Wait(), + Clear(), + + Speak(u8"wilczur", u8"Maybe I'm cursed to wait in dim rooms forever."), + Wait(), + Clear(), + + // wiktor + SetScale("wikor", 1.05f, TRANS_FADE, 200.0f), + SetZ("wikor", 3), + SetScale("maksw", 1.0f, TRANS_FADE, 200.0f), + SetZ("maksw", 1), + + Speak(u8"admirał wiktorov", u8"Or blessed with patience you haven't earned yet."), + Wait(), + Clear(), + + Speak(u8"admirał wiktorov", u8"Either way, keep the coffee coming and nobody gets dramatic."), + Wait(), + Clear(), + + // narrator + //SetScale("maksw", 1.0f, TRANS_FADE, 150.0f), + //SetZ("maksw", 1), + SetScale("wikor", 1.0f, TRANS_FADE, 150.0f), + SetZ("wikor", 1), + + Speak(u8"", u8"A faint orange band slid behind the clouds like a secret smile."), + Wait(), + Clear(), + + // wilczur + SetScale("maksw", 1.05f, TRANS_FADE, 200.0f), + SetZ("maksw", 3), + //SetScale("wikor", 1.0f, TRANS_FADE, 200.0f), + //SetZ("wikor", 1), + + Speak(u8"wilczur", u8"Did you see that? A flare, or the heavens showing off."), + Wait(), + Clear(), + + Speak(u8"wilczur", u8"If it's a flare, somebody's throwing a party I wasn't invited to."), + Wait(), + Clear(), + + // wiktor + SetScale("wikor", 1.05f, TRANS_FADE, 200.0f), + SetZ("wikor", 3), + SetScale("maksw", 1.0f, TRANS_FADE, 200.0f), + SetZ("maksw", 1), + + Speak(u8"admirał wiktorov", u8"Not every bright thing is celebration. Could be dust, reflection."), + Wait(), + Clear(), + + Speak(u8"admirał wiktorov", u8"But reflection's a good guess — keeps us calmer than panic does."), + Wait(), + Clear(), + + // narrator + //SetScale("maksw", 1.0f, TRANS_FADE, 150.0f), + //SetZ("maksw", 1), + SetScale("wikor", 1.0f, TRANS_FADE, 150.0f), + SetZ("wikor", 1), + + Speak(u8"", u8"The distant rumble that followed was more felt than heard."), + Wait(), + Clear(), + + // final small exchange + SetScale("maksw", 1.05f, TRANS_FADE, 200.0f), + SetZ("maksw", 3), + //SetScale("wikor", 1.0f, TRANS_FADE, 200.0f), + //SetZ("wikor", 1), + + Speak(u8"wilczur", u8"If the sky's putting on a show, at least the scenery's decent."), + Wait(), + Clear(), + + Speak(u8"wilczur", u8"Make a note: next time, bring proper snacks."), + Wait(), + Clear(), + + SetScale("wikor", 1.05f, TRANS_FADE, 200.0f), + SetZ("wikor", 3), + SetScale("maksw", 1.0f, TRANS_FADE, 200.0f), + SetZ("maksw", 1), + + Speak(u8"admirał wiktorov", u8"Noted. I'll smuggle provisions like a cunning admiral."), + Wait(), + Clear(), + + Speak(u8"admirał wiktorov", u8"Till then, keep an eye on the horizon and your soda stash safe."), + Wait(), + Clear(), + + // exits + Hide("maksw", TRANS_FADE, 500.0f, false), + Hide("wikor", TRANS_FADE, 500.0f, true), }; Scene scene = { scene_commands, sizeof(scene_commands) / sizeof(Command), 0 }; @@ -567,10 +740,11 @@ int main() { AnimationTracker anim_tracker; // Track multiple animations auto last_frame_time = std::chrono::high_resolution_clock::now(); + auto last_report_time = last_frame_time; int frame_count = 0; float frame_time_sum = 0.0f; - const int FPS_REPORT_FRAME_COUNT = 60; + const std::chrono::duration REPORT_INTERVAL = std::chrono::seconds(5); while (running) { if (window_pollevent(window)) running = false; @@ -583,14 +757,24 @@ int main() { frame_count++; frame_time_sum += delta_time_sec; - if (frame_count >= FPS_REPORT_FRAME_COUNT) { - float avg_delta_time = frame_time_sum / (float)frame_count; - float fps = 1.0f / avg_delta_time; - printf("FPS: %.2f (over %d frames)\n", fps, FPS_REPORT_FRAME_COUNT); + std::chrono::duration time_since_last_report = current_time - last_report_time; - // Reset counters + if (time_since_last_report >= REPORT_INTERVAL) { + // Only report if at least one frame has passed + if (frame_count > 0) { + float avg_delta_time = frame_time_sum / (float)frame_count; + float fps = 1.0f / avg_delta_time; + + // Calculate the actual duration the FPS was measured over (should be approx 5.0f) + float actual_duration = time_since_last_report.count(); + + printf("FPS: %.2f (over %d frames in %.2f seconds)\n", + fps, frame_count, actual_duration); + } + // Reset counters and update last_report_time frame_count = 0; frame_time_sum = 0.0f; + last_report_time = current_time; // Mark the current time as the new report start } // Update animation tracker