diff --git a/Extra2D/include/extra2d/app/application.h b/Extra2D/include/extra2d/app/application.h index cecb694..4724881 100644 --- a/Extra2D/include/extra2d/app/application.h +++ b/Extra2D/include/extra2d/app/application.h @@ -21,16 +21,24 @@ class Camera; // ============================================================================ // Application 配置 // ============================================================================ + +enum class PlatformType { + Auto = 0, + PC, + Switch +}; + struct AppConfig { String title = "Easy2D Application"; int width = 800; int height = 600; bool fullscreen = false; - bool resizable = true; // 窗口是否可调整大小 + bool resizable = true; bool vsync = true; - int fpsLimit = 0; // 0 = 不限制 + int fpsLimit = 0; BackendType renderBackend = BackendType::OpenGL; int msaaSamples = 0; + PlatformType platform = PlatformType::Auto; }; // ============================================================================ diff --git a/Extra2D/include/extra2d/extra2d.h b/Extra2D/include/extra2d/extra2d.h index 4424b26..6cde05b 100644 --- a/Extra2D/include/extra2d/extra2d.h +++ b/Extra2D/include/extra2d/extra2d.h @@ -12,7 +12,6 @@ // Platform #include #include -#include // Graphics #include @@ -96,3 +95,7 @@ // Script #include #include + +#ifdef __SWITCH__ +#include +#endif \ No newline at end of file diff --git a/Extra2D/include/extra2d/platform/file_system.h b/Extra2D/include/extra2d/platform/file_system.h deleted file mode 100644 index 2cc61a9..0000000 --- a/Extra2D/include/extra2d/platform/file_system.h +++ /dev/null @@ -1,166 +0,0 @@ -#pragma once - -/** - * @file file_system.h - * @brief 跨平台文件系统工具 - * - * 提供统一的文件路径处理和文件操作接口 - * 支持平台: Nintendo Switch, Windows, Linux, macOS - */ - -#include -#include -#include - -namespace extra2d { - -// ============================================================================ -// 文件系统工具类 -// ============================================================================ -class FileSystem { -public: - /** - * @brief 获取资源根目录 - * @return 资源根目录路径 - * - * Switch: "romfs:/" - * PC: 可执行文件所在目录 + "/assets/" 或当前工作目录 - */ - static std::string getResourceRoot(); - - /** - * @brief 解析资源路径 - * @param relativePath 相对路径 (例如 "assets/font.ttf") - * @return 完整路径 - * - * Switch: "romfs:/assets/font.ttf" - * PC: "./assets/font.ttf" 或 exe目录/assets/font.ttf - */ - static std::string resolvePath(const std::string& relativePath); - - /** - * @brief 检查文件是否存在 - * @param path 文件路径 - * @return true 如果文件存在 - */ - static bool fileExists(const std::string& path); - - /** - * @brief 检查目录是否存在 - * @param path 目录路径 - * @return true 如果目录存在 - */ - static bool directoryExists(const std::string& path); - - /** - * @brief 获取可执行文件所在目录 - * @return 可执行文件目录路径 - */ - static std::string getExecutableDirectory(); - - /** - * @brief 获取当前工作目录 - * @return 当前工作目录路径 - */ - static std::string getCurrentWorkingDirectory(); - - /** - * @brief 组合路径 - * @param base 基础路径 - * @param relative 相对路径 - * @return 组合后的路径 - */ - static std::string combinePath(const std::string& base, const std::string& relative); - - /** - * @brief 获取文件名(不含路径) - * @param path 完整路径 - * @return 文件名 - */ - static std::string getFileName(const std::string& path); - - /** - * @brief 获取文件扩展名 - * @param path 文件路径 - * @return 扩展名(包含点,例如 ".ttf") - */ - static std::string getFileExtension(const std::string& path); - - /** - * @brief 获取目录名 - * @param path 文件路径 - * @return 目录路径 - */ - static std::string getDirectoryName(const std::string& path); - - /** - * @brief 规范化路径(统一分隔符,去除冗余) - * @param path 原始路径 - * @return 规范化后的路径 - */ - static std::string normalizePath(const std::string& path); - - /** - * @brief 读取文件内容为字符串 - * @param path 文件路径 - * @return 文件内容,失败返回空字符串 - */ - static std::string readFileText(const std::string& path); - - /** - * @brief 读取文件内容为字节数组 - * @param path 文件路径 - * @return 文件内容,失败返回空vector - */ - static std::vector readFileBytes(const std::string& path); - - /** - * @brief 获取文件大小 - * @param path 文件路径 - * @return 文件大小(字节),失败返回 -1 - */ - static int64_t getFileSize(const std::string& path); - - /** - * @brief 创建目录 - * @param path 目录路径 - * @return true 如果成功 - */ - static bool createDirectory(const std::string& path); - - /** - * @brief 创建多级目录 - * @param path 目录路径 - * @return true 如果成功 - */ - static bool createDirectories(const std::string& path); - -private: - // 禁止实例化 - FileSystem() = delete; - ~FileSystem() = delete; -}; - -// ============================================================================ -// 便捷函数 -// ============================================================================ - -/** - * @brief 解析资源路径的便捷函数 - * @param path 相对路径 - * @return 完整路径 - */ -inline std::string resolvePath(const std::string& path) { - return FileSystem::resolvePath(path); -} - -/** - * @brief 检查文件是否存在的便捷函数 - * @param path 文件路径 - * @return true 如果文件存在 - */ -inline bool fileExists(const std::string& path) { - return FileSystem::fileExists(path); -} - -} // namespace extra2d diff --git a/Extra2D/include/extra2d/platform/input.h b/Extra2D/include/extra2d/platform/input.h index e35952a..ff16b13 100644 --- a/Extra2D/include/extra2d/platform/input.h +++ b/Extra2D/include/extra2d/platform/input.h @@ -3,7 +3,6 @@ #include #include #include -#include #include #include diff --git a/Extra2D/include/extra2d/platform/platform_compat.h b/Extra2D/include/extra2d/platform/platform_compat.h deleted file mode 100644 index 6c3703f..0000000 --- a/Extra2D/include/extra2d/platform/platform_compat.h +++ /dev/null @@ -1,263 +0,0 @@ -#pragma once - -/** - * @file platform_compat.h - * @brief 跨平台兼容性头文件 - * - * 提供所有支持平台的兼容性定义和宏 - * 支持平台: Nintendo Switch, Windows, Linux, macOS - */ - -// ============================================================================ -// 平台检测 -// ============================================================================ - -#ifdef __SWITCH__ - // Nintendo Switch 平台 - #define PLATFORM_SWITCH 1 - #define PLATFORM_NAME "Nintendo Switch" - -#elif defined(_WIN32) - // Windows 平台 - #define PLATFORM_PC 1 - #define PLATFORM_WINDOWS 1 - #define PLATFORM_NAME "Windows" - #ifndef NOMINMAX - #define NOMINMAX - #endif - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - // 禁用 SDL 的 main 重定义,使用标准 main 函数 - #define SDL_MAIN_HANDLED - -#elif defined(__linux__) - // Linux 平台 - #define PLATFORM_PC 1 - #define PLATFORM_LINUX 1 - #define PLATFORM_NAME "Linux" - -#elif defined(__APPLE__) && defined(__MACH__) - // macOS 平台 - #define PLATFORM_PC 1 - #define PLATFORM_MACOS 1 - #define PLATFORM_NAME "macOS" - -#else - #error "Unsupported platform" -#endif - -// ============================================================================ -// Nintendo Switch 平台包含 -// ============================================================================ - -#ifdef PLATFORM_SWITCH - -#include -#include -#include -#include -#include -#include -#include - -// RomFS路径前缀 -#define ROMFS_PREFIX "romfs:/" - -// Switch 特定的编译器属性 -#define E2D_LIKELY(x) __builtin_expect(!!(x), 1) -#define E2D_UNLIKELY(x) __builtin_expect(!!(x), 0) - -// Switch 调试输出 -#ifdef E2D_DEBUG - #define E2D_PLATFORM_LOG(fmt, ...) printf("[Extra2D] " fmt "\n", ##__VA_ARGS__) -#else - #define E2D_PLATFORM_LOG(fmt, ...) ((void)0) -#endif - -#endif // PLATFORM_SWITCH - -// ============================================================================ -// PC 平台包含 (Windows/Linux/macOS) -// ============================================================================ - -#ifdef PLATFORM_PC - -#include -#include -#include -#include -#include -#include - -// PC 平台使用标准文件路径 -#define ROMFS_PREFIX "" - -// PC 平台编译器属性 -#if defined(__GNUC__) || defined(__clang__) - #define E2D_LIKELY(x) __builtin_expect(!!(x), 1) - #define E2D_UNLIKELY(x) __builtin_expect(!!(x), 0) -#else - #define E2D_LIKELY(x) (x) - #define E2D_UNLIKELY(x) (x) -#endif - -// PC 调试输出 -#ifdef E2D_DEBUG - #ifdef PLATFORM_WINDOWS - #include - #define E2D_PLATFORM_LOG(fmt, ...) OutputDebugStringA((std::string("[Extra2D] ") + fmt + "\n").c_str()) - #else - #define E2D_PLATFORM_LOG(fmt, ...) printf("[Extra2D] " fmt "\n", ##__VA_ARGS__) - #endif -#else - #define E2D_PLATFORM_LOG(fmt, ...) ((void)0) -#endif - -#endif // PLATFORM_PC - -// ============================================================================ -// 跨平台通用定义 -// ============================================================================ - -namespace extra2d { -namespace platform { - -/** - * @brief 获取当前平台名称 - * @return 平台名称字符串 - */ -inline const char* getPlatformName() { - return PLATFORM_NAME; -} - -/** - * @brief 检查当前是否为 Switch 平台 - * @return true 如果是 Switch 平台 - */ -inline bool isSwitch() { -#ifdef PLATFORM_SWITCH - return true; -#else - return false; -#endif -} - -/** - * @brief 检查当前是否为 PC 平台 - * @return true 如果是 PC 平台 (Windows/Linux/macOS) - */ -inline bool isPC() { -#ifdef PLATFORM_PC - return true; -#else - return false; -#endif -} - -/** - * @brief 检查当前是否为 Windows 平台 - * @return true 如果是 Windows 平台 - */ -inline bool isWindows() { -#ifdef PLATFORM_WINDOWS - return true; -#else - return false; -#endif -} - -/** - * @brief 检查当前是否为 Linux 平台 - * @return true 如果是 Linux 平台 - */ -inline bool isLinux() { -#ifdef PLATFORM_LINUX - return true; -#else - return false; -#endif -} - -/** - * @brief 检查当前是否为 macOS 平台 - * @return true 如果是 macOS 平台 - */ -inline bool isMacOS() { -#ifdef PLATFORM_MACOS - return true; -#else - return false; -#endif -} - -} // namespace platform - -// ============================================================================ -// 文件系统路径工具 -// ============================================================================ - -namespace romfs { - -/** - * @brief RomFS 根路径常量 - */ -#ifdef PLATFORM_SWITCH - static constexpr const char* ROOT = "romfs:/"; -#else - static constexpr const char* ROOT = ""; -#endif - -/** - * @brief 检查文件是否存在 - * @param path 文件路径 - * @return true 如果文件存在 - */ -inline bool fileExists(const char* path) { - struct stat st; - return stat(path, &st) == 0; -} - -/** - * @brief 检查路径是否为 romfs 路径 (Switch) 或普通路径 (PC) - * @param path 文件路径 - * @return true 如果是 romfs 格式路径 - */ -inline bool isRomfsPath(const char* path) { - return path && (strncmp(path, "romfs:/", 7) == 0 || strncmp(path, "romfs:\\", 7) == 0); -} - -/** - * @brief 构建完整路径 - * @param relativePath 相对路径 - * @return 完整路径 (Switch 添加 romfs:/ 前缀,PC 保持原样) - */ -inline std::string makePath(const char* relativePath) { -#ifdef PLATFORM_SWITCH - std::string result = ROOT; - result += relativePath; - return result; -#else - return std::string(relativePath); -#endif -} - -} // namespace romfs - -} // namespace extra2d - -// ============================================================================ -// 向后兼容:保留 switch_compat.h 的宏定义 -// ============================================================================ - -#ifdef PLATFORM_SWITCH - #define IS_SWITCH_PLATFORM 1 - #define SWITCH_ROMFS_PREFIX "romfs:/" - #define SWITCH_LIKELY(x) E2D_LIKELY(x) - #define SWITCH_UNLIKELY(x) E2D_UNLIKELY(x) - #ifdef E2D_DEBUG - #define SWITCH_DEBUG_PRINTF(fmt, ...) E2D_PLATFORM_LOG(fmt, ##__VA_ARGS__) - #else - #define SWITCH_DEBUG_PRINTF(fmt, ...) ((void)0) - #endif -#endif diff --git a/Extra2D/include/extra2d/platform/switch_compat.h b/Extra2D/include/extra2d/platform/switch_compat.h deleted file mode 100644 index 2f559c3..0000000 --- a/Extra2D/include/extra2d/platform/switch_compat.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -/** - * @file switch_compat.h - * @brief Nintendo Switch 兼容性头文件 (已弃用) - * - * @deprecated 请使用 platform_compat.h 替代 - * 此文件保留用于向后兼容 - */ - -// 包含新的跨平台兼容性头文件 -#include "platform_compat.h" - -// 发出弃用警告(仅在非 Switch 平台或调试模式下) -#if !defined(__SWITCH__) && defined(E2D_DEBUG) - #warning "switch_compat.h is deprecated, use platform_compat.h instead" -#endif diff --git a/Extra2D/include/extra2d/platform/window.h b/Extra2D/include/extra2d/platform/window.h index e084e9b..b53b53a 100644 --- a/Extra2D/include/extra2d/platform/window.h +++ b/Extra2D/include/extra2d/platform/window.h @@ -3,7 +3,6 @@ #include #include #include -#include #include #include @@ -21,11 +20,13 @@ struct WindowConfig { String title = "Extra2D Application"; int width = 1280; int height = 720; - bool fullscreen = true; // Switch 始终全屏,PC 可配置 - bool resizable = false; // PC 端可调整大小 + bool fullscreen = true; + bool resizable = false; bool vsync = true; int msaaSamples = 0; - bool centerWindow = true; // PC 端窗口居中 + bool centerWindow = true; + bool enableCursors = true; + bool enableDpiScale = true; }; // ============================================================================ @@ -132,6 +133,7 @@ private: bool focused_; float contentScaleX_; float contentScaleY_; + bool enableDpiScale_; void* userData_; EventQueue* eventQueue_; UniquePtr input_; diff --git a/Extra2D/include/extra2d/resource/resource_manager.h b/Extra2D/include/extra2d/resource/resource_manager.h index 9710ec6..11cf8f9 100644 --- a/Extra2D/include/extra2d/resource/resource_manager.h +++ b/Extra2D/include/extra2d/resource/resource_manager.h @@ -8,7 +8,6 @@ #include #include #include -#include namespace extra2d { @@ -22,27 +21,6 @@ public: // ------------------------------------------------------------------------ static ResourceManager &getInstance(); - // ------------------------------------------------------------------------ - // 搜索路径管理 - // ------------------------------------------------------------------------ - - /// 添加资源搜索路径 - void addSearchPath(const std::string &path); - - /// 移除资源搜索路径 - void removeSearchPath(const std::string &path); - - /// 清空所有搜索路径 - void clearSearchPaths(); - - /// 获取搜索路径列表 - const std::vector &getSearchPaths() const { - return searchPaths_; - } - - /// 查找资源文件完整路径 - std::string findResourcePath(const std::string &filename) const; - // ------------------------------------------------------------------------ // 纹理资源 // ------------------------------------------------------------------------ @@ -83,14 +61,6 @@ public: Ptr loadFont(const std::string &filepath, int fontSize, bool useSDF = false); - /// 尝试从多个候选路径加载字体,返回第一个成功加载的字体 - Ptr loadFontWithFallbacks(const std::vector &fontPaths, - int fontSize, bool useSDF = false); - - /// 加载字体,使用默认系统字体作为后备 - Ptr loadFontWithDefaultFallback(const std::string &filepath, - int fontSize, bool useSDF = false); - /// 通过key获取已缓存的字体图集 Ptr getFont(const std::string &key) const; @@ -151,9 +121,6 @@ public: mutable std::mutex fontMutex_; mutable std::mutex soundMutex_; - // 搜索路径 - std::vector searchPaths_; - // 资源缓存 - 使用弱指针实现自动清理 std::unordered_map> textureCache_; std::unordered_map> fontCache_; diff --git a/Extra2D/src/app/application.cpp b/Extra2D/src/app/application.cpp index d155e0b..4572987 100644 --- a/Extra2D/src/app/application.cpp +++ b/Extra2D/src/app/application.cpp @@ -53,27 +53,39 @@ bool Application::init(const AppConfig &config) { config_ = config; + // 确定平台类型 + PlatformType platform = config_.platform; + if (platform == PlatformType::Auto) { #ifdef __SWITCH__ - // ======================================== - // 1. 初始化 RomFS 文件系统(Switch 平台) - // ======================================== - Result rc; - rc = romfsInit(); - if (R_SUCCEEDED(rc)) { - E2D_LOG_INFO("RomFS initialized successfully"); - } else { - E2D_LOG_WARN("romfsInit failed: {:#08X}, will use regular filesystem", rc); + platform = PlatformType::Switch; +#else + platform = PlatformType::PC; +#endif } - // ======================================== - // 2. 初始化 nxlink 调试输出(Switch 平台) - // ======================================== - rc = socketInitializeDefault(); - if (R_FAILED(rc)) { - E2D_LOG_WARN( - "socketInitializeDefault failed, nxlink will not be available"); - } + if (platform == PlatformType::Switch) { +#ifdef __SWITCH__ + // ======================================== + // 1. 初始化 RomFS 文件系统(Switch 平台) + // ======================================== + Result rc; + rc = romfsInit(); + if (R_SUCCEEDED(rc)) { + E2D_LOG_INFO("RomFS initialized successfully"); + } else { + E2D_LOG_WARN("romfsInit failed: {:#08X}, will use regular filesystem", rc); + } + + // ======================================== + // 2. 初始化 nxlink 调试输出(Switch 平台) + // ======================================== + rc = socketInitializeDefault(); + if (R_FAILED(rc)) { + E2D_LOG_WARN( + "socketInitializeDefault failed, nxlink will not be available"); + } #endif + } // ======================================== // 3. 创建窗口(包含 SDL_Init + GLES 3.2 上下文创建) @@ -83,14 +95,18 @@ bool Application::init(const AppConfig &config) { winConfig.title = config.title; winConfig.width = 1280; winConfig.height = 720; -#ifdef __SWITCH__ - winConfig.fullscreen = true; - winConfig.resizable = false; -#else - // PC 平台默认窗口模式 - winConfig.fullscreen = config.fullscreen; - winConfig.resizable = true; -#endif + if (platform == PlatformType::Switch) { + winConfig.fullscreen = true; + winConfig.resizable = false; + winConfig.enableCursors = false; + winConfig.enableDpiScale = false; + } else { + // PC 平台默认窗口模式 + winConfig.fullscreen = config.fullscreen; + winConfig.resizable = true; + winConfig.enableCursors = true; + winConfig.enableDpiScale = true; + } winConfig.vsync = config.vsync; winConfig.msaaSamples = config.msaaSamples; @@ -138,14 +154,6 @@ bool Application::init(const AppConfig &config) { // 初始化音频引擎 AudioEngine::getInstance().initialize(); -#ifdef __SWITCH__ - // 添加 romfs:/ 到资源搜索路径(Switch 平台) - resourceManager_->addSearchPath("romfs:/"); -#endif - // 添加默认资源路径 - resourceManager_->addSearchPath("assets/"); - resourceManager_->addSearchPath("./"); - initialized_ = true; running_ = true; @@ -185,11 +193,21 @@ void Application::shutdown() { window_.reset(); } -#ifdef __SWITCH__ // Switch 平台清理 - romfsExit(); - socketExit(); + PlatformType platform = config_.platform; + if (platform == PlatformType::Auto) { +#ifdef __SWITCH__ + platform = PlatformType::Switch; +#else + platform = PlatformType::PC; #endif + } + if (platform == PlatformType::Switch) { +#ifdef __SWITCH__ + romfsExit(); + socketExit(); +#endif + } initialized_ = false; running_ = false; diff --git a/Extra2D/src/graphics/render_command.cpp b/Extra2D/src/graphics/render_command.cpp deleted file mode 100644 index 9ff0abb..0000000 --- a/Extra2D/src/graphics/render_command.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -namespace extra2d { -// This file exists to allow compilation of the render_command header -// The RenderCommand struct is header-only for performance -} // namespace extra2d diff --git a/Extra2D/src/platform/file_system.cpp b/Extra2D/src/platform/file_system.cpp deleted file mode 100644 index edf4df9..0000000 --- a/Extra2D/src/platform/file_system.cpp +++ /dev/null @@ -1,315 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -#ifdef PLATFORM_WINDOWS - #include - #include - #include - #pragma comment(lib, "shlwapi.lib") -#else - #include - #include - #include - #include - #include -#endif - -namespace extra2d { - -// ============================================================================ -// 平台特定辅助函数 -// ============================================================================ - -#ifdef PLATFORM_WINDOWS - static const char PATH_SEPARATOR = '\\'; - static const char PATH_SEPARATOR_ALT = '/'; -#else - static const char PATH_SEPARATOR = '/'; - static const char PATH_SEPARATOR_ALT = '\\'; -#endif - -static std::string normalizeSeparators(const std::string& path) { - std::string result = path; - std::replace(result.begin(), result.end(), PATH_SEPARATOR_ALT, PATH_SEPARATOR); - return result; -} - -// ============================================================================ -// 资源根目录 -// ============================================================================ - -std::string FileSystem::getResourceRoot() { -#ifdef PLATFORM_SWITCH - return "romfs:/"; -#else - // PC 端:优先使用可执行文件目录下的 assets 文件夹 - std::string exeDir = getExecutableDirectory(); - std::string assetsDir = combinePath(exeDir, "assets"); - - if (directoryExists(assetsDir)) { - return assetsDir; - } - - // 备选:当前工作目录 - std::string cwd = getCurrentWorkingDirectory(); - assetsDir = combinePath(cwd, "assets"); - - if (directoryExists(assetsDir)) { - return assetsDir; - } - - // 默认返回当前工作目录 - return cwd; -#endif -} - -// ============================================================================ -// 路径解析 -// ============================================================================ - -std::string FileSystem::resolvePath(const std::string& relativePath) { - std::string normalized = normalizeSeparators(relativePath); - -#ifdef PLATFORM_SWITCH - // Switch: 添加 romfs:/ 前缀 - if (normalized.find("romfs:/") == 0) { - return normalized; - } - return "romfs:/" + normalized; -#else - // PC: 如果已经是绝对路径,直接返回 -#ifdef PLATFORM_WINDOWS - if (normalized.size() >= 2 && normalized[1] == ':') { - return normalized; - } -#else - if (!normalized.empty() && normalized[0] == '/') { - return normalized; - } -#endif - - // 组合资源根目录和相对路径 - return combinePath(getResourceRoot(), normalized); -#endif -} - -// ============================================================================ -// 文件/目录检查 -// ============================================================================ - -bool FileSystem::fileExists(const std::string& path) { - struct stat st; - if (stat(path.c_str(), &st) != 0) { - return false; - } - return (st.st_mode & S_IFREG) != 0; -} - -bool FileSystem::directoryExists(const std::string& path) { - struct stat st; - if (stat(path.c_str(), &st) != 0) { - return false; - } - return (st.st_mode & S_IFDIR) != 0; -} - -// ============================================================================ -// 路径操作 -// ============================================================================ - -std::string FileSystem::getExecutableDirectory() { - std::string exePath; - -#ifdef PLATFORM_WINDOWS - char buffer[MAX_PATH]; - DWORD len = GetModuleFileNameA(NULL, buffer, MAX_PATH); - if (len > 0 && len < MAX_PATH) { - exePath = buffer; - } -#elif defined(PLATFORM_SWITCH) - // Switch: 返回当前工作目录(不支持获取可执行文件路径) - return getCurrentWorkingDirectory(); -#else - char buffer[PATH_MAX]; - ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1); - if (len != -1) { - buffer[len] = '\0'; - exePath = buffer; - } -#endif - - if (!exePath.empty()) { - size_t lastSep = exePath.find_last_of("/\\"); - if (lastSep != std::string::npos) { - return exePath.substr(0, lastSep); - } - } - - return getCurrentWorkingDirectory(); -} - -std::string FileSystem::getCurrentWorkingDirectory() { -#ifdef PLATFORM_WINDOWS - char buffer[MAX_PATH]; - DWORD len = GetCurrentDirectoryA(MAX_PATH, buffer); - if (len > 0 && len < MAX_PATH) { - return std::string(buffer); - } -#else - char buffer[PATH_MAX]; - if (getcwd(buffer, sizeof(buffer)) != nullptr) { - return std::string(buffer); - } -#endif - return "."; -} - -std::string FileSystem::combinePath(const std::string& base, const std::string& relative) { - if (base.empty()) { - return normalizeSeparators(relative); - } - if (relative.empty()) { - return normalizeSeparators(base); - } - - std::string result = normalizeSeparators(base); - std::string rel = normalizeSeparators(relative); - - // 移除末尾的分隔符 - while (!result.empty() && result.back() == PATH_SEPARATOR) { - result.pop_back(); - } - - // 移除开头的分隔符 - size_t relStart = 0; - while (relStart < rel.size() && rel[relStart] == PATH_SEPARATOR) { - ++relStart; - } - - if (relStart < rel.size()) { - result += PATH_SEPARATOR; - result += rel.substr(relStart); - } - - return result; -} - -std::string FileSystem::getFileName(const std::string& path) { - std::string normalized = normalizeSeparators(path); - size_t lastSep = normalized.find_last_of(PATH_SEPARATOR); - if (lastSep != std::string::npos) { - return normalized.substr(lastSep + 1); - } - return normalized; -} - -std::string FileSystem::getFileExtension(const std::string& path) { - std::string fileName = getFileName(path); - size_t lastDot = fileName.find_last_of('.'); - if (lastDot != std::string::npos && lastDot > 0) { - return fileName.substr(lastDot); - } - return ""; -} - -std::string FileSystem::getDirectoryName(const std::string& path) { - std::string normalized = normalizeSeparators(path); - size_t lastSep = normalized.find_last_of(PATH_SEPARATOR); - if (lastSep != std::string::npos) { - return normalized.substr(0, lastSep); - } - return "."; -} - -std::string FileSystem::normalizePath(const std::string& path) { - return normalizeSeparators(path); -} - -// ============================================================================ -// 文件读写 -// ============================================================================ - -std::string FileSystem::readFileText(const std::string& path) { - std::ifstream file(path, std::ios::in | std::ios::binary); - if (!file.is_open()) { - E2D_LOG_ERROR("Failed to open file: {}", path); - return ""; - } - - std::stringstream buffer; - buffer << file.rdbuf(); - return buffer.str(); -} - -std::vector FileSystem::readFileBytes(const std::string& path) { - std::ifstream file(path, std::ios::in | std::ios::binary | std::ios::ate); - if (!file.is_open()) { - E2D_LOG_ERROR("Failed to open file: {}", path); - return {}; - } - - auto size = file.tellg(); - file.seekg(0, std::ios::beg); - - std::vector buffer(static_cast(size)); - file.read(reinterpret_cast(buffer.data()), size); - - return buffer; -} - -int64_t FileSystem::getFileSize(const std::string& path) { - struct stat st; - if (stat(path.c_str(), &st) != 0) { - return -1; - } - return static_cast(st.st_size); -} - -// ============================================================================ -// 目录操作 -// ============================================================================ - -bool FileSystem::createDirectory(const std::string& path) { - std::string normalized = normalizeSeparators(path); - -#ifdef PLATFORM_WINDOWS - int result = _mkdir(normalized.c_str()); -#else - int result = mkdir(normalized.c_str(), 0755); -#endif - - return result == 0 || errno == EEXIST; -} - -bool FileSystem::createDirectories(const std::string& path) { - std::string normalized = normalizeSeparators(path); - - if (normalized.empty()) { - return true; - } - - // 逐级创建目录 - size_t pos = 0; - while (pos < normalized.size()) { - pos = normalized.find(PATH_SEPARATOR, pos + 1); - if (pos == std::string::npos) { - pos = normalized.size(); - } - - std::string subPath = normalized.substr(0, pos); - if (!subPath.empty() && !directoryExists(subPath)) { - if (!createDirectory(subPath)) { - return false; - } - } - } - - return true; -} - -} // namespace extra2d diff --git a/Extra2D/src/platform/window.cpp b/Extra2D/src/platform/window.cpp index 3b1ebd9..e9e375a 100644 --- a/Extra2D/src/platform/window.cpp +++ b/Extra2D/src/platform/window.cpp @@ -13,7 +13,7 @@ Window::Window() : sdlWindow_(nullptr), glContext_(nullptr), currentCursor_(nullptr), width_(1280), height_(720), vsync_(true), shouldClose_(false), fullscreen_(true), focused_(true), contentScaleX_(1.0f), contentScaleY_(1.0f), - userData_(nullptr), eventQueue_(nullptr) { + enableDpiScale_(true), userData_(nullptr), eventQueue_(nullptr) { // 初始化光标数组 for (int i = 0; i < 9; ++i) { sdlCursors_[i] = nullptr; @@ -32,6 +32,7 @@ bool Window::create(const WindowConfig &config) { height_ = config.height; vsync_ = config.vsync; fullscreen_ = config.fullscreen; + enableDpiScale_ = config.enableDpiScale; // 初始化 SDL2 + 创建窗口 + GL 上下文 if (!initSDL(config)) { @@ -43,13 +44,12 @@ bool Window::create(const WindowConfig &config) { input_ = makeUnique(); input_->init(); - // PC 端初始化光标 -#ifdef PLATFORM_PC - initCursors(); -#endif + // 初始化光标 + if (config.enableCursors) { + initCursors(); + } - E2D_LOG_INFO("Window created: {}x{} (Platform: {})", - width_, height_, platform::getPlatformName()); + E2D_LOG_INFO("Window created: {}x{}", width_, height_); return true; } @@ -79,13 +79,7 @@ bool Window::initSDL(const WindowConfig &config) { // 创建 SDL2 窗口 Uint32 windowFlags = SDL_WINDOW_OPENGL; -#ifdef PLATFORM_SWITCH - // Switch 始终全屏 - windowFlags |= SDL_WINDOW_FULLSCREEN; - width_ = 1280; - height_ = 720; -#else - // PC 端根据配置设置 + // 根据配置设置窗口模式 if (config.fullscreen) { windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } else { @@ -95,7 +89,6 @@ bool Window::initSDL(const WindowConfig &config) { // 注意:SDL_WINDOWPOS_CENTERED 是位置参数,不是窗口标志 // 窗口居中在 SDL_CreateWindow 的位置参数中处理 } -#endif sdlWindow_ = SDL_CreateWindow( config.title.c_str(), @@ -143,10 +136,10 @@ bool Window::initSDL(const WindowConfig &config) { // 设置 VSync SDL_GL_SetSwapInterval(vsync_ ? 1 : 0); - // PC 端更新 DPI 缩放 -#ifndef PLATFORM_SWITCH - updateContentScale(); -#endif + // 更新 DPI 缩放 + if (config.enableDpiScale) { + updateContentScale(); + } E2D_LOG_INFO("SDL2 + GLES 3.2 initialized successfully"); E2D_LOG_INFO("OpenGL Version: {}", @@ -199,9 +192,7 @@ void Window::pollEvents() { case SDL_WINDOWEVENT_SIZE_CHANGED: width_ = event.window.data1; height_ = event.window.data2; -#ifndef PLATFORM_SWITCH updateContentScale(); -#endif if (resizeCallback_) { resizeCallback_(width_, height_); } @@ -240,49 +231,31 @@ bool Window::shouldClose() const { return shouldClose_; } void Window::setShouldClose(bool close) { shouldClose_ = close; } void Window::setTitle(const String &title) { -#ifdef PLATFORM_PC if (sdlWindow_) { SDL_SetWindowTitle(sdlWindow_, title.c_str()); } -#else - (void)title; -#endif } void Window::setSize(int width, int height) { -#ifdef PLATFORM_PC if (sdlWindow_) { SDL_SetWindowSize(sdlWindow_, width, height); width_ = width; height_ = height; } -#else - (void)width; - (void)height; -#endif } void Window::setPosition(int x, int y) { -#ifdef PLATFORM_PC if (sdlWindow_) { SDL_SetWindowPosition(sdlWindow_, x, y); } -#else - (void)x; - (void)y; -#endif } void Window::setFullscreen(bool fullscreen) { -#ifdef PLATFORM_PC if (sdlWindow_) { Uint32 flags = fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; SDL_SetWindowFullscreen(sdlWindow_, flags); fullscreen_ = fullscreen; } -#else - (void)fullscreen; -#endif } void Window::setVSync(bool enabled) { @@ -291,40 +264,26 @@ void Window::setVSync(bool enabled) { } void Window::setResizable(bool resizable) { -#ifdef PLATFORM_PC if (sdlWindow_) { SDL_SetWindowResizable(sdlWindow_, resizable ? SDL_TRUE : SDL_FALSE); } -#else - (void)resizable; -#endif } Vec2 Window::getPosition() const { -#ifdef PLATFORM_PC if (sdlWindow_) { int x, y; SDL_GetWindowPosition(sdlWindow_, &x, &y); return Vec2(static_cast(x), static_cast(y)); } -#endif return Vec2::Zero(); } float Window::getContentScaleX() const { -#ifdef PLATFORM_SWITCH - return 1.0f; -#else - return contentScaleX_; -#endif + return enableDpiScale_ ? contentScaleX_ : 1.0f; } float Window::getContentScaleY() const { -#ifdef PLATFORM_SWITCH - return 1.0f; -#else - return contentScaleY_; -#endif + return enableDpiScale_ ? contentScaleY_ : 1.0f; } Vec2 Window::getContentScale() const { @@ -332,27 +291,22 @@ Vec2 Window::getContentScale() const { } bool Window::isMinimized() const { -#ifdef PLATFORM_PC if (sdlWindow_) { Uint32 flags = SDL_GetWindowFlags(sdlWindow_); return (flags & SDL_WINDOW_MINIMIZED) != 0; } -#endif return false; } bool Window::isMaximized() const { -#ifdef PLATFORM_PC if (sdlWindow_) { Uint32 flags = SDL_GetWindowFlags(sdlWindow_); return (flags & SDL_WINDOW_MAXIMIZED) != 0; } -#endif return true; } void Window::initCursors() { -#ifdef PLATFORM_PC sdlCursors_[0] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); sdlCursors_[1] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); sdlCursors_[2] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR); @@ -362,11 +316,9 @@ void Window::initCursors() { sdlCursors_[6] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); sdlCursors_[7] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); sdlCursors_[8] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); -#endif } void Window::deinitCursors() { -#ifdef PLATFORM_PC for (int i = 0; i < 9; ++i) { if (sdlCursors_[i]) { SDL_FreeCursor(sdlCursors_[i]); @@ -374,38 +326,26 @@ void Window::deinitCursors() { } } currentCursor_ = nullptr; -#endif } void Window::setCursor(CursorShape shape) { -#ifdef PLATFORM_PC int index = static_cast(shape); if (index >= 0 && index < 9 && sdlCursors_[index]) { SDL_SetCursor(sdlCursors_[index]); currentCursor_ = sdlCursors_[index]; } -#else - (void)shape; -#endif } void Window::resetCursor() { -#ifdef PLATFORM_PC SDL_SetCursor(SDL_GetDefaultCursor()); currentCursor_ = nullptr; -#endif } void Window::setMouseVisible(bool visible) { -#ifdef PLATFORM_PC SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE); -#else - (void)visible; -#endif } void Window::updateContentScale() { -#ifndef PLATFORM_SWITCH if (sdlWindow_) { // 使用 DPI 计算内容缩放比例 int displayIndex = SDL_GetWindowDisplayIndex(sdlWindow_); @@ -418,7 +358,6 @@ void Window::updateContentScale() { } } } -#endif } } // namespace extra2d diff --git a/Extra2D/src/resource/resource_manager.cpp b/Extra2D/src/resource/resource_manager.cpp index dfadd0a..5b88f1a 100644 --- a/Extra2D/src/resource/resource_manager.cpp +++ b/Extra2D/src/resource/resource_manager.cpp @@ -9,50 +9,6 @@ namespace extra2d { -ResourceManager::ResourceManager() { -#ifdef __SWITCH__ - addSearchPath("romfs:/"); - addSearchPath("sdmc:/"); -#endif -} -ResourceManager::~ResourceManager() = default; - -ResourceManager &ResourceManager::getInstance() { - static ResourceManager instance; - return instance; -} - -// ============================================================================ -// 搜索路径管理 -// ============================================================================ - -void ResourceManager::addSearchPath(const std::string &path) { - std::lock_guard lock(textureMutex_); - - // 避免重复添加 - auto it = std::find(searchPaths_.begin(), searchPaths_.end(), path); - if (it == searchPaths_.end()) { - searchPaths_.push_back(path); - E2D_LOG_DEBUG("ResourceManager: added search path: {}", path); - } -} - -void ResourceManager::removeSearchPath(const std::string &path) { - std::lock_guard lock(textureMutex_); - - auto it = std::find(searchPaths_.begin(), searchPaths_.end(), path); - if (it != searchPaths_.end()) { - searchPaths_.erase(it); - E2D_LOG_DEBUG("ResourceManager: removed search path: {}", path); - } -} - -void ResourceManager::clearSearchPaths() { - std::lock_guard lock(textureMutex_); - searchPaths_.clear(); - E2D_LOG_DEBUG("ResourceManager: cleared all search paths"); -} - // 辅助函数:检查文件是否存在 static bool fileExists(const std::string &path) { struct stat st; @@ -64,51 +20,41 @@ static bool isRomfsPath(const std::string &path) { return path.find("romfs:/") == 0 || path.find("romfs:\\") == 0; } -// 辅助函数:拼接路径 -static std::string joinPath(const std::string &dir, - const std::string &filename) { - if (dir.empty()) - return filename; - char lastChar = dir.back(); - if (lastChar == '/' || lastChar == '\\') { - return dir + filename; - } - return dir + "/" + filename; -} - -std::string -ResourceManager::findResourcePath(const std::string &filename) const { - // 首先检查是否是 romfs 路径(Switch 平台) - if (isRomfsPath(filename)) { - if (fileExists(filename)) { - return filename; - } - return ""; +// 解析资源路径(优先尝试 romfs:/ 前缀,然后 sdmc:/) +static std::string resolveResourcePath(const std::string &filepath) { + // 如果已经是 romfs 或 sdmc 路径,直接返回 + if (isRomfsPath(filepath) || filepath.find("sdmc:/") == 0) { + return filepath; } - // 首先检查是否是绝对路径或相对当前目录存在 - if (fileExists(filename)) { - return filename; - } - - // 在搜索路径中查找 - std::lock_guard lock(textureMutex_); - for (const auto &path : searchPaths_) { - std::string fullPath = joinPath(path, filename); - if (fileExists(fullPath)) { - return fullPath; - } - } - - // 最后尝试在 romfs 中查找(自动添加 romfs:/ 前缀) - std::string romfsPath = "romfs:/" + filename; + // 优先尝试 romfs:/ 前缀的路径(Switch 平台) + std::string romfsPath = "romfs:/" + filepath; if (fileExists(romfsPath)) { return romfsPath; } + // 尝试 sdmc:/ 前缀的路径(Switch SD卡) + std::string sdmcPath = "sdmc:/" + filepath; + if (fileExists(sdmcPath)) { + return sdmcPath; + } + + // 如果都不存在,尝试原路径 + if (fileExists(filepath)) { + return filepath; + } + return ""; } +ResourceManager::ResourceManager() = default; +ResourceManager::~ResourceManager() = default; + +ResourceManager &ResourceManager::getInstance() { + static ResourceManager instance; + return instance; +} + // ============================================================================ // 纹理资源 // ============================================================================ @@ -127,14 +73,14 @@ Ptr ResourceManager::loadTexture(const std::string &filepath) { textureCache_.erase(it); } - // 查找完整路径 - std::string fullPath = findResourcePath(filepath); + // 解析资源路径(优先尝试 romfs:/ 前缀) + std::string fullPath = resolveResourcePath(filepath); if (fullPath.empty()) { E2D_LOG_ERROR("ResourceManager: texture file not found: {}", filepath); return nullptr; } - // 创建新纹理(根据扩展名自动选择加载路径) + // 创建新纹理 try { auto texture = makePtr(fullPath); if (!texture->isValid()) { @@ -261,8 +207,8 @@ Ptr ResourceManager::loadFont(const std::string &filepath, fontCache_.erase(it); } - // 查找完整路径 - std::string fullPath = findResourcePath(filepath); + // 解析资源路径(优先尝试 romfs:/ 前缀) + std::string fullPath = resolveResourcePath(filepath); if (fullPath.empty()) { E2D_LOG_ERROR("ResourceManager: font file not found: {}", filepath); return nullptr; @@ -313,92 +259,6 @@ void ResourceManager::unloadFont(const std::string &key) { E2D_LOG_DEBUG("ResourceManager: unloaded font: {}", key); } -// ============================================================================ -// 多字体后备加载 -// ============================================================================ - -Ptr ResourceManager::loadFontWithFallbacks( - const std::vector &fontPaths, int fontSize, bool useSDF) { - - // 尝试加载每一个候选字体 - for (const auto &fontPath : fontPaths) { - auto font = loadFont(fontPath, fontSize, useSDF); - if (font) { - E2D_LOG_INFO("ResourceManager: successfully loaded font from fallback list: {}", - fontPath); - return font; - } - } - - E2D_LOG_ERROR("ResourceManager: failed to load any font from fallback list ({} candidates)", - fontPaths.size()); - return nullptr; -} - -Ptr ResourceManager::loadFontWithDefaultFallback( - const std::string &filepath, int fontSize, bool useSDF) { - - // 首先尝试加载用户指定的字体 - auto font = loadFont(filepath, fontSize, useSDF); - if (font) { - return font; - } - - E2D_LOG_WARN("ResourceManager: failed to load font '{}', trying system fallbacks...", - filepath); - - // 定义系统默认字体候选列表 - std::vector fallbackFonts; - -#ifdef __SWITCH__ - // Switch 平台默认字体路径 - fallbackFonts = { - "romfs:/assets/font.ttf", // 应用自带字体 - "romfs:/assets/default.ttf", // 默认字体备选 - "romfs:/font.ttf", // 根目录字体 - "sdmc:/switch/fonts/default.ttf", // SD卡字体目录 - "sdmc:/switch/fonts/font.ttf", - }; -#else - // PC 平台系统字体路径(Windows/Linux/macOS) -#ifdef _WIN32 - fallbackFonts = { - "C:/Windows/Fonts/arial.ttf", - "C:/Windows/Fonts/segoeui.ttf", - "C:/Windows/Fonts/calibri.ttf", - "C:/Windows/Fonts/tahoma.ttf", - "C:/Windows/Fonts/msyh.ttc", // 微软雅黑 - }; -#elif __APPLE__ - fallbackFonts = { - "/System/Library/Fonts/Helvetica.ttc", - "/System/Library/Fonts/SFNSDisplay.ttf", - "/Library/Fonts/Arial.ttf", - }; -#else - // Linux - fallbackFonts = { - "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", - "/usr/share/fonts/truetype/freefont/FreeSans.ttf", - "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", - "/usr/share/fonts/truetype/noto/NotoSans-Regular.ttf", - }; -#endif -#endif - - // 尝试加载后备字体 - for (const auto &fallbackPath : fallbackFonts) { - font = loadFont(fallbackPath, fontSize, useSDF); - if (font) { - E2D_LOG_INFO("ResourceManager: loaded fallback font: {}", fallbackPath); - return font; - } - } - - E2D_LOG_ERROR("ResourceManager: all font fallbacks exhausted, no font available"); - return nullptr; -} - // ============================================================================ // 音效资源 // ============================================================================ @@ -422,8 +282,8 @@ Ptr ResourceManager::loadSound(const std::string &name, soundCache_.erase(it); } - // 查找完整路径 - std::string fullPath = findResourcePath(filepath); + // 解析资源路径(优先尝试 romfs:/ 前缀) + std::string fullPath = resolveResourcePath(filepath); if (fullPath.empty()) { E2D_LOG_ERROR("ResourceManager: sound file not found: {}", filepath); return nullptr; diff --git a/examples/collision_demo/main.cpp b/examples/collision_demo/main.cpp index 109cd5a..2b7fcdd 100644 --- a/examples/collision_demo/main.cpp +++ b/examples/collision_demo/main.cpp @@ -123,13 +123,8 @@ private: */ void loadFonts() { auto &resources = Application::instance().resources(); - - std::vector fontPaths = { - "romfs:/assets/font.ttf" // 备选字体 - }; - - titleFont_ = resources.loadFontWithFallbacks(fontPaths, 60, true); - infoFont_ = resources.loadFontWithFallbacks(fontPaths, 28, true); + titleFont_ = resources.loadFont("assets/font.ttf", 60, true); + infoFont_ = resources.loadFont("assets/font.ttf", 28, true); if (!titleFont_) { E2D_LOG_WARN("无法加载标题字体"); diff --git a/examples/collision_demo/xmake.lua b/examples/collision_demo/xmake.lua index 1e10e59..9914b7e 100644 --- a/examples/collision_demo/xmake.lua +++ b/examples/collision_demo/xmake.lua @@ -7,6 +7,9 @@ local host_plat = os.host() local target_plat = get_config("plat") or host_plat +-- 获取当前脚本所在目录(示例根目录) +local example_dir = os.scriptdir() + -- 可执行文件目标 target("collision_demo") set_kind("binary") @@ -18,7 +21,7 @@ target("collision_demo") set_plat("switch") set_arch("arm64") set_toolchains("switch") - set_targetdir("build/switch") + set_targetdir("../../build/examples/collision_demo") after_build(function (target) local devkitPro = os.getenv("DEVKITPRO") or "C:/devkitPro" @@ -31,7 +34,7 @@ target("collision_demo") if os.isfile(nacptool) and os.isfile(elf2nro) then os.vrunv(nacptool, {"--create", "Collision Demo", "Extra2D Team", "1.0.0", nacp_file}) - local romfs = path.absolute("romfs") + local romfs = path.join(example_dir, "romfs") if os.isdir(romfs) then os.vrunv(elf2nro, {elf_file, nro_file, "--nacp=" .. nacp_file, "--romfsdir=" .. romfs}) else @@ -43,11 +46,12 @@ target("collision_demo") elseif target_plat == "mingw" then set_plat("mingw") set_arch("x86_64") - set_targetdir("build/mingw") + set_targetdir("../../build/examples/collision_demo") add_ldflags("-mwindows", {force = true}) + -- 复制资源 after_build(function (target) - local romfs = path.absolute("romfs") + local romfs = path.join(example_dir, "romfs") if os.isdir(romfs) then local target_dir = path.directory(target:targetfile()) local assets_dir = path.join(target_dir, "assets") @@ -55,6 +59,9 @@ target("collision_demo") os.mkdir(assets_dir) end os.cp(path.join(romfs, "assets/*"), assets_dir) + print("Copied assets from " .. romfs .. " to " .. assets_dir) + else + print("Warning: romfs directory not found at " .. romfs) end end) end diff --git a/examples/hello_world/main.cpp b/examples/hello_world/main.cpp index 88ef188..edd4ef9 100644 --- a/examples/hello_world/main.cpp +++ b/examples/hello_world/main.cpp @@ -85,7 +85,6 @@ int main(int argc, char **argv) E2D_LOG_INFO("========================"); E2D_LOG_INFO("Easy2D Hello World Demo"); - E2D_LOG_INFO("Platform: {}", platform::getPlatformName()); E2D_LOG_INFO("========================"); // 获取应用实例 diff --git a/examples/hello_world/xmake.lua b/examples/hello_world/xmake.lua index 4b84725..2b665e6 100644 --- a/examples/hello_world/xmake.lua +++ b/examples/hello_world/xmake.lua @@ -7,6 +7,9 @@ local host_plat = os.host() local target_plat = get_config("plat") or host_plat +-- 获取当前脚本所在目录(示例根目录) +local example_dir = os.scriptdir() + -- 可执行文件目标 target("hello_world") set_kind("binary") @@ -18,7 +21,7 @@ target("hello_world") set_plat("switch") set_arch("arm64") set_toolchains("switch") - set_targetdir("build/switch") + set_targetdir("../../build/examples/hello_world") -- 生成 NRO after_build(function (target) @@ -32,7 +35,7 @@ target("hello_world") if os.isfile(nacptool) and os.isfile(elf2nro) then os.vrunv(nacptool, {"--create", "Hello World", "Extra2D Team", "1.0.0", nacp_file}) - local romfs = path.absolute("romfs") + local romfs = path.join(example_dir, "romfs") if os.isdir(romfs) then os.vrunv(elf2nro, {elf_file, nro_file, "--nacp=" .. nacp_file, "--romfsdir=" .. romfs}) else @@ -44,12 +47,12 @@ target("hello_world") elseif target_plat == "mingw" then set_plat("mingw") set_arch("x86_64") - set_targetdir("build/mingw") + set_targetdir("../../build/examples/hello_world") add_ldflags("-mwindows", {force = true}) -- 复制资源 after_build(function (target) - local romfs = path.absolute("romfs") + local romfs = path.join(example_dir, "romfs") if os.isdir(romfs) then local target_dir = path.directory(target:targetfile()) local assets_dir = path.join(target_dir, "assets") @@ -57,6 +60,9 @@ target("hello_world") os.mkdir(assets_dir) end os.cp(path.join(romfs, "assets/*"), assets_dir) + print("Copied assets from " .. romfs .. " to " .. assets_dir) + else + print("Warning: romfs directory not found at " .. romfs) end end) end diff --git a/examples/push_box/StartScene.cpp b/examples/push_box/StartScene.cpp index 8d20786..ad80009 100644 --- a/examples/push_box/StartScene.cpp +++ b/examples/push_box/StartScene.cpp @@ -16,7 +16,7 @@ StartScene::StartScene() { static extra2d::Ptr loadMenuFont() { auto& resources = extra2d::Application::instance().resources(); - auto font = resources.loadFont("assets/font.ttf", 28); + auto font = resources.loadFont("assets/font.ttf", 28,true); return font; } diff --git a/examples/push_box/main.cpp b/examples/push_box/main.cpp index 00e10e8..148cdbd 100644 --- a/examples/push_box/main.cpp +++ b/examples/push_box/main.cpp @@ -16,7 +16,6 @@ int main(int argc, char **argv) E2D_LOG_INFO("========================"); E2D_LOG_INFO("Extra2D push_box"); - E2D_LOG_INFO("Platform: {}", platform::getPlatformName()); E2D_LOG_INFO("========================"); auto &app = Application::instance(); diff --git a/examples/push_box/xmake.lua b/examples/push_box/xmake.lua index 1a69ffc..a138c36 100644 --- a/examples/push_box/xmake.lua +++ b/examples/push_box/xmake.lua @@ -7,6 +7,9 @@ local host_plat = os.host() local target_plat = get_config("plat") or host_plat +-- 获取当前脚本所在目录(示例根目录) +local example_dir = os.scriptdir() + -- 可执行文件目标 target("push_box") set_kind("binary") @@ -18,7 +21,7 @@ target("push_box") set_plat("switch") set_arch("arm64") set_toolchains("switch") - set_targetdir("build/switch") + set_targetdir("../../build/examples/push_box") after_build(function (target) local devkitPro = os.getenv("DEVKITPRO") or "C:/devkitPro" @@ -31,7 +34,7 @@ target("push_box") if os.isfile(nacptool) and os.isfile(elf2nro) then os.vrunv(nacptool, {"--create", "Push Box", "Extra2D Team", "1.0.0", nacp_file}) - local romfs = path.absolute("romfs") + local romfs = path.join(example_dir, "romfs") if os.isdir(romfs) then os.vrunv(elf2nro, {elf_file, nro_file, "--nacp=" .. nacp_file, "--romfsdir=" .. romfs}) else @@ -43,11 +46,12 @@ target("push_box") elseif target_plat == "mingw" then set_plat("mingw") set_arch("x86_64") - set_targetdir("build/mingw") + set_targetdir("../../build/examples/push_box") add_ldflags("-mwindows", {force = true}) + -- 复制资源 after_build(function (target) - local romfs = path.absolute("romfs") + local romfs = path.join(example_dir, "romfs") if os.isdir(romfs) then local target_dir = path.directory(target:targetfile()) local assets_dir = path.join(target_dir, "assets") @@ -55,6 +59,9 @@ target("push_box") os.mkdir(assets_dir) end os.cp(path.join(romfs, "assets/*"), assets_dir) + print("Copied assets from " .. romfs .. " to " .. assets_dir) + else + print("Warning: romfs directory not found at " .. romfs) end end) end diff --git a/examples/spatial_index_demo/main.cpp b/examples/spatial_index_demo/main.cpp index 99fc4db..8969bd7 100644 --- a/examples/spatial_index_demo/main.cpp +++ b/examples/spatial_index_demo/main.cpp @@ -185,14 +185,8 @@ private: void loadFonts() { auto &resources = Application::instance().resources(); - std::vector fontPaths = { - "romfs:/assets/msjh.ttf", - "romfs:/assets/default.ttf", - "romfs:/assets/font.ttf", - }; - - titleFont_ = resources.loadFontWithFallbacks(fontPaths, 28, true); - infoFont_ = resources.loadFontWithFallbacks(fontPaths, 16, true); + titleFont_ = resources.loadFont("assets/font.ttf", 28, true); + infoFont_ = resources.loadFont("assets/font.ttf", 16, true); } /** diff --git a/examples/spatial_index_demo/xmake.lua b/examples/spatial_index_demo/xmake.lua index d6d796c..b7e2719 100644 --- a/examples/spatial_index_demo/xmake.lua +++ b/examples/spatial_index_demo/xmake.lua @@ -7,6 +7,9 @@ local host_plat = os.host() local target_plat = get_config("plat") or host_plat +-- 获取当前脚本所在目录(示例根目录) +local example_dir = os.scriptdir() + -- 可执行文件目标 target("spatial_index_demo") set_kind("binary") @@ -18,7 +21,7 @@ target("spatial_index_demo") set_plat("switch") set_arch("arm64") set_toolchains("switch") - set_targetdir("build/switch") + set_targetdir("../../build/examples/spatial_index_demo") after_build(function (target) local devkitPro = os.getenv("DEVKITPRO") or "C:/devkitPro" @@ -31,7 +34,7 @@ target("spatial_index_demo") if os.isfile(nacptool) and os.isfile(elf2nro) then os.vrunv(nacptool, {"--create", "Spatial Index Demo", "Extra2D Team", "1.0.0", nacp_file}) - local romfs = path.absolute("romfs") + local romfs = path.join(example_dir, "romfs") if os.isdir(romfs) then os.vrunv(elf2nro, {elf_file, nro_file, "--nacp=" .. nacp_file, "--romfsdir=" .. romfs}) else @@ -43,11 +46,12 @@ target("spatial_index_demo") elseif target_plat == "mingw" then set_plat("mingw") set_arch("x86_64") - set_targetdir("build/mingw") + set_targetdir("../../build/examples/spatial_index_demo") add_ldflags("-mwindows", {force = true}) + -- 复制资源 after_build(function (target) - local romfs = path.absolute("romfs") + local romfs = path.join(example_dir, "romfs") if os.isdir(romfs) then local target_dir = path.directory(target:targetfile()) local assets_dir = path.join(target_dir, "assets") @@ -55,6 +59,9 @@ target("spatial_index_demo") os.mkdir(assets_dir) end os.cp(path.join(romfs, "assets/*"), assets_dir) + print("Copied assets from " .. romfs .. " to " .. assets_dir) + else + print("Warning: romfs directory not found at " .. romfs) end end) end