diff --git a/include/app/application.h b/include/app/application.h index 7f369ac..3b202d2 100644 --- a/include/app/application.h +++ b/include/app/application.h @@ -5,15 +5,6 @@ namespace extra2d { -/** - * @brief 平台类型枚举 - */ -enum class PlatformType { - Auto = 0, - PC, - Switch -}; - /** * @brief 应用程序配置 */ @@ -27,7 +18,6 @@ struct AppConfig { int32 fpsLimit = 0; int32 glMajor = 3; int32 glMinor = 3; - PlatformType platform = PlatformType::Auto; bool enableCursors = true; bool enableDpiScale = false; }; diff --git a/src/app/application.cpp b/src/app/application.cpp index ad0e8ba..fa5c26c 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -1,11 +1,11 @@ #include #include -#include #include +#include +#include +#include #include #include -#include -#include #include #include @@ -22,222 +22,200 @@ namespace extra2d { */ static double getTimeSeconds() { #ifdef __SWITCH__ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return static_cast(ts.tv_sec) + static_cast(ts.tv_nsec) / 1000000000.0; + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return static_cast(ts.tv_sec) + + static_cast(ts.tv_nsec) / 1000000000.0; #else - using namespace std::chrono; - auto now = steady_clock::now(); - auto duration = now.time_since_epoch(); - return duration_cast>(duration).count(); + using namespace std::chrono; + auto now = steady_clock::now(); + auto duration = now.time_since_epoch(); + return duration_cast>(duration).count(); #endif } -Application& Application::instance() { - static Application instance; - return instance; +Application &Application::instance() { + static Application instance; + return instance; } -Application::~Application() { - shutdown(); -} +Application::~Application() { shutdown(); } -bool Application::init(const AppConfig& config) { - if (initialized_) { - E2D_LOG_WARN("Application already initialized"); - return true; - } - - config_ = config; - - PlatformType platform = config_.platform; - if (platform == PlatformType::Auto) { -#ifdef __SWITCH__ - platform = PlatformType::Switch; -#else - platform = PlatformType::PC; -#endif - } - - if (platform == PlatformType::Switch) { -#ifdef __SWITCH__ - Result rc; - rc = romfsInit(); - if (R_SUCCEEDED(rc)) { - E2D_LOG_INFO("RomFS initialized successfully"); - } else { - E2D_LOG_WARN("romfsInit failed: {:#08X}", rc); - } - - rc = socketInitializeDefault(); - if (R_FAILED(rc)) { - E2D_LOG_WARN("socketInitializeDefault failed"); - } -#endif - } - - if (!Sdl2::initAll()) { - E2D_LOG_ERROR("Failed to initialize SDL2"); - return false; - } - - SVC_MGR.reg(&WINDOW); - SVC_MGR.reg(&INPUT_SVC); - SVC_MGR.reg(&FILE_SVC); - - if (!SVC_MGR.initAll()) { - E2D_LOG_ERROR("Failed to initialize services"); - return false; - } - - WindowCfg winCfg; - winCfg.title = config_.title; - winCfg.width = config_.width; - winCfg.height = config_.height; - winCfg.fullscreen = config_.fullscreen; - winCfg.resizable = config_.resizable; - winCfg.vsync = config_.vsync; - winCfg.glMajor = config_.glMajor; - winCfg.glMinor = config_.glMinor; - - if (!WINDOW.create(winCfg)) { - E2D_LOG_ERROR("Failed to create window"); - return false; - } - - if (!DIRECTOR.init()) { - E2D_LOG_ERROR("Failed to initialize Director"); - return false; - } - - WINDOW.setOnClose([this]() { - quit(); - }); - - initialized_ = true; - running_ = true; - - events::OnInit::emit(); - - E2D_LOG_INFO("Application initialized successfully"); - E2D_LOG_INFO("Window: {}x{}, Fullscreen: {}, VSync: {}", - config_.width, config_.height, config_.fullscreen, config_.vsync); +bool Application::init(const AppConfig &config) { + if (initialized_) { + E2D_LOG_WARN("Application already initialized"); return true; + } + + config_ = config; + +#ifdef __SWITCH__ + Result rc; + rc = romfsInit(); + if (R_SUCCEEDED(rc)) { + E2D_LOG_INFO("RomFS initialized successfully"); + } else { + E2D_LOG_WARN("romfsInit failed: {:#08X}", rc); + } + + rc = socketInitializeDefault(); + if (R_FAILED(rc)) { + E2D_LOG_WARN("socketInitializeDefault failed"); + } +#endif + + if (!Sdl2::initAll()) { + E2D_LOG_ERROR("Failed to initialize SDL2"); + return false; + } + + SVC_MGR.reg(&WINDOW); + SVC_MGR.reg(&INPUT_SVC); + SVC_MGR.reg(&FILE_SVC); + + if (!SVC_MGR.initAll()) { + E2D_LOG_ERROR("Failed to initialize services"); + return false; + } + + if (!WINDOW.create([&] { + WindowCfg cfg; + cfg.title = config_.title; + cfg.width = config_.width; + cfg.height = config_.height; + cfg.fullscreen = config_.fullscreen; + cfg.resizable = config_.resizable; + cfg.vsync = config_.vsync; + cfg.glMajor = config_.glMajor; + cfg.glMinor = config_.glMinor; + return cfg; + }())) { + E2D_LOG_ERROR("Failed to create window"); + return false; + } + + if (!DIRECTOR.init()) { + E2D_LOG_ERROR("Failed to initialize Director"); + return false; + } + + WINDOW.setOnClose([this]() { quit(); }); + + initialized_ = true; + running_ = true; + + events::OnInit::emit(); + + E2D_LOG_INFO("Application initialized successfully"); + E2D_LOG_INFO("Window: {}x{}, Fullscreen: {}, VSync: {}", config_.width, + config_.height, config_.fullscreen, config_.vsync); + return true; } void Application::shutdown() { - if (!initialized_) return; + if (!initialized_) + return; - events::OnShutdown::emit(); + events::OnShutdown::emit(); - E2D_LOG_INFO("Shutting down application..."); + E2D_LOG_INFO("Shutting down application..."); - DIRECTOR.shutdown(); - SVC_MGR.shutdownAll(); - Sdl2::shutdown(); + DIRECTOR.shutdown(); + SVC_MGR.shutdownAll(); + Sdl2::shutdown(); - PlatformType platform = config_.platform; - if (platform == PlatformType::Auto) { #ifdef __SWITCH__ - platform = PlatformType::Switch; -#else - platform = PlatformType::PC; + romfsExit(); + socketExit(); #endif - } - if (platform == PlatformType::Switch) { -#ifdef __SWITCH__ - romfsExit(); - socketExit(); -#endif - } + initialized_ = false; + running_ = false; - initialized_ = false; - running_ = false; - - E2D_LOG_INFO("Application shutdown complete"); + E2D_LOG_INFO("Application shutdown complete"); } void Application::run() { - if (!initialized_) { - E2D_LOG_ERROR("Application not initialized"); - return; - } + if (!initialized_) { + E2D_LOG_ERROR("Application not initialized"); + return; + } - lastFrameTime_ = getTimeSeconds(); + lastFrameTime_ = getTimeSeconds(); - while (running_ && !WINDOW.shouldClose()) { - mainLoop(); - } + while (running_ && !WINDOW.shouldClose()) { + mainLoop(); + } } void Application::quit() { - shouldQuit_ = true; - running_ = false; - WINDOW.requestClose(); + shouldQuit_ = true; + running_ = false; + WINDOW.requestClose(); } void Application::pause() { - if (!paused_) { - paused_ = true; - SVC_MGR.pauseAll(); - DIRECTOR.pause(); - events::OnPause::emit(); - E2D_LOG_INFO("Application paused"); - } + if (!paused_) { + paused_ = true; + SVC_MGR.pauseAll(); + DIRECTOR.pause(); + events::OnPause::emit(); + E2D_LOG_INFO("Application paused"); + } } void Application::resume() { - if (paused_) { - paused_ = false; - SVC_MGR.resumeAll(); - DIRECTOR.resume(); - lastFrameTime_ = getTimeSeconds(); - events::OnResume::emit(); - E2D_LOG_INFO("Application resumed"); - } + if (paused_) { + paused_ = false; + SVC_MGR.resumeAll(); + DIRECTOR.resume(); + lastFrameTime_ = getTimeSeconds(); + events::OnResume::emit(); + E2D_LOG_INFO("Application resumed"); + } } void Application::mainLoop() { - if (!WINDOW.pollEvents()) { - running_ = false; - return; - } - - double currentTime = getTimeSeconds(); - deltaTime_ = static_cast(currentTime - lastFrameTime_); - lastFrameTime_ = currentTime; - - totalTime_ += deltaTime_; - - frameCount_++; - fpsTimer_ += deltaTime_; - if (fpsTimer_ >= 1.0f) { - currentFps_ = frameCount_; - frameCount_ = 0; - fpsTimer_ -= 1.0f; - } - - if (!paused_) { - update(); - } - - WINDOW.swapBuffers(); - - if (!config_.vsync && config_.fpsLimit > 0) { - double frameEndTime = getTimeSeconds(); - double frameTime = frameEndTime - currentTime; - double target = 1.0 / static_cast(config_.fpsLimit); - if (frameTime < target) { - std::this_thread::sleep_for(std::chrono::duration(target - frameTime)); - } + if (!WINDOW.pollEvents()) { + running_ = false; + return; + } + + double currentTime = getTimeSeconds(); + deltaTime_ = static_cast(currentTime - lastFrameTime_); + lastFrameTime_ = currentTime; + + totalTime_ += deltaTime_; + + frameCount_++; + fpsTimer_ += deltaTime_; + if (fpsTimer_ >= 1.0f) { + currentFps_ = frameCount_; + frameCount_ = 0; + fpsTimer_ -= 1.0f; + } + + if (!paused_) { + update(); + } + + WINDOW.swapBuffers(); + + if (!config_.vsync && config_.fpsLimit > 0) { + double frameEndTime = getTimeSeconds(); + double frameTime = frameEndTime - currentTime; + double target = 1.0 / static_cast(config_.fpsLimit); + if (frameTime < target) { + std::this_thread::sleep_for( + std::chrono::duration(target - frameTime)); } + } } void Application::update() { - SVC_MGR.updateAll(deltaTime_); - events::OnUpdate::emit(deltaTime_); - DIRECTOR.mainLoop(deltaTime_); + SVC_MGR.updateAll(deltaTime_); + events::OnUpdate::emit(deltaTime_); + DIRECTOR.mainLoop(deltaTime_); } } // namespace extra2d diff --git a/src/platform/window.cpp b/src/platform/window.cpp index 80a70e9..126ea50 100644 --- a/src/platform/window.cpp +++ b/src/platform/window.cpp @@ -1,177 +1,178 @@ -#include +#include #include #include -#include +#include namespace extra2d { -WindowSvc& WindowSvc::inst() { - static WindowSvc instance; - return instance; +WindowSvc &WindowSvc::inst() { + static WindowSvc instance; + return instance; } bool WindowSvc::init() { - if (isInited()) return true; - - if (!Sdl2::initVideo()) { - return false; - } - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - - state_ = SvcState::Inited; + if (isInited()) return true; + + if (!Sdl2::initVideo()) { + return false; + } + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + + state_ = SvcState::Inited; + return true; } void WindowSvc::shutdown() { - if (glCtx_) { - SDL_GL_DeleteContext(glCtx_); - glCtx_ = nullptr; - } - if (window_) { - SDL_DestroyWindow(window_); - window_ = nullptr; - } - state_ = SvcState::Shutdown; + if (glCtx_) { + SDL_GL_DeleteContext(glCtx_); + glCtx_ = nullptr; + } + if (window_) { + SDL_DestroyWindow(window_); + window_ = nullptr; + } + state_ = SvcState::Shutdown; } -bool WindowSvc::create(const WindowCfg& cfg) { - if (window_) return true; - - uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; - if (cfg.resizable) { - flags |= SDL_WINDOW_RESIZABLE; - } - if (cfg.fullscreen) { - flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - } - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, cfg.glMajor); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, cfg.glMinor); - - window_ = SDL_CreateWindow( - cfg.title.c_str(), - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - cfg.width, - cfg.height, - flags - ); - - if (!window_) { - return false; - } - - glCtx_ = SDL_GL_CreateContext(window_); - if (!glCtx_) { - SDL_DestroyWindow(window_); - window_ = nullptr; - return false; - } - - setVsync(cfg.vsync); - vsync_ = cfg.vsync; - +bool WindowSvc::create(const WindowCfg &cfg) { + if (window_) return true; + + uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; + if (cfg.resizable) { + flags |= SDL_WINDOW_RESIZABLE; + } + if (cfg.fullscreen) { + flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + } + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, cfg.glMajor); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, cfg.glMinor); + + window_ = + SDL_CreateWindow(cfg.title.c_str(), SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, cfg.width, cfg.height, flags); + + if (!window_) { + return false; + } + + glCtx_ = SDL_GL_CreateContext(window_); + if (!glCtx_) { + SDL_DestroyWindow(window_); + window_ = nullptr; + return false; + } + + setVsync(cfg.vsync); + vsync_ = cfg.vsync; + + return true; } bool WindowSvc::pollEvents() { - SDL_Event evt; - while (SDL_PollEvent(&evt)) { - switch (evt.type) { - case SDL_QUIT: - shouldClose_ = true; - if (onClose_) onClose_(); - break; - case SDL_WINDOWEVENT: - if (evt.window.event == SDL_WINDOWEVENT_RESIZED) { - if (onResize_) { - onResize_(evt.window.data1, evt.window.data2); - } - } - break; - default: - if (INPUT_SVC.isInited()) { - INPUT_SVC.processEvent(evt); - } - break; + SDL_Event evt; + while (SDL_PollEvent(&evt)) { + switch (evt.type) { + case SDL_QUIT: + shouldClose_ = true; + if (onClose_) + onClose_(); + break; + case SDL_WINDOWEVENT: + if (evt.window.event == SDL_WINDOWEVENT_RESIZED) { + if (onResize_) { + onResize_(evt.window.data1, evt.window.data2); } + } + break; + default: + if (INPUT_SVC.isInited()) { + INPUT_SVC.processEvent(evt); + } + break; } - return !shouldClose_; + } + return !shouldClose_; } void WindowSvc::swapBuffers() { - if (window_ && glCtx_) { - SDL_GL_SwapWindow(window_); - } + if (window_ && glCtx_) { + SDL_GL_SwapWindow(window_); + } } Size WindowSvc::getSize() const { - if (!window_) return Size(0, 0); - int w, h; - SDL_GetWindowSize(window_, &w, &h); - return Size(w, h); + if (!window_) + return Size(0, 0); + int w, h; + SDL_GetWindowSize(window_, &w, &h); + return Size(w, h); } Vec2 WindowSvc::getPosition() const { - if (!window_) return Vec2(0, 0); - int x, y; - SDL_GetWindowPosition(window_, &x, &y); - return Vec2(static_cast(x), static_cast(y)); + if (!window_) + return Vec2(0, 0); + int x, y; + SDL_GetWindowPosition(window_, &x, &y); + return Vec2(static_cast(x), static_cast(y)); } void WindowSvc::setSize(int32 w, int32 h) { - if (window_) { - SDL_SetWindowSize(window_, w, h); - } + if (window_) { + SDL_SetWindowSize(window_, w, h); + } } -void WindowSvc::setTitle(const std::string& title) { - if (window_) { - SDL_SetWindowTitle(window_, title.c_str()); - } +void WindowSvc::setTitle(const std::string &title) { + if (window_) { + SDL_SetWindowTitle(window_, title.c_str()); + } } void WindowSvc::setFullscreen(bool fullscreen) { - if (window_) { - SDL_SetWindowFullscreen(window_, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - } + if (window_) { + SDL_SetWindowFullscreen(window_, + fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + } } bool WindowSvc::isFullscreen() const { - if (!window_) return false; - uint32 flags = SDL_GetWindowFlags(window_); - return (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; + if (!window_) + return false; + uint32 flags = SDL_GetWindowFlags(window_); + return (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; } void WindowSvc::setVsync(bool vsync) { - SDL_GL_SetSwapInterval(vsync ? 1 : 0); - vsync_ = vsync; + SDL_GL_SetSwapInterval(vsync ? 1 : 0); + vsync_ = vsync; } -bool WindowSvc::isVsync() const { - return vsync_; -} +bool WindowSvc::isVsync() const { return vsync_; } void WindowSvc::setVisible(bool visible) { - if (window_) { - if (visible) { - SDL_ShowWindow(window_); - } else { - SDL_HideWindow(window_); - } + if (window_) { + if (visible) { + SDL_ShowWindow(window_); + } else { + SDL_HideWindow(window_); } + } } bool WindowSvc::isVisible() const { - if (!window_) return false; - uint32 flags = SDL_GetWindowFlags(window_); - return (flags & SDL_WINDOW_SHOWN) != 0; + if (!window_) + return false; + uint32 flags = SDL_GetWindowFlags(window_); + return (flags & SDL_WINDOW_SHOWN) != 0; } } // namespace extra2d