#include "engine/app.h" #include #include "engine/config.h" namespace { // Безрамочное окно на весь монитор. Отдельно, потому что порядок здесь важен: // raylib разворачивает окно по ТЕКУЩЕМУ монитору, поэтому сначала размер по // монитору, потом снятие рамки. void GoBorderless() { const int mon = GetCurrentMonitor(); const int w = GetMonitorWidth(mon); const int h = GetMonitorHeight(mon); if (w > 0 && h > 0) SetWindowSize(w, h); ToggleBorderlessWindowed(); } } // namespace bool App::Init(const AppConfig& cfg) { if (cfg.vsync) SetConfigFlags(FLAG_VSYNC_HINT); const int w = (cfg.frameW > 0) ? cfg.frameW : INTERNAL_W; const int h = (cfg.frameH > 0) ? cfg.frameH : INTERNAL_H; InitWindow(w * WINDOW_SCALE, h * WINDOW_SCALE, cfg.title); // Esc не закрывает окно сам. Приложение решает, что он значит: в игре это // пауза, в редакторе — закрыть терминал. Выход по случайному нажатию // посреди вылазки — не то, за что игрок скажет спасибо. SetExitKey(KEY_NULL); if (cfg.borderless) GoBorderless(); fb.Init(w, h); screen.Init(w, h); return IsWindowReady(); } void App::Shutdown() { screen.Shutdown(); CloseWindow(); } bool App::NextFrame() { if (quit || WindowShouldClose()) return false; if (IsKeyPressed(KEY_F11)) ToggleBorderlessWindowed(); winW = GetScreenWidth(); winH = GetScreenHeight(); fit = ScreenFitRect(fb.w, fb.h, winW, winH); frameDt = GetFrameTime(); return true; } int App::Advance(bool halted) { if (halted) { accumulator = 0.0; return 0; } accumulator += double(frameDt); int steps = 0; while (accumulator >= FIXED_DT && steps < MAX_STEPS_PER_FRAME) { accumulator -= FIXED_DT; ++steps; } // Не успели за кадр — остаток выбрасывается целиком. Копить его значит // копить долг, который никогда не отдать: следующий кадр будет таким же. if (accumulator > FIXED_DT * MAX_STEPS_PER_FRAME) accumulator = 0.0; return steps; } float App::Alpha() const { return float(accumulator / FIXED_DT); } void App::Present() { BeginDrawing(); ClearBackground(BLACK); screen.Present(fb, winW, winH); } void App::Finish() { EndDrawing(); } void App::Screenshot(const char* file) const { if (file) TakeScreenshot(file); }