commit 1a378aebf073c709e23d5375263cdc4aeaa799d0 Author: chris bell Date: Sun Aug 23 20:57:32 2026 -0500 Added raylib+rmlui template diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e35aca9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +build/ +build-wasm/ +.envrc +.direnv/ +.vscode/ +result +.cache/ +compile_commands.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..967e195 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,69 @@ +cmake_minimum_required(VERSION 3.20) +project(gamejam LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +# --------------------------------------------------------------------------- +# Dependencies +# +# Native build: raylib + RmlUi come from nixpkgs / the `rmlui` derivation, +# found on the default system paths set up by the dev shell. +# +# Wasm build: raylib + RmlUi come from the `raylibWasm` / `rmluiWasm` +# derivations, located via -DCMAKE_PREFIX_PATH set by devShells.wasm. +# --------------------------------------------------------------------------- +find_package(raylib REQUIRED) +find_package(RmlUi REQUIRED) + +add_executable(gamejam + src/main.cpp + src/Application.cpp + src/backend/RaylibSystemInterface.cpp + src/backend/RaylibRenderInterface.cpp + src/backend/RaylibInput.cpp +) + +target_link_libraries(gamejam PRIVATE + raylib + RmlUi::Core + RmlUi::Debugger +) + +target_include_directories(gamejam PRIVATE ${CMAKE_SOURCE_DIR}/src) + +set(ASSET_DIR ${CMAKE_SOURCE_DIR}/assets) + +if(EMSCRIPTEN) + # ----------------------------------------------------------------------- + # Wasm-specific settings + # ----------------------------------------------------------------------- + set(CMAKE_EXECUTABLE_SUFFIX ".html") + + target_link_options(gamejam PRIVATE + "-sUSE_GLFW=3" + "-sASYNCIFY" + "-sALLOW_MEMORY_GROWTH=1" + "-sFORCE_FILESYSTEM=1" + "--preload-file=${ASSET_DIR}@assets" + # "--shell-file=${CMAKE_SOURCE_DIR}/shell.html" + ) + + +else() + add_custom_command(TARGET gamejam POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${ASSET_DIR} $/assets + COMMENT "Copying assets to build output" + ) +endif() + +install(TARGETS gamejam RUNTIME DESTINATION bin) + +if(NOT EMSCRIPTEN) + install(DIRECTORY ${ASSET_DIR} DESTINATION bin) +endif() diff --git a/assets/main.rcss b/assets/main.rcss new file mode 100644 index 0000000..8cc2cf6 --- /dev/null +++ b/assets/main.rcss @@ -0,0 +1,39 @@ +body { + font-family: rmlui-debugger-font; + font-size: 16px; + color: white; +} + +#panel { + position: absolute; + top: 40px; + left: 40px; + width: 300px; + padding: 20px; + background-color: rgba(20, 20, 20, 220); + border: 2px #888; +} + +h1 { + font-size: 24px; + color: #ffd35c; + margin-bottom: 10px; +} + +p { + margin-bottom: 15px; +} + +#start-btn { + display: block; + width: 100px; + padding: 8px; + text-align: center; + background-color: #3a6ea5; + color: white; + border: 1px #5a8ec5; +} + +#start-btn:hover { + background-color: #4a7eb5; +} diff --git a/assets/main.rml b/assets/main.rml new file mode 100644 index 0000000..3a8102c --- /dev/null +++ b/assets/main.rml @@ -0,0 +1,13 @@ + + + gamejam + + + +
+

gamejam

+

RmlUi + raylib scaffold is alive.

+ +
+ +
diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..06d7f8b --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1787360063, + "narHash": "sha256-dt4WdcvsA8/RCe+VZZwqU0X+XMM3wBbGCWA0/sFWzGo=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2c423e03bbafcff28bfadc6781a4a8257f205cb5", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "utils": "utils" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..32fdea5 --- /dev/null +++ b/flake.nix @@ -0,0 +1,195 @@ +{ + description = "Raylib + RmlUI gamejam dev environment (desktop + wasm)"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, utils }: + utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + + rmluiSrc = pkgs.fetchFromGitHub { + owner = "mikke89"; + repo = "RmlUi"; + rev = "9c74c4fadc2ad7f1496239e560bab19ca2fe5072"; + hash = "sha256-YZz41ViE3+a0VPypnbJ1Orlf5Hyxd65se5yzyHIY7ZI="; + }; + + rmluiCmakeFlags = [ + "-DRMLUI_LUA_BINDINGS=OFF" + "-DRMLUI_SVG_PLUGIN=OFF" + "-DBUILD_SAMPLES=OFF" + "-DBUILD_TESTING=OFF" + ]; + + # Emscripten's toolchain file restricts find_library/find_path/find_package + # to CMAKE_FIND_ROOT_PATH (its own sysroot) by default. Our externally-built + # wasm deps (freetypeWasm, raylibWasm, rmluiWasm) live in the Nix store, + # outside that sysroot, so CMAKE_PREFIX_PATH alone is silently ignored + # unless we relax these three modes to BOTH. + wasmFindOverrides = [ + "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH" + "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH" + "-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH" + ]; + + # ---- native RmlUi (shared lib) -------------------------------------- + rmlui = pkgs.stdenv.mkDerivation { + pname = "rmlui"; + version = "master"; + src = rmluiSrc; + nativeBuildInputs = [ pkgs.cmake pkgs.pkg-config ]; + buildInputs = [ pkgs.freetype ]; + cmakeFlags = rmluiCmakeFlags ++ [ "-DBUILD_SHARED_LIBS=ON" ]; + }; + + # ---- WASM Freetype (static, minimal deps) --------------------------- + freetypeWasm = pkgs.stdenv.mkDerivation { + pname = "freetype-wasm"; + version = pkgs.freetype.version; + src = pkgs.freetype.src; + nativeBuildInputs = [ pkgs.cmake pkgs.emscripten ]; + dontFixup = true; + configurePhase = '' + emcmake cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DFT_DISABLE_ZLIB=TRUE \ + -DFT_DISABLE_BZIP2=TRUE \ + -DFT_DISABLE_PNG=TRUE \ + -DFT_DISABLE_HARFBUZZ=TRUE \ + -DFT_DISABLE_BROTLI=TRUE \ + -DCMAKE_INSTALL_PREFIX=$out + ''; + buildPhase = "emmake make -C build -j$NIX_BUILD_CORES"; + installPhase = "emmake make -C build install"; + }; + + # ---- WASM RmlUi (static) --------------------------------------------- + rmluiWasm = pkgs.stdenv.mkDerivation { + pname = "rmlui-wasm"; + version = "master"; + src = rmluiSrc; + nativeBuildInputs = [ pkgs.cmake pkgs.emscripten ]; + dontFixup = true; + configurePhase = '' + emcmake cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + ${pkgs.lib.concatStringsSep " " rmluiCmakeFlags} \ + ${pkgs.lib.concatStringsSep " " wasmFindOverrides} \ + -DCMAKE_PREFIX_PATH="${freetypeWasm}" \ + -DCMAKE_INSTALL_PREFIX=$out + ''; + buildPhase = "emmake make -C build -j$NIX_BUILD_CORES"; + installPhase = "emmake make -C build install"; + }; + + # ---- WASM raylib (PLATFORM=Web) --------------------------------------- + raylibWasm = pkgs.stdenv.mkDerivation { + pname = "raylib-wasm"; + version = pkgs.raylib.version; + src = pkgs.raylib.src; + nativeBuildInputs = [ pkgs.cmake pkgs.emscripten ]; + dontFixup = true; + configurePhase = '' + emcmake cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DPLATFORM=Web \ + -DBUILD_EXAMPLES=OFF \ + -DCMAKE_INSTALL_PREFIX=$out + ''; + buildPhase = "emmake make -C build -j$NIX_BUILD_CORES"; + installPhase = "emmake make -C build install"; + }; + + # ---- native toolchain / runtime --------------------------------------- + nativeBuildTools = with pkgs; [ + cmake + pkg-config + clang-tools + ]; + + nativeRuntimeDeps = with pkgs; [ + raylib + libGL + libX11 + libXcursor + libXrandr + libXinerama + libXi + wayland + libxkbcommon + rmlui + freetype + ]; + in + { + devShells.default = pkgs.mkShell { + nativeBuildInputs = nativeBuildTools; + buildInputs = nativeRuntimeDeps; + shellHook = '' + export C_INCLUDE_PATH="${rmlui}/include:${pkgs.raylib}/include" + export CPLUS_INCLUDE_PATH="$C_INCLUDE_PATH" + export LIBRARY_PATH="${pkgs.lib.makeLibraryPath nativeRuntimeDeps}" + export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH" + echo "native dev shell ready (raylib + rmlui)" + ''; + }; + + devShells.wasm = pkgs.mkShell { + nativeBuildInputs = [ pkgs.cmake pkgs.emscripten pkgs.python3 ]; + shellHook = '' + export RAYLIB_WASM="${raylibWasm}" + export RMLUI_WASM="${rmluiWasm}" + export FREETYPE_WASM="${freetypeWasm}" + echo "wasm dev shell ready — configure with:" + echo " emcmake cmake -B build-wasm -DPLATFORM=Web \\" + echo " -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH \\" + echo " -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \\" + echo " -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH \\" + echo " -DCMAKE_PREFIX_PATH=\"\$RAYLIB_WASM;\$RMLUI_WASM;\$FREETYPE_WASM\"" + echo " emmake make -C build-wasm" + ''; + }; + + packages.default = pkgs.stdenv.mkDerivation { + pname = "gamejam"; + version = "0.1.0"; + src = ./.; + nativeBuildInputs = nativeBuildTools ++ [ pkgs.makeWrapper ]; + buildInputs = nativeRuntimeDeps; + cmakeFlags = [ "-DCMAKE_BUILD_TYPE=Release" ]; + postInstall = '' + wrapProgram $out/bin/gamejam \ + --prefix LD_LIBRARY_PATH : "${pkgs.lib.makeLibraryPath nativeRuntimeDeps}" + ''; + }; + + packages.wasm = pkgs.stdenv.mkDerivation { + pname = "gamejam-wasm"; + version = "0.1.0"; + src = ./.; + nativeBuildInputs = [ pkgs.cmake pkgs.emscripten ]; + dontFixup = true; + configurePhase = '' + emcmake cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DPLATFORM=Web \ + ${pkgs.lib.concatStringsSep " " wasmFindOverrides} \ + -DCMAKE_PREFIX_PATH="${raylibWasm};${rmluiWasm};${freetypeWasm}" \ + -DCMAKE_INSTALL_PREFIX=$out + ''; + buildPhase = "emmake make -C build -j$NIX_BUILD_CORES"; + installPhase = '' + mkdir -p $out + cp -r build/*.html build/*.js build/*.wasm $out/ 2>/dev/null || true + emmake make -C build install || true + ''; + }; + } + ); +} diff --git a/src/Application.cpp b/src/Application.cpp new file mode 100644 index 0000000..e2efddd --- /dev/null +++ b/src/Application.cpp @@ -0,0 +1,51 @@ +#include "Application.h" +#include "backend/RaylibInput.h" + +#include +#include +#include + +bool Application::Init(int width, int height, const char* title, const char* documentPath) { + InitWindow(width, height, title); + SetTargetFPS(60); + + Rml::SetSystemInterface(&system_interface); + Rml::SetRenderInterface(&render_interface); + Rml::Initialise(); + + context = Rml::CreateContext("main", Rml::Vector2i(width, height)); + Rml::Debugger::Initialise(context); + + // TODO: load a real font + + if (Rml::ElementDocument* document = context->LoadDocument(documentPath)) { + document->Show(); + } else { + TraceLog(LOG_WARNING, "Failed to load %s", documentPath); + } + + return true; +} + +void Application::Frame() { + if (WindowShouldClose()) { + running = false; + return; + } + + ForwardInputToRml(context); + context->Update(); + + BeginDrawing(); + ClearBackground(DARKGRAY); + + // --- game world rendering goes here, before the UI --- + + context->Render(); + EndDrawing(); +} + +void Application::Shutdown() { + Rml::Shutdown(); + CloseWindow(); +} \ No newline at end of file diff --git a/src/Application.h b/src/Application.h new file mode 100644 index 0000000..c12a923 --- /dev/null +++ b/src/Application.h @@ -0,0 +1,19 @@ +#pragma once +#include +#include "backend/RaylibSystemInterface.h" +#include "backend/RaylibRenderInterface.h" + +class Application { +public: + bool Init(int width, int height, const char* title, const char* documentPath); + void Frame(); + void Shutdown(); + + bool IsRunning() const { return running; } + +private: + RaylibSystemInterface system_interface; + RaylibRenderInterface render_interface; + Rml::Context* context = nullptr; + bool running = true; +}; \ No newline at end of file diff --git a/src/backend/RaylibInput.cpp b/src/backend/RaylibInput.cpp new file mode 100644 index 0000000..7c2d267 --- /dev/null +++ b/src/backend/RaylibInput.cpp @@ -0,0 +1,25 @@ +#include "RaylibInput.h" +#include + +namespace { + int GetRmlKeyModifiers() { + int mods = 0; + if (IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT)) mods |= Rml::Input::KM_SHIFT; + if (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL)) mods |= Rml::Input::KM_CTRL; + if (IsKeyDown(KEY_LEFT_ALT) || IsKeyDown(KEY_RIGHT_ALT)) mods |= Rml::Input::KM_ALT; + return mods; + } +} + +void ForwardInputToRml(Rml::Context* context) { + Vector2 mouse = GetMousePosition(); + context->ProcessMouseMove((int)mouse.x, (int)mouse.y, GetRmlKeyModifiers()); + + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) context->ProcessMouseButtonDown(0, GetRmlKeyModifiers()); + if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) context->ProcessMouseButtonUp(0, GetRmlKeyModifiers()); + if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) context->ProcessMouseButtonDown(1, GetRmlKeyModifiers()); + if (IsMouseButtonReleased(MOUSE_BUTTON_RIGHT)) context->ProcessMouseButtonUp(1, GetRmlKeyModifiers()); + + float wheel = GetMouseWheelMove(); + if (wheel != 0.0f) context->ProcessMouseWheel(-wheel, GetRmlKeyModifiers()); +} \ No newline at end of file diff --git a/src/backend/RaylibInput.h b/src/backend/RaylibInput.h new file mode 100644 index 0000000..8b553bc --- /dev/null +++ b/src/backend/RaylibInput.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void ForwardInputToRml(Rml::Context* context); \ No newline at end of file diff --git a/src/backend/RaylibRenderInterface.cpp b/src/backend/RaylibRenderInterface.cpp new file mode 100644 index 0000000..d1a9d31 --- /dev/null +++ b/src/backend/RaylibRenderInterface.cpp @@ -0,0 +1,109 @@ +#include "RaylibRenderInterface.h" + +#include +#include + +#include +#include + +namespace { + + struct GeometryData { + std::vector vertices; + std::vector indices; + }; + +} + +Rml::CompiledGeometryHandle RaylibRenderInterface::CompileGeometry( + Rml::Span vertices, Rml::Span indices) { + auto* geo = new GeometryData(); + geo->vertices.assign(vertices.begin(), vertices.end()); + geo->indices.assign(indices.begin(), indices.end()); + return reinterpret_cast(geo); +} + +void RaylibRenderInterface::RenderGeometry(Rml::CompiledGeometryHandle handle, + Rml::Vector2f translation, + Rml::TextureHandle texture) { + auto* geo = reinterpret_cast(handle); + + if (texture) { + Texture2D* tex = reinterpret_cast(texture); + rlSetTexture(tex->id); + } else { + rlSetTexture(rlGetTextureIdDefault()); + } + + rlPushMatrix(); + rlTranslatef(translation.x, translation.y, 0.0f); + + rlBegin(RL_TRIANGLES); + for (size_t i = 0; i + 2 < geo->indices.size(); i += 3) { + for (int j = 0; j < 3; ++j) { + const Rml::Vertex& v = geo->vertices[geo->indices[i + j]]; + rlColor4ub(v.colour.red, v.colour.green, v.colour.blue, v.colour.alpha); + rlTexCoord2f(v.tex_coord.x, v.tex_coord.y); + rlVertex2f(v.position.x, v.position.y); + } + } + rlEnd(); + + rlPopMatrix(); + rlSetTexture(0); +} + +void RaylibRenderInterface::ReleaseGeometry(Rml::CompiledGeometryHandle handle) { + delete reinterpret_cast(handle); +} + +Rml::TextureHandle RaylibRenderInterface::LoadTexture(Rml::Vector2i& texture_dimensions, + const Rml::String& source) { + Texture2D tex = ::LoadTexture(source.c_str()); + if (tex.id == 0) { + TraceLog(LOG_WARNING, "[RmlUi] failed to load texture: %s", source.c_str()); + return 0; + } + texture_dimensions = Rml::Vector2i(tex.width, tex.height); + return reinterpret_cast(new Texture2D(tex)); +} + +Rml::TextureHandle RaylibRenderInterface::GenerateTexture(Rml::Span source_data, + Rml::Vector2i source_dimensions) { + Image img{}; + img.width = source_dimensions.x; + img.height = source_dimensions.y; + img.mipmaps = 1; + img.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + + size_t byte_count = static_cast(img.width) * img.height * 4; + img.data = RL_MALLOC(byte_count); + std::memcpy(img.data, source_data.data(), byte_count); + + Texture2D tex = LoadTextureFromImage(img); + UnloadImage(img); // frees img.data + + return reinterpret_cast(new Texture2D(tex)); +} + +void RaylibRenderInterface::ReleaseTexture(Rml::TextureHandle handle) { + Texture2D* tex = reinterpret_cast(handle); + UnloadTexture(*tex); + delete tex; +} + +void RaylibRenderInterface::EnableScissorRegion(bool enable) { + scissor_enabled = enable; + if (enable) ApplyScissor(); + else EndScissorMode(); +} + +void RaylibRenderInterface::SetScissorRegion(Rml::Rectanglei region) { + scissor_region = region; + if (scissor_enabled) ApplyScissor(); +} + +void RaylibRenderInterface::ApplyScissor() { + BeginScissorMode(scissor_region.Left(), scissor_region.Top(), + scissor_region.Width(), scissor_region.Height()); +} \ No newline at end of file diff --git a/src/backend/RaylibRenderInterface.h b/src/backend/RaylibRenderInterface.h new file mode 100644 index 0000000..5ca4273 --- /dev/null +++ b/src/backend/RaylibRenderInterface.h @@ -0,0 +1,37 @@ +#pragma once +#include + + +// NOTE: RmlUi's RenderInterface signature has shifted across versions +// (raw pointer+count vs. Rml::Span<>). If this fails to compile against +// a different RmlUi commit, check RmlUi/Core/RenderInterface.h and adjust +// CompileGeometry/GenerateTexture's parameter types, internal logic +// stays the same. + +class RaylibRenderInterface : public Rml::RenderInterface { +public: + Rml::CompiledGeometryHandle CompileGeometry(Rml::Span vertices, + Rml::Span indices) override; + + void RenderGeometry(Rml::CompiledGeometryHandle handle, Rml::Vector2f translation, + Rml::TextureHandle texture) override; + + void ReleaseGeometry(Rml::CompiledGeometryHandle handle) override; + + Rml::TextureHandle LoadTexture(Rml::Vector2i& texture_dimensions, + const Rml::String& source) override; + + Rml::TextureHandle GenerateTexture(Rml::Span source_data, + Rml::Vector2i source_dimensions) override; + + void ReleaseTexture(Rml::TextureHandle handle) override; + + void EnableScissorRegion(bool enable) override; + void SetScissorRegion(Rml::Rectanglei region) override; + +private: + void ApplyScissor(); + + bool scissor_enabled = false; + Rml::Rectanglei scissor_region; +}; \ No newline at end of file diff --git a/src/backend/RaylibSystemInterface.cpp b/src/backend/RaylibSystemInterface.cpp new file mode 100644 index 0000000..b954b5f --- /dev/null +++ b/src/backend/RaylibSystemInterface.cpp @@ -0,0 +1,14 @@ +#include "RaylibSystemInterface.h" +#include + +double RaylibSystemInterface::GetElapsedTime() { + return GetTime(); +} + +bool RaylibSystemInterface::LogMessage(Rml::Log::Type type, const Rml::String& message) { + TraceLogLevel level = LOG_INFO; + if (type == Rml::Log::LT_WARNING) level = LOG_WARNING; + if (type == Rml::Log::LT_ERROR || type == Rml::Log::LT_ASSERT) level = LOG_ERROR; + TraceLog(level, "[RmlUi] %s", message.c_str()); + return true; +} \ No newline at end of file diff --git a/src/backend/RaylibSystemInterface.h b/src/backend/RaylibSystemInterface.h new file mode 100644 index 0000000..4907bb4 --- /dev/null +++ b/src/backend/RaylibSystemInterface.h @@ -0,0 +1,8 @@ +#pragma once +#include + +class RaylibSystemInterface : public Rml::SystemInterface { +public: + double GetElapsedTime() override; + bool LogMessage(Rml::Log::Type type, const Rml::String& message) override; +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..8f74dff --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,33 @@ +#include "Application.h" + +#ifdef __EMSCRIPTEN__ +#include +#endif + +namespace { + +Application* g_app = nullptr; + +void MainLoopStep() { + g_app->Frame(); +} + +} // namespace + +int main() { + static Application app; + g_app = &app; + + app.Init(1280, 720, "gamejam", "assets/main.rml"); + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(MainLoopStep, 0, 1); +#else + while (app.IsRunning()) { + app.Frame(); + } +#endif + + app.Shutdown(); + return 0; +} \ No newline at end of file