ServiceMenu: afegida opció per a canviar el idioma
This commit is contained in:
@@ -74,6 +74,10 @@
|
||||
"[SERVICE_MENU] MUSIC_VOLUME": "Volumen de la musica",
|
||||
"[SERVICE_MENU] SFX_VOLUME": "Volumen dels sons",
|
||||
"[SERVICE_MENU] AUTOFIRE": "Dispar automatic",
|
||||
"[SERVICE_MENU] LANGUAGE": "Idioma",
|
||||
"[SERVICE_MENU] LANG ES": "Castella",
|
||||
"[SERVICE_MENU] LANG EN": "Angles",
|
||||
"[SERVICE_MENU] LANG BA": "Balooncia",
|
||||
"[SERVICE_MENU] VIDEO": "Video",
|
||||
"[SERVICE_MENU] AUDIO": "Audio",
|
||||
"[SERVICE_MENU] GAME": "Joc",
|
||||
|
||||
@@ -74,6 +74,10 @@
|
||||
"[SERVICE_MENU] MUSIC_VOLUME": "Music Volume",
|
||||
"[SERVICE_MENU] SFX_VOLUME": "Sound Volume",
|
||||
"[SERVICE_MENU] AUTOFIRE": "Autofire",
|
||||
"[SERVICE_MENU] LANGUAGE": "Language",
|
||||
"[SERVICE_MENU] LANG ES": "Spanish",
|
||||
"[SERVICE_MENU] LANG EN": "English",
|
||||
"[SERVICE_MENU] LANG BA": "Balooncia",
|
||||
"[SERVICE_MENU] VIDEO": "Video",
|
||||
"[SERVICE_MENU] AUDIO": "Audio",
|
||||
"[SERVICE_MENU] GAME": "Game",
|
||||
|
||||
@@ -74,6 +74,10 @@
|
||||
"[SERVICE_MENU] MUSIC_VOLUME": "Volumen de la musica",
|
||||
"[SERVICE_MENU] SFX_VOLUME": "Volumen de los efectos",
|
||||
"[SERVICE_MENU] AUTOFIRE": "Disparo automatico",
|
||||
"[SERVICE_MENU] LANGUAGE": "Idioma",
|
||||
"[SERVICE_MENU] LANG ES": "Castellano",
|
||||
"[SERVICE_MENU] LANG EN": "Ingles",
|
||||
"[SERVICE_MENU] LANG BA": "Balooncia",
|
||||
"[SERVICE_MENU] VIDEO": "Video",
|
||||
"[SERVICE_MENU] AUDIO": "Audio",
|
||||
"[SERVICE_MENU] GAME": "Juego",
|
||||
|
||||
@@ -93,15 +93,15 @@ void Director::init()
|
||||
loadScoreFile(); // Carga el archivo de puntuaciones
|
||||
|
||||
// Inicialización de subsistemas principales
|
||||
lang::loadFromFile(getLangFile(static_cast<lang::Code>(options.game.language))); // Carga el archivo de idioma
|
||||
Screen::init(); // Inicializa la pantalla y el sistema de renderizado
|
||||
Audio::init(); // Activa el sistema de audio
|
||||
Resource::init(); // Inicializa el sistema de gestión de recursos
|
||||
Input::init(Asset::get()->get("gamecontrollerdb.txt")); // Carga configuración de controles
|
||||
bindInputs(); // Asigna los controles a la entrada del sistema
|
||||
ServiceMenu::init(); // Inicializa el menú de servicio
|
||||
Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones
|
||||
Screen::get()->getSingletons(); // Obtiene los punteros al resto de singletones
|
||||
lang::setLanguage(options.game.language); // Carga el archivo de idioma
|
||||
Screen::init(); // Inicializa la pantalla y el sistema de renderizado
|
||||
Audio::init(); // Activa el sistema de audio
|
||||
Resource::init(); // Inicializa el sistema de gestión de recursos
|
||||
Input::init(Asset::get()->get("gamecontrollerdb.txt")); // Carga configuración de controles
|
||||
bindInputs(); // Asigna los controles a la entrada del sistema
|
||||
ServiceMenu::init(); // Inicializa el menú de servicio
|
||||
Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones
|
||||
Screen::get()->getSingletons(); // Obtiene los punteros al resto de singletones
|
||||
}
|
||||
|
||||
// Cierra todo y libera recursos del sistema y de los singletons
|
||||
@@ -616,9 +616,12 @@ void Director::runDemoGame()
|
||||
game->run();
|
||||
}
|
||||
|
||||
// Ejecuta la sección init
|
||||
void Director::runInit()
|
||||
// Reinicia objetos y vuelve a la sección inicial
|
||||
void Director::reset()
|
||||
{
|
||||
saveOptionsFile(Asset::get()->get("config.txt"));
|
||||
loadOptionsFile(Asset::get()->get("config.txt"));
|
||||
lang::setLanguage(options.game.language);
|
||||
Audio::get()->stopMusic();
|
||||
Audio::get()->stopAllSounds();
|
||||
if (section::options == section::Options::RELOAD || true)
|
||||
@@ -636,8 +639,8 @@ int Director::run()
|
||||
{
|
||||
switch (section::name)
|
||||
{
|
||||
case section::Name::INIT:
|
||||
runInit();
|
||||
case section::Name::RESET:
|
||||
reset();
|
||||
break;
|
||||
case section::Name::LOGO:
|
||||
runLogo();
|
||||
@@ -687,27 +690,6 @@ int Director::run()
|
||||
return (section::options == section::Options::QUIT_WITH_CONTROLLER) ? 1 : 0;
|
||||
}
|
||||
|
||||
// Obtiene una fichero a partir de un lang::Code
|
||||
std::string Director::getLangFile(lang::Code code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case lang::Code::VALENCIAN:
|
||||
return Asset::get()->get("ba_BA.json");
|
||||
break;
|
||||
case lang::Code::SPANISH:
|
||||
return Asset::get()->get("es_ES.json");
|
||||
break;
|
||||
case lang::Code::ENGLISH:
|
||||
return Asset::get()->get("en_UK.json");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Asset::get()->get("en_UK.json");
|
||||
}
|
||||
|
||||
#ifdef ARCADE
|
||||
// Apaga el sistema
|
||||
void Director::shutdownSystem(bool should_shutdown)
|
||||
|
||||
@@ -46,7 +46,7 @@ private:
|
||||
void runCredits(); // Muestra los créditos del juego
|
||||
void runHiScoreTable(); // Muestra la tabla de puntuaciones
|
||||
void runDemoGame(); // Ejecuta el modo demo
|
||||
void runInit(); // Ejecuta la fase de inicialización
|
||||
void reset(); // Reinicia objetos y vuelve a la sección inicial
|
||||
|
||||
// Gestión de archivos de idioma
|
||||
std::string getLangFile(lang::Code code); // Obtiene un fichero de idioma según el código
|
||||
|
||||
@@ -1724,13 +1724,13 @@ void Game::initDifficultyVars()
|
||||
void Game::initPlayers(int player_id)
|
||||
{
|
||||
// Crea los dos jugadores
|
||||
const int y = param.game.play_area.rect.h - 30;
|
||||
players_.emplace_back(std::make_unique<Player>(1, param.game.play_area.first_quarter_x - 15, y, demo_.enabled, param.game.play_area.rect, player_textures_[0], player_animations_));
|
||||
const int Y = param.game.play_area.rect.h - 30;
|
||||
players_.emplace_back(std::make_unique<Player>(1, param.game.play_area.first_quarter_x - 15, Y, demo_.enabled, param.game.play_area.rect, player_textures_[0], player_animations_));
|
||||
players_.back()->setScoreBoardPanel(SCOREBOARD_LEFT_PANEL);
|
||||
players_.back()->setName(lang::getText("[SCOREBOARD] 1"));
|
||||
players_.back()->setController(getController(players_.back()->getId()));
|
||||
|
||||
players_.emplace_back(std::make_unique<Player>(2, param.game.play_area.third_quarter_x - 15, y, demo_.enabled, param.game.play_area.rect, player_textures_[1], player_animations_));
|
||||
players_.emplace_back(std::make_unique<Player>(2, param.game.play_area.third_quarter_x - 15, Y, demo_.enabled, param.game.play_area.rect, player_textures_[1], player_animations_));
|
||||
players_.back()->setScoreBoardPanel(SCOREBOARD_RIGHT_PANEL);
|
||||
players_.back()->setName(lang::getText("[SCOREBOARD] 2"));
|
||||
players_.back()->setController(getController(players_.back()->getId()));
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace globalInputs
|
||||
const std::string CODE = "RESET";
|
||||
if (Notifier::get()->checkCode(CODE))
|
||||
{
|
||||
section::name = section::Name::INIT;
|
||||
section::name = section::Name::RESET;
|
||||
Notifier::get()->show({lang::getText("[NOTIFICATIONS] 15")});
|
||||
}
|
||||
else
|
||||
@@ -124,7 +124,7 @@ namespace globalInputs
|
||||
{
|
||||
options.game.language = lang::getNextLangCode(options.game.language);
|
||||
lang::loadFromFile(getLangFile(static_cast<lang::Code>(options.game.language)));
|
||||
section::name = section::Name::INIT;
|
||||
section::name = section::Name::RESET;
|
||||
section::options = section::Options::RELOAD;
|
||||
Notifier::get()->show({lang::getText("[NOTIFICATIONS] 05") + getLangName(options.game.language)});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include "json.hpp"
|
||||
#include "options.h"
|
||||
#include "asset.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
@@ -9,6 +11,12 @@ namespace lang
|
||||
{
|
||||
std::unordered_map<std::string, std::string> texts;
|
||||
|
||||
// Vector con los idiomas soportados
|
||||
std::vector<Language> languages = {
|
||||
{Code::SPANISH, "Castellano", "es_ES.json"},
|
||||
{Code::VALENCIAN, "Balooncia", "ba_BA.json"},
|
||||
{Code::ENGLISH, "Ingles", "en_UK.json"}};
|
||||
|
||||
// Inicializa los textos del juego en el idioma seleccionado
|
||||
bool loadFromFile(const std::string &file_path)
|
||||
{
|
||||
@@ -50,8 +58,81 @@ namespace lang
|
||||
// Obtiene el código del siguiente idioma disponible
|
||||
Code getNextLangCode(Code lang)
|
||||
{
|
||||
auto index = static_cast<int>(lang);
|
||||
index = (index + 1) % 3;
|
||||
return static_cast<Code>(index);
|
||||
for (size_t i = 0; i < languages.size(); ++i)
|
||||
{
|
||||
if (languages[i].code == lang)
|
||||
{
|
||||
return languages[(i + 1) % languages.size()].code;
|
||||
}
|
||||
}
|
||||
// Si no se encuentra, devuelve el primero por defecto
|
||||
return languages[0].code;
|
||||
}
|
||||
|
||||
// Obtiene un idioma del vector de idiomas a partir de un código
|
||||
Language getLanguage(Code code)
|
||||
{
|
||||
for (const auto &lang : languages)
|
||||
{
|
||||
if (lang.code == code)
|
||||
return lang;
|
||||
}
|
||||
// Si no se encuentra, devuelve el primero por defecto
|
||||
return languages[0];
|
||||
}
|
||||
|
||||
// Devuelve el código de un idioma a partir de un nombre
|
||||
Code getCodeFromName(const std::string& name)
|
||||
{
|
||||
for (const auto& lang : languages)
|
||||
{
|
||||
if (lang.name == name)
|
||||
return lang.code;
|
||||
}
|
||||
// Si no se encuentra, devuelve el primero por defecto
|
||||
return languages[0].code;
|
||||
}
|
||||
|
||||
// Actualiza los nombres de los idiomas
|
||||
void updateLanguageNames()
|
||||
{
|
||||
for (auto &lang : languages)
|
||||
{
|
||||
switch (lang.code)
|
||||
{
|
||||
case Code::SPANISH:
|
||||
lang.name = lang::getText("[SERVICE_MENU] LANG ES");
|
||||
break;
|
||||
case Code::VALENCIAN:
|
||||
lang.name = lang::getText("[SERVICE_MENU] LANG BA");
|
||||
break;
|
||||
case Code::ENGLISH:
|
||||
lang.name = lang::getText("[SERVICE_MENU] LANG EN");
|
||||
break;
|
||||
default:
|
||||
lang.name = "Unknown";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Obtiene una fichero a partir de un lang::Code
|
||||
std::string getLanguageFileName(lang::Code code)
|
||||
{
|
||||
for (const auto &lang : languages)
|
||||
{
|
||||
if (lang.code == code)
|
||||
return Asset::get()->get(lang.file_name);
|
||||
}
|
||||
// Si no se encuentra, devuelve el fichero del primer idioma por defecto
|
||||
return Asset::get()->get(languages[0].file_name);
|
||||
}
|
||||
|
||||
// Establece el idioma
|
||||
void setLanguage(Code lang)
|
||||
{
|
||||
options.game.language = lang;
|
||||
loadFromFile(Asset::get()->get(getLanguage(lang).file_name));
|
||||
updateLanguageNames();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace lang
|
||||
{
|
||||
@@ -12,12 +13,38 @@ namespace lang
|
||||
ENGLISH = 2
|
||||
};
|
||||
|
||||
// Estructura que representa un idioma
|
||||
struct Language
|
||||
{
|
||||
Code code; // Código que identifica al idioma
|
||||
std::string name; // Nombre que identifica el idioma
|
||||
std::string file_name; // Nombre del fichero con los textos
|
||||
|
||||
Language(Code c, const std::string &n, const std::string &fn)
|
||||
: code(c), name(n), file_name(fn) {}
|
||||
};
|
||||
|
||||
// Carga los textos desde el fichero JSON especificado
|
||||
bool loadFromFile(const std::string &file_path);
|
||||
|
||||
// Obtiene un texto a partir de una clave
|
||||
// Obtiene el texto por clave
|
||||
std::string getText(const std::string &key);
|
||||
|
||||
// Obtiene el código del siguiente idioma (circular)
|
||||
Code getNextLangCode(Code lang);
|
||||
Code getNextLangCode(Code current_lang);
|
||||
|
||||
// Obtiene el idioma correspondiente al código proporcionado
|
||||
Language getLanguage(Code code);
|
||||
|
||||
// Devuelve el código de un idioma a partir de un nombre
|
||||
Code getCodeFromName(const std::string& name);
|
||||
|
||||
// Actualiza los nombres de los idiomas
|
||||
void updateLanguageNames();
|
||||
|
||||
// Obtiene el nombre del fichero de textos asociado a un código de idioma
|
||||
std::string getLanguageFileName(Code code);
|
||||
|
||||
// Establece el idioma actual
|
||||
void setLanguage(Code lang);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@ void initOptions()
|
||||
options.controllers.at(0).player_id = 1;
|
||||
options.controllers.at(1).player_id = 2;
|
||||
setKeyboardToPlayer(1);
|
||||
|
||||
// Opciones pendientes
|
||||
options.pending_changes.new_language = options.game.language;
|
||||
options.pending_changes.new_difficulty = options.game.difficulty;
|
||||
options.pending_changes.has_pending_changes = false;
|
||||
}
|
||||
|
||||
// Carga el fichero de configuración
|
||||
@@ -115,6 +120,8 @@ bool saveOptionsFile(std::string file_path)
|
||||
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(file_path).c_str());
|
||||
|
||||
applyPendingChanges();
|
||||
|
||||
// Opciones de video
|
||||
file << "## VIDEO\n";
|
||||
file << "## video.scale_mode [" << static_cast<int>(SDL_ScaleMode::SDL_SCALEMODE_NEAREST) << ": nearest, " << static_cast<int>(SDL_ScaleMode::SDL_SCALEMODE_LINEAR) << ": lineal]\n";
|
||||
@@ -237,10 +244,12 @@ bool setOptions(const std::string &var, const std::string &value)
|
||||
else if (var == "game.language")
|
||||
{
|
||||
options.game.language = static_cast<lang::Code>(std::stoi(value));
|
||||
options.pending_changes.new_language = options.game.language;
|
||||
}
|
||||
else if (var == "game.difficulty")
|
||||
{
|
||||
options.game.difficulty = static_cast<GameDifficulty>(std::stoi(value));
|
||||
options.pending_changes.new_difficulty = options.game.difficulty;
|
||||
}
|
||||
else if (var == "game.autofire")
|
||||
{
|
||||
@@ -365,4 +374,15 @@ int getPlayerWhoUsesKeyboard()
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Aplica los cambios pendientes copiando los valores a sus variables
|
||||
void applyPendingChanges()
|
||||
{
|
||||
if (options.pending_changes.has_pending_changes)
|
||||
{
|
||||
options.game.language = options.pending_changes.new_language;
|
||||
options.game.difficulty = options.pending_changes.new_difficulty;
|
||||
options.pending_changes.has_pending_changes = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,14 @@ struct GamepadOptions
|
||||
buttons{SDL_GAMEPAD_BUTTON_WEST, SDL_GAMEPAD_BUTTON_NORTH, SDL_GAMEPAD_BUTTON_EAST, SDL_GAMEPAD_BUTTON_START, SDL_GAMEPAD_BUTTON_BACK} {}
|
||||
};
|
||||
|
||||
// --- Opciones pendientes de aplicar ---
|
||||
struct PendingChanges
|
||||
{
|
||||
lang::Code new_language; // Idioma en espera de aplicar
|
||||
GameDifficulty new_difficulty; // Dificultad en espera de aplicar
|
||||
bool has_pending_changes = false; // Indica si hay cambios pendientes
|
||||
};
|
||||
|
||||
// --- Opciones generales del programa ---
|
||||
struct Options
|
||||
{
|
||||
@@ -105,6 +113,7 @@ struct Options
|
||||
VideoOptions video; // Opciones de vídeo
|
||||
AudioOptions audio; // Opciones de audio
|
||||
std::vector<GamepadOptions> controllers; // Opciones de mando para cada jugador
|
||||
PendingChanges pending_changes; // Opciones que se aplican al cerrar
|
||||
};
|
||||
|
||||
// --- Variables globales ---
|
||||
@@ -117,4 +126,5 @@ bool saveOptionsFile(std::string file_path); // Guarda el fichero de configuraci
|
||||
void setKeyboardToPlayer(int player_id); // Asigna el teclado al jugador
|
||||
void swapOptionsKeyboard(); // Intercambia el teclado de jugador
|
||||
void swapOptionsControllers(); // Intercambia los jugadores asignados a los dos primeros mandos
|
||||
int getPlayerWhoUsesKeyboard(); // Averigua quién está usando el teclado
|
||||
int getPlayerWhoUsesKeyboard(); // Averigua quién está usando el teclado
|
||||
void applyPendingChanges(); // Aplica los cambios pendientes copiando los valores a sus variables
|
||||
@@ -11,7 +11,7 @@ namespace section
|
||||
// --- Enumeraciones de secciones del programa ---
|
||||
enum class Name
|
||||
{
|
||||
INIT, // Inicialización
|
||||
RESET, // Inicialización
|
||||
LOGO, // Pantalla de logo
|
||||
INTRO, // Introducción
|
||||
TITLE, // Pantalla de título/menú principal
|
||||
|
||||
@@ -38,7 +38,9 @@ void ServiceMenu::toggle()
|
||||
{
|
||||
enabled_ = !enabled_;
|
||||
if (!enabled_)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja el menú de servicio en pantalla
|
||||
@@ -135,14 +137,8 @@ void ServiceMenu::setAnchors()
|
||||
// Establce la posición donde empezar a escribir las opciones del menu
|
||||
void ServiceMenu::setOptionsPosition()
|
||||
{
|
||||
/*
|
||||
const size_t MAX_ENTRIES = findLargestGroupSize();
|
||||
const size_t CURRENT_ENTRIES = display_options_.size();
|
||||
const size_t ADDED_SPACE = ((MAX_ENTRIES - CURRENT_ENTRIES) * (options_height_ + options_padding_)) / 2;
|
||||
options_y_ = rect_.y + upper_height_ + lower_padding_ + ADDED_SPACE;
|
||||
*/
|
||||
resize();
|
||||
options_y_ = rect_.y + upper_height_ + lower_padding_;
|
||||
resize();
|
||||
options_y_ = rect_.y + upper_height_ + lower_padding_;
|
||||
}
|
||||
|
||||
// Cambia el tamaño de la ventana de menu
|
||||
@@ -222,11 +218,13 @@ void ServiceMenu::setSelectorDown()
|
||||
void ServiceMenu::adjustOption(bool adjust_up)
|
||||
{
|
||||
if (display_options_.empty() || selected_ >= display_options_.size())
|
||||
return;
|
||||
|
||||
if (display_options_.at(selected_).behavior == OptionBehavior::ADJUST)
|
||||
{
|
||||
display_options_.at(selected_).adjustValue(adjust_up);
|
||||
return;
|
||||
}
|
||||
|
||||
if (display_options_.at(selected_)->behavior == OptionBehavior::ADJUST)
|
||||
{
|
||||
display_options_.at(selected_)->adjustValue(adjust_up);
|
||||
option_pairs_ = getOptionPairs(current_settings_group_);
|
||||
applySettings(current_settings_group_);
|
||||
playMenuSound();
|
||||
@@ -237,13 +235,15 @@ void ServiceMenu::adjustOption(bool adjust_up)
|
||||
void ServiceMenu::selectOption()
|
||||
{
|
||||
if (display_options_.empty() || selected_ >= display_options_.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Carpeta
|
||||
if (display_options_.at(selected_).type == ValueType::FOLDER)
|
||||
if (display_options_.at(selected_)->type == ValueType::FOLDER)
|
||||
{
|
||||
previous_settings_group_ = current_settings_group_;
|
||||
current_settings_group_ = display_options_.at(selected_).target_group;
|
||||
current_settings_group_ = display_options_.at(selected_)->target_group;
|
||||
updateMenu(current_settings_group_);
|
||||
selected_ = 0;
|
||||
setOptionsPosition();
|
||||
@@ -252,21 +252,21 @@ void ServiceMenu::selectOption()
|
||||
}
|
||||
|
||||
// Opción
|
||||
if (display_options_.at(selected_).behavior == OptionBehavior::SELECT)
|
||||
if (display_options_.at(selected_)->behavior == OptionBehavior::SELECT)
|
||||
{
|
||||
if (display_options_.at(selected_).caption == lang::getText("[SERVICE_MENU] RESET"))
|
||||
if (display_options_.at(selected_)->caption == lang::getText("[SERVICE_MENU] RESET"))
|
||||
{
|
||||
section::name = section::Name::INIT;
|
||||
section::name = section::Name::RESET;
|
||||
toggle();
|
||||
return;
|
||||
}
|
||||
else if (display_options_.at(selected_).caption == lang::getText("[SERVICE_MENU] QUIT"))
|
||||
else if (display_options_.at(selected_)->caption == lang::getText("[SERVICE_MENU] QUIT"))
|
||||
{
|
||||
section::name = section::Name::QUIT;
|
||||
section::options = section::Options::QUIT_WITH_KEYBOARD;
|
||||
return;
|
||||
}
|
||||
else if (display_options_.at(selected_).caption == lang::getText("[SERVICE_MENU] SHUTDOWN"))
|
||||
else if (display_options_.at(selected_)->caption == lang::getText("[SERVICE_MENU] SHUTDOWN"))
|
||||
{
|
||||
section::name = section::Name::QUIT;
|
||||
section::options = section::Options::QUIT_WITH_CONTROLLER;
|
||||
@@ -314,6 +314,15 @@ void ServiceMenu::initializeOptions()
|
||||
|
||||
// Game
|
||||
options_.emplace_back(lang::getText("[SERVICE_MENU] AUTOFIRE"), SettingsGroup::GAME, OptionBehavior::ADJUST, &options.game.autofire, ValueType::BOOL);
|
||||
options_.emplace_back(
|
||||
lang::getText("[SERVICE_MENU] LANGUAGE"),
|
||||
SettingsGroup::GAME,
|
||||
OptionBehavior::ADJUST,
|
||||
&options.pending_changes.new_language,
|
||||
std::vector<std::string>{
|
||||
lang::getText("[SERVICE_MENU] LANG ES"),
|
||||
lang::getText("[SERVICE_MENU] LANG BA"),
|
||||
lang::getText("[SERVICE_MENU] LANG EN")});
|
||||
|
||||
// System
|
||||
options_.emplace_back(lang::getText("[SERVICE_MENU] RESET"), SettingsGroup::SYSTEM, OptionBehavior::SELECT, nullptr, ValueType::NONE);
|
||||
@@ -330,33 +339,31 @@ void ServiceMenu::initializeOptions()
|
||||
// Devuelve las opciones del grupo como pares (nombre, valor)
|
||||
ServiceMenu::OptionPairs ServiceMenu::getOptionPairs(ServiceMenu::SettingsGroup group) const
|
||||
{
|
||||
OptionPairs optionPairs;
|
||||
OptionPairs option_pairs;
|
||||
|
||||
for (const auto &option : options_)
|
||||
{
|
||||
if (option.group == group)
|
||||
{
|
||||
optionPairs.emplace_back(option.caption, option.getValueAsString());
|
||||
option_pairs.emplace_back(option.caption, option.getValueAsString());
|
||||
}
|
||||
}
|
||||
|
||||
return optionPairs;
|
||||
return option_pairs;
|
||||
}
|
||||
|
||||
// Devuelve las opciones del grupo como un vector de OptionEntry
|
||||
std::vector<ServiceMenu::OptionEntry> ServiceMenu::getOptionsByGroup(SettingsGroup group) const
|
||||
std::vector<ServiceMenu::OptionEntry *> ServiceMenu::getOptionsByGroup(SettingsGroup group)
|
||||
{
|
||||
std::vector<OptionEntry> filteredOptions;
|
||||
|
||||
for (const auto &option : options_)
|
||||
std::vector<OptionEntry *> filtered_options;
|
||||
for (auto &option : options_)
|
||||
{
|
||||
if (option.group == group)
|
||||
{
|
||||
filteredOptions.push_back(option);
|
||||
filtered_options.push_back(&option);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredOptions;
|
||||
return filtered_options;
|
||||
}
|
||||
|
||||
// Aplica la configuración correspondiente al grupo seleccionado
|
||||
@@ -367,11 +374,11 @@ void ServiceMenu::applySettings(ServiceMenu::SettingsGroup group)
|
||||
case SettingsGroup::VIDEO:
|
||||
Screen::get()->applySettings();
|
||||
break;
|
||||
|
||||
case SettingsGroup::AUDIO:
|
||||
Audio::get()->applySettings();
|
||||
break;
|
||||
|
||||
case SettingsGroup::GAME:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -380,6 +387,7 @@ void ServiceMenu::applySettings(ServiceMenu::SettingsGroup group)
|
||||
// Actualiza las opciones mostradas según el grupo seleccionado
|
||||
void ServiceMenu::updateMenu(SettingsGroup group)
|
||||
{
|
||||
AdjustListValues();
|
||||
option_pairs_ = getOptionPairs(group);
|
||||
display_options_ = getOptionsByGroup(group);
|
||||
}
|
||||
@@ -423,8 +431,34 @@ ServiceMenu::GroupAlignment ServiceMenu::getGroupAlignment(SettingsGroup group)
|
||||
case SettingsGroup::AUDIO:
|
||||
case SettingsGroup::GAME:
|
||||
return GroupAlignment::LEFT;
|
||||
|
||||
default:
|
||||
return GroupAlignment::CENTERED;
|
||||
}
|
||||
}
|
||||
|
||||
// Devuelve un puntero a OptionEntry a partir del caption, o nullptr si no se encuentra
|
||||
ServiceMenu::OptionEntry *ServiceMenu::getOptionEntryByCaption(const std::string &caption)
|
||||
{
|
||||
for (auto &option : options_)
|
||||
{
|
||||
if (option.caption == caption)
|
||||
{
|
||||
return &option;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Ajusta los valores de las opciones tipo lista
|
||||
void ServiceMenu::AdjustListValues()
|
||||
{
|
||||
// Idioma
|
||||
auto option = getOptionEntryByCaption(lang::getText("[SERVICE_MENU] LANGUAGE"));
|
||||
for (size_t i = 0; i < option->value_list.size(); ++i)
|
||||
{
|
||||
if (lang::getCodeFromName(option->value_list[i]) == options.game.language)
|
||||
{
|
||||
option->list_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include "utils.h"
|
||||
#include "lang.h"
|
||||
#include "options.h"
|
||||
|
||||
class Text;
|
||||
|
||||
@@ -68,6 +69,7 @@ private:
|
||||
{
|
||||
BOOL, // Valor booleano
|
||||
INT, // Valor entero
|
||||
LIST, // Lista de valores
|
||||
FOLDER, // Referencia a otro grupo
|
||||
NONE // Sin valor asociado
|
||||
};
|
||||
@@ -85,28 +87,35 @@ private:
|
||||
SettingsGroup group; // Categoría de la opción
|
||||
OptionBehavior behavior; // Cómo se interactúa con la opción
|
||||
void *linked_variable; // Puntero a la variable que controla la opción
|
||||
ValueType type; // Tipo de la variable (bool, int, folder, none)
|
||||
ValueType type; // Tipo de la variable
|
||||
|
||||
int min_value; // Valor mínimo (solo aplicable si type == INT)
|
||||
int max_value; // Valor máximo (solo aplicable si type == INT)
|
||||
int step_value; // Incremento al modificar la opción (solo aplicable si type == INT)
|
||||
int min_value; // Valor mínimo (solo aplicable si type == INT)
|
||||
int max_value; // Valor máximo (solo aplicable si type == INT)
|
||||
int step_value; // Incremento al modificar la opción (solo aplicable si type == INT)
|
||||
std::vector<std::string> value_list; // Lista de valores posibles (solo aplicable si type == LIST)
|
||||
size_t list_index; // Índice del valor seleccionado dentro de value_list
|
||||
|
||||
SettingsGroup target_group; // Grupo al que hace referencia la opción si es de tipo FOLDER
|
||||
|
||||
// Constructor para opciones de tipo BOOL, NONE o FOLDER
|
||||
// Constructor para opciones de tipo BOOL, NONE, FOLDER
|
||||
OptionEntry(std::string cap, SettingsGroup grp, OptionBehavior beh, void *var, ValueType t)
|
||||
: caption(cap), group(grp), behavior(beh), linked_variable(var), type(t),
|
||||
min_value(0), max_value(0), step_value(0), target_group(SettingsGroup::SYSTEM) {}
|
||||
min_value(0), max_value(0), step_value(0), list_index(0), target_group(SettingsGroup::SYSTEM) {}
|
||||
|
||||
// Constructor para opciones de tipo INT con valores mínimos, máximos e incremento
|
||||
// Constructor para opciones de tipo INT
|
||||
OptionEntry(std::string cap, SettingsGroup grp, OptionBehavior beh, void *var, ValueType t, int min, int max, int step)
|
||||
: caption(cap), group(grp), behavior(beh), linked_variable(var), type(t),
|
||||
min_value(min), max_value(max), step_value(step), target_group(SettingsGroup::SYSTEM) {}
|
||||
min_value(min), max_value(max), step_value(step), list_index(0), target_group(SettingsGroup::SYSTEM) {}
|
||||
|
||||
// Constructor para opciones de tipo FOLDER que referencian otro grupo
|
||||
// Constructor para opciones de tipo LIST
|
||||
OptionEntry(std::string cap, SettingsGroup grp, OptionBehavior beh, void *var, std::vector<std::string> values)
|
||||
: caption(cap), group(grp), behavior(beh), linked_variable(var), type(ValueType::LIST),
|
||||
min_value(0), max_value(0), step_value(0), value_list(values), list_index(0), target_group(SettingsGroup::SYSTEM) {}
|
||||
|
||||
// Constructor para opciones de tipo FOLDER
|
||||
OptionEntry(std::string cap, SettingsGroup grp, OptionBehavior beh, SettingsGroup tgtGrp)
|
||||
: caption(cap), group(grp), behavior(beh), linked_variable(nullptr), type(ValueType::FOLDER),
|
||||
min_value(0), max_value(0), step_value(0), target_group(tgtGrp) {}
|
||||
min_value(0), max_value(0), step_value(0), list_index(0), target_group(tgtGrp) {}
|
||||
|
||||
// Método para modificar el valor de la opción
|
||||
void adjustValue(bool adjust_up)
|
||||
@@ -124,6 +133,25 @@ private:
|
||||
bool &value = *(static_cast<bool *>(linked_variable));
|
||||
value = !value;
|
||||
}
|
||||
else if (type == ValueType::LIST && !value_list.empty())
|
||||
{
|
||||
list_index = adjust_up ? (list_index + 1) % value_list.size()
|
||||
: (list_index - 1 + value_list.size()) % value_list.size();
|
||||
|
||||
// Idioma
|
||||
if (linked_variable == &options.pending_changes.new_language)
|
||||
{
|
||||
options.pending_changes.new_language = lang::getCodeFromName(value_list[list_index]);
|
||||
options.pending_changes.has_pending_changes = true;
|
||||
}
|
||||
|
||||
// Dificultad
|
||||
if (linked_variable == &options.pending_changes.new_difficulty)
|
||||
{
|
||||
// options.pending_changes.new_difficulty =
|
||||
options.pending_changes.has_pending_changes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +164,8 @@ private:
|
||||
return (*(static_cast<bool *>(linked_variable))) ? lang::getText("[SERVICE_MENU] ON") : lang::getText("[SERVICE_MENU] OFF");
|
||||
case ValueType::INT:
|
||||
return std::to_string(*(static_cast<int *>(linked_variable)));
|
||||
case ValueType::LIST:
|
||||
return value_list.empty() ? "" : value_list[list_index];
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
@@ -143,18 +173,18 @@ private:
|
||||
};
|
||||
|
||||
// --- Variables internas ---
|
||||
bool enabled_ = false; // Indica si el menú de servicio está activo
|
||||
SDL_FRect rect_; // Rectángulo que define el área del menú de servicio
|
||||
std::shared_ptr<Text> element_text_; // Objeto para escribir el texto de los elementos
|
||||
std::shared_ptr<Text> title_text_; // Objeto para escribir el texto del título
|
||||
size_t selected_ = 0; // Índice del elemento del menú seleccionado
|
||||
Uint32 counter_ = 0; // Contador interno
|
||||
std::vector<OptionEntry> options_; // Listado con todas las opciones del menú de servicio
|
||||
std::vector<OptionEntry> display_options_; // Opciones actualmente mostradas en pantalla
|
||||
OptionPairs option_pairs_; // Opciones actuales del menú (filtradas por grupo)
|
||||
SettingsGroup current_settings_group_; // Grupo de opciones actualmente activo
|
||||
SettingsGroup previous_settings_group_; // Grupo de opciones anterior
|
||||
Aspect aspect_ = Aspect::ASPECT1; // Estilo visual del menú
|
||||
bool enabled_ = false; // Indica si el menú de servicio está activo
|
||||
SDL_FRect rect_; // Rectángulo que define el área del menú de servicio
|
||||
std::shared_ptr<Text> element_text_; // Objeto para escribir el texto de los elementos
|
||||
std::shared_ptr<Text> title_text_; // Objeto para escribir el texto del título
|
||||
size_t selected_ = 0; // Índice del elemento del menú seleccionado
|
||||
Uint32 counter_ = 0; // Contador interno
|
||||
std::vector<OptionEntry> options_; // Listado con todas las opciones del menú de servicio
|
||||
std::vector<OptionEntry *> display_options_; // Opciones actualmente mostradas en pantalla (punteros)
|
||||
OptionPairs option_pairs_; // Opciones actuales del menú (filtradas por grupo)
|
||||
SettingsGroup current_settings_group_; // Grupo de opciones actualmente activo
|
||||
SettingsGroup previous_settings_group_; // Grupo de opciones anterior
|
||||
Aspect aspect_ = Aspect::ASPECT1; // Estilo visual del menú
|
||||
|
||||
// --- Variables de aspecto ---
|
||||
Color bg_color_ = SERV_MENU_BG_COLOR; // Color de fondo
|
||||
@@ -179,19 +209,21 @@ private:
|
||||
void resize(); // Cambia el tamaño de la ventana de menu
|
||||
|
||||
// --- Métodos internos: Gestión de opciones ---
|
||||
void initializeOptions(); // Crea todas las opciones del menú de servicio
|
||||
OptionPairs getOptionPairs(SettingsGroup group) const; // Devuelve las opciones como pares de strings para un grupo
|
||||
std::vector<OptionEntry> getOptionsByGroup(SettingsGroup group) const; // Devuelve las opciones de un grupo
|
||||
void initializeOptions(); // Crea todas las opciones del menú de servicio
|
||||
OptionPairs getOptionPairs(SettingsGroup group) const; // Devuelve las opciones como pares de strings para un grupo
|
||||
std::vector<OptionEntry *> getOptionsByGroup(SettingsGroup group); // Devuelve punteros a las opciones de un grupo
|
||||
|
||||
// --- Métodos internos: Lógica de menú ---
|
||||
void applySettings(SettingsGroup group); // Aplica la configuración de un grupo
|
||||
void updateMenu(SettingsGroup group); // Actualiza las opciones mostradas según el grupo
|
||||
void AdjustListValues(); // Ajusta los valores de las opciones tipo lista
|
||||
|
||||
// --- Métodos internos: Utilidades ---
|
||||
void updateCounter(); // Actualiza el contador interno
|
||||
int calculateMenuHeight() const; // Calcula la altura del menú
|
||||
int findLargestGroupSize() const; // Devuelve el tamaño del grupo más grande
|
||||
GroupAlignment getGroupAlignment(SettingsGroup group) const; // Devuelve la alineación del grupo
|
||||
void updateCounter(); // Actualiza el contador interno
|
||||
int calculateMenuHeight() const; // Calcula la altura del menú
|
||||
int findLargestGroupSize() const; // Devuelve el tamaño del grupo más grande
|
||||
GroupAlignment getGroupAlignment(SettingsGroup group) const; // Devuelve la alineación del grupo
|
||||
OptionEntry *getOptionEntryByCaption(const std::string &caption); // Devuelve un puntero a OptionEntry a partir del caption
|
||||
|
||||
// --- Patrón Singleton ---
|
||||
ServiceMenu(); // Constructor privado
|
||||
|
||||
Reference in New Issue
Block a user