108 lines
2.7 KiB
C++
108 lines
2.7 KiB
C++
|
|
#include "engine/app.h"
|
|||
|
|
|
|||
|
|
#include <raylib.h>
|
|||
|
|
|
|||
|
|
#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);
|
|||
|
|
}
|