diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ecf4dc..294e404 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,25 +3,34 @@ project(MassSprings) set(CMAKE_CXX_STANDARD 23) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) find_package(raylib REQUIRED) -find_package(OpenMP REQUIRED) # Need to enable/disable this based on a variable for nix build if(USE_TRACY) -include(FetchContent) -FetchContent_Declare(tracy - GIT_REPOSITORY https://github.com/wolfpld/tracy.git - GIT_TAG v0.11.1 - GIT_SHALLOW TRUE - GIT_PROGRESS TRUE -) -FetchContent_MakeAvailable(tracy) -option(TRACY_ENABLE "" ON) -option(TRACY_ON_DEMAND "" ON) + include(FetchContent) + FetchContent_Declare(tracy + GIT_REPOSITORY https://github.com/wolfpld/tracy.git + GIT_TAG v0.11.1 + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + ) + FetchContent_MakeAvailable(tracy) + option(TRACY_ENABLE "" ON) + option(TRACY_ON_DEMAND "" ON) endif() +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wno-unused-parameter -Wunreachable-code") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -ggdb -fsanitize=undefined") # -fsanitize=address already fails on InitWindow() +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -march=native") + +message("-- CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") +message("-- CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}") +message("-- CMAKE_C_FLAGS_RELEASE: ${CMAKE_C_FLAGS_RELEASE}") +message("-- CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") +message("-- CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") +message("-- CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") + include_directories(include) add_executable(masssprings @@ -33,11 +42,22 @@ add_executable(masssprings src/puzzle.cpp src/state.cpp src/input.cpp + src/tracy.cpp ) target_include_directories(masssprings PUBLIC ${RAYLIB_CPP_INCLUDE_DIR}) + if(USE_TRACY) -target_link_libraries(masssprings PUBLIC raylib OpenMP::OpenMP_CXX TracyClient) + target_link_libraries(masssprings PUBLIC raylib TracyClient) else() -target_link_libraries(masssprings PUBLIC raylib OpenMP::OpenMP_CXX) + target_link_libraries(masssprings PUBLIC raylib) +endif() + +include(CheckIPOSupported) +check_ipo_supported(RESULT supported OUTPUT error) +if(supported) + message(STATUS "IPO / LTO enabled") + set_property(TARGET masssprings PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) +else() + message(STATUS "IPO / LTO not supported: <${error}>") endif() diff --git a/compile_commands.json b/compile_commands.json index fd9db9d..66636ac 120000 --- a/compile_commands.json +++ b/compile_commands.json @@ -1 +1 @@ -./cmake-build-release/compile_commands.json \ No newline at end of file +./cmake-build-debug/compile_commands.json \ No newline at end of file diff --git a/flake.nix b/flake.nix index 3caaadb..694ed91 100644 --- a/flake.nix +++ b/flake.nix @@ -26,76 +26,76 @@ rec { # =========================================================================================== # 64 bit C/C++ compilers that don't collide (use the same libc) - bintools = pkgs.wrapBintoolsWith { - bintools = pkgs.bintools.bintools; # Unwrapped bintools - libc = pkgs.glibc; - }; - gcc = lib.hiPrio (pkgs.wrapCCWith { - cc = pkgs.gcc.cc; # Unwrapped gcc - libc = pkgs.glibc; - bintools = bintools; - }); - clang = pkgs.wrapCCWith { - cc = pkgs.clang.cc; # Unwrapped clang - libc = pkgs.glibc; - bintools = bintools; - }; + # bintools = pkgs.wrapBintoolsWith { + # bintools = pkgs.bintools.bintools; # Unwrapped bintools + # libc = pkgs.glibc; + # }; + # gcc = lib.hiPrio (pkgs.wrapCCWith { + # cc = pkgs.gcc.cc; # Unwrapped gcc + # libc = pkgs.glibc; + # bintools = bintools; + # }); + # clang = pkgs.wrapCCWith { + # cc = pkgs.clang.cc; # Unwrapped clang + # libc = pkgs.glibc; + # bintools = bintools; + # }; # Raylib CPP wrapper - raylib-cpp = stdenv.mkDerivation { - pname = "raylib-cpp"; - version = "5.5.0-unstable-2025-11-12"; + # raylib-cpp = stdenv.mkDerivation { + # pname = "raylib-cpp"; + # version = "5.5.0-unstable-2025-11-12"; + # + # src = pkgs.fetchFromGitHub { + # owner = "RobLoach"; + # repo = "raylib-cpp"; + # rev = "21b0d0f57a09a7f741d20b7157f440ae87f02c76"; + # hash = "sha256-P9x6Zc5t648gR7oYXe38PEX/a4oh4PfuVCnjT0vC10k="; + # }; + # + # # autoPatchelfHook is needed for appendRunpaths + # nativeBuildInputs = with pkgs; [ + # cmake + # # autoPatchelfHook + # ]; + # + # buildInputs = with pkgs; [ + # raylib + # glfw + # SDL2 + # ]; + # + # propagatedBuildInputs = with pkgs; [ + # libGLU + # libx11 + # ]; + # + # cmakeFlags = [ + # "-DBUILD_RAYLIB_CPP_EXAMPLES=OFF" + # "-DBUILD_TESTING=OFF" + # # Point CMake to the nixpkgs raylib so it doesn't try to fetch its own + # "-Draylib_DIR=${pkgs.raylib}/lib/cmake/raylib" + # ]; + # }; - src = pkgs.fetchFromGitHub { - owner = "RobLoach"; - repo = "raylib-cpp"; - rev = "21b0d0f57a09a7f741d20b7157f440ae87f02c76"; - hash = "sha256-P9x6Zc5t648gR7oYXe38PEX/a4oh4PfuVCnjT0vC10k="; - }; - - # autoPatchelfHook is needed for appendRunpaths - nativeBuildInputs = with pkgs; [ - cmake - # autoPatchelfHook - ]; - - buildInputs = with pkgs; [ - raylib - glfw - SDL2 - ]; - - propagatedBuildInputs = with pkgs; [ - libGLU - libx11 - ]; - - cmakeFlags = [ - "-DBUILD_RAYLIB_CPP_EXAMPLES=OFF" - "-DBUILD_TESTING=OFF" - # Point CMake to the nixpkgs raylib so it doesn't try to fetch its own - "-Draylib_DIR=${pkgs.raylib}/lib/cmake/raylib" - ]; - }; - - octree = stdenv.mkDerivation { - pname = "octree"; - version = "2.5-unstable-2025-12-18"; - - src = pkgs.fetchFromGitHub { - owner = "attcs"; - repo = "octree"; - rev = "5058b3090c8b88e405fe2bfddd6c1c872f2b79d2"; - hash = "sha256-a/aDGQ7cj1GbCjts2s9VEaxyFnL6PF+xJOsSxm9o+4M="; - }; - - # Header-only library - dontBuild = true; - installPhase = '' - mkdir -p $out/include - mv ./*.h $out/include/ - ''; - }; + # octree = stdenv.mkDerivation { + # pname = "octree"; + # version = "2.5-unstable-2025-12-18"; + # + # src = pkgs.fetchFromGitHub { + # owner = "attcs"; + # repo = "octree"; + # rev = "5058b3090c8b88e405fe2bfddd6c1c872f2b79d2"; + # hash = "sha256-a/aDGQ7cj1GbCjts2s9VEaxyFnL6PF+xJOsSxm9o+4M="; + # }; + # + # # Header-only library + # dontBuild = true; + # installPhase = '' + # mkdir -p $out/include + # mv ./*.h $out/include/ + # ''; + # }; thread-pool = stdenv.mkDerivation { pname = "thread-pool"; @@ -130,10 +130,6 @@ rec { # Languages: # bintools gcc - # clang - # bintools_multilib - # gcc_multilib - # clang_multilib # C/C++: gdb @@ -161,9 +157,9 @@ rec { # sfml raylib # octree # this one doesn't store center of mass per node - which I need :( - llvmPackages.openmp # not required for compilation but for clangd to find the headers - tracy + tracy-wayland thread-pool + # llvmPackages.openmp # not required for compilation but for clangd to find the headers # raylib-cpp # tinyobjloader # gperftools @@ -235,8 +231,8 @@ rec { pkgs.writers.writeFish "cmake-${typeLower}.fish" '' cd $FLAKE_PROJECT_ROOT - # set -g -x CC ${clang}/bin/clang - # set -g -x CXX ${clang}/bin/clang++ + # set -g -x CC ${pkgs.clang}/bin/clang + # set -g -x CXX ${pkgs.clang}/bin/clang++ echo "Removing build directory ./cmake-build-${typeLower}/" rm -rf ./cmake-build-${typeLower} @@ -266,7 +262,7 @@ rec { cd $FLAKE_PROJECT_ROOT/cmake-build-${typeLower} echo "Running cmake" - cmake --build . -j$(nproc) + NIX_ENFORCE_NO_NATIVE=0 cmake --build . -j$(nproc) ''; buildDebug = mkBuildScript "Debug"; @@ -286,6 +282,8 @@ rec { abbr -a build-release "${buildRelease}" abbr -a debug "${buildDebug} && ./cmake-build-debug/masssprings" abbr -a release "${buildRelease} && ./cmake-build-release/masssprings" + abbr -a rungdb "${buildDebug} && gdb --tui ./cmake-build-debug/masssprings" + abbr -a runtracy "tracy -a 127.0.0.1" ''; in builtins.concatStringsSep "\n" [ diff --git a/include/camera.hpp b/include/camera.hpp index 749cbd3..ebb227d 100644 --- a/include/camera.hpp +++ b/include/camera.hpp @@ -26,7 +26,8 @@ private: public: OrbitCamera3D() - : camera({0}), position(Vector3Zero()), target(Vector3Zero()), + : camera(Camera(Vector3Zero(), Vector3Zero(), Vector3Zero(), 0.0, 0)), + position(Vector3Zero()), target(Vector3Zero()), distance(CAMERA_DISTANCE), angle_x(0.0), angle_y(0.0), last_mouse(Vector2Zero()), rotating(false), panning(false), target_lock(true) { diff --git a/include/input.hpp b/include/input.hpp index bad4dc9..69e0bc5 100644 --- a/include/input.hpp +++ b/include/input.hpp @@ -19,8 +19,8 @@ public: int block_add_y; public: - InputHandler(StateManager &state, Renderer &renderer) - : state(state), renderer(renderer), hov_x(-1), hov_y(-1), sel_x(0), + InputHandler(StateManager &_state, Renderer &_renderer) + : state(_state), renderer(_renderer), hov_x(-1), hov_y(-1), sel_x(0), sel_y(0), has_block_add_xy(false), block_add_x(-1), block_add_y(-1) {} InputHandler(const InputHandler ©) = delete; diff --git a/include/physics.hpp b/include/physics.hpp index 7268dec..25bfaaa 100644 --- a/include/physics.hpp +++ b/include/physics.hpp @@ -27,9 +27,9 @@ public: const bool fixed; public: - Mass(float mass, Vector3 position, bool fixed) - : mass(mass), position(position), previous_position(position), - velocity(Vector3Zero()), force(Vector3Zero()), fixed(fixed) {} + Mass(float _mass, Vector3 _position, bool _fixed) + : mass(_mass), position(_position), previous_position(_position), + velocity(Vector3Zero()), force(Vector3Zero()), fixed(_fixed) {} public: auto ClearForce() -> void; @@ -50,10 +50,10 @@ public: const float rest_length; public: - Spring(Mass &massA, Mass &massB, float spring_constant, - float dampening_constant, float rest_length) - : massA(massA), massB(massB), spring_constant(spring_constant), - dampening_constant(dampening_constant), rest_length(rest_length) {} + Spring(Mass &_massA, Mass &_massB, float _spring_constant, + float _dampening_constant, float _rest_length) + : massA(_massA), massB(_massB), spring_constant(_spring_constant), + dampening_constant(_dampening_constant), rest_length(_rest_length) {} public: auto CalculateSpringForce() const -> void; diff --git a/include/puzzle.hpp b/include/puzzle.hpp index a169387..a197487 100644 --- a/include/puzzle.hpp +++ b/include/puzzle.hpp @@ -31,15 +31,15 @@ public: bool target; public: - Block(int x, int y, int width, int height, bool target) - : x(x), y(y), width(width), height(height), target(target) { - if (x < 0 || x + width >= 10 || y < 0 || y + height >= 10) { + Block(int _x, int _y, int _width, int _height, bool _target) + : x(_x), y(_y), width(_width), height(_height), target(_target) { + if (_x < 0 || _x + _width >= 10 || _y < 0 || _y + _height >= 10) { std::cerr << "Block must fit on a 9x9 board!" << std::endl; exit(1); } } - Block(int x, int y, std::string block) : x(x), y(y) { + Block(int _x, int _y, std::string block) : x(_x), y(_y) { if (block == "..") { this->x = 0; this->y = 0; @@ -68,7 +68,7 @@ public: height = std::stoi(block.substr(1, 1)); } - if (x < 0 || x + width >= 10 || y < 0 || y + height >= 10) { + if (_x < 0 || _x + width >= 10 || _y < 0 || _y + height >= 10) { std::cerr << "Block must fit on a 9x9 board!" << std::endl; exit(1); } @@ -125,10 +125,10 @@ public: int current_pos; public: - BlockIterator(const State &state) : state(state), current_pos(0) {} + BlockIterator(const State &_state) : state(_state), current_pos(0) {} - BlockIterator(const State &state, int current_pos) - : state(state), current_pos(current_pos) {} + BlockIterator(const State &_state, int _current_pos) + : state(_state), current_pos(_current_pos) {} Block operator*() const { return Block(current_pos % state.width, current_pos / state.width, @@ -150,25 +150,25 @@ public: }; public: - State(int width, int height, bool restricted) - : width(width), height(height), restricted(restricted), - state(std::format("{}{}x{}:{}", restricted ? "R" : "F", width, height, - std::string(width * height * 2, '.'))) { - if (width <= 0 || width >= 10 || height <= 0 || height >= 10) { + State(int _width, int _height, bool _restricted) + : width(_width), height(_height), restricted(_restricted), + state(std::format("{}{}x{}:{}", _restricted ? "R" : "F", _width, + _height, std::string(_width * _height * 2, '.'))) { + if (_width <= 0 || _width >= 10 || _height <= 0 || _height >= 10) { std::cerr << "State width/height must be in [1, 9]!" << std::endl; exit(1); } } - explicit State(std::string state) - : width(std::stoi(state.substr(1, 1))), - height(std::stoi(state.substr(3, 1))), - restricted(state.substr(0, 1) == "R"), state(state) { + explicit State(std::string _state) + : width(std::stoi(_state.substr(1, 1))), + height(std::stoi(_state.substr(3, 1))), + restricted(_state.substr(0, 1) == "R"), state(_state) { if (width <= 0 || width >= 10 || height <= 0 || height >= 10) { std::cerr << "State width/height must be in [1, 9]!" << std::endl; exit(1); } - if (state.length() != width * height * 2 + 5) { + if (static_cast(_state.length()) != width * height * 2 + 5) { std::cerr << "State representation must have length [width * height * 2 + 5]!" << std::endl; diff --git a/include/renderer.hpp b/include/renderer.hpp index 92612fe..2dfbcaa 100644 --- a/include/renderer.hpp +++ b/include/renderer.hpp @@ -19,7 +19,7 @@ private: // Instancing Material vertex_mat; - int transforms_size; + std::size_t transforms_size; Matrix *transforms; Mesh cube_instance; Shader instancing_shader; @@ -29,9 +29,9 @@ public: bool connect_solutions; public: - Renderer(const OrbitCamera3D &camera) - : camera(camera), mark_solutions(false), connect_solutions(false), - transforms_size(0), transforms(nullptr) { + Renderer(const OrbitCamera3D &_camera) + : camera(_camera), transforms_size(0), transforms(nullptr), + mark_solutions(false), connect_solutions(false) { render_target = LoadRenderTexture(GetScreenWidth() / 2.0, GetScreenHeight() - MENU_HEIGHT); klotski_target = LoadRenderTexture(GetScreenWidth() / 2.0, diff --git a/include/state.hpp b/include/state.hpp index 3678360..dfd3684 100644 --- a/include/state.hpp +++ b/include/state.hpp @@ -13,6 +13,7 @@ public: MassSpringSystem &mass_springs; int current_preset; + State starting_state; State current_state; State previous_state; @@ -22,10 +23,11 @@ public: std::unordered_set visited_states; public: - StateManager(MassSpringSystem &mass_springs) - : mass_springs(mass_springs), current_preset(0), - current_state(generators[current_preset]()), - previous_state(current_state), edited(false) { + StateManager(MassSpringSystem &_mass_springs) + : mass_springs(_mass_springs), current_preset(0), + starting_state(generators[current_preset]()), + current_state(starting_state), previous_state(starting_state), + edited(false) { mass_springs.AddMass(MASS, false, current_state); } diff --git a/include/tracy.hpp b/include/tracy.hpp new file mode 100644 index 0000000..be7031c --- /dev/null +++ b/include/tracy.hpp @@ -0,0 +1,10 @@ +#ifndef __TRACY_HPP_ +#define __TRACY_HPP_ + +#include + +void *operator new(std::size_t count); +void operator delete(void *ptr) noexcept; +void operator delete(void *ptr, std::size_t count) noexcept; + +#endif diff --git a/src/camera.cpp b/src/camera.cpp index ba3c517..b838f2a 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,5 +1,6 @@ #include "camera.hpp" #include "config.hpp" +#include "tracy.hpp" #include #include diff --git a/src/input.cpp b/src/input.cpp index df06a17..78d1800 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1,9 +1,10 @@ +#include "input.hpp" +#include "config.hpp" +#include "tracy.hpp" + #include #include -#include "config.hpp" -#include "input.hpp" - auto InputHandler::HandleMouseHover() -> void { const int board_width = GetScreenWidth() / 2.0 - 2 * BOARD_PADDING; const int board_height = GetScreenHeight() - MENU_HEIGHT - 2 * BOARD_PADDING; diff --git a/src/main.cpp b/src/main.cpp index fd7d0c4..6ddc04b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,15 @@ -#include -#include -#include - #include "config.hpp" #include "input.hpp" #include "physics.hpp" #include "renderer.hpp" #include "state.hpp" +#include "tracy.hpp" + +#include +#include +#include +#include +// #include #ifdef PRINT_TIMINGS #include @@ -38,6 +41,8 @@ auto main(int argc, char *argv[]) -> int { SetConfigFlags(FLAG_WINDOW_ALWAYS_RUN); InitWindow(INITIAL_WIDTH * 2, INITIAL_HEIGHT + MENU_HEIGHT, "MassSprings"); + // TracyGpuContext; + // Game setup OrbitCamera3D camera; Renderer renderer(camera); @@ -101,7 +106,7 @@ auto main(int argc, char *argv[]) -> int { renderer.UpdateTextureSizes(); renderer.DrawMassSprings(mass_springs, state.current_state, - state.CurrentGenerator()(), state.winning_states, + state.starting_state, state.winning_states, state.visited_states); renderer.DrawKlotski(state.current_state, input.hov_x, input.hov_y, diff --git a/src/octree.cpp b/src/octree.cpp index 9e6c262..2bbcd41 100644 --- a/src/octree.cpp +++ b/src/octree.cpp @@ -1,5 +1,6 @@ #include "octree.hpp" #include "config.hpp" +#include "tracy.hpp" #include "util.hpp" #include @@ -131,7 +132,7 @@ auto Octree::CalculateForce(int node_idx, const Vector3 &pos) const -> Vector3 { } const OctreeNode &node = nodes[node_idx]; - if (node.mass_total == 0.0f) { + if (std::abs(node.mass_total) <= 0.001f) { return Vector3Zero(); } diff --git a/src/physics.cpp b/src/physics.cpp index 4c846ff..7055cff 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -1,9 +1,10 @@ #include "physics.hpp" #include "config.hpp" -#include "util.hpp" +#include "tracy.hpp" #include #include +#include #include #include #include @@ -62,23 +63,19 @@ auto Mass::VerletUpdate(const float delta_time) -> void { } auto Spring::CalculateSpringForce() const -> void { - Vector3 delta_position; - float current_length; - Vector3 delta_velocity; - Vector3 force_a; - Vector3 force_b; - - delta_position = Vector3Subtract(massA.position, massB.position); - current_length = Vector3Length(delta_position); - delta_velocity = Vector3Subtract(massA.velocity, massB.velocity); + Vector3 delta_position = Vector3Subtract(massA.position, massB.position); + float current_length = Vector3Length(delta_position); + float inv_current_length = 1.0 / current_length; + Vector3 delta_velocity = Vector3Subtract(massA.velocity, massB.velocity); float hooke = spring_constant * (current_length - rest_length); float dampening = dampening_constant * - Vector3DotProduct(delta_velocity, delta_position) / - current_length; + Vector3DotProduct(delta_velocity, delta_position) * + inv_current_length; - force_a = Vector3Scale(delta_position, -(hooke + dampening) / current_length); - force_b = Vector3Scale(force_a, -1.0); + Vector3 force_a = + Vector3Scale(delta_position, -(hooke + dampening) * inv_current_length); + Vector3 force_b = Vector3Scale(force_a, -1.0); massA.force = Vector3Add(massA.force, force_a); massB.force = Vector3Add(massB.force, force_b); @@ -133,6 +130,8 @@ auto MassSpringSystem::Clear() -> void { } auto MassSpringSystem::ClearForces() -> void { + ZoneScoped; + for (auto &[state, mass] : masses) { mass.ClearForce(); } @@ -144,6 +143,20 @@ auto MassSpringSystem::CalculateSpringForces() -> void { for (auto &[states, spring] : springs) { spring.CalculateSpringForce(); } + + // spring_pointers.clear(); + // spring_pointers.reserve(springs.size()); + // for (auto &[states, spring] : springs) { + // spring_pointers.push_back(&spring); + // } + // + // auto solve_spring = [&](int i) { + // spring_pointers[i]->CalculateSpringForce(); + // }; + // + // BS::multi_future loop_future = + // threads.submit_loop(0, spring_pointers.size(), solve_spring, 4096); + // loop_future.wait(); } #ifdef BARNES_HUT @@ -184,7 +197,7 @@ auto MassSpringSystem::BuildOctree() -> void { for (auto &[state, mass] : masses) { mass_pointers.push_back(&mass); } - for (int i = 0; i < mass_pointers.size(); ++i) { + for (std::size_t i = 0; i < mass_pointers.size(); ++i) { octree.Insert(root, i, mass_pointers[i]->position, mass_pointers[i]->mass); } } @@ -307,7 +320,7 @@ auto MassSpringSystem::CalculateRepulsionForces() -> void { Vector3 direction = Vector3Subtract(mass->position, neighbor->position); float distance = Vector3Length(direction); - if (distance == 0.0f || distance >= REPULSION_RANGE) { + if (std::abs(distance) <= 0.001f || distance >= REPULSION_RANGE) { continue; } diff --git a/src/puzzle.cpp b/src/puzzle.cpp index 4d91958..d8719a0 100644 --- a/src/puzzle.cpp +++ b/src/puzzle.cpp @@ -1,4 +1,5 @@ #include "puzzle.hpp" +#include "tracy.hpp" auto Block::Hash() const -> int { std::string s = std::format("{},{},{},{}", x, y, width, height); @@ -144,12 +145,11 @@ auto State::ToggleTarget(int x, int y) -> bool { // Remove the current target int index; - for (const auto &block : *this) { - if (block.target) { - index = GetIndex(block.x, block.y); - state.replace( - index, 2, - Block(block.x, block.y, block.width, block.height, false).ToString()); + for (const auto &b : *this) { + if (b.target) { + index = GetIndex(b.x, b.y); + state.replace(index, 2, + Block(b.x, b.y, b.width, b.height, false).ToString()); break; } } diff --git a/src/renderer.cpp b/src/renderer.cpp index 57f7ad2..7dae4b8 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1,4 +1,8 @@ #include "renderer.hpp" +#include "config.hpp" +#include "physics.hpp" +#include "puzzle.hpp" +#include "tracy.hpp" #include #include @@ -8,10 +12,6 @@ #include #include -#include "config.hpp" -#include "physics.hpp" -#include "puzzle.hpp" - #ifdef BATCHING #include #endif @@ -314,4 +314,5 @@ auto Renderer::DrawTextures() -> void { Vector2(GetScreenWidth() / 2.0, MENU_HEIGHT), WHITE); DrawFPS(GetScreenWidth() / 2 + 10, MENU_HEIGHT + 10); EndDrawing(); + FrameMark; } diff --git a/src/state.cpp b/src/state.cpp index 7c515f5..41faaca 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -1,6 +1,7 @@ #include "state.hpp" #include "config.hpp" #include "presets.hpp" +#include "tracy.hpp" #include @@ -76,6 +77,9 @@ auto StateManager::ClearGraph() -> void { // The previous_state is no longer in the graph previous_state = current_state; + + // The starting state is no longer in the graph + starting_state = current_state; } auto StateManager::FindWinningStates() -> void { diff --git a/src/tracy.cpp b/src/tracy.cpp new file mode 100644 index 0000000..b1d591a --- /dev/null +++ b/src/tracy.cpp @@ -0,0 +1,17 @@ +#include "tracy.hpp" + +#include + +void *operator new(std::size_t count) { + auto ptr = malloc(count); + TracyAlloc(ptr, count); + return ptr; +} +void operator delete(void *ptr) noexcept { + TracyFree(ptr); + free(ptr); +} +void operator delete(void *ptr, std::size_t count) noexcept { + TracyFree(ptr); + free(ptr); +}