diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 9fd45b7c..01be6a6a 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -1,29 +1,7 @@ { "permissions": { "allow": [ - "Bash(cmake --build:*)", - "Bash(test:*)", - "Bash(tools/linter/run_clang-tidy.sh:*)", - "Bash(make resources.pack:*)", - "Bash(tools/linter/run_cppcheck.sh:*)", - "Bash(cat:*)", - "Bash(git add:*)", - "Bash(git commit:*)", - "Bash(git checkout:*)", - "Bash(sort:*)", - "Bash(cmake:*)", - "Bash(chmod:*)", - "Bash(python3:*)", - "Bash(make:*)", - "Bash(ldd:*)", - "WebSearch", - "Bash(find:*)", - "WebFetch(domain:github.com)", - "WebFetch(domain:raw.githubusercontent.com)", - "Bash(curl:*)", - "WebFetch(domain:fktn-k.github.io)", - "Bash(./jaildoctors_dilemma)", - "Bash(timeout 5 ./jaildoctors_dilemma:*)" + "Bash(clang-tidy:*)" ], "deny": [], "ask": [] diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index fcf4e8b8..724b76f6 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -85,7 +85,7 @@ void Player::move(float delta_time) { #ifdef _DEBUG Debug::get()->add(std::string("X : " + std::to_string(static_cast(x_)))); Debug::get()->add(std::string("Y : " + std::to_string(static_cast(y_)))); - Debug::get()->add(std::string("LGP: " + std::to_string(static_cast(last_grounded_position_)))); + Debug::get()->add(std::string("LGP: " + std::to_string(last_grounded_position_))); #endif } diff --git a/source/game/gameplay/tilemap_renderer.cpp b/source/game/gameplay/tilemap_renderer.cpp index 689ac401..c04f5d1d 100644 --- a/source/game/gameplay/tilemap_renderer.cpp +++ b/source/game/gameplay/tilemap_renderer.cpp @@ -56,6 +56,46 @@ void TilemapRenderer::render() { } #ifdef _DEBUG +// Renderiza las superficies de colisión en modo debug (función helper estática) +static void renderDebugCollisionSurfaces(const CollisionMap* collision_map) { + auto surface = Screen::get()->getRendererSurface(); + + // BottomSurfaces + for (auto l : collision_map->getBottomFloors()) { + surface->drawLine(l.x1, l.y, l.x2, l.y, static_cast(PaletteColor::BLUE)); + } + + // TopSurfaces + for (auto l : collision_map->getTopFloors()) { + surface->drawLine(l.x1, l.y, l.x2, l.y, static_cast(PaletteColor::RED)); + } + + // LeftSurfaces + for (auto l : collision_map->getLeftWalls()) { + surface->drawLine(l.x, l.y1, l.x, l.y2, static_cast(PaletteColor::GREEN)); + } + + // RightSurfaces + for (auto l : collision_map->getRightWalls()) { + surface->drawLine(l.x, l.y1, l.x, l.y2, static_cast(PaletteColor::MAGENTA)); + } + + // LeftSlopes + for (auto l : collision_map->getLeftSlopes()) { + surface->drawLine(l.x1, l.y1, l.x2, l.y2, static_cast(PaletteColor::CYAN)); + } + + // RightSlopes + for (auto l : collision_map->getRightSlopes()) { + surface->drawLine(l.x1, l.y1, l.x2, l.y2, static_cast(PaletteColor::YELLOW)); + } + + // AutoSurfaces (Conveyor Belts) + for (auto l : collision_map->getConveyorBeltFloors()) { + surface->drawLine(l.x1, l.y, l.x2, l.y, static_cast(PaletteColor::WHITE)); + } +} + // Redibuja el tilemap (para actualizar modo debug) void TilemapRenderer::redrawMap(const CollisionMap* collision_map) { fillMapTexture(collision_map); @@ -98,58 +138,8 @@ void TilemapRenderer::fillMapTexture(const CollisionMap* collision_map) { #ifdef _DEBUG // Pinta las superficies en el modo debug if (Debug::get()->isEnabled()) { - auto surface = Screen::get()->getRendererSurface(); - - // BottomSurfaces - { - for (auto l : collision_map->getBottomFloors()) { - surface->drawLine(l.x1, l.y, l.x2, l.y, static_cast(PaletteColor::BLUE)); - } - } - - // TopSurfaces - { - for (auto l : collision_map->getTopFloors()) { - surface->drawLine(l.x1, l.y, l.x2, l.y, static_cast(PaletteColor::RED)); - } - } - - // LeftSurfaces - { - for (auto l : collision_map->getLeftWalls()) { - surface->drawLine(l.x, l.y1, l.x, l.y2, static_cast(PaletteColor::GREEN)); - } - } - - // RightSurfaces - { - for (auto l : collision_map->getRightWalls()) { - surface->drawLine(l.x, l.y1, l.x, l.y2, static_cast(PaletteColor::MAGENTA)); - } - } - - // LeftSlopes - { - for (auto l : collision_map->getLeftSlopes()) { - surface->drawLine(l.x1, l.y1, l.x2, l.y2, static_cast(PaletteColor::CYAN)); - } - } - - // RightSlopes - { - for (auto l : collision_map->getRightSlopes()) { - surface->drawLine(l.x1, l.y1, l.x2, l.y2, static_cast(PaletteColor::YELLOW)); - } - } - - // AutoSurfaces - { - for (auto l : collision_map->getConveyorBeltFloors()) { - surface->drawLine(l.x1, l.y, l.x2, l.y, static_cast(PaletteColor::WHITE)); - } - } + renderDebugCollisionSurfaces(collision_map); } - #endif // _DEBUG Screen::get()->setRendererSurface(previous_renderer); } diff --git a/source/game/options.cpp b/source/game/options.cpp index 4ed5aabe..0826cd81 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -257,12 +257,201 @@ auto stringToGamepadButton(const std::string& str, int default_value) -> int { } auto isValidPalette(const std::string& palette) -> bool { - for (const auto& valid : VALID_PALETTES) { - if (valid == palette) { - return true; + return std::ranges::any_of(VALID_PALETTES, [&palette](const auto& valid) { return valid == palette; }); +} + +// --- Funciones helper para loadFromFile() --- + +// Carga configuración de ventana desde YAML +void loadWindowConfigFromYaml(const fkyaml::node& yaml) { + if (yaml.contains("window")) { + const auto& win = yaml["window"]; + if (win.contains("zoom")) { + try { + int val = win["zoom"].get_value(); + window.zoom = (val > 0) ? val : GameDefaults::WINDOW_ZOOM; + } catch (...) { + window.zoom = GameDefaults::WINDOW_ZOOM; + } + } + } +} + +// Carga configuración de borde desde YAML +void loadBorderConfigFromYaml(const fkyaml::node& border) { + if (border.contains("enabled")) { + try { + video.border.enabled = border["enabled"].get_value(); + } catch (...) { + video.border.enabled = GameDefaults::BORDER_ENABLED; + } + } + + if (border.contains("width")) { + try { + auto val = border["width"].get_value(); + video.border.width = (val > 0) ? val : GameDefaults::BORDER_WIDTH; + } catch (...) { + video.border.width = GameDefaults::BORDER_WIDTH; + } + } + + if (border.contains("height")) { + try { + auto val = border["height"].get_value(); + video.border.height = (val > 0) ? val : GameDefaults::BORDER_HEIGHT; + } catch (...) { + video.border.height = GameDefaults::BORDER_HEIGHT; + } + } +} + +// Carga los campos básicos de configuración de video +void loadBasicVideoFieldsFromYaml(const fkyaml::node& vid) { + // fullscreen (antes era "mode") + if (vid.contains("fullscreen")) { + try { + video.fullscreen = vid["fullscreen"].get_value(); + } catch (...) { + video.fullscreen = GameDefaults::VIDEO_FULLSCREEN; + } + } + + // filter (ahora es string) + if (vid.contains("filter")) { + try { + auto filter_str = vid["filter"].get_value(); + video.filter = stringToFilter(filter_str); + } catch (...) { + video.filter = GameDefaults::VIDEO_FILTER; + } + } + + if (vid.contains("shaders")) { + try { + video.shaders = vid["shaders"].get_value(); + } catch (...) { + video.shaders = GameDefaults::VIDEO_SHADERS; + } + } + + if (vid.contains("vertical_sync")) { + try { + video.vertical_sync = vid["vertical_sync"].get_value(); + } catch (...) { + video.vertical_sync = GameDefaults::VIDEO_VERTICAL_SYNC; + } + } + + if (vid.contains("integer_scale")) { + try { + video.integer_scale = vid["integer_scale"].get_value(); + } catch (...) { + video.integer_scale = GameDefaults::VIDEO_INTEGER_SCALE; + } + } + + if (vid.contains("keep_aspect")) { + try { + video.keep_aspect = vid["keep_aspect"].get_value(); + } catch (...) { + video.keep_aspect = GameDefaults::VIDEO_KEEP_ASPECT; + } + } + + if (vid.contains("palette")) { + try { + auto palette_str = vid["palette"].get_value(); + if (isValidPalette(palette_str)) { + video.palette = palette_str; + } else { + video.palette = GameDefaults::PALETTE_NAME; + } + } catch (...) { + video.palette = GameDefaults::PALETTE_NAME; + } + } +} + +// Carga configuración de video desde YAML +void loadVideoConfigFromYaml(const fkyaml::node& yaml) { + if (yaml.contains("video")) { + const auto& vid = yaml["video"]; + loadBasicVideoFieldsFromYaml(vid); + + // Lee border + if (vid.contains("border")) { + loadBorderConfigFromYaml(vid["border"]); + } + } +} + +// Carga controles de teclado desde YAML +void loadKeyboardControlsFromYaml(const fkyaml::node& yaml) { + if (yaml.contains("keyboard_controls")) { + const auto& ctrl = yaml["keyboard_controls"]; + + if (ctrl.contains("key_left")) { + try { + auto key_str = ctrl["key_left"].get_value(); + keyboard_controls.key_left = stringToScancode(key_str, GameDefaults::CONTROL_KEY_LEFT); + } catch (...) { + keyboard_controls.key_left = GameDefaults::CONTROL_KEY_LEFT; + } + } + + if (ctrl.contains("key_right")) { + try { + auto key_str = ctrl["key_right"].get_value(); + keyboard_controls.key_right = stringToScancode(key_str, GameDefaults::CONTROL_KEY_RIGHT); + } catch (...) { + keyboard_controls.key_right = GameDefaults::CONTROL_KEY_RIGHT; + } + } + + if (ctrl.contains("key_jump")) { + try { + auto key_str = ctrl["key_jump"].get_value(); + keyboard_controls.key_jump = stringToScancode(key_str, GameDefaults::CONTROL_KEY_JUMP); + } catch (...) { + keyboard_controls.key_jump = GameDefaults::CONTROL_KEY_JUMP; + } + } + } +} + +// Carga controles de gamepad desde YAML +void loadGamepadControlsFromYaml(const fkyaml::node& yaml) { + if (yaml.contains("gamepad_controls")) { + const auto& gp = yaml["gamepad_controls"]; + + if (gp.contains("button_left")) { + try { + auto button_str = gp["button_left"].get_value(); + gamepad_controls.button_left = stringToGamepadButton(button_str, GameDefaults::GAMEPAD_BUTTON_LEFT); + } catch (...) { + gamepad_controls.button_left = GameDefaults::GAMEPAD_BUTTON_LEFT; + } + } + + if (gp.contains("button_right")) { + try { + auto button_str = gp["button_right"].get_value(); + gamepad_controls.button_right = stringToGamepadButton(button_str, GameDefaults::GAMEPAD_BUTTON_RIGHT); + } catch (...) { + gamepad_controls.button_right = GameDefaults::GAMEPAD_BUTTON_RIGHT; + } + } + + if (gp.contains("button_jump")) { + try { + auto button_str = gp["button_jump"].get_value(); + gamepad_controls.button_jump = stringToGamepadButton(button_str, GameDefaults::GAMEPAD_BUTTON_JUMP); + } catch (...) { + gamepad_controls.button_jump = GameDefaults::GAMEPAD_BUTTON_JUMP; + } } } - return false; } // Crea e inicializa las opciones del programa @@ -322,182 +511,11 @@ auto loadFromFile() -> bool { return true; } - // Lee window - if (yaml.contains("window")) { - const auto& win = yaml["window"]; - if (win.contains("zoom")) { - try { - int val = win["zoom"].get_value(); - window.zoom = (val > 0) ? val : GameDefaults::WINDOW_ZOOM; - } catch (...) { - window.zoom = GameDefaults::WINDOW_ZOOM; - } - } - } - - // Lee video - if (yaml.contains("video")) { - const auto& vid = yaml["video"]; - - // fullscreen (antes era "mode") - if (vid.contains("fullscreen")) { - try { - video.fullscreen = vid["fullscreen"].get_value(); - } catch (...) { - video.fullscreen = GameDefaults::VIDEO_FULLSCREEN; - } - } - - // filter (ahora es string) - if (vid.contains("filter")) { - try { - auto filter_str = vid["filter"].get_value(); - video.filter = stringToFilter(filter_str); - } catch (...) { - video.filter = GameDefaults::VIDEO_FILTER; - } - } - - if (vid.contains("shaders")) { - try { - video.shaders = vid["shaders"].get_value(); - } catch (...) { - video.shaders = GameDefaults::VIDEO_SHADERS; - } - } - - if (vid.contains("vertical_sync")) { - try { - video.vertical_sync = vid["vertical_sync"].get_value(); - } catch (...) { - video.vertical_sync = GameDefaults::VIDEO_VERTICAL_SYNC; - } - } - - if (vid.contains("integer_scale")) { - try { - video.integer_scale = vid["integer_scale"].get_value(); - } catch (...) { - video.integer_scale = GameDefaults::VIDEO_INTEGER_SCALE; - } - } - - if (vid.contains("keep_aspect")) { - try { - video.keep_aspect = vid["keep_aspect"].get_value(); - } catch (...) { - video.keep_aspect = GameDefaults::VIDEO_KEEP_ASPECT; - } - } - - if (vid.contains("palette")) { - try { - auto palette_str = vid["palette"].get_value(); - if (isValidPalette(palette_str)) { - video.palette = palette_str; - } else { - video.palette = GameDefaults::PALETTE_NAME; - } - } catch (...) { - video.palette = GameDefaults::PALETTE_NAME; - } - } - - // Lee border - if (vid.contains("border")) { - const auto& border = vid["border"]; - - if (border.contains("enabled")) { - try { - video.border.enabled = border["enabled"].get_value(); - } catch (...) { - video.border.enabled = GameDefaults::BORDER_ENABLED; - } - } - - if (border.contains("width")) { - try { - auto val = border["width"].get_value(); - video.border.width = (val > 0) ? val : GameDefaults::BORDER_WIDTH; - } catch (...) { - video.border.width = GameDefaults::BORDER_WIDTH; - } - } - - if (border.contains("height")) { - try { - auto val = border["height"].get_value(); - video.border.height = (val > 0) ? val : GameDefaults::BORDER_HEIGHT; - } catch (...) { - video.border.height = GameDefaults::BORDER_HEIGHT; - } - } - } - } - - // Lee keyboard_controls (antes era "controls") - if (yaml.contains("keyboard_controls")) { - const auto& ctrl = yaml["keyboard_controls"]; - - if (ctrl.contains("key_left")) { - try { - auto key_str = ctrl["key_left"].get_value(); - keyboard_controls.key_left = stringToScancode(key_str, GameDefaults::CONTROL_KEY_LEFT); - } catch (...) { - keyboard_controls.key_left = GameDefaults::CONTROL_KEY_LEFT; - } - } - - if (ctrl.contains("key_right")) { - try { - auto key_str = ctrl["key_right"].get_value(); - keyboard_controls.key_right = stringToScancode(key_str, GameDefaults::CONTROL_KEY_RIGHT); - } catch (...) { - keyboard_controls.key_right = GameDefaults::CONTROL_KEY_RIGHT; - } - } - - if (ctrl.contains("key_jump")) { - try { - auto key_str = ctrl["key_jump"].get_value(); - keyboard_controls.key_jump = stringToScancode(key_str, GameDefaults::CONTROL_KEY_JUMP); - } catch (...) { - keyboard_controls.key_jump = GameDefaults::CONTROL_KEY_JUMP; - } - } - } - - // Lee gamepad_controls - if (yaml.contains("gamepad_controls")) { - const auto& gp = yaml["gamepad_controls"]; - - if (gp.contains("button_left")) { - try { - auto button_str = gp["button_left"].get_value(); - gamepad_controls.button_left = stringToGamepadButton(button_str, GameDefaults::GAMEPAD_BUTTON_LEFT); - } catch (...) { - gamepad_controls.button_left = GameDefaults::GAMEPAD_BUTTON_LEFT; - } - } - - if (gp.contains("button_right")) { - try { - auto button_str = gp["button_right"].get_value(); - gamepad_controls.button_right = stringToGamepadButton(button_str, GameDefaults::GAMEPAD_BUTTON_RIGHT); - } catch (...) { - gamepad_controls.button_right = GameDefaults::GAMEPAD_BUTTON_RIGHT; - } - } - - if (gp.contains("button_jump")) { - try { - auto button_str = gp["button_jump"].get_value(); - gamepad_controls.button_jump = stringToGamepadButton(button_str, GameDefaults::GAMEPAD_BUTTON_JUMP); - } catch (...) { - gamepad_controls.button_jump = GameDefaults::GAMEPAD_BUTTON_JUMP; - } - } - } + // Carga las diferentes secciones de configuración usando funciones helper + loadWindowConfigFromYaml(yaml); + loadVideoConfigFromYaml(yaml); + loadKeyboardControlsFromYaml(yaml); + loadGamepadControlsFromYaml(yaml); if (console) { std::cout << "Config file loaded successfully\n\n"; diff --git a/source/game/options.hpp b/source/game/options.hpp index d1ca5aba..4c188b07 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -129,7 +129,7 @@ inline GamepadControls gamepad_controls{}; // Botones del gamepad usados para // Ruta completa del fichero de configuración (establecida mediante setConfigFile) inline std::string config_file_path{}; -// --- Funciones --- +// --- Funciones públicas --- void init(); // Crea e inicializa las opciones del programa void setConfigFile(const std::string& path); // Establece la ruta del fichero de configuración auto loadFromFile() -> bool; // Carga las opciones desde el fichero configurado