| 894 | } |
| 895 | |
| 896 | void GameApplication::RunMainLoop() |
| 897 | { |
| 898 | // Wait for startup progress script (startup.sqs) to complete. |
| 899 | // Dedicated servers skip this — the dummy engine can't advance the script. |
| 900 | if (!ENGINE_CONFIG.doCreateDedicatedServer) |
| 901 | { |
| 902 | // I_AM_ALIVE() triggers GlobalAliveImplementation::Alive() → ProgressSystem::Refresh() → Draw() → |
| 903 | // ProgressScript->Simulate() |
| 904 | while (Poseidon::ProgressScript) |
| 905 | { |
| 906 | I_AM_ALIVE(); |
| 907 | if (Poseidon::ProgressScript && Poseidon::ProgressScript->IsTerminated()) |
| 908 | { |
| 909 | Poseidon::ProgressScript.Free(); |
| 910 | } |
| 911 | } |
| 912 | } |
| 913 | else if (Poseidon::ProgressScript) |
| 914 | { |
| 915 | Poseidon::ProgressScript.Free(); |
| 916 | } |
| 917 | GWorld->SetTitleEffect(nullptr); |
| 918 | GWorld->SetCutEffect(nullptr); |
| 919 | |
| 920 | // Screenshot mode (menu only, no --test-mission): render a few frames for menu to settle, capture, then exit |
| 921 | const std::string& screenshotPath = AppConfig::Instance().GetScreenshotPath(); |
| 922 | const bool screenshotTestMode = |
| 923 | AppConfig::Instance().IsScreenshotTest() && !AppConfig::Instance().GetTestMissionPath().empty(); |
| 924 | if (!screenshotPath.empty() && !screenshotTestMode) |
| 925 | { |
| 926 | for (int i = 0; i < 5; i++) |
| 927 | { |
| 928 | m_forceRender = true; |
| 929 | Poseidon::AppIdle(); |
| 930 | } |
| 931 | GEngine->Screenshot(screenshotPath.c_str()); |
| 932 | m_forceRender = true; |
| 933 | Poseidon::AppIdle(); // renders frame that captures screenshot before swap |
| 934 | LOG_INFO(Core, "Screenshot saved to: {}", screenshotPath); |
| 935 | _exit(0); |
| 936 | } |
| 937 | |
| 938 | // Screenshot test mode (--test-mission + --test-type screenshot): |
| 939 | // Wait for mission to enter gameplay (GModeArcade), render frames, capture, exit |
| 940 | const int screenshotDelay = AppConfig::Instance().GetScreenshotDelay(); |
| 941 | int screenshotFrameCount = 0; |
| 942 | bool screenshotCaptured = false; |
| 943 | std::string screenshotTestPath; |
| 944 | if (screenshotTestMode) |
| 945 | { |
| 946 | screenshotTestPath = screenshotPath.empty() ? "tmp/test_screenshot.png" : screenshotPath; |
| 947 | std::filesystem::create_directories(std::filesystem::path(screenshotTestPath).parent_path()); |
| 948 | LOG_INFO(Core, "Screenshot test mode: waiting for mission to enter gameplay..."); |
| 949 | } |
| 950 | |
| 951 | #ifdef _WIN32 |
| 952 | const bool benchmarkMode = AppConfig::Instance().BenchmarkMode(); |
| 953 | const int benchmarkMaxFrames = 300; // ~10s at 30fps |
nothing calls this directly
no test coverage detected