treballant en redefinir els botons i axis del joystick

This commit is contained in:
2025-11-02 18:57:24 +01:00
parent 6c766be023
commit b79f30a57b
6 changed files with 243 additions and 8 deletions

View File

@@ -115,8 +115,12 @@ void Title::handleEvents() {
break;
case SDLK_2:
// Redefinir joystick (futuro)
// controls_menu_state_ = ControlsMenuState::JOYSTICK_REMAP;
// Redefinir joystick - solo si hay gamepads conectados
if (Input::get()->gameControllerFound()) {
controls_menu_state_ = ControlsMenuState::JOYSTICK_REMAP;
remap_step_ = 0;
remap_error_message_.clear();
}
break;
default:
@@ -125,6 +129,9 @@ void Title::handleEvents() {
} else if (controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP) {
// Captura de teclas para redefinir
handleControlsMenuKeyboardRemap(event);
} else if (controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP) {
// Captura de botones del gamepad para redefinir
handleControlsMenuJoystickRemap(event);
}
break;
@@ -336,6 +343,16 @@ void Title::updateControlsMenu(float delta_time) {
transitionToState(State::MAIN_MENU);
}
}
// Si estamos mostrando los botones definidos, esperar antes de guardar
else if (controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP_COMPLETE) {
state_time_ += delta_time;
if (state_time_ >= KEYBOARD_REMAP_DISPLAY_DELAY) {
// Aplicar y guardar los botones
applyJoystickRemap();
// Volver al menu principal
transitionToState(State::MAIN_MENU);
}
}
}
// Actualiza el estado FADE_MENU
@@ -484,12 +501,21 @@ void Title::renderControlsMenu() {
if (controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP ||
controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP_COMPLETE) {
renderKeyboardRemap();
} else if (controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP ||
controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP_COMPLETE) {
renderJoystickRemap();
} else {
// Menu principal de controles
const Uint8 COLOR = stringToColor("green");
const Uint8 DISABLED_COLOR = stringToColor("dark grey");
const int TEXT_SIZE = menu_text_->getCharacterSize();
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1. REDEFINE KEYBOARD", 1, COLOR);
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2. REDEFINE JOYSTICK", 1, COLOR);
// Deshabilitar opcion de joystick si no hay gamepads conectados
const bool gamepad_available = Input::get()->gameControllerFound();
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE,
"2. REDEFINE JOYSTICK", 1, gamepad_available ? COLOR : DISABLED_COLOR);
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 17 * TEXT_SIZE, "ENTER TO GO BACK", 1, COLOR);
}
}
@@ -662,4 +688,140 @@ void Title::renderKeyboardRemap() {
if (!remap_error_message_.empty()) {
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 18 * TEXT_SIZE, remap_error_message_, 1, ERROR_COLOR);
}
}
// Dibuja la pantalla de redefinir joystick
void Title::renderJoystickRemap() {
const Uint8 COLOR = stringToColor("green");
const Uint8 ERROR_COLOR = stringToColor("red");
const int TEXT_SIZE = menu_text_->getCharacterSize();
// Mensaje principal: "PRESS BUTTON FOR [ACTION]" o "BUTTONS DEFINED" si completado
if (remap_step_ >= 3) {
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 12 * TEXT_SIZE, "BUTTONS DEFINED", 1, COLOR);
} else {
const std::string ACTION = getActionName(remap_step_);
const std::string MESSAGE = "PRESS BUTTON FOR " + ACTION;
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 12 * TEXT_SIZE, MESSAGE, 1, COLOR);
}
// Mostrar botones ya capturados
if (remap_step_ > 0) {
const std::string LEFT_BTN = getButtonName(temp_buttons_[0]);
const std::string LEFT_MSG = "LEFT: " + LEFT_BTN;
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 14 * TEXT_SIZE, LEFT_MSG, 1, COLOR);
}
if (remap_step_ > 1) {
const std::string RIGHT_BTN = getButtonName(temp_buttons_[1]);
const std::string RIGHT_MSG = "RIGHT: " + RIGHT_BTN;
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 15 * TEXT_SIZE, RIGHT_MSG, 1, COLOR);
}
if (remap_step_ >= 3) {
const std::string JUMP_BTN = getButtonName(temp_buttons_[2]);
const std::string JUMP_MSG = "JUMP: " + JUMP_BTN;
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 16 * TEXT_SIZE, JUMP_MSG, 1, COLOR);
}
// Mensaje de error si existe
if (!remap_error_message_.empty()) {
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 18 * TEXT_SIZE, remap_error_message_, 1, ERROR_COLOR);
}
}
// Maneja la captura de botones del gamepad para redefinir
void Title::handleControlsMenuJoystickRemap(const SDL_Event& event) {
int captured_button = -1;
// Capturar botones del gamepad
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
captured_button = static_cast<int>(event.gbutton.button);
}
// Capturar triggers como botones (usando valores especiales 100/101)
else if (event.type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
constexpr Sint16 TRIGGER_THRESHOLD = 20000;
if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) {
captured_button = Input::TRIGGER_L2_AS_BUTTON; // 100
} else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) {
captured_button = Input::TRIGGER_R2_AS_BUTTON; // 101
}
// Capturar ejes del stick analógico (usando valores especiales 200+)
else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFTX) {
constexpr Sint16 AXIS_THRESHOLD = 20000;
if (event.gaxis.value < -AXIS_THRESHOLD) {
captured_button = 200; // Left stick izquierda
} else if (event.gaxis.value > AXIS_THRESHOLD) {
captured_button = 201; // Left stick derecha
}
}
}
// Si no se capturó ningún input válido, salir
if (captured_button == -1) {
return;
}
// Verifica duplicados
if (isButtonDuplicate(captured_button, remap_step_)) {
remap_error_message_ = "BUTTON ALREADY USED! TRY ANOTHER";
return;
}
// Botón válido, guardar
temp_buttons_[remap_step_] = captured_button;
remap_error_message_.clear();
remap_step_++;
// Si completamos los 3 pasos, mostrar resultado y esperar
if (remap_step_ >= 3) {
controls_menu_state_ = ControlsMenuState::JOYSTICK_REMAP_COMPLETE;
state_time_ = 0.0F; // Resetear el timer para el delay
}
}
// Valida si un botón está duplicado
bool Title::isButtonDuplicate(int button, int current_step) {
for (int i = 0; i < current_step; ++i) {
if (temp_buttons_[i] == button) {
return true;
}
}
return false;
}
// Aplica y guarda los botones del gamepad redefinidos
void Title::applyJoystickRemap() {
// Guardar los nuevos botones en Options::gamepad_controls
Options::gamepad_controls.button_left = temp_buttons_[0];
Options::gamepad_controls.button_right = temp_buttons_[1];
Options::gamepad_controls.button_jump = temp_buttons_[2];
// Aplicar los bindings al sistema de Input
Input::get()->applyGamepadBindingsFromOptions();
// Guardar a archivo de configuracion
Options::saveToFile(Asset::get()->get("config.txt"));
}
// Retorna el nombre amigable del botón del gamepad
std::string Title::getButtonName(int button) {
// Triggers especiales
if (button == Input::TRIGGER_L2_AS_BUTTON) {
return "L2";
}
if (button == Input::TRIGGER_R2_AS_BUTTON) {
return "R2";
}
// Ejes del stick analógico
if (button == 200) {
return "LEFT STICK LEFT";
}
if (button == 201) {
return "LEFT STICK RIGHT";
}
// Botones estándar SDL
const auto sdl_button = static_cast<SDL_GamepadButton>(button);
const char* button_name = SDL_GetGamepadStringForButton(sdl_button);
return button_name ? std::string(button_name) : "UNKNOWN";
}