refactor: eliminar Options::physics/audio/gameplay (codi mort)

Aquestes tres seccions s'estaven carregant del YAML, parsejant,
validant i escrivint, però cap d'elles tenia consumidor en runtime:
- Options::physics: l'únic call-site era un std::cout informatiu a
  director.cpp:109. Ship/Enemy/Bullet llegeixen Defaults::Physics
  directament.
- Options::audio: explícitament desacoblat (audio.hpp:22-25) — la
  font de configuració era Defaults::Audio via Audio::Config.
- Options::gameplay: zero readers. Els arrays són compile-time.

Esborrats:
- Structs Physics/Gameplay/Music/Sound/Audio i les globals.
- Defaults a init(), helpers loadXxxConfigFromYaml, secció escrita
  a saveToFile, crides al loadFromFile.
- La línia "Física: rotation=..." del console output del Director.

Es manté Options::window i Options::rendering (sí utilitzats).

Hallazgo #21 de CODE_REVIEW.md (opció a: borrar).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 18:07:27 +02:00
parent e4b6d2df6a
commit 11e9d6569b
3 changed files with 493 additions and 661 deletions
+7 -11
View File
@@ -9,10 +9,6 @@
#include <iostream>
#include <memory>
#include "debug_overlay.hpp"
#include "scene.hpp"
#include "scene_context.hpp"
#include "global_events.hpp"
#include "core/audio/audio.hpp"
#include "core/audio/audio_adapter.hpp"
#include "core/defaults.hpp"
@@ -22,11 +18,15 @@
#include "core/resources/resource_helper.hpp"
#include "core/resources/resource_loader.hpp"
#include "core/utils/path_utils.hpp"
#include "debug_overlay.hpp"
#include "game/options.hpp"
#include "game/scenes/game_scene.hpp"
#include "game/scenes/logo_scene.hpp"
#include "game/scenes/title_scene.hpp"
#include "game/options.hpp"
#include "global_events.hpp"
#include "project.h"
#include "scene.hpp"
#include "scene_context.hpp"
#ifndef _WIN32
#include <pwd.h>
@@ -106,8 +106,6 @@ Director::Director(std::vector<std::string> const& args) {
std::cout << "Configuración carregada\n";
std::cout << " Finestra: " << Options::window.width << "×"
<< Options::window.height << '\n';
std::cout << " Física: rotation=" << Options::physics.rotation_speed
<< " rad/s\n";
std::cout << " Input: " << Input::get()->getNumGamepads()
<< " gamepad(s) detectat(s)\n";
}
@@ -291,8 +289,7 @@ auto Director::buildScene(SceneType type, SDLManager& sdl, SceneContext& context
}
}
void Director::runFrameLoop(Scene& scene, SDLManager& sdl, SceneContext& context,
System::DebugOverlay& debug_overlay) {
void Director::runFrameLoop(Scene& scene, SDLManager& sdl, SceneContext& context, System::DebugOverlay& debug_overlay) {
SDL_Event event;
Uint64 last_time = SDL_GetTicks();
@@ -315,8 +312,7 @@ void Director::runFrameLoop(Scene& scene, SDLManager& sdl, SceneContext& context
if (GlobalEvents::handle(event, sdl, context)) {
continue;
}
if (event.type == SDL_EVENT_KEY_DOWN
&& event.key.scancode == SDL_SCANCODE_F11) {
if (event.type == SDL_EVENT_KEY_DOWN && event.key.scancode == SDL_SCANCODE_F11) {
debug_overlay.toggle();
continue;
}
+4 -134
View File
@@ -192,29 +192,9 @@ void init() {
window.fullscreen = Defaults::Window::FULLSCREEN;
window.zoom_factor = Defaults::Window::BASE_ZOOM;
// Physics
physics.rotation_speed = Defaults::Physics::ROTATION_SPEED;
physics.acceleration = Defaults::Physics::ACCELERATION;
physics.max_velocity = Defaults::Physics::MAX_VELOCITY;
physics.friction = Defaults::Physics::FRICTION;
physics.enemy_speed = Defaults::Physics::ENEMY_SPEED;
physics.bullet_speed = Defaults::Physics::BULLET_SPEED;
// Gameplay
gameplay.max_enemies = Defaults::Entities::MAX_ORNIS;
gameplay.max_bullets = Defaults::Entities::MAX_BALES;
// Rendering
rendering.vsync = Defaults::Rendering::VSYNC_DEFAULT;
// Audio
audio.enabled = Defaults::Audio::ENABLED;
audio.volume = Defaults::Audio::VOLUME;
audio.music.enabled = Defaults::Audio::MUSIC_ENABLED;
audio.music.volume = Defaults::Audio::MUSIC_VOLUME;
audio.sound.enabled = Defaults::Audio::SOUND_ENABLED;
audio.sound.volume = Defaults::Audio::SOUND_VOLUME;
// Version
version = std::string(Project::VERSION);
}
@@ -228,8 +208,7 @@ void setConfigFile(const std::string& path) { config_file_path = path; }
// existe, deja `dest` intacto; si la conversió o la validació fallen,
// asigna `fallback`. Estàtic per quedar dins de la unitat de traducció.
template <typename T, typename Validator>
static void readField(const fkyaml::node& parent, const char* key, T& dest,
T fallback, Validator&& validate) {
static void readField(const fkyaml::node& parent, const char* key, T& dest, T fallback, Validator&& validate) {
if (!parent.contains(key)) {
return;
}
@@ -260,15 +239,12 @@ static void loadWindowConfigFromYaml(const fkyaml::node& yaml) {
}
const auto& win = yaml["window"];
readField(win, "width", window.width, Defaults::Window::WIDTH,
[](int v) { return v >= Defaults::Window::MIN_WIDTH; });
readField(win, "height", window.height, Defaults::Window::HEIGHT,
[](int v) { return v >= Defaults::Window::MIN_HEIGHT; });
readField(win, "width", window.width, Defaults::Window::WIDTH, [](int v) { return v >= Defaults::Window::MIN_WIDTH; });
readField(win, "height", window.height, Defaults::Window::HEIGHT, [](int v) { return v >= Defaults::Window::MIN_HEIGHT; });
readField(win, "fullscreen", window.fullscreen, false);
if (win.contains("zoom_factor")) {
readField(win, "zoom_factor", window.zoom_factor, Defaults::Window::BASE_ZOOM,
[](float v) { return v >= Defaults::Window::MIN_ZOOM && v <= 10.0F; });
readField(win, "zoom_factor", window.zoom_factor, Defaults::Window::BASE_ZOOM, [](float v) { return v >= Defaults::Window::MIN_ZOOM && v <= 10.0F; });
} else {
// Legacy config: infer zoom from width
window.zoom_factor = static_cast<float>(window.width) / Defaults::Window::WIDTH;
@@ -276,47 +252,6 @@ static void loadWindowConfigFromYaml(const fkyaml::node& yaml) {
}
}
static void loadPhysicsConfigFromYaml(const fkyaml::node& yaml) {
if (!yaml.contains("physics")) {
return;
}
const auto& phys = yaml["physics"];
constexpr auto POSITIVE = [](float v) { return v > 0.0F; };
readField(phys, "rotation_speed", physics.rotation_speed, Defaults::Physics::ROTATION_SPEED, POSITIVE);
readField(phys, "acceleration", physics.acceleration, Defaults::Physics::ACCELERATION, POSITIVE);
readField(phys, "max_velocity", physics.max_velocity, Defaults::Physics::MAX_VELOCITY, POSITIVE);
readField(phys, "friction", physics.friction, Defaults::Physics::FRICTION, POSITIVE);
readField(phys, "enemy_speed", physics.enemy_speed, Defaults::Physics::ENEMY_SPEED, POSITIVE);
readField(phys, "bullet_speed", physics.bullet_speed, Defaults::Physics::BULLET_SPEED, POSITIVE);
}
static void loadGameplayConfigFromYaml(const fkyaml::node& yaml) {
if (yaml.contains("gameplay")) {
const auto& game = yaml["gameplay"];
if (game.contains("max_enemies")) {
try {
auto val = game["max_enemies"].get_value<int>();
gameplay.max_enemies =
(val > 0 && val <= 50) ? val : Defaults::Entities::MAX_ORNIS;
} catch (...) {
gameplay.max_enemies = Defaults::Entities::MAX_ORNIS;
}
}
if (game.contains("max_bullets")) {
try {
auto val = game["max_bullets"].get_value<int>();
gameplay.max_bullets =
(val > 0 && val <= 10) ? val : Defaults::Entities::MAX_BALES;
} catch (...) {
gameplay.max_bullets = Defaults::Entities::MAX_BALES;
}
}
}
}
static void loadRenderingConfigFromYaml(const fkyaml::node& yaml) {
if (yaml.contains("rendering")) {
const auto& rend = yaml["rendering"];
@@ -333,41 +268,6 @@ static void loadRenderingConfigFromYaml(const fkyaml::node& yaml) {
}
}
static void loadAudioMusicSection(const fkyaml::node& aud) {
if (!aud.contains("music")) {
return;
}
const auto& mus = aud["music"];
constexpr auto UNIT_RANGE = [](float v) { return v >= 0.0F && v <= 1.0F; };
readField(mus, "enabled", audio.music.enabled, Defaults::Audio::MUSIC_ENABLED);
readField(mus, "volume", audio.music.volume, Defaults::Audio::MUSIC_VOLUME, UNIT_RANGE);
}
static void loadAudioSoundSection(const fkyaml::node& aud) {
if (!aud.contains("sound")) {
return;
}
const auto& snd = aud["sound"];
constexpr auto UNIT_RANGE = [](float v) { return v >= 0.0F && v <= 1.0F; };
readField(snd, "enabled", audio.sound.enabled, Defaults::Audio::SOUND_ENABLED);
readField(snd, "volume", audio.sound.volume, Defaults::Audio::SOUND_VOLUME, UNIT_RANGE);
}
static void loadAudioConfigFromYaml(const fkyaml::node& yaml) {
if (!yaml.contains("audio")) {
return;
}
const auto& aud = yaml["audio"];
constexpr auto UNIT_RANGE = [](float v) { return v >= 0.0F && v <= 1.0F; };
readField(aud, "enabled", audio.enabled, Defaults::Audio::ENABLED);
readField(aud, "volume", audio.volume, Defaults::Audio::VOLUME, UNIT_RANGE);
loadAudioMusicSection(aud);
loadAudioSoundSection(aud);
}
// Carregar controls del player 1 desde YAML
static void loadPlayer1ControlsFromYaml(const fkyaml::node& yaml) {
if (!yaml.contains("player1")) {
@@ -507,10 +407,7 @@ auto loadFromFile() -> bool {
// Carregar seccions
loadWindowConfigFromYaml(yaml);
loadPhysicsConfigFromYaml(yaml);
loadGameplayConfigFromYaml(yaml);
loadRenderingConfigFromYaml(yaml);
loadAudioConfigFromYaml(yaml);
loadPlayer1ControlsFromYaml(yaml);
loadPlayer2ControlsFromYaml(yaml);
@@ -592,37 +489,10 @@ auto saveToFile() -> bool {
file << " fullscreen: " << (window.fullscreen ? "true" : "false") << "\n";
file << " zoom_factor: " << window.zoom_factor << " # 0.5x-max (0.1 increments)\n\n";
file << "# FÍSICA (todos los valors en px/s, rad/s, etc.)\n";
file << "physics:\n";
file << " rotation_speed: " << physics.rotation_speed << " # rad/s\n";
file << " acceleration: " << physics.acceleration << " # px/s²\n";
file << " max_velocity: " << physics.max_velocity << " # px/s\n";
file << " friction: " << physics.friction << " # px/s²\n";
file << " enemy_speed: " << physics.enemy_speed
<< " # unitats/frame\n";
file << " bullet_speed: " << physics.bullet_speed
<< " # unitats/frame\n\n";
file << "# GAMEPLAY\n";
file << "gameplay:\n";
file << " max_enemies: " << gameplay.max_enemies << "\n";
file << " max_bullets: " << gameplay.max_bullets << "\n\n";
file << "# RENDERITZACIÓ\n";
file << "rendering:\n";
file << " vsync: " << rendering.vsync << " # 0=disabled, 1=enabled\n\n";
file << "# AUDIO\n";
file << "audio:\n";
file << " enabled: " << (audio.enabled ? "true" : "false") << "\n";
file << " volume: " << audio.volume << " # 0.0 to 1.0\n";
file << " music:\n";
file << " enabled: " << (audio.music.enabled ? "true" : "false") << "\n";
file << " volume: " << audio.music.volume << " # 0.0 to 1.0\n";
file << " sound:\n";
file << " enabled: " << (audio.sound.enabled ? "true" : "false") << "\n";
file << " volume: " << audio.sound.volume << " # 0.0 to 1.0\n\n";
// Guardar controls de jugadors
savePlayer1ControlsToYaml(file);
savePlayer2ControlsToYaml(file);
-34
View File
@@ -15,41 +15,10 @@ struct Window {
float zoom_factor{1.0F}; // Zoom level (0.5x to max_zoom)
};
struct Physics {
float rotation_speed{3.14F}; // rad/s
float acceleration{400.0F}; // px/s²
float max_velocity{120.0F}; // px/s
float friction{20.0F}; // px/s²
float enemy_speed{2.0F}; // unitats/frame
float bullet_speed{6.0F}; // unitats/frame
};
struct Gameplay {
int max_enemies{15};
int max_bullets{3};
};
struct Rendering {
int vsync{1}; // 0=disabled, 1=enabled
};
struct Music {
bool enabled{true};
float volume{0.8F};
};
struct Sound {
bool enabled{true};
float volume{1.0F};
};
struct Audio {
Music music{};
Sound sound{};
bool enabled{true};
float volume{1.0F};
};
// Controles de jugadors
struct KeyboardControls {
@@ -78,10 +47,7 @@ struct PlayerControls {
inline std::string version{}; // Versión del config per validació
inline bool console{false}; // Eixida de debug
inline Window window{};
inline Physics physics{};
inline Gameplay gameplay{};
inline Rendering rendering{};
inline Audio audio{};
// Controles per player
inline PlayerControls player1{