Files
IMX6U-Game/src/Apps/Desktop/Main.cpp
T
2026-07-08 15:55:13 +08:00

151 lines
3.5 KiB
C++

#include <chrono>
#include <cstdint>
#include <iostream>
#include <thread>
#include "DefaultHardware.h"
#include "DrawContext.h"
#include "IDisplay.h"
#include "TimeSource.h"
#include "Timer.h"
#include "app/DesktopApp.h"
#include "ui/GameLauncher.h"
#ifdef TARGET_IMX
#include "FBDisplay.h"
#endif
#ifdef TARGET_PC
#include "SDLDisplay.h"
#endif
namespace
{
const int32_t ScreenWidth = 1024;
const int32_t ScreenHeight = 600;
const int32_t RestoreRetryCount = 5;
const uint32_t RestoreRetryDelayMs = 300;
static Platform::IDisplay* CreateDisplay()
{
#ifdef TARGET_IMX
return new Platform::FBDisplay();
#endif
#ifdef TARGET_PC
return new Platform::SDLDisplay();
#endif
}
static void SleepRemainingFrameTime(const Core::Timer& timer, const Platform::ITimeSource& timeSource)
{
const uint32_t sleepMs = timer.remaining_frame_ms(timeSource.get_time_ms());
if (sleepMs > 0u)
{
std::this_thread::sleep_for(std::chrono::milliseconds(sleepMs));
}
}
static bool RestoreDesktopHardware(
Platform::IDisplay* display,
Platform::DefaultPointerInput& pointerInput)
{
for (int32_t attempt = 1; attempt <= RestoreRetryCount; ++attempt)
{
if (display->init(ScreenWidth, ScreenHeight))
{
if (!pointerInput.init("", ScreenWidth, ScreenHeight))
{
std::cerr << "[WARN] Pointer input restore failed; desktop touch is disabled." << std::endl;
}
return true;
}
std::cerr << "[WARN] Failed to restore desktop display, retry "
<< attempt << "/" << RestoreRetryCount << "." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(RestoreRetryDelayMs));
}
std::cerr << "[ERROR] Failed to restore desktop display after retries." << std::endl;
return false;
}
static bool LaunchGameAndRestoreDesktop(
const Desktop::GameEntry& game,
Desktop::GameLauncher& launcher,
Platform::IDisplay* display,
Platform::DefaultPointerInput& pointerInput)
{
pointerInput.shutdown();
display->shutdown();
const bool launched = launcher.launch_and_wait(game);
if (!launched)
{
std::cerr << "[WARN] Game launch failed: " << (game.title ? game.title : "(unnamed)") << std::endl;
}
return RestoreDesktopHardware(display, pointerInput);
}
}
int main(int argc, char* argv[])
{
(void)argc;
(void)argv;
Platform::IDisplay* display = CreateDisplay();
if (!display->init(ScreenWidth, ScreenHeight))
{
delete display;
return -1;
}
Platform::DefaultPointerInput pointerInput;
if (!pointerInput.init("", ScreenWidth, ScreenHeight))
{
std::cerr << "[WARN] Pointer input init failed; desktop touch is disabled." << std::endl;
}
Core::DrawContext ctx(ScreenWidth, ScreenHeight);
Core::Timer timer(30);
Platform::SteadyTimeSource timeSource;
Desktop::DesktopApp app(ScreenWidth, ScreenHeight, &pointerInput);
Desktop::GameLauncher launcher;
std::cout << "[INFO] Desktop started. Target FPS: " << timer.target_fps() << std::endl;
bool isRunning = true;
while (isRunning)
{
timer.begin_frame(timeSource.get_time_ms());
bool shouldQuit = false;
display->poll_events(shouldQuit);
if (shouldQuit)
{
isRunning = false;
}
app.update(timer.fixed_delta_ms());
const Desktop::GameEntry* launchGame = app.consume_pending_launch();
if (launchGame != nullptr)
{
if (!LaunchGameAndRestoreDesktop(*launchGame, launcher, display, pointerInput))
{
isRunning = false;
break;
}
timer.begin_frame(timeSource.get_time_ms());
}
app.draw(ctx);
ctx.present(display);
SleepRemainingFrameTime(timer, timeSource);
}
pointerInput.shutdown();
display->shutdown();
delete display;
return 0;
}