diff --git a/source/options.cpp b/source/options.cpp index 3b9ee0c..b4ac558 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -43,8 +43,6 @@ void init() { // Opciones de control gamepads.init(); - assignGamepadByName("", Player::Id::PLAYER1); - //assignGamepadByName("", Player::Id::PLAYER2); setKeyboardToPlayer(Player::Id::PLAYER1); // Opciones de cambios pendientes @@ -55,47 +53,44 @@ void init() { // Carga el fichero de configuración auto loadFromFile() -> bool { - // Inicializa las opciones del programa + // 1. Inicializa las opciones con valores por defecto. init(); - // Indicador de éxito en la carga - bool success = true; - - // Variables para manejar el fichero std::ifstream file(settings.config_file); - // Si el fichero se puede abrir + // 2. Si el fichero existe, lo leemos para obtener los nombres de los mandos. if (file.good()) { - // Procesa el fichero línea a línea + // --- CASO: EL FICHERO EXISTE --- SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(settings.config_file).c_str()); std::string line; while (std::getline(file, line)) { - // Comprueba que la línea no sea un comentario if (line.substr(0, 1) != "#") { - // Encuentra la posición del carácter '=' int pos = line.find("="); - // Procesa las dos subcadenas if (!set(line.substr(0, pos), line.substr(pos + 1, line.length()))) { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Unknown parameter: %s", line.substr(0, pos).c_str()); - success = false; + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Unknown parameter: %s", line.substr(0, pos).c_str()); } } } file.close(); } - // El fichero no existe - else { - saveToFile(); // Crea el fichero con los valores por defecto + + // 3. Llamamos al asignador inteligente. + gamepads.assignAndLinkGamepads(); + + // 4. Si el fichero no existía, lo creamos ahora con la configuración por defecto. + if (!file.good()) { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Config file not found. Creating default settings."); + saveToFile(); } - // Normaliza los valores + // Normaliza valores como antes... if (settings.language != Lang::Code::ENGLISH && settings.language != Lang::Code::VALENCIAN && settings.language != Lang::Code::SPANISH) { settings.language = Lang::Code::ENGLISH; } - return success; + return true; } // Guarda el fichero de configuración @@ -280,13 +275,12 @@ void checkPendingChanges() { } // Buscar y asignar un mando disponible por nombre -bool assignGamepadByName(const std::string& gamepad_name, Player::Id player_id) { - auto available_gamepad = Input::get()->findAvailableGamepadByName(gamepad_name); +bool assignGamepadByName(const std::string& gamepad_name_to_find, Player::Id player_id) { + auto found_gamepad = Input::get()->findAvailableGamepadByName(gamepad_name_to_find); - if (available_gamepad) { - const std::string& actual_gamepad_name = available_gamepad->name; - return gamepads.assignGamepadToPlayer(player_id, available_gamepad, actual_gamepad_name); - } + if (found_gamepad) { + return gamepads.assignGamepadToPlayer(player_id, found_gamepad, found_gamepad->name); + } return false; } @@ -300,4 +294,76 @@ std::string getGamepadInfo(Player::Id player_id) { return "Invalid player"; } } + +// Asigna los mandos físicos basándose en la configuración actual de nombres. +void GamepadManager::assignAndLinkGamepads() { + // 1. Obtenemos todos los mandos físicos que están conectados ahora mismo. + auto physical_gamepads = Input::get()->getGamepads(); + + // 2. Reiniciamos las asignaciones actuales y guardamos los nombres que teníamos en la config. + std::array desired_names; + for (size_t i = 0; i < MAX_PLAYERS; ++i) { + desired_names[i] = gamepads[i].name; // Guardamos el nombre deseado + gamepads[i].instance = nullptr; // Limpiamos la instancia + } + + // 3. Vector para rastrear los mandos físicos que ya hemos asignado. + std::vector> assigned_instances; + + // --- PRIMERA PASADA: Buscar coincidencias exactas por nombre --- + // Recorremos la configuración de nuestros jugadores (P1, P2). + for (size_t i = 0; i < MAX_PLAYERS; ++i) { + const std::string& desired_name = desired_names[i]; + if (desired_name.empty()) { + continue; // Si no se pide un nombre específico, pasamos a la siguiente fase. + } + + // Buscamos un mando físico que coincida con el nombre deseado. + for (const auto& physical_gamepad : physical_gamepads) { + if (physical_gamepad->name == desired_name) { + // ¡Coincidencia! Ahora, comprobamos que no lo hayamos asignado ya. + bool already_assigned = false; + for (const auto& assigned : assigned_instances) { + if (assigned == physical_gamepad) { + already_assigned = true; + break; + } + } + + if (!already_assigned) { + gamepads[i].instance = physical_gamepad; // Enlazamos la instancia + assigned_instances.push_back(physical_gamepad); // Lo marcamos como asignado + break; // Mando encontrado para este jugador, pasamos al siguiente. + } + } + } + } + + // --- SEGUNDA PASADA: Asignar los mandos restantes a los jugadores sin mando --- + // Recorremos de nuevo la configuración de nuestros jugadores. + for (size_t i = 0; i < MAX_PLAYERS; ++i) { + if (gamepads[i].instance == nullptr) { // Si este jugador aún no tiene mando... + + // ...buscamos un mando físico que todavía esté libre. + for (const auto& physical_gamepad : physical_gamepads) { + bool already_assigned = false; + for (const auto& assigned : assigned_instances) { + if (assigned == physical_gamepad) { + already_assigned = true; + break; + } + } + + if (!already_assigned) { + gamepads[i].instance = physical_gamepad; // Se lo asignamos + // MUY IMPORTANTE: Actualizamos el nombre en la configuración. + // Si guardamos, ahora se guardará el nombre del mando real que se le asignó. + gamepads[i].name = physical_gamepad->name; + assigned_instances.push_back(physical_gamepad); // Lo marcamos como asignado + break; // Mando encontrado, pasamos al siguiente jugador. + } + } + } + } +} } // namespace Options \ No newline at end of file diff --git a/source/options.h b/source/options.h index 09bef98..73116fb 100644 --- a/source/options.h +++ b/source/options.h @@ -202,6 +202,9 @@ class GamepadManager { return false; } + // Asigna los mandos físicos basándose en la configuración actual de nombres. + void assignAndLinkGamepads(); + // Iteradores auto begin() { return gamepads.begin(); } auto end() { return gamepads.end(); }