From 237f9061270318dc76c6c0a96ffc63c1c9d1053f Mon Sep 17 00:00:00 2001 From: ShadesAndGrays Date: Fri, 10 Jul 2026 10:33:49 +0100 Subject: [PATCH] add web --- makefile | 67 ++++++++++++-- src/animation.cpp | 0 src/engine_variant.cpp | 0 src/include/animation.hpp | 22 +++++ src/include/engine_variant.hpp | 109 +++++++++++++++++++++++ src/include/engine_variant_operation.hpp | 74 +++++++++++++++ src/main.cpp | 66 ++++++++------ src/test.cpp | 69 ++++++-------- 8 files changed, 332 insertions(+), 75 deletions(-) create mode 100644 src/animation.cpp create mode 100644 src/engine_variant.cpp create mode 100644 src/include/animation.hpp create mode 100644 src/include/engine_variant.hpp create mode 100644 src/include/engine_variant_operation.hpp diff --git a/makefile b/makefile index 2ed6890..a882662 100644 --- a/makefile +++ b/makefile @@ -1,15 +1,30 @@ -.PHONY: all build-gui build-game run +.PHONY: all build-gui build-game run-desktop clean web CXX = g++ +WSL = wsl --shell-type login +WEB_CXX = $(WSL) em++ +# EMSCRIPTE_H_PATH = "//wsl.localhost/archlinux/home/shadow/dev/external/emsdk/upstream/emscripten/system/include/emscripten.h" +BROWSER = "C:\Program Files\Mozilla Firefox\firefox.exe" +# upstream/emscripten/system/include/emscripten.h +ASSETS = "data.dat" + + LDFLAGS = -L./external/raylib/lib \ -L./external/box2d/build/src \ -L./external/asset_packer/bin \ +WEB_LDFLAGS = -L./external/raylib-web/lib \ + -L./external/asset_packer/bin \ + -sUSE_GLFW=3 \ + --preload-file $(ASSETS) + LIBS = -lraylib -lwinmm -lgdi32 -lbox2d -lassetpacker +WEB_LIBS = -lraylib.web -lassetpacker.web + CXXFLAGS = -std=c++20 -O2 \ - -MMD -MP + -MMD -MP DEBUGFLAGS = -std=c++20 -g -O0 @@ -22,6 +37,16 @@ INCLUDES = -I./external/raylib/include \ -I./external/nhlohmann_json_3.12.0/ \ -I./external/asset_packer/bin/include \ +WEB_INCLUDES = -I./external/raylib-web/include \ + -I./external/entt/single_include \ + -I./src/include \ + -I./external/imgui \ + -I./external/rlImGui \ + -I./external/box2d/include \ + -I./external/nhlohmann_json_3.12.0/ \ + -I./external/asset_packer/bin/include \ + # -I./external/emscripten/include \ + IMGUI_SRCS = ./external/imgui/imgui.cpp \ ./external/imgui/imgui_demo.cpp \ ./external/imgui/imgui_draw.cpp \ @@ -50,7 +75,7 @@ OBJS_FILES = $(patsubst ./src/%.cpp,./bin/%.o,$(SRC_FILES)) DEP_FILES = $(patsubst ./bin/%.o,./bin/%.d,$(OBJS_FILES)) -all: build-game run +all: build-game run-desktop ./bin/%.o: ./external/imgui/%.cpp @mkdir -p bin @@ -65,10 +90,18 @@ all: build-game run @mkdir -p $(dir $@) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ -compile_commands.json: clean +ccj: clean @echo "Generating compile_commands.json..." bear -- $(MAKE) +ccj-web: clean + @echo "Generating web compile_commands.json..." + $(WSL) bear -- $(MAKE) web-native + @sed -i '$$ s/,$$//' compile_commands.json + @sed -i 's|"/home/|"\\\\\\\\wsl.localhost\\\\archlinux\\\\home\\\\|g' compile_commands.json + @sed -i 's|=/home/|=\\\\\\\\wsl.localhost\\\\archlinux\\\\home\\\\|g' compile_commands.json + @sed -i 's|"/mnt/c/|"C:/|g' compile_commands.json + -include $(DEP_FILES) build-gui: $(IMGUI_OBJS) @@ -93,22 +126,42 @@ build-debug: $(CXX) $(DEBUGFLAGS) $(INCLUDES) $(ENTRY_POINT) $(SRC_FILES) $(IMGUI_OBJS) $(IMGUI_BACKEND_OBJS) $(LDFLAGS) $(LIBS) -o ./debug/d.exe cp ./data.dat ./debug -rf +web: + @mkdir -p web + $(WEB_CXX) $(CXXFLAGS) $(WEB_INCLUDES) $(ENTRY_POINT) $(SRC_FILES) $(IMGUI_SRCS) $(IMGUI_BACKEND) $(WEB_LDFLAGS) $(WEB_LIBS) -o ./web/web.html +web-native: + @mkdir -p web + em++ $(CXXFLAGS) $(WEB_INCLUDES) $(ENTRY_POINT) $(SRC_FILES) $(IMGUI_SRCS) $(IMGUI_BACKEND) $(WEB_LDFLAGS) $(WEB_LIBS) -o ./web/web.html -clean: +clean-desktop: @rm -r -f ./bin @rm -f compile_commands.json clean-debug: @rm -r -f ./debug -clean-all: clean clean-debug +clean-web: + @rm -r -f ./web -run: +clean: clean-desktop clean-debug clean-web + +run-desktop: ./bin/main.exe +open-browser: + $(BROWSER) + +start-server: + $(WSL) python -m http.server 3000 -d ./web +run-web: + $(BROWSER) http://localhost:3000/web.html + $(WSL) python -m http.server 3000 -d ./web + # $(WSL) node ./web/web.js + run-debug: ./debug/d.exe run-test: build-test ./bin/test.exe + diff --git a/src/animation.cpp b/src/animation.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/engine_variant.cpp b/src/engine_variant.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/include/animation.hpp b/src/include/animation.hpp new file mode 100644 index 0000000..e66aa35 --- /dev/null +++ b/src/include/animation.hpp @@ -0,0 +1,22 @@ +#pragma once +#include + +class AnimationManager{ + private: + unsigned int glboal_id; + + public: + + +}; + +// Component attacked to an object for playing animation +struct AnimationComponent{ + unsigned int id; + std::string track_key; + float elapsed_time; + bool is_playing; + bool is_completed; + float speed_scale; + std::string group_name; +}; diff --git a/src/include/engine_variant.hpp b/src/include/engine_variant.hpp new file mode 100644 index 0000000..f4849d8 --- /dev/null +++ b/src/include/engine_variant.hpp @@ -0,0 +1,109 @@ +#pragma once +#include +#include +#include +#include + +struct Vec2 { + float x = 0.0f; + float y = 0.0f; + + bool operator==(const Vec2& o) const { return x == o.x && y == o.y; } + bool operator!=(const Vec2& o) const { return !(*this == o); } + Vec2 operator+(const Vec2& o) const { return { x + o.x, y + o.y }; } + Vec2 operator-(const Vec2& o) const { return { x - o.x, y - o.y }; } + Vec2 operator*(float scalar) const { return { x * scalar, y * scalar }; } +}; + +struct Vec3 { + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + + bool operator==(const Vec3& o) const { return x == o.x && y == o.y && z == o.z; } + bool operator!=(const Vec3& o) const { return !(*this == o); } + Vec3 operator+(const Vec3& o) const { return { x + o.x, y + o.y, z + o.z }; } + Vec3 operator-(const Vec3& o) const { return { x - o.x, y - o.y, z - o.z }; } + Vec3 operator*(float scalar) const { return { x * scalar, y * scalar, z * scalar }; } +}; + +struct Vec4 { + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + float w = 1.0f; + + bool operator==(const Vec4& o) const { return x == o.x && y == o.y && z == o.z && w == o.w; } + bool operator!=(const Vec4& o) const { return !(*this == o); } + Vec4 operator+(const Vec4& o) const { return { x + o.x, y + o.y, z + o.z, w + o.w }; } + Vec4 operator-(const Vec4& o) const { return { x - o.x, y - o.y, z - o.z, w - o.w }; } + Vec4 operator*(float scalar) const { return { x * scalar, y * scalar, z * scalar, w * scalar }; } +}; + + +// Standalone Interpolation Helpers +inline Vec2 Vec2Lerp(const Vec2& s, const Vec2& e, float a) { return { s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a }; } +inline Vec3 Vec3Lerp(const Vec3& s, const Vec3& e, float a) { return { s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a, s.z + (e.z - s.z) * a }; } +inline Vec4 Vec4Lerp(const Vec4& s, const Vec4& e, float a) { return { s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a, s.z + (e.z - s.z) * a, s.w + (e.w - s.w) * a }; } + + + + +enum class VariantType { Null, Float, Vector2, Vector3, Vector4, String }; + +class EngineVariant{ + + public: + using InternalVariant = std::variant; + + EngineVariant() : data(std::monostate{}), type(VariantType::Null){} + EngineVariant(float v) : data(v), type(VariantType::Float){} + EngineVariant(Vec2 v) : data(v), type(VariantType::Vector2){} + EngineVariant(Vec3 v) : data(v), type(VariantType::Vector3){} + EngineVariant(Vec4 v) : data(v), type(VariantType::Vector4){} + EngineVariant(std::string v) : data(v), type(VariantType::String){} + + VariantType GetType() const { return type; } + + template + T Get() const { + std::lock_guard lock(v_mutex); + return std::get(data); + } + + void Print() const { + + std::lock_guard lock(v_mutex); + std::cout << "[Variant " << TypeToString(type) << "]: "; + std::visit([](auto &&arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) std::cout << "Null"; + else if constexpr (std::is_same_v) std::cout << arg; + else if constexpr (std::is_same_v) std::cout << "(" << arg.x << ", " << arg.y << ")"; + else if constexpr (std::is_same_v) std::cout << "(" << arg.x << ", " << arg.y << ", " << arg.z << ")"; + else if constexpr (std::is_same_v) std::cout << "(" << arg.x << ", " << arg.y << ", " << arg.z << ", " << arg.w << ")"; + else if constexpr (std::is_same_v) std::cout << "\"" << arg << "\""; + + },data); + + std::cout << "\n"; + } + + private: + InternalVariant data; + VariantType type; + mutable std::mutex v_mutex; + + static std::string TypeToString(VariantType t) { + switch(t) { + case VariantType::Float: return "Float"; + case VariantType::Vector2: return "Vector2"; + case VariantType::Vector3: return "Vector3"; + case VariantType::Vector4: return "Vector4"; + case VariantType::String: return "String"; + default: return "Null"; + } + } + + friend class VariantOpManager; +}; diff --git a/src/include/engine_variant_operation.hpp b/src/include/engine_variant_operation.hpp new file mode 100644 index 0000000..db02cd9 --- /dev/null +++ b/src/include/engine_variant_operation.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include + +template struct overloaded : Ts... { using Ts::operator()...; }; +template overloaded(Ts...) -> overloaded; + +enum class OpType { + Assign, // Replace the old value entirely + Add, // Add to the current value + Multiply, // Add to the current value + Lerp // Smoothly blend toward a value +}; + +struct VariantOpRequest { + EngineVariant* target; // The variable we want to change + OpType operation; // How we want to change it + EngineVariant operand; // The value we are using to make the change + float alpha; // Used ONLY for Lerp (0.0 to 1.0) +}; + +class VariantOpManager{ + + public: + VariantOpManager(){} + void ExecuteOperation(const VariantOpRequest& req) { + + if (req.target == nullptr) return; + + switch (req.operation){ + + case OpType::Assign: + req.target->data = req.operand.data; + req.target->type = req.operand.type; + break; + case OpType::Add: + req.target->data = std::visit( + overloaded{ + [](float p, float n) -> EngineVariant::InternalVariant {return p + n;}, + [](Vec2 p, Vec2 n) -> EngineVariant::InternalVariant {return p + n;}, + [](Vec3 p, Vec3 n) -> EngineVariant::InternalVariant {return p + n;}, + [](Vec4 p, Vec4 n) -> EngineVariant::InternalVariant {return p + n;}, + + // Fallback + [](auto p, auto n) -> EngineVariant::InternalVariant {return p;}, + },req.target->data,req.operand.data); + break; + + case OpType::Lerp: + req.target->data = std::visit(overloaded{ + [&](float p, float n) -> EngineVariant::InternalVariant { return p + (n - p) * req.alpha; }, + [&](Vec2 p, Vec2 n) -> EngineVariant::InternalVariant { return Vec2Lerp(p, n, req.alpha); }, + [&](Vec3 p, Vec3 n) -> EngineVariant::InternalVariant { return Vec3Lerp(p, n, req.alpha); }, + [&](Vec4 p, Vec4 n) -> EngineVariant::InternalVariant { return Vec4Lerp(p, n, req.alpha); }, + [&](const std::string& p, const std::string& n) -> EngineVariant::InternalVariant { + return req.alpha >= 0.5f ? n : p; // Discrete switch for strings + }, + + // Fallback + [](auto p, auto n) -> EngineVariant::InternalVariant { return p; } + }, req.target->data, req.operand.data); + break; + + case OpType::Multiply: + req.target->data = std::visit(overloaded{ + [](float p, float n) -> EngineVariant::InternalVariant { return p * n; }, + [](Vec2 p, float n) -> EngineVariant::InternalVariant { return p * n; }, // Scale a vector! + [](auto p, auto n) -> EngineVariant::InternalVariant { return p; } + }, req.target->data, req.operand.data); + break; + } + + } +}; diff --git a/src/main.cpp b/src/main.cpp index 0cb9607..8a42615 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,23 +12,50 @@ #include +#ifdef __EMSCRIPTEN__ +#include +#endif // Globals EngineState g_Engine; RaylibAssetLoader asset_loader; +entt::registry * registry; +SceneManager* scene_manager; + +void UpdateDrawFrame(void) { + // Update + + float dt = GetFrameTime(); + // cap dt just for now + if (dt > 0.1f) dt = 0.1f; + + // Draw + scene_manager->update(dt); + + BeginDrawing(); + ClearBackground(RAYWHITE); + + scene_manager->render(); + + rlImGuiBegin(); + scene_manager->ui(); + rlImGuiEnd(); + + EndDrawing(); + + scene_manager->process_scene_switch(); // !!! After scene_manager is done with the current loop +} + int main(){ -// + int screen_width = 1280; int screen_height = 800; - - // initialized scene manager - SceneManager scene_manager; - - entt::registry registry; + scene_manager = new SceneManager(); + registry = new entt::registry(); rlImGuiSetup(true); @@ -50,35 +77,24 @@ int main(){ style.ScrollbarSize = 15.0f; SetTargetFPS(60); - SetTraceLogLevel(TraceLogLevel::LOG_NONE); + // SetTraceLogLevel(TraceLogLevel::LOG_NONE); InitWindow(screen_width, screen_height, "Bullet bird"); SetWindowState(FLAG_WINDOW_RESIZABLE); +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); +#else while (!WindowShouldClose() && !g_Engine.shouldQuit){ - - float dt = GetFrameTime(); - if (dt > 0.1f) dt = 0.1f; // cap dt just for now - - scene_manager.update(dt); - - BeginDrawing(); - ClearBackground(RAYWHITE); - - scene_manager.render(); - - rlImGuiBegin(); - scene_manager.ui(); - rlImGuiEnd(); - - EndDrawing(); - - scene_manager.process_scene_switch(); // !!! After scene_manager is done with the current loop + UpdateDrawFrame(); } +#endif CloseWindow(); rlImGuiShutdown(); + delete scene_manager; + delete registry; return 0; } diff --git a/src/test.cpp b/src/test.cpp index 69126d6..da0f077 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1,3 +1,4 @@ +#include "engine_variant_operation.hpp" #include #include #include @@ -9,67 +10,49 @@ #include #include #include +#include +// #include #include #include #include #include +#include -// #include -// #include EngineState g_Engine; RaylibAssetLoader asset_loader; -// size_t get_current_ram_usage() { -// PROCESS_MEMORY_COUNTERS pmc; -// if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) { -// return pmc.WorkingSetSize; -// } -// return 0; -// } -void asset_thread(){ - // for (int i = 0; i < 1000000; i++){ - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - asset_loader.load_asset("assets/bird.png"); - // asset_loader.unload_asset("assets/bird.png"); - // if (WindowShouldClose()) break; - // } -} +class Counter { + public: + int value; + +}; int main() { + // std::variant v1; - int* num = reinterpret_cast(new char[4]); - SetTraceLogLevel(LOG_NONE); - InitWindow(800,800,"test"); - // std::cout << "Starting Test..." << std::endl; - // std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + // v1 = "hero"; - // std::thread t(asset_thread); - // asset_loader.load_asset("assets/bird.png"); + // std::cout << v1.index(); - while(!WindowShouldClose()){ - // size_t ram_bytes = get_current_ram_usage(); - asset_loader.load_asset("assets/bird.png"); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - asset_loader.unload_asset("assets/bird.png"); + Vec2 v1(1,2); - BeginDrawing(); - ClearBackground(RAYWHITE); - // auto tex = asset_loader.get_texture("assets/bird.png"); - // if (tex != nullptr){ - // DrawTexture(*tex, 0,0,WHITE); - // } - rlImGuiBegin(); - ImGui::TextUnformatted(std::format("hello {}","world").c_str()); - // ImGui::TextUnformatted(std::format("Memory usage: %.2f",ram_bytes/(1024*1024)).c_str()); - rlImGuiEnd(); - EndDrawing(); - } + EngineVariant position(v1); - // t.join(); - CloseWindow(); + VariantOpRequest op{ + &position, + OpType::Multiply, + EngineVariant (2), + 0.0f + + }; + VariantOpManager().ExecuteOperation(op); + + position.Print(); + + // std::cout << var.Get(); return 0; }