使用xmake 包仓库 sdl2

This commit is contained in:
lenheart 2026-02-16 19:19:14 +08:00
parent 945d65eb18
commit 01ac7d34e9
15 changed files with 702 additions and 14 deletions

4
.gitignore vendored
View File

@ -6,3 +6,7 @@ build/
.DS_Store .DS_Store
.vscode/
.cache/
*.json

View File

@ -1,6 +1,6 @@
[ [
{ {
"directory": "/home/lenheart/Game/Frostbite2D", "directory": "d:\\Game\\Frostbite2D",
"arguments": ["/usr/bin/g++", "-c", "-m64", "-fvisibility=hidden", "-fvisibility-inlines-hidden", "-O3", "-std=c++17", "-finput-charset=UTF-8", "-fexec-charset=UTF-8", "-DNDEBUG", "-o", "build/.objs/Frostbite2D/linux/x86_64/release/src/main.cpp.o", "src/main.cpp"], "arguments": ["D:\\Visual Studio\\App\\VC\\Tools\\MSVC\\14.44.35207\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/O2", "/std:c++17", "/EHsc", "/utf-8", "/DNDEBUG", "/Fobuild\\.objs\\Frostbite2D\\windows\\x64\\release\\Fostbite2D\\src\\main.cpp.obj", "Fostbite2D\\src\\main.cpp", "-imsvc", "D:\\Visual Studio\\App\\VC\\Tools\\MSVC\\14.44.35207\\include", "-imsvc", "D:\\Visual Studio\\App\\VC\\Tools\\MSVC\\14.44.35207\\ATLMFC\\include", "-imsvc", "D:\\Visual Studio\\App\\VC\\Auxiliary\\VS\\include", "-imsvc", "D:\\Windows Kits\\10\\include\\10.0.26100.0\\ucrt", "-imsvc", "D:\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\um", "-imsvc", "D:\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\shared", "-imsvc", "D:\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\winrt", "-imsvc", "D:\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um"],
"file": "src/main.cpp" "file": "Fostbite2D\\src\\main.cpp"
}] }]

View File

@ -0,0 +1,215 @@
#pragma once
#include <fostbite2D/module/module.h>
#include <fostbite2D/config/app_config.h>
#include <string>
namespace frostbite2D {
/**
* @brief
*/
class Application {
public:
/**
* @brief
* @return
*/
static Application& get();
Application(const Application&) = delete;
Application& operator=(const Application&) = delete;
/**
* @brief
* @param m
*/
void use(Module& m);
/**
* @brief
* @param modules
*/
void use(std::initializer_list<Module*> modules);
/**
* @brief 使
* @return true
*/
bool init();
/**
* @brief 使
* @param config
* @return true
*/
bool init(const AppConfig& config);
/**
* @brief 使
* @param configPath
* @return true
*/
bool init(const std::string& configPath);
/**
* @brief
*/
void shutdown();
/**
* @brief
*/
void run();
/**
* @brief 退
*/
void quit();
/**
* @brief
*/
void pause();
/**
* @brief
*/
void resume();
/**
* @brief
* @return true
*/
bool isPaused() const { return paused_; }
/**
* @brief
* @return true
*/
bool isRunning() const { return running_; }
// /**
// * @brief 获取窗口
// * @return 窗口引用
// */
// IWindow& window() { return *window_; }
// /**
// * @brief 获取渲染器
// * @return 渲染器引用
// */
// RenderBackend& renderer();
// /**
// * @brief 获取场景服务
// * @return 场景服务共享指针
// */
// SharedPtr<class ISceneService> scenes();
// /**
// * @brief 获取计时器服务
// * @return 计时器服务共享指针
// */
// SharedPtr<class ITimerService> timers();
// /**
// * @brief 获取事件服务
// * @return 事件服务共享指针
// */
// SharedPtr<class IEventService> events();
// /**
// * @brief 获取相机服务
// * @return 相机服务共享指针
// */
// SharedPtr<class ICameraService> camera();
// /**
// * @brief 进入场景
// * @param scene 场景指针
// */
// void enterScene(Ptr<class Scene> scene);
/**
* @brief
* @return
*/
float deltaTime() const { return deltaTime_; }
/**
* @brief
* @return
*/
float totalTime() const { return totalTime_; }
/**
* @brief
* @return
*/
int fps() const { return currentFps_; }
/**
* @brief
* @return
*/
const AppConfig& getConfig() const;
private:
Application() = default;
~Application();
/**
* @brief
* @return true
*/
bool initCoreModules();
/**
* @brief
*/
void setupAllModules();
/**
* @brief
*/
void destroyAllModules();
/**
* @brief
*/
void registerCoreServices();
/**
* @brief
*/
void mainLoop();
/**
* @brief
*/
void update();
/**
* @brief
*/
void render();
std::vector<Module*> modules_;
// IWindow* window_ = nullptr;
bool initialized_ = false;
bool running_ = false;
bool paused_ = false;
bool shouldQuit_ = false;
float deltaTime_ = 0.0f;
float totalTime_ = 0.0f;
double lastFrameTime_ = 0.0;
int frameCount_ = 0;
float fpsTimer_ = 0.0f;
int currentFps_ = 0;
};
}

View File

@ -0,0 +1,38 @@
#pragma once
#include <fostbite2D/config/platform_config.h>
#include <string>
namespace frostbite2D {
/**
* @file app_config.h
* @brief
*
*
* IModuleConfig
*
* ModuleRegistry ConfigManager
*
*/
/**
* @brief
*
*/
struct AppConfig {
std::string appName = "frostbite2D App";
std::string appVersion = "1.0.0";
std::string organization = "";
std::string configFile = "config.json";
PlatformType targetPlatform = PlatformType::Auto;
/**
* @brief
* @return
*/
static AppConfig createDefault();
};
}

View File

@ -0,0 +1,86 @@
#pragma once
#include <fostbite2D/core/types.h>
namespace frostbite2D {
/**
* @file platform_config.h
* @brief
*
*
* IModuleConfig::applyPlatformConstraints()
*/
/**
* @brief
*/
enum class PlatformType {
Auto,
Windows,
Switch,
Linux,
macOS
};
/**
* @brief
*/
struct PlatformCapabilities {
bool supportsWindowed = true;
bool supportsFullscreen = true;
bool supportsBorderless = true;
bool supportsCursor = true;
bool supportsCursorHide = true;
bool supportsDPIAwareness = true;
bool supportsVSync = true;
bool supportsMultiMonitor = true;
bool supportsClipboard = true;
bool supportsGamepad = true;
bool supportsTouch = false;
bool supportsKeyboard = true;
bool supportsMouse = true;
bool supportsResize = true;
bool supportsHighDPI = true;
int maxTextureSize = 16384;
int preferredScreenWidth = 1920;
int preferredScreenHeight = 1080;
float defaultDPI = 96.0f;
bool hasWindowSupport() const { return supportsWindowed || supportsFullscreen || supportsBorderless; }
bool hasInputSupport() const { return supportsKeyboard || supportsMouse || supportsGamepad || supportsTouch; }
bool isDesktop() const { return supportsKeyboard && supportsMouse && supportsWindowed; }
bool isConsole() const { return !supportsWindowed && supportsGamepad; }
};
/**
* @brief
*/
class PlatformConfig {
public:
virtual ~PlatformConfig() = default;
virtual PlatformType platformType() const = 0;
virtual const char* platformName() const = 0;
virtual const PlatformCapabilities& capabilities() const = 0;
virtual int getRecommendedWidth() const = 0;
virtual int getRecommendedHeight() const = 0;
virtual bool isResolutionSupported(int width, int height) const = 0;
};
/**
* @brief
* @param type Auto
* @return
*/
UniquePtr<PlatformConfig> createPlatformConfig(PlatformType type = PlatformType::Auto);
/**
* @brief
* @param type
* @return
*/
const char* getPlatformTypeName(PlatformType type);
}

View File

@ -0,0 +1,58 @@
#pragma once
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
namespace frostbite2D {
// ---------------------------------------------------------------------------
// 宏定义
// ---------------------------------------------------------------------------
#define E2D_CONCAT_IMPL(a, b) a##b
#define E2D_CONCAT(a, b) E2D_CONCAT_IMPL(a, b)
// ---------------------------------------------------------------------------
// 智能指针别名
// ---------------------------------------------------------------------------
template <typename T> using Ptr = std::shared_ptr<T>;
template <typename T> using SharedPtr = std::shared_ptr<T>;
template <typename T> using UniquePtr = std::unique_ptr<T>;
template <typename T> using WeakPtr = std::weak_ptr<T>;
/// 创建 shared_ptr 的便捷函数
template <typename T, typename... Args> inline Ptr<T> makePtr(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
template <typename T, typename... Args> inline SharedPtr<T> makeShared(Args &&...args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
/// 创建 unique_ptr 的便捷函数
template <typename T, typename... Args>
inline UniquePtr<T> makeUnique(Args &&...args) {
return std::make_unique<T>(std::forward<Args>(args)...);
}
// ---------------------------------------------------------------------------
// 函数别名
// ---------------------------------------------------------------------------
template <typename Sig> using Function = std::function<Sig>;
// ---------------------------------------------------------------------------
// 基础类型别名
// ---------------------------------------------------------------------------
using int8 = std::int8_t;
using int16 = std::int16_t;
using int32 = std::int32_t;
using int64 = std::int64_t;
using uint8 = std::uint8_t;
using uint16 = std::uint16_t;
using uint32 = std::uint32_t;
using uint64 = std::uint64_t;
} // namespace frostbite2D

View File

@ -0,0 +1,93 @@
#pragma once
namespace frostbite2D {
/**
* @brief
*
*/
class Module {
public:
/**
* @brief
*/
virtual ~Module() = default;
/**
* @brief
* Application::run()
*/
virtual void setupModule() {}
/**
* @brief
* Application
*/
virtual void destroyModule() {}
/**
* @brief
*
* @param ctx
*/
virtual void onUpdate() { }
/**
* @brief
*
* @param ctx
*/
virtual void beforeRender() { }
/**
* @brief
*
* @param ctx
*/
virtual void onRender() {}
/**
* @brief
*
* @param ctx
*/
virtual void afterRender() { }
/**
* @brief
*
* @param ctx
*/
virtual void handleEvent() { }
/**
* @brief
* @return
*/
virtual const char *getName() const = 0;
/**
* @brief
*
* @return
*/
virtual int getPriority() const { return 0; }
/**
* @brief
* @return true
*/
bool isInitialized() const { return initialized_; }
protected:
friend class Application;
/**
* @brief
* @param initialized
*/
void setInitialized(bool initialized) { initialized_ = initialized; }
bool initialized_ = false;
};
} // namespace frostbite2D

View File

@ -0,0 +1,66 @@
#include "SDL2/SDL_log.h"
#include <fostbite2D/app/application.h>
#include <iostream>
#include <SDL2/SDL.h>
namespace frostbite2D {
Application &Application::get() {
static Application instance;
return instance;
}
void Application::use(Module &m) {
for (auto *existing : modules_) {
if (existing == &m) {
return;
}
}
modules_.push_back(&m);
}
void Application::use(std::initializer_list<Module *> modules) {
for (auto *m : modules) {
if (m) {
use(*m);
}
}
}
bool Application::init() {
AppConfig cfg;
return init(cfg);
}
bool Application::init(const AppConfig &config) {
if (initialized_) {
return true;
}
SDL_Log("Frostbite2D 启动成功!");
return true;
}
void Application::shutdown() {
if (!initialized_)
return;
// VRAMMgr::get().printStats();
// ServiceLocator::instance().clear();
// window_ = nullptr;
initialized_ = false;
running_ = false;
}
Application::~Application() {
if (initialized_) {
shutdown();
}
}
} // namespace frostbite2D

View File

@ -0,0 +1,19 @@
#include <fostbite2D/config/app_config.h>
namespace frostbite2D {
AppConfig AppConfig::createDefault() {
AppConfig config;
config.appName = "Frostbite2D App";
config.appVersion = "1.0.0";
config.organization = "";
config.configFile = "config.json";
config.targetPlatform = PlatformType::Auto;
return config;
}
}

94
Fostbite2D/src/main.cpp Normal file
View File

@ -0,0 +1,94 @@
#include <fostbite2D/app/application.h>
#include <iostream>
#include <SDL2/SDL.h>
using namespace frostbite2D;
int main(int argc, char **argv) {
// AppConfig config = AppConfig::createDefault();
// config.appName = "Extra2D Scene Graph Demo";
// config.appVersion = "1.0.0";
// Application &app = Application::get();
// if (!app.init(config)) {
// std::cerr << "Failed to initialize application!" << std::endl;
// return -1;
// }
// 初始化 SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cerr << "SDL 初始化失败: " << SDL_GetError() << std::endl;
return 1;
}
// 创建窗口
SDL_Window* window = SDL_CreateWindow(
"Frostbite2D - SDL2 Demo",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
800, 600,
SDL_WINDOW_SHOWN
);
if (!window) {
std::cerr << "窗口创建失败: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
// 创建渲染器
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED); if (!renderer) {
std::cerr << "渲染器创建失败: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
std::cout << "Frostbite2D 启动成功!" << std::endl;
std::cout << "按 ESC 键退出程序" << std::endl;
// 主循环
bool running = true;
SDL_Event event;
while (running) {
// 处理事件
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
if (event.type == SDL_KEYDOWN) {
if (event.key.keysym.sym == SDLK_ESCAPE) {
running = false;
}
}
}
// 清屏 (黑色)
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// 绘制一个红色矩形
SDL_Rect rect = {350, 250, 100, 100};
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
// 绘制一个绿色边框
SDL_Rect border = {300, 200, 200, 200};
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_RenderDrawRect(renderer, &border);
// 更新屏幕
SDL_RenderPresent(renderer);
}
// 清理资源
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
std::cout << "程序正常退出" << std::endl;
return 0;
}

View File

@ -1 +0,0 @@
{}

12
platform/windows.lua Normal file
View File

@ -0,0 +1,12 @@
-- MinGW 编译配置
set_toolchains("mingw")
add_requires("libsdl2", {configs = {shared = true}})
target("Frostbite2D")
set_kind("binary")
add_files(path.join(os.projectdir(), "Fostbite2D/src/**.cpp"))
add_includedirs(path.join(os.projectdir(), "Fostbite2D/include"))
add_packages("libsdl2")
target_end()

View File

@ -1 +0,0 @@
{}

View File

@ -1,6 +0,0 @@
#include <iostream>
int main(int argc, char **argv) {
std::cout << "hello world!" << std::endl;
return 0;
}

View File

@ -12,7 +12,18 @@ local host_plat = os.host()
local target_plat = get_config("plat") or host_plat local target_plat = get_config("plat") or host_plat
local supported_plats = {mingw = true, windows = true, linux = true, macosx = true, switch = true} local supported_plats = {mingw = true, windows = true, linux = true, macosx = true, switch = true}
-- 自动选择平台
if not supported_plats[target_plat] then
raise("Unsupported platform: " .. target_plat .. ". Supported platforms: mingw, windows, linux, macosx, switch")
end
-- 引入对应平台的配置文件
local platform_config_file = "platform/" .. target_plat .. ".lua"
if os.isfile(platform_config_file) then
includes(platform_config_file)
else
raise("Platform config file not found: " .. platform_config_file)
end
target("Frostbite2D")
set_kind("binary")
add_files("src/*.cpp")