diff --git a/CMakeLists.txt b/CMakeLists.txt index 116e16d..f826316 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(MassSprings) set(CMAKE_CXX_STANDARD 26) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -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 "${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} -O2 -ggdb") # -fsanitize=address already fails on InitWindow(), -fsanitize=undefined, -fsanitize=leak set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -march=native") diff --git a/include/config.hpp b/include/config.hpp index ae77731..2318ae6 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -12,12 +12,12 @@ // Window constexpr int INITIAL_WIDTH = 800; constexpr int INITIAL_HEIGHT = 800; -constexpr int MENU_HEIGHT = 200; +constexpr int MENU_HEIGHT = 250; // Menu constexpr int MENU_PAD = 5; constexpr int BUTTON_PAD = 12; -constexpr int MENU_ROWS = 4; +constexpr int MENU_ROWS = 5; constexpr int MENU_COLS = 3; // Camera Controls diff --git a/include/state.hpp b/include/state.hpp index d4ef7ca..392cb04 100644 --- a/include/state.hpp +++ b/include/state.hpp @@ -16,6 +16,7 @@ public: ThreadedPhysics &physics; std::vector presets; + std::vector comments; // Some stuff is faster to map from state to mass (e.g. in the renderer) std::unordered_map states; diff --git a/src/main.cpp b/src/main.cpp index 87f84e7..7f65bea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,8 @@ #include #endif -// TODO: Click states to display them in the board +// TODO: Click states in the graph to display them in the board +// TODO: Add walls (unmoveable blocks) // NOTE: Tracy uses a huge amount of memory. For longer testing disable Tracy. diff --git a/src/renderer.cpp b/src/renderer.cpp index 3eed467..a33b705 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -322,13 +322,26 @@ auto Renderer::DrawMenu(const std::vector &masses) -> void { auto draw_btn = [&](int x, int y, std::string text, Color color) { int posx = MENU_PAD + x * (MENU_PAD + btn_width); - int posy = MENU_PAD + y * (MENU_PAD + btn_height); + int posy = MENU_PAD + (y + 1) * (MENU_PAD + btn_height); DrawRectangle(posx, posy, btn_width, btn_height, Fade(color, 0.7)); DrawRectangleLines(posx, posy, btn_width, btn_height, color); DrawText(text.data(), posx + BUTTON_PAD, posy + BUTTON_PAD, btn_height - 2.0 * BUTTON_PAD, WHITE); }; + auto draw_subtitle = [&](std::string text, Color color) { + int posx = MENU_PAD; + int posy = MENU_PAD; + DrawRectangle(posx, posy, + btn_width * MENU_COLS + MENU_PAD * (MENU_COLS - 1), + btn_height, Fade(color, 0.7)); + DrawRectangleLines(posx, posy, + btn_width * MENU_COLS + MENU_PAD * (MENU_COLS - 1), + btn_height, color); + DrawText(text.data(), posx + BUTTON_PAD, posy + BUTTON_PAD, + btn_height = 2.0 * BUTTON_PAD, WHITE); + }; + // Left column draw_btn(0, 0, std::format("States: {} / Transitions: {} / Winning: {}", @@ -336,7 +349,7 @@ auto Renderer::DrawMenu(const std::vector &masses) -> void { state.winning_states.size()), ORANGE); draw_btn(0, 1, - std::format("Preset (M/N): {}, {} (F)", state.current_preset, + std::format("Preset (M/N) / {} (F)", state.current_state.restricted ? "Restricted" : "Free"), ORANGE); draw_btn(0, 2, std::format("Pan (LMB) / Rotate (RMB) / Zoom (Wheel)"), @@ -350,27 +363,31 @@ auto Renderer::DrawMenu(const std::vector &masses) -> void { draw_btn(1, 0, std::format("Select (LMB) / Move (W, A, S, D) / Target (T)"), DARKBLUE); draw_btn(1, 1, std::format("Add/Remove Col/Row (Arrow Keys)"), DARKBLUE); - draw_btn(1, 2, std::format("Add/Remove Block (LMB/RMB), Set Goal (MMB)"), + draw_btn(1, 2, std::format("Add/Remove Block (LMB/RMB) / Set Goal (MMB)"), DARKBLUE); draw_btn(1, 3, std::format("Print State (P) / Reset State (R)"), DARKBLUE); // Right column - draw_btn(2, 0, std::format("Populate Graph (G), Clear Graph (C)"), + draw_btn(2, 0, std::format("Populate Graph (G) / Clear Graph (C)"), DARKPURPLE); draw_btn(2, 1, - std::format("Path (U): {} / Goals (I): {} / Connect (O): {}", + std::format("Path (U): {} / Goals (I): {} / Lines (O): {}", input.mark_path, input.mark_solutions, input.connect_solutions), DARKPURPLE); draw_btn(2, 2, std::format("Best move (Space) / Move back (Backspace)"), DARKPURPLE); draw_btn(2, 3, - std::format("Worst (V) / Nearest target (B) / Moves remaining: {}", + std::format("Worst (V) / Target (B) / Distance: {}", state.winning_path.size() > 0 ? state.winning_path.size() - 1 : 0), DARKPURPLE); + draw_subtitle(std::format("Puzzle {}: {}", state.current_preset + 1, + state.comments.at(state.current_preset)), + BLACK); + DrawLine(0, MENU_HEIGHT - 1, GetScreenWidth(), MENU_HEIGHT - 1, BLACK); EndTextureMode(); } diff --git a/src/state.cpp b/src/state.cpp index 56ab476..8494c03 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -20,25 +20,29 @@ auto StateManager::ParsePresetFile(const std::string &preset_file) -> void { } std::string line; - std::vector lines; + std::vector comment_lines; + std::vector preset_lines; while (std::getline(file, line)) { if (line.starts_with("F") || line.starts_with("R")) { - lines.push_back(line); + preset_lines.push_back(line); + } else if (line.starts_with("#")) { + comment_lines.push_back(line); } } - if (lines.size() == 0) { + if (preset_lines.size() == 0 || comment_lines.size() != preset_lines.size()) { std::cout << "Preset file \"" << preset_file << "\" couldn't be loaded." << std::endl; return; } presets.clear(); - for (const auto &preset : lines) { + for (const auto &preset : preset_lines) { presets.emplace_back(preset); } + comments = comment_lines; - std::cout << "Loaded " << lines.size() << " presets." << std::endl; + std::cout << "Loaded " << preset_lines.size() << " presets." << std::endl; } auto StateManager::LoadPreset(int preset) -> void {