treball en curs: correccions de tidy
This commit is contained in:
@@ -8,29 +8,29 @@ namespace GlobalInputs {
|
|||||||
auto handle() -> bool {
|
auto handle() -> bool {
|
||||||
if (Screen::get() == nullptr || Input::get() == nullptr) { return false; }
|
if (Screen::get() == nullptr || Input::get() == nullptr) { return false; }
|
||||||
|
|
||||||
if (Input::get()->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(WINDOW_FULLSCREEN, REPEAT_FALSE)) {
|
||||||
Screen::get()->toggleVideoMode();
|
Screen::get()->toggleVideoMode();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Input::get()->checkInput(input_window_dec_size, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(WINDOW_DEC_ZOOM, REPEAT_FALSE)) {
|
||||||
Screen::get()->decWindowZoom();
|
Screen::get()->decWindowZoom();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Input::get()->checkInput(input_window_inc_size, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(WINDOW_INC_ZOOM, REPEAT_FALSE)) {
|
||||||
Screen::get()->incWindowZoom();
|
Screen::get()->incWindowZoom();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Input::get()->checkInput(input_toggle_shader, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(TOGGLE_SHADER, REPEAT_FALSE)) {
|
||||||
Screen::get()->toggleShaderEnabled();
|
Screen::get()->toggleShaderEnabled();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// F5/F6 només actuen quan el post-procesado està actiu.
|
// F5/F6 només actuen quan el post-procesado està actiu.
|
||||||
if (Screen::get()->isShaderEnabled()) {
|
if (Screen::get()->isShaderEnabled()) {
|
||||||
if (Input::get()->checkInput(input_toggle_shader_type, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(TOGGLE_SHADER_TYPE, REPEAT_FALSE)) {
|
||||||
Screen::get()->toggleActiveShader();
|
Screen::get()->toggleActiveShader();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Input::get()->checkInput(input_next_preset, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(NEXT_SHADER_PRESET, REPEAT_FALSE)) {
|
||||||
Screen::get()->nextPreset();
|
Screen::get()->nextPreset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+166
-169
@@ -45,8 +45,8 @@ static void installWebStandardMapping(SDL_JoystickID jid) {
|
|||||||
Input *Input::instance = nullptr;
|
Input *Input::instance = nullptr;
|
||||||
|
|
||||||
// Singleton API
|
// Singleton API
|
||||||
void Input::init(const std::string &gameControllerDbPath) {
|
void Input::init(const std::string &game_controller_db_path) {
|
||||||
Input::instance = new Input(gameControllerDbPath);
|
Input::instance = new Input(game_controller_db_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::destroy() {
|
void Input::destroy() {
|
||||||
@@ -60,111 +60,99 @@ auto Input::get() -> Input * {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Input::Input(std::string file)
|
Input::Input(std::string file)
|
||||||
: dbPath(std::move(file)) {
|
: db_path_(std::move(file)) {
|
||||||
// Inicializa las variables
|
// Inicializa las variables
|
||||||
KeyBindings kb;
|
KeyBindings kb;
|
||||||
kb.scancode = 0;
|
kb.scancode = 0;
|
||||||
kb.active = false;
|
kb.active = false;
|
||||||
keyBindings.resize(input_number_of_inputs, kb);
|
key_bindings_.resize(NUMBER_OF_INPUTS, kb);
|
||||||
|
|
||||||
GameControllerBindings gcb;
|
GameControllerBindings gcb;
|
||||||
gcb.button = SDL_GAMEPAD_BUTTON_INVALID;
|
gcb.button = SDL_GAMEPAD_BUTTON_INVALID;
|
||||||
gcb.active = false;
|
gcb.active = false;
|
||||||
gameControllerBindings.resize(input_number_of_inputs, gcb);
|
game_controller_bindings_.resize(NUMBER_OF_INPUTS, gcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Input::~Input() {
|
Input::~Input() {
|
||||||
for (auto *pad : connectedControllers) {
|
for (auto *pad : connected_controllers_) {
|
||||||
if (pad != nullptr) {
|
if (pad != nullptr) {
|
||||||
SDL_CloseGamepad(pad);
|
SDL_CloseGamepad(pad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connectedControllers.clear();
|
connected_controllers_.clear();
|
||||||
connectedControllerIds.clear();
|
connected_controller_ids_.clear();
|
||||||
controllerNames.clear();
|
controller_names_.clear();
|
||||||
numGamepads = 0;
|
num_gamepads_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el estado del objeto
|
// Actualiza el estado del objeto
|
||||||
void Input::update() {
|
void Input::update() {
|
||||||
if (disabledUntil == d_keyPressed && !checkAnyInput()) {
|
if (disabled_until_ == KEY_PRESSED && !checkAnyInput()) {
|
||||||
enable();
|
enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asigna inputs a teclas
|
// Asigna inputs a teclas
|
||||||
void Input::bindKey(Uint8 input, SDL_Scancode code) {
|
void Input::bindKey(Uint8 input, SDL_Scancode code) {
|
||||||
keyBindings[input].scancode = code;
|
key_bindings_[input].scancode = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asigna inputs a botones del mando
|
// Asigna inputs a botones del mando
|
||||||
void Input::bindGameControllerButton(Uint8 input, SDL_GamepadButton button) {
|
void Input::bindGameControllerButton(Uint8 input, SDL_GamepadButton button) {
|
||||||
gameControllerBindings[input].button = button;
|
game_controller_bindings_[input].button = button;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si un input esta activo
|
// Comprueba si un input esta activo
|
||||||
auto Input::checkInput(Uint8 input, bool repeat, int device, int index) -> bool {
|
auto Input::checkInput(Uint8 input, bool repeat, int device, int index) -> bool {
|
||||||
if (!enabled) {
|
if (!enabled_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool successKeyboard = false;
|
|
||||||
bool successGameController = false;
|
|
||||||
|
|
||||||
if (device == INPUT_USE_ANY) {
|
if (device == INPUT_USE_ANY) {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool success_keyboard = false;
|
||||||
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) {
|
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) {
|
||||||
const bool *keyStates = SDL_GetKeyboardState(nullptr);
|
success_keyboard = checkKeyboardInput(input, repeat);
|
||||||
|
|
||||||
if (repeat) {
|
|
||||||
successKeyboard = keyStates[keyBindings[input].scancode];
|
|
||||||
} else {
|
|
||||||
if (!keyBindings[input].active) {
|
|
||||||
if (keyStates[keyBindings[input].scancode]) {
|
|
||||||
keyBindings[input].active = true;
|
|
||||||
successKeyboard = true;
|
|
||||||
} else {
|
|
||||||
successKeyboard = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!keyStates[keyBindings[input].scancode]) {
|
|
||||||
keyBindings[input].active = false;
|
|
||||||
successKeyboard = false;
|
|
||||||
} else {
|
|
||||||
successKeyboard = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameControllerFound() && index >= 0 && index < (int)connectedControllers.size()) {
|
bool success_game_controller = false;
|
||||||
if ((device == INPUT_USE_GAMECONTROLLER) || (device == INPUT_USE_ANY)) {
|
if ((device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY) && gameControllerFound() && index >= 0 && index < (int)connected_controllers_.size()) {
|
||||||
if (repeat) {
|
success_game_controller = checkGameControllerInput(input, repeat, index);
|
||||||
successGameController = SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button);
|
|
||||||
} else {
|
|
||||||
if (!gameControllerBindings[input].active) {
|
|
||||||
if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) {
|
|
||||||
gameControllerBindings[input].active = true;
|
|
||||||
successGameController = true;
|
|
||||||
} else {
|
|
||||||
successGameController = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) {
|
|
||||||
gameControllerBindings[input].active = false;
|
|
||||||
successGameController = false;
|
|
||||||
} else {
|
|
||||||
successGameController = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (successKeyboard || successGameController);
|
return success_keyboard || success_game_controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper de checkInput: comprueba el estado de una tecla
|
||||||
|
auto Input::checkKeyboardInput(Uint8 input, bool repeat) -> bool {
|
||||||
|
const bool *key_states = SDL_GetKeyboardState(nullptr);
|
||||||
|
const bool IS_DOWN = key_states[key_bindings_[input].scancode];
|
||||||
|
|
||||||
|
if (repeat) {
|
||||||
|
return IS_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modo edge-trigger: éxito sólo en el frame en que la tecla pasa de up a down
|
||||||
|
const bool PRESS_EDGE = IS_DOWN && !key_bindings_[input].active;
|
||||||
|
key_bindings_[input].active = IS_DOWN;
|
||||||
|
return PRESS_EDGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper de checkInput: comprueba el estado de un botón de mando
|
||||||
|
auto Input::checkGameControllerInput(Uint8 input, bool repeat, int index) -> bool {
|
||||||
|
const bool IS_DOWN = SDL_GetGamepadButton(connected_controllers_[index], game_controller_bindings_[input].button);
|
||||||
|
|
||||||
|
if (repeat) {
|
||||||
|
return IS_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modo edge-trigger: éxito sólo en el frame en que el botón pasa de up a down
|
||||||
|
const bool PRESS_EDGE = IS_DOWN && !game_controller_bindings_[input].active;
|
||||||
|
game_controller_bindings_[input].active = IS_DOWN;
|
||||||
|
return PRESS_EDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si hay almenos un input activo
|
// Comprueba si hay almenos un input activo
|
||||||
@@ -174,19 +162,19 @@ auto Input::checkAnyInput(int device, int index) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) {
|
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) {
|
||||||
const bool *mKeystates = SDL_GetKeyboardState(nullptr);
|
const bool *key_states = SDL_GetKeyboardState(nullptr);
|
||||||
|
|
||||||
for (auto &keyBinding : keyBindings) {
|
for (auto &key_binding : key_bindings_) {
|
||||||
if (mKeystates[keyBinding.scancode]) {
|
if (key_states[key_binding.scancode]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameControllerFound() && index >= 0 && index < (int)connectedControllers.size()) {
|
if (gameControllerFound() && index >= 0 && index < (int)connected_controllers_.size()) {
|
||||||
if (device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY) {
|
if (device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY) {
|
||||||
for (auto &gameControllerBinding : gameControllerBindings) {
|
for (auto &game_controller_binding : game_controller_bindings_) {
|
||||||
if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBinding.button)) {
|
if (SDL_GetGamepadButton(connected_controllers_[index], game_controller_binding.button)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,13 +187,13 @@ auto Input::checkAnyInput(int device, int index) -> bool {
|
|||||||
// Construye el nombre visible de un mando.
|
// Construye el nombre visible de un mando.
|
||||||
// Recorta des del primer '(' o '[' (per a evitar coses tipus
|
// Recorta des del primer '(' o '[' (per a evitar coses tipus
|
||||||
// "Retroid Controller (vendor: 1001) ...") i talla a 25 caràcters.
|
// "Retroid Controller (vendor: 1001) ...") i talla a 25 caràcters.
|
||||||
auto Input::buildControllerName(SDL_Gamepad *pad, int padIndex) -> std::string {
|
auto Input::buildControllerName(SDL_Gamepad *pad, int pad_index) -> std::string {
|
||||||
(void)padIndex;
|
(void)pad_index;
|
||||||
const char *padName = SDL_GetGamepadName(pad);
|
const char *pad_name = SDL_GetGamepadName(pad);
|
||||||
std::string name = (padName != nullptr) ? padName : "Unknown";
|
std::string name = (pad_name != nullptr) ? pad_name : "Unknown";
|
||||||
const auto pos = name.find_first_of("([");
|
const auto POS = name.find_first_of("([");
|
||||||
if (pos != std::string::npos) {
|
if (POS != std::string::npos) {
|
||||||
name.erase(pos);
|
name.erase(POS);
|
||||||
}
|
}
|
||||||
while (!name.empty() && name.back() == ' ') {
|
while (!name.empty() && name.back() == ' ') {
|
||||||
name.pop_back();
|
name.pop_back();
|
||||||
@@ -219,136 +207,145 @@ auto Input::buildControllerName(SDL_Gamepad *pad, int padIndex) -> std::string {
|
|||||||
// Busca si hay un mando conectado. Cierra y limpia el estado previo para
|
// Busca si hay un mando conectado. Cierra y limpia el estado previo para
|
||||||
// que la función sea idempotente si se invoca más de una vez.
|
// que la función sea idempotente si se invoca más de una vez.
|
||||||
auto Input::discoverGameController() -> bool {
|
auto Input::discoverGameController() -> bool {
|
||||||
// Cierra los mandos ya abiertos y limpia los vectores paralelos
|
resetGameControllerState();
|
||||||
for (auto *pad : connectedControllers) {
|
ensureGamepadSubsystem();
|
||||||
|
|
||||||
|
int num_joysticks = 0;
|
||||||
|
SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks);
|
||||||
|
if (joysticks == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gamepad_count = 0;
|
||||||
|
for (int i = 0; i < num_joysticks; ++i) {
|
||||||
|
if (SDL_IsGamepad(joysticks[i])) {
|
||||||
|
gamepad_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose_) {
|
||||||
|
std::cout << "\nChecking for game controllers...\n";
|
||||||
|
std::cout << num_joysticks << " joysticks found, " << gamepad_count << " are gamepads\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
if (gamepad_count > 0) {
|
||||||
|
found = true;
|
||||||
|
int pad_index = 0;
|
||||||
|
for (int i = 0; i < num_joysticks; i++) {
|
||||||
|
if (!SDL_IsGamepad(joysticks[i])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (openGamepad(joysticks[i], pad_index)) {
|
||||||
|
pad_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_SetGamepadEventsEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(joysticks);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper de discoverGameController: cierra mandos previos y limpia vectores paralelos
|
||||||
|
void Input::resetGameControllerState() {
|
||||||
|
for (auto *pad : connected_controllers_) {
|
||||||
if (pad != nullptr) {
|
if (pad != nullptr) {
|
||||||
SDL_CloseGamepad(pad);
|
SDL_CloseGamepad(pad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connectedControllers.clear();
|
connected_controllers_.clear();
|
||||||
connectedControllerIds.clear();
|
connected_controller_ids_.clear();
|
||||||
controllerNames.clear();
|
controller_names_.clear();
|
||||||
numGamepads = 0;
|
num_gamepads_ = 0;
|
||||||
|
}
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
|
// Helper de discoverGameController: inicializa el subsystem de gamepad y carga el mapping
|
||||||
|
void Input::ensureGamepadSubsystem() {
|
||||||
if (SDL_WasInit(SDL_INIT_GAMEPAD) != SDL_INIT_GAMEPAD) {
|
if (SDL_WasInit(SDL_INIT_GAMEPAD) != SDL_INIT_GAMEPAD) {
|
||||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||||
}
|
}
|
||||||
|
if (SDL_AddGamepadMappingsFromFile(db_path_.c_str()) < 0 && verbose_) {
|
||||||
|
std::cout << "Error, could not load " << db_path_.c_str() << " file: " << SDL_GetError() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (SDL_AddGamepadMappingsFromFile(dbPath.c_str()) < 0) {
|
// Helper de discoverGameController: abre y registra un mando. Devuelve true si tuvo éxito.
|
||||||
if (verbose) {
|
auto Input::openGamepad(SDL_JoystickID joystick_id, int pad_index) -> bool {
|
||||||
std::cout << "Error, could not load " << dbPath.c_str() << " file: " << SDL_GetError() << '\n';
|
installWebStandardMapping(joystick_id);
|
||||||
|
SDL_Gamepad *pad = SDL_OpenGamepad(joystick_id);
|
||||||
|
if (pad == nullptr) {
|
||||||
|
if (verbose_) {
|
||||||
|
std::cout << "SDL_GetError() = " << SDL_GetError() << '\n';
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nJoysticks = 0;
|
const std::string NAME = buildControllerName(pad, pad_index);
|
||||||
SDL_JoystickID *joysticks = SDL_GetJoysticks(&nJoysticks);
|
connected_controllers_.push_back(pad);
|
||||||
|
connected_controller_ids_.push_back(joystick_id);
|
||||||
if (joysticks != nullptr) {
|
controller_names_.push_back(NAME);
|
||||||
int gamepadCount = 0;
|
num_gamepads_++;
|
||||||
for (int i = 0; i < nJoysticks; ++i) {
|
if (verbose_) {
|
||||||
if (SDL_IsGamepad(joysticks[i])) {
|
std::cout << NAME << '\n';
|
||||||
gamepadCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
std::cout << "\nChecking for game controllers...\n";
|
|
||||||
std::cout << nJoysticks << " joysticks found, " << gamepadCount << " are gamepads\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gamepadCount > 0) {
|
|
||||||
found = true;
|
|
||||||
int padIndex = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < nJoysticks; i++) {
|
|
||||||
if (!SDL_IsGamepad(joysticks[i])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
installWebStandardMapping(joysticks[i]);
|
|
||||||
SDL_Gamepad *pad = SDL_OpenGamepad(joysticks[i]);
|
|
||||||
if (pad != nullptr) {
|
|
||||||
const std::string name = buildControllerName(pad, padIndex);
|
|
||||||
connectedControllers.push_back(pad);
|
|
||||||
connectedControllerIds.push_back(joysticks[i]);
|
|
||||||
controllerNames.push_back(name);
|
|
||||||
numGamepads++;
|
|
||||||
padIndex++;
|
|
||||||
if (verbose) {
|
|
||||||
std::cout << name << '\n';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (verbose) {
|
|
||||||
std::cout << "SDL_GetError() = " << SDL_GetError() << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_SetGamepadEventsEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_free(joysticks);
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Procesa un evento SDL_EVENT_GAMEPAD_ADDED
|
// Procesa un evento SDL_EVENT_GAMEPAD_ADDED
|
||||||
auto Input::handleGamepadAdded(SDL_JoystickID jid, std::string &outName) -> bool {
|
auto Input::handleGamepadAdded(SDL_JoystickID jid, std::string &out_name) -> bool {
|
||||||
if (!SDL_IsGamepad(jid)) {
|
if (!SDL_IsGamepad(jid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si el mando ya está registrado no hace nada (ej. evento retroactivo tras el scan inicial)
|
// Si el mando ya está registrado no hace nada (ej. evento retroactivo tras el scan inicial)
|
||||||
if (std::ranges::any_of(connectedControllerIds, [jid](SDL_JoystickID existing) { return existing == jid; })) {
|
if (std::ranges::any_of(connected_controller_ids_, [jid](SDL_JoystickID existing) { return existing == jid; })) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
installWebStandardMapping(jid);
|
installWebStandardMapping(jid);
|
||||||
SDL_Gamepad *pad = SDL_OpenGamepad(jid);
|
SDL_Gamepad *pad = SDL_OpenGamepad(jid);
|
||||||
if (pad == nullptr) {
|
if (pad == nullptr) {
|
||||||
if (verbose) {
|
if (verbose_) {
|
||||||
std::cout << "Failed to open gamepad " << jid << ": " << SDL_GetError() << '\n';
|
std::cout << "Failed to open gamepad " << jid << ": " << SDL_GetError() << '\n';
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int padIndex = (int)connectedControllers.size();
|
const int PAD_INDEX = (int)connected_controllers_.size();
|
||||||
const std::string name = buildControllerName(pad, padIndex);
|
const std::string NAME = buildControllerName(pad, PAD_INDEX);
|
||||||
connectedControllers.push_back(pad);
|
connected_controllers_.push_back(pad);
|
||||||
connectedControllerIds.push_back(jid);
|
connected_controller_ids_.push_back(jid);
|
||||||
controllerNames.push_back(name);
|
controller_names_.push_back(NAME);
|
||||||
numGamepads++;
|
num_gamepads_++;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose_) {
|
||||||
std::cout << "Gamepad connected: " << name << '\n';
|
std::cout << "Gamepad connected: " << NAME << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
outName = name;
|
out_name = NAME;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Procesa un evento SDL_EVENT_GAMEPAD_REMOVED
|
// Procesa un evento SDL_EVENT_GAMEPAD_REMOVED
|
||||||
auto Input::handleGamepadRemoved(SDL_JoystickID jid, std::string &outName) -> bool {
|
auto Input::handleGamepadRemoved(SDL_JoystickID jid, std::string &out_name) -> bool {
|
||||||
for (size_t i = 0; i < connectedControllerIds.size(); ++i) {
|
for (size_t i = 0; i < connected_controller_ids_.size(); ++i) {
|
||||||
if (connectedControllerIds[i] != jid) {
|
if (connected_controller_ids_[i] != jid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
outName = controllerNames[i];
|
out_name = controller_names_[i];
|
||||||
if (connectedControllers[i] != nullptr) {
|
if (connected_controllers_[i] != nullptr) {
|
||||||
SDL_CloseGamepad(connectedControllers[i]);
|
SDL_CloseGamepad(connected_controllers_[i]);
|
||||||
}
|
}
|
||||||
connectedControllers.erase(connectedControllers.begin() + i);
|
connected_controllers_.erase(connected_controllers_.begin() + i);
|
||||||
connectedControllerIds.erase(connectedControllerIds.begin() + i);
|
connected_controller_ids_.erase(connected_controller_ids_.begin() + i);
|
||||||
controllerNames.erase(controllerNames.begin() + i);
|
controller_names_.erase(controller_names_.begin() + i);
|
||||||
numGamepads--;
|
num_gamepads_--;
|
||||||
numGamepads = std::max(numGamepads, 0);
|
num_gamepads_ = std::max(num_gamepads_, 0);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose_) {
|
||||||
std::cout << "Gamepad disconnected: " << outName << '\n';
|
std::cout << "Gamepad disconnected: " << out_name << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -358,35 +355,35 @@ auto Input::handleGamepadRemoved(SDL_JoystickID jid, std::string &outName) -> bo
|
|||||||
|
|
||||||
// Comprueba si hay algun mando conectado
|
// Comprueba si hay algun mando conectado
|
||||||
auto Input::gameControllerFound() const -> bool {
|
auto Input::gameControllerFound() const -> bool {
|
||||||
return numGamepads > 0;
|
return num_gamepads_ > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obten el nombre de un mando de juego
|
// Obten el nombre de un mando de juego
|
||||||
auto Input::getControllerName(int index) -> std::string {
|
auto Input::getControllerName(int index) -> std::string {
|
||||||
if (numGamepads > 0) {
|
if (num_gamepads_ > 0) {
|
||||||
return controllerNames[index];
|
return controller_names_[index];
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obten el numero de mandos conectados
|
// Obten el numero de mandos conectados
|
||||||
auto Input::getNumControllers() const -> int {
|
auto Input::getNumControllers() const -> int {
|
||||||
return numGamepads;
|
return num_gamepads_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece si ha de mostrar mensajes
|
// Establece si ha de mostrar mensajes
|
||||||
void Input::setVerbose(bool value) {
|
void Input::setVerbose(bool value) {
|
||||||
verbose = value;
|
verbose_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deshabilita las entradas durante un periodo de tiempo
|
// Deshabilita las entradas durante un periodo de tiempo
|
||||||
void Input::disableUntil(InputDisable value) {
|
void Input::disableUntil(InputDisable value) {
|
||||||
disabledUntil = value;
|
disabled_until_ = value;
|
||||||
enabled = false;
|
enabled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hablita las entradas
|
// Hablita las entradas
|
||||||
void Input::enable() {
|
void Input::enable() {
|
||||||
enabled = true;
|
enabled_ = true;
|
||||||
disabledUntil = d_notDisabled;
|
disabled_until_ = NOT_DISABLED;
|
||||||
}
|
}
|
||||||
|
|||||||
+77
-90
@@ -17,40 +17,73 @@ constexpr int INPUT_USE_ANY = 2;
|
|||||||
|
|
||||||
enum InputAction : std::uint8_t {
|
enum InputAction : std::uint8_t {
|
||||||
// Inputs obligatorios
|
// Inputs obligatorios
|
||||||
input_null,
|
INVALID,
|
||||||
input_up,
|
UP,
|
||||||
input_down,
|
DOWN,
|
||||||
input_left,
|
LEFT,
|
||||||
input_right,
|
RIGHT,
|
||||||
input_pause,
|
PAUSE,
|
||||||
input_exit,
|
EXIT,
|
||||||
input_accept,
|
ACCEPT,
|
||||||
input_cancel,
|
CANCEL,
|
||||||
|
|
||||||
// Inputs personalizados
|
// Inputs personalizados
|
||||||
input_fire_left,
|
FIRE_LEFT,
|
||||||
input_fire_center,
|
FIRE_CENTER,
|
||||||
input_fire_right,
|
FIRE_RIGHT,
|
||||||
input_window_fullscreen,
|
WINDOW_FULLSCREEN,
|
||||||
input_window_inc_size,
|
WINDOW_INC_ZOOM,
|
||||||
input_window_dec_size,
|
WINDOW_DEC_ZOOM,
|
||||||
|
|
||||||
// GPU / shaders (hotkeys provisionales hasta que haya menú de opciones)
|
// GPU / shaders (hotkeys provisionales hasta que haya menú de opciones)
|
||||||
input_next_preset,
|
NEXT_SHADER_PRESET,
|
||||||
input_toggle_shader,
|
TOGGLE_SHADER,
|
||||||
input_toggle_shader_type,
|
TOGGLE_SHADER_TYPE,
|
||||||
|
|
||||||
// Input obligatorio
|
// Input obligatorio
|
||||||
input_number_of_inputs
|
NUMBER_OF_INPUTS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum InputDisable : std::uint8_t {
|
enum InputDisable : std::uint8_t {
|
||||||
d_notDisabled,
|
NOT_DISABLED,
|
||||||
d_forever,
|
FOREVER,
|
||||||
d_keyPressed
|
KEY_PRESSED
|
||||||
};
|
};
|
||||||
|
|
||||||
class Input {
|
class Input {
|
||||||
|
public:
|
||||||
|
// Singleton API
|
||||||
|
static void init(const std::string &game_controller_db_path); // Crea la instancia
|
||||||
|
static void destroy(); // Libera la instancia
|
||||||
|
static auto get() -> Input *; // Obtiene el puntero a la instancia
|
||||||
|
|
||||||
|
~Input(); // Destructor
|
||||||
|
|
||||||
|
void update(); // Actualiza el estado del objeto
|
||||||
|
void bindKey(Uint8 input, SDL_Scancode code); // Asigna inputs a teclas
|
||||||
|
void bindGameControllerButton(Uint8 input, SDL_GamepadButton button); // Asigna inputs a botones del mando
|
||||||
|
|
||||||
|
auto checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0) -> bool; // Comprueba si un input esta activo
|
||||||
|
auto checkAnyInput(int device = INPUT_USE_ANY, int index = 0) -> bool; // Comprueba si hay almenos un input activo
|
||||||
|
|
||||||
|
auto discoverGameController() -> bool; // Busca si hay un mando conectado
|
||||||
|
|
||||||
|
// Procesa un evento SDL_EVENT_GAMEPAD_ADDED. Devuelve true si el mando se ha añadido
|
||||||
|
// (no estaba ya registrado) y escribe el nombre visible en outName.
|
||||||
|
auto handleGamepadAdded(SDL_JoystickID jid, std::string &out_name) -> bool;
|
||||||
|
|
||||||
|
// Procesa un evento SDL_EVENT_GAMEPAD_REMOVED. Devuelve true si se ha encontrado y
|
||||||
|
// eliminado, y escribe el nombre visible en outName.
|
||||||
|
auto handleGamepadRemoved(SDL_JoystickID jid, std::string &out_name) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto gameControllerFound() const -> bool; // Comprueba si hay algun mando conectado
|
||||||
|
[[nodiscard]] auto getNumControllers() const -> int; // Obten el numero de mandos conectados
|
||||||
|
auto getControllerName(int index) -> std::string; // Obten el nombre de un mando de juego
|
||||||
|
|
||||||
|
void setVerbose(bool value); // Establece si ha de mostrar mensajes
|
||||||
|
void disableUntil(InputDisable value); // Deshabilita las entradas durante un periodo de tiempo
|
||||||
|
void enable(); // Hablita las entradas
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct KeyBindings {
|
struct KeyBindings {
|
||||||
Uint8 scancode; // Scancode asociado
|
Uint8 scancode; // Scancode asociado
|
||||||
@@ -63,78 +96,32 @@ class Input {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Objetos y punteros
|
// Objetos y punteros
|
||||||
std::vector<SDL_Gamepad *> connectedControllers; // Vector con todos los mandos conectados
|
std::vector<SDL_Gamepad *> connected_controllers_; // Vector con todos los mandos conectados
|
||||||
std::vector<SDL_JoystickID> connectedControllerIds; // Instance IDs paralelos para mapear eventos
|
std::vector<SDL_JoystickID> connected_controller_ids_; // Instance IDs paralelos para mapear eventos
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
std::vector<KeyBindings> keyBindings; // Vector con las teclas asociadas a los inputs predefinidos
|
std::vector<KeyBindings> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
|
||||||
std::vector<GameControllerBindings> gameControllerBindings; // Vector con las teclas asociadas a los inputs predefinidos
|
std::vector<GameControllerBindings> game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
|
||||||
std::vector<std::string> controllerNames; // Vector con los nombres de los mandos
|
std::vector<std::string> controller_names_; // Vector con los nombres de los mandos
|
||||||
int numGamepads{0}; // Numero de mandos conectados
|
int num_gamepads_{0}; // Numero de mandos conectados
|
||||||
std::string dbPath; // Ruta al archivo gamecontrollerdb.txt
|
std::string db_path_; // Ruta al archivo gamecontrollerdb.txt
|
||||||
bool verbose{true}; // Indica si ha de mostrar mensajes
|
bool verbose_{true}; // Indica si ha de mostrar mensajes
|
||||||
InputDisable disabledUntil{d_notDisabled}; // Tiempo que esta deshabilitado
|
InputDisable disabled_until_{NOT_DISABLED}; // Tiempo que esta deshabilitado
|
||||||
bool enabled{true}; // Indica si está habilitado
|
bool enabled_{true}; // Indica si está habilitado
|
||||||
|
|
||||||
|
static Input *instance; // Instancia única
|
||||||
|
|
||||||
|
explicit Input(std::string file); // Constructor privado (usar Input::init)
|
||||||
|
|
||||||
// Construye el nombre visible de un mando (name truncado + sufijo #N)
|
// Construye el nombre visible de un mando (name truncado + sufijo #N)
|
||||||
static auto buildControllerName(SDL_Gamepad *pad, int padIndex) -> std::string;
|
static auto buildControllerName(SDL_Gamepad *pad, int pad_index) -> std::string;
|
||||||
|
|
||||||
// Constructor privado (usar Input::init)
|
// Helpers de checkInput
|
||||||
explicit Input(std::string file);
|
auto checkKeyboardInput(Uint8 input, bool repeat) -> bool;
|
||||||
|
auto checkGameControllerInput(Uint8 input, bool repeat, int index) -> bool;
|
||||||
|
|
||||||
// Instancia única
|
// Helpers de discoverGameController
|
||||||
static Input *instance;
|
void resetGameControllerState();
|
||||||
|
void ensureGamepadSubsystem();
|
||||||
public:
|
auto openGamepad(SDL_JoystickID joystick_id, int pad_index) -> bool;
|
||||||
// Singleton API
|
|
||||||
static void init(const std::string &gameControllerDbPath); // Crea la instancia
|
|
||||||
static void destroy(); // Libera la instancia
|
|
||||||
static auto get() -> Input *; // Obtiene el puntero a la instancia
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
~Input();
|
|
||||||
|
|
||||||
// Actualiza el estado del objeto
|
|
||||||
void update();
|
|
||||||
|
|
||||||
// Asigna inputs a teclas
|
|
||||||
void bindKey(Uint8 input, SDL_Scancode code);
|
|
||||||
|
|
||||||
// Asigna inputs a botones del mando
|
|
||||||
void bindGameControllerButton(Uint8 input, SDL_GamepadButton button);
|
|
||||||
|
|
||||||
// Comprueba si un input esta activo
|
|
||||||
auto checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0) -> bool;
|
|
||||||
|
|
||||||
// Comprueba si hay almenos un input activo
|
|
||||||
auto checkAnyInput(int device = INPUT_USE_ANY, int index = 0) -> bool;
|
|
||||||
|
|
||||||
// Busca si hay un mando conectado
|
|
||||||
auto discoverGameController() -> bool;
|
|
||||||
|
|
||||||
// Procesa un evento SDL_EVENT_GAMEPAD_ADDED. Devuelve true si el mando se ha añadido
|
|
||||||
// (no estaba ya registrado) y escribe el nombre visible en outName.
|
|
||||||
auto handleGamepadAdded(SDL_JoystickID jid, std::string &outName) -> bool;
|
|
||||||
|
|
||||||
// Procesa un evento SDL_EVENT_GAMEPAD_REMOVED. Devuelve true si se ha encontrado y
|
|
||||||
// eliminado, y escribe el nombre visible en outName.
|
|
||||||
auto handleGamepadRemoved(SDL_JoystickID jid, std::string &outName) -> bool;
|
|
||||||
|
|
||||||
// Comprueba si hay algun mando conectado
|
|
||||||
[[nodiscard]] auto gameControllerFound() const -> bool;
|
|
||||||
|
|
||||||
// Obten el numero de mandos conectados
|
|
||||||
[[nodiscard]] auto getNumControllers() const -> int;
|
|
||||||
|
|
||||||
// Obten el nombre de un mando de juego
|
|
||||||
auto getControllerName(int index) -> std::string;
|
|
||||||
|
|
||||||
// Establece si ha de mostrar mensajes
|
|
||||||
void setVerbose(bool value);
|
|
||||||
|
|
||||||
// Deshabilita las entradas durante un periodo de tiempo
|
|
||||||
void disableUntil(InputDisable value);
|
|
||||||
|
|
||||||
// Hablita las entradas
|
|
||||||
void enable();
|
|
||||||
};
|
};
|
||||||
+11
-11
@@ -1,16 +1,16 @@
|
|||||||
#include "core/input/mouse.hpp"
|
#include "core/input/mouse.hpp"
|
||||||
|
|
||||||
namespace Mouse {
|
namespace Mouse {
|
||||||
Uint32 cursorHideTime = 3000; // Tiempo en milisegundos para ocultar el cursor por inactividad
|
Uint32 cursor_hide_time = 3000; // Tiempo en milisegundos para ocultar el cursor por inactividad
|
||||||
Uint32 lastMouseMoveTime = 0; // Última vez que el ratón se movió
|
Uint32 last_mouse_move_time = 0; // Última vez que el ratón se movió
|
||||||
bool cursorVisible = true; // Estado del cursor
|
bool cursor_visible = true; // Estado del cursor
|
||||||
|
|
||||||
void handleEvent(const SDL_Event &event, bool fullscreen) {
|
void handleEvent(const SDL_Event &event, bool fullscreen) {
|
||||||
if (event.type == SDL_EVENT_MOUSE_MOTION) {
|
if (event.type == SDL_EVENT_MOUSE_MOTION) {
|
||||||
lastMouseMoveTime = SDL_GetTicks();
|
last_mouse_move_time = SDL_GetTicks();
|
||||||
if (!cursorVisible && !fullscreen) {
|
if (!cursor_visible && !fullscreen) {
|
||||||
SDL_ShowCursor();
|
SDL_ShowCursor();
|
||||||
cursorVisible = true;
|
cursor_visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,18 +18,18 @@ namespace Mouse {
|
|||||||
void updateCursorVisibility(bool fullscreen) {
|
void updateCursorVisibility(bool fullscreen) {
|
||||||
// En pantalla completa el cursor siempre está oculto
|
// En pantalla completa el cursor siempre está oculto
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
if (cursorVisible) {
|
if (cursor_visible) {
|
||||||
SDL_HideCursor();
|
SDL_HideCursor();
|
||||||
cursorVisible = false;
|
cursor_visible = false;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// En modo ventana, lo oculta tras el periodo de inactividad
|
// En modo ventana, lo oculta tras el periodo de inactividad
|
||||||
const Uint32 currentTime = SDL_GetTicks();
|
const Uint32 CURRENT_TIME = SDL_GetTicks();
|
||||||
if (cursorVisible && (currentTime - lastMouseMoveTime > cursorHideTime)) {
|
if (cursor_visible && (CURRENT_TIME - last_mouse_move_time > cursor_hide_time)) {
|
||||||
SDL_HideCursor();
|
SDL_HideCursor();
|
||||||
cursorVisible = false;
|
cursor_visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace Mouse
|
} // namespace Mouse
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
namespace Mouse {
|
namespace Mouse {
|
||||||
extern Uint32 cursorHideTime; // Tiempo en milisegundos para ocultar el cursor por inactividad
|
extern Uint32 cursor_hide_time; // Tiempo en milisegundos para ocultar el cursor por inactividad
|
||||||
extern Uint32 lastMouseMoveTime; // Última vez que el ratón se movió
|
extern Uint32 last_mouse_move_time; // Última vez que el ratón se movió
|
||||||
extern bool cursorVisible; // Estado del cursor
|
extern bool cursor_visible; // Estado del cursor
|
||||||
|
|
||||||
// Procesa un evento de ratón. En pantalla completa ignora el movimiento
|
// Procesa un evento de ratón. En pantalla completa ignora el movimiento
|
||||||
// para no volver a mostrar el cursor.
|
// para no volver a mostrar el cursor.
|
||||||
|
|||||||
@@ -340,11 +340,11 @@ void Screen::applyFullscreen(bool fullscreen) {
|
|||||||
SDL_SetWindowFullscreen(window, fullscreen);
|
SDL_SetWindowFullscreen(window, fullscreen);
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
SDL_HideCursor();
|
SDL_HideCursor();
|
||||||
Mouse::cursorVisible = false;
|
Mouse::cursor_visible = false;
|
||||||
} else {
|
} else {
|
||||||
SDL_ShowCursor();
|
SDL_ShowCursor();
|
||||||
Mouse::cursorVisible = true;
|
Mouse::cursor_visible = true;
|
||||||
Mouse::lastMouseMoveTime = SDL_GetTicks();
|
Mouse::last_mouse_move_time = SDL_GetTicks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,44 +210,44 @@ void Director::initInput() {
|
|||||||
Input::get()->discoverGameController();
|
Input::get()->discoverGameController();
|
||||||
|
|
||||||
// Teclado - Movimiento del jugador
|
// Teclado - Movimiento del jugador
|
||||||
Input::get()->bindKey(input_up, SDL_SCANCODE_UP);
|
Input::get()->bindKey(UP, SDL_SCANCODE_UP);
|
||||||
Input::get()->bindKey(input_down, SDL_SCANCODE_DOWN);
|
Input::get()->bindKey(DOWN, SDL_SCANCODE_DOWN);
|
||||||
Input::get()->bindKey(input_left, SDL_SCANCODE_LEFT);
|
Input::get()->bindKey(LEFT, SDL_SCANCODE_LEFT);
|
||||||
Input::get()->bindKey(input_right, SDL_SCANCODE_RIGHT);
|
Input::get()->bindKey(RIGHT, SDL_SCANCODE_RIGHT);
|
||||||
Input::get()->bindKey(input_fire_left, SDL_SCANCODE_Q);
|
Input::get()->bindKey(FIRE_LEFT, SDL_SCANCODE_Q);
|
||||||
Input::get()->bindKey(input_fire_center, SDL_SCANCODE_W);
|
Input::get()->bindKey(FIRE_CENTER, SDL_SCANCODE_W);
|
||||||
Input::get()->bindKey(input_fire_right, SDL_SCANCODE_E);
|
Input::get()->bindKey(FIRE_RIGHT, SDL_SCANCODE_E);
|
||||||
|
|
||||||
// Teclado - Otros
|
// Teclado - Otros
|
||||||
Input::get()->bindKey(input_accept, SDL_SCANCODE_RETURN);
|
Input::get()->bindKey(ACCEPT, SDL_SCANCODE_RETURN);
|
||||||
Input::get()->bindKey(input_cancel, SDL_SCANCODE_ESCAPE);
|
Input::get()->bindKey(CANCEL, SDL_SCANCODE_ESCAPE);
|
||||||
Input::get()->bindKey(input_pause, SDL_SCANCODE_ESCAPE);
|
Input::get()->bindKey(PAUSE, SDL_SCANCODE_ESCAPE);
|
||||||
Input::get()->bindKey(input_exit, SDL_SCANCODE_ESCAPE);
|
Input::get()->bindKey(EXIT, SDL_SCANCODE_ESCAPE);
|
||||||
Input::get()->bindKey(input_window_dec_size, SDL_SCANCODE_F1);
|
Input::get()->bindKey(WINDOW_DEC_ZOOM, SDL_SCANCODE_F1);
|
||||||
Input::get()->bindKey(input_window_inc_size, SDL_SCANCODE_F2);
|
Input::get()->bindKey(WINDOW_INC_ZOOM, SDL_SCANCODE_F2);
|
||||||
Input::get()->bindKey(input_window_fullscreen, SDL_SCANCODE_F3);
|
Input::get()->bindKey(WINDOW_FULLSCREEN, SDL_SCANCODE_F3);
|
||||||
Input::get()->bindKey(input_toggle_shader, SDL_SCANCODE_F4);
|
Input::get()->bindKey(TOGGLE_SHADER, SDL_SCANCODE_F4);
|
||||||
Input::get()->bindKey(input_toggle_shader_type, SDL_SCANCODE_F5);
|
Input::get()->bindKey(TOGGLE_SHADER_TYPE, SDL_SCANCODE_F5);
|
||||||
Input::get()->bindKey(input_next_preset, SDL_SCANCODE_F6);
|
Input::get()->bindKey(NEXT_SHADER_PRESET, SDL_SCANCODE_F6);
|
||||||
|
|
||||||
// Mando - Movimiento del jugador
|
// Mando - Movimiento del jugador
|
||||||
Input::get()->bindGameControllerButton(input_up, SDL_GAMEPAD_BUTTON_DPAD_UP);
|
Input::get()->bindGameControllerButton(UP, SDL_GAMEPAD_BUTTON_DPAD_UP);
|
||||||
Input::get()->bindGameControllerButton(input_down, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
|
Input::get()->bindGameControllerButton(DOWN, SDL_GAMEPAD_BUTTON_DPAD_DOWN);
|
||||||
Input::get()->bindGameControllerButton(input_left, SDL_GAMEPAD_BUTTON_DPAD_LEFT);
|
Input::get()->bindGameControllerButton(LEFT, SDL_GAMEPAD_BUTTON_DPAD_LEFT);
|
||||||
Input::get()->bindGameControllerButton(input_right, SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
|
Input::get()->bindGameControllerButton(RIGHT, SDL_GAMEPAD_BUTTON_DPAD_RIGHT);
|
||||||
Input::get()->bindGameControllerButton(input_fire_left, SDL_GAMEPAD_BUTTON_WEST);
|
Input::get()->bindGameControllerButton(FIRE_LEFT, SDL_GAMEPAD_BUTTON_WEST);
|
||||||
Input::get()->bindGameControllerButton(input_fire_center, SDL_GAMEPAD_BUTTON_NORTH);
|
Input::get()->bindGameControllerButton(FIRE_CENTER, SDL_GAMEPAD_BUTTON_NORTH);
|
||||||
Input::get()->bindGameControllerButton(input_fire_right, SDL_GAMEPAD_BUTTON_EAST);
|
Input::get()->bindGameControllerButton(FIRE_RIGHT, SDL_GAMEPAD_BUTTON_EAST);
|
||||||
|
|
||||||
// Mando - Otros
|
// Mando - Otros
|
||||||
// SOUTH queda sin asignar para evitar salidas accidentales: pausa/cancel se hace con START/BACK.
|
// SOUTH queda sin asignar para evitar salidas accidentales: pausa/cancel se hace con START/BACK.
|
||||||
Input::get()->bindGameControllerButton(input_accept, SDL_GAMEPAD_BUTTON_EAST);
|
Input::get()->bindGameControllerButton(ACCEPT, SDL_GAMEPAD_BUTTON_EAST);
|
||||||
#ifdef GAME_CONSOLE
|
#ifdef GAME_CONSOLE
|
||||||
Input::get()->bindGameControllerButton(input_pause, SDL_GAMEPAD_BUTTON_BACK);
|
Input::get()->bindGameControllerButton(input_pause, SDL_GAMEPAD_BUTTON_BACK);
|
||||||
Input::get()->bindGameControllerButton(input_exit, SDL_GAMEPAD_BUTTON_START);
|
Input::get()->bindGameControllerButton(input_exit, SDL_GAMEPAD_BUTTON_START);
|
||||||
#else
|
#else
|
||||||
Input::get()->bindGameControllerButton(input_pause, SDL_GAMEPAD_BUTTON_START);
|
Input::get()->bindGameControllerButton(PAUSE, SDL_GAMEPAD_BUTTON_START);
|
||||||
Input::get()->bindGameControllerButton(input_exit, SDL_GAMEPAD_BUTTON_BACK);
|
Input::get()->bindGameControllerButton(EXIT, SDL_GAMEPAD_BUTTON_BACK);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,25 +97,25 @@ void Player::init() {
|
|||||||
// Actua en consecuencia de la entrada recibida
|
// Actua en consecuencia de la entrada recibida
|
||||||
void Player::setInput(Uint8 input) {
|
void Player::setInput(Uint8 input) {
|
||||||
switch (input) {
|
switch (input) {
|
||||||
case input_left:
|
case LEFT:
|
||||||
vel_x_ = -base_speed_;
|
vel_x_ = -base_speed_;
|
||||||
setWalkingStatus(STATUS_WALKING_LEFT);
|
setWalkingStatus(STATUS_WALKING_LEFT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case input_right:
|
case RIGHT:
|
||||||
vel_x_ = base_speed_;
|
vel_x_ = base_speed_;
|
||||||
setWalkingStatus(STATUS_WALKING_RIGHT);
|
setWalkingStatus(STATUS_WALKING_RIGHT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case input_fire_center:
|
case FIRE_CENTER:
|
||||||
setFiringStatus(STATUS_FIRING_UP);
|
setFiringStatus(STATUS_FIRING_UP);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case input_fire_left:
|
case FIRE_LEFT:
|
||||||
setFiringStatus(STATUS_FIRING_LEFT);
|
setFiringStatus(STATUS_FIRING_LEFT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case input_fire_right:
|
case FIRE_RIGHT:
|
||||||
setFiringStatus(STATUS_FIRING_RIGHT);
|
setFiringStatus(STATUS_FIRING_RIGHT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
+253
-225
@@ -29,6 +29,28 @@
|
|||||||
#include "game/ui/menu.h" // for Menu
|
#include "game/ui/menu.h" // for Menu
|
||||||
struct JA_Sound_t;
|
struct JA_Sound_t;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Constantes geométricas y temporales compartidas por los helpers de initEnemyFormations
|
||||||
|
constexpr int Y4 = (PLAY_AREA_TOP - BLOCK);
|
||||||
|
constexpr int X4_0 = PLAY_AREA_LEFT;
|
||||||
|
constexpr int X4_100 = PLAY_AREA_RIGHT - Balloon::WIDTH_4;
|
||||||
|
|
||||||
|
constexpr int Y3 = (PLAY_AREA_TOP - BLOCK);
|
||||||
|
constexpr int X3_0 = PLAY_AREA_LEFT;
|
||||||
|
constexpr int X3_100 = PLAY_AREA_RIGHT - Balloon::WIDTH_3;
|
||||||
|
|
||||||
|
constexpr int Y2 = (PLAY_AREA_TOP - BLOCK);
|
||||||
|
constexpr int X2_0 = PLAY_AREA_LEFT;
|
||||||
|
constexpr int X2_100 = PLAY_AREA_RIGHT - Balloon::WIDTH_2;
|
||||||
|
|
||||||
|
constexpr int Y1 = (PLAY_AREA_TOP - BLOCK);
|
||||||
|
constexpr int X1_0 = PLAY_AREA_LEFT;
|
||||||
|
constexpr int X1_50 = PLAY_AREA_CENTER_X - (Balloon::WIDTH_1 / 2);
|
||||||
|
constexpr int X1_100 = PLAY_AREA_RIGHT - Balloon::WIDTH_1;
|
||||||
|
|
||||||
|
constexpr Uint16 CREATION_TIME = 300;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Game::Game(int num_players, int current_stage, SDL_Renderer *renderer, bool demo, Section *section)
|
Game::Game(int num_players, int current_stage, SDL_Renderer *renderer, bool demo, Section *section)
|
||||||
: last_stage_reached_(current_stage) {
|
: last_stage_reached_(current_stage) {
|
||||||
@@ -45,8 +67,8 @@ Game::Game(int num_players, int current_stage, SDL_Renderer *renderer, bool demo
|
|||||||
this->current_stage_ = current_stage;
|
this->current_stage_ = current_stage;
|
||||||
#endif
|
#endif
|
||||||
if (num_players == 1) { // Si solo juega un jugador, permite jugar tanto con teclado como con mando
|
if (num_players == 1) { // Si solo juega un jugador, permite jugar tanto con teclado como con mando
|
||||||
player_one_control_ = Options::inputs[0].deviceType;
|
player_one_control_ = Options::inputs[0].device_type;
|
||||||
Options::inputs[0].deviceType = INPUT_USE_ANY;
|
Options::inputs[0].device_type = INPUT_USE_ANY;
|
||||||
}
|
}
|
||||||
difficulty_ = Options::settings.difficulty;
|
difficulty_ = Options::settings.difficulty;
|
||||||
|
|
||||||
@@ -93,7 +115,7 @@ Game::~Game() {
|
|||||||
|
|
||||||
// Restaura el metodo de control
|
// Restaura el metodo de control
|
||||||
if (num_players_ == 1) {
|
if (num_players_ == 1) {
|
||||||
Options::inputs[0].deviceType = player_one_control_;
|
Options::inputs[0].device_type = player_one_control_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elimina todos los objetos contenidos en vectores (jugadores, balas, etc.)
|
// Elimina todos los objetos contenidos en vectores (jugadores, balas, etc.)
|
||||||
@@ -517,10 +539,10 @@ auto Game::loadDemoFile() -> bool {
|
|||||||
for (auto &i : demo_.data_file) {
|
for (auto &i : demo_.data_file) {
|
||||||
demo_.keys.left = 0;
|
demo_.keys.left = 0;
|
||||||
demo_.keys.right = 0;
|
demo_.keys.right = 0;
|
||||||
demo_.keys.noInput = 0;
|
demo_.keys.no_input = 0;
|
||||||
demo_.keys.fire = 0;
|
demo_.keys.fire = 0;
|
||||||
demo_.keys.fireLeft = 0;
|
demo_.keys.fire_left = 0;
|
||||||
demo_.keys.fireRight = 0;
|
demo_.keys.fire_right = 0;
|
||||||
i = demo_.keys;
|
i = demo_.keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -583,24 +605,14 @@ auto Game::saveDemoFile() -> bool {
|
|||||||
|
|
||||||
// Inicializa las formaciones enemigas
|
// Inicializa las formaciones enemigas
|
||||||
void Game::initEnemyFormations() {
|
void Game::initEnemyFormations() {
|
||||||
const int Y4 = (PLAY_AREA_TOP - BLOCK);
|
initEnemyFormationsZero();
|
||||||
const int X4_0 = PLAY_AREA_LEFT;
|
initEnemyFormationsLinear();
|
||||||
const int X4_100 = (PLAY_AREA_RIGHT)-Balloon::WIDTH_4;
|
initEnemyFormationsSymmetric();
|
||||||
|
initEnemyFormationsHexagonsAndTest();
|
||||||
|
}
|
||||||
|
|
||||||
const int Y3 = (PLAY_AREA_TOP - BLOCK);
|
// Pone a cero todas las formaciones
|
||||||
const int X3_0 = PLAY_AREA_LEFT;
|
void Game::initEnemyFormationsZero() {
|
||||||
const int X3_100 = (PLAY_AREA_RIGHT)-Balloon::WIDTH_3;
|
|
||||||
|
|
||||||
const int Y2 = (PLAY_AREA_TOP - BLOCK);
|
|
||||||
const int X2_0 = PLAY_AREA_LEFT;
|
|
||||||
const int X2_100 = (PLAY_AREA_RIGHT)-Balloon::WIDTH_2;
|
|
||||||
|
|
||||||
const int Y1 = (PLAY_AREA_TOP - BLOCK);
|
|
||||||
const int X1_0 = PLAY_AREA_LEFT;
|
|
||||||
const int X1_50 = PLAY_AREA_CENTER_X - (Balloon::WIDTH_1 / 2);
|
|
||||||
const int X1_100 = (PLAY_AREA_RIGHT)-Balloon::WIDTH_1;
|
|
||||||
|
|
||||||
// Inicializa a cero las variables
|
|
||||||
for (auto &i : enemy_formation_) {
|
for (auto &i : enemy_formation_) {
|
||||||
i.number_of_enemies = 0;
|
i.number_of_enemies = 0;
|
||||||
for (auto &j : i.init) {
|
for (auto &j : i.init) {
|
||||||
@@ -611,8 +623,10 @@ void Game::initEnemyFormations() {
|
|||||||
j.creation_counter = 0;
|
j.creation_counter = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Uint16 CREATION_TIME = 300;
|
// Formaciones 0..19: bucles lineales (todos los enemigos van en la misma dirección)
|
||||||
|
void Game::initEnemyFormationsLinear() {
|
||||||
int inc_x = 0;
|
int inc_x = 0;
|
||||||
Uint8 inc_time = 0;
|
Uint8 inc_time = 0;
|
||||||
Uint8 j = 0;
|
Uint8 j = 0;
|
||||||
@@ -876,6 +890,13 @@ void Game::initEnemyFormations() {
|
|||||||
enemy_formation_[j].init[i].kind = Balloon::BALLOON_1;
|
enemy_formation_[j].init[i].kind = Balloon::BALLOON_1;
|
||||||
enemy_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
|
enemy_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formaciones 20..25: simétricas (la primera mitad va hacia un lado, la segunda hacia el otro)
|
||||||
|
void Game::initEnemyFormationsSymmetric() {
|
||||||
|
int inc_x = 0;
|
||||||
|
Uint8 inc_time = 0;
|
||||||
|
Uint8 j = 0;
|
||||||
|
|
||||||
// #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos
|
// #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos
|
||||||
j = 20;
|
j = 20;
|
||||||
@@ -993,9 +1014,14 @@ void Game::initEnemyFormations() {
|
|||||||
enemy_formation_[j].init[i].y = Y1;
|
enemy_formation_[j].init[i].y = Y1;
|
||||||
enemy_formation_[j].init[i].kind = Balloon::BALLOON_1;
|
enemy_formation_[j].init[i].kind = Balloon::BALLOON_1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplica las formaciones 0..25 como hexágonos en el rango 50..75, y configura la formación 99 (TEST)
|
||||||
|
void Game::initEnemyFormationsHexagonsAndTest() {
|
||||||
|
constexpr Uint8 LAST_SYMMETRIC = 25;
|
||||||
|
|
||||||
// Crea las mismas formaciones pero con hexagonos a partir de la posición 50 del vector
|
// Crea las mismas formaciones pero con hexagonos a partir de la posición 50 del vector
|
||||||
for (int k = 0; k < j + 1; k++) {
|
for (int k = 0; k < LAST_SYMMETRIC + 1; k++) {
|
||||||
enemy_formation_[k + 50].number_of_enemies = enemy_formation_[k].number_of_enemies;
|
enemy_formation_[k + 50].number_of_enemies = enemy_formation_[k].number_of_enemies;
|
||||||
for (int i = 0; i < enemy_formation_[k + 50].number_of_enemies; i++) {
|
for (int i = 0; i < enemy_formation_[k + 50].number_of_enemies; i++) {
|
||||||
enemy_formation_[k + 50].init[i].x = enemy_formation_[k].init[i].x;
|
enemy_formation_[k + 50].init[i].x = enemy_formation_[k].init[i].x;
|
||||||
@@ -1843,44 +1869,48 @@ void Game::checkPlayerItemCollision(Player *player) {
|
|||||||
void Game::checkBulletBalloonCollision() {
|
void Game::checkBulletBalloonCollision() {
|
||||||
for (auto *bullet : bullets_) {
|
for (auto *bullet : bullets_) {
|
||||||
for (auto *balloon : balloons_) {
|
for (auto *balloon : balloons_) {
|
||||||
if (balloon->isEnabled() && (!balloon->isInvulnerable()) && bullet->isEnabled()) {
|
if (!balloon->isEnabled() || balloon->isInvulnerable() || !bullet->isEnabled()) {
|
||||||
if (checkCollision(balloon->getCollider(), bullet->getCollider())) {
|
continue;
|
||||||
// Otorga los puntos correspondientes al globo al jugador que disparó la bala
|
}
|
||||||
int index = bullet->getOwner();
|
if (checkCollision(balloon->getCollider(), bullet->getCollider())) {
|
||||||
players_[index]->incScoreMultiplier();
|
resolveBulletBalloonHit(bullet, balloon);
|
||||||
players_[index]->addScore(Uint32(balloon->getScore() * players_[index]->getScoreMultiplier() * difficulty_score_multiplier_));
|
break;
|
||||||
updateHiScore();
|
|
||||||
|
|
||||||
// Explota el globo
|
|
||||||
popBalloon(balloon);
|
|
||||||
|
|
||||||
// Si no es el modo demo, genera un sonido
|
|
||||||
if (!demo_.enabled) {
|
|
||||||
Audio::get()->playSound(balloon_sound_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deshabilita la bala
|
|
||||||
bullet->disable();
|
|
||||||
|
|
||||||
// Suelta el item en caso de que salga uno
|
|
||||||
const Item::Id droppeditem = dropItem();
|
|
||||||
if ((droppeditem != Item::Id::NONE) && !(demo_.enabled) && !(demo_.recording)) {
|
|
||||||
if (droppeditem != Item::Id::COFFEE_MACHINE) {
|
|
||||||
createItem(droppeditem, balloon->getPosX(), balloon->getPosY());
|
|
||||||
Audio::get()->playSound(item_drop_sound_);
|
|
||||||
} else {
|
|
||||||
createItem(droppeditem, players_[index]->getPosX(), 0);
|
|
||||||
coffee_machine_enabled_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resuelve un impacto bala-globo: puntos, sonido, explosión, drop de item
|
||||||
|
void Game::resolveBulletBalloonHit(Bullet *bullet, Balloon *balloon) {
|
||||||
|
// Otorga los puntos al jugador que disparó la bala
|
||||||
|
const int INDEX = bullet->getOwner();
|
||||||
|
players_[INDEX]->incScoreMultiplier();
|
||||||
|
players_[INDEX]->addScore(Uint32(balloon->getScore() * players_[INDEX]->getScoreMultiplier() * difficulty_score_multiplier_));
|
||||||
|
updateHiScore();
|
||||||
|
|
||||||
|
popBalloon(balloon);
|
||||||
|
|
||||||
|
if (!demo_.enabled) {
|
||||||
|
Audio::get()->playSound(balloon_sound_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bullet->disable();
|
||||||
|
|
||||||
|
// Suelta el item en caso de que salga uno
|
||||||
|
const Item::Id DROPPED_ITEM = dropItem();
|
||||||
|
if ((DROPPED_ITEM == Item::Id::NONE) || demo_.enabled || demo_.recording) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DROPPED_ITEM != Item::Id::COFFEE_MACHINE) {
|
||||||
|
createItem(DROPPED_ITEM, balloon->getPosX(), balloon->getPosY());
|
||||||
|
Audio::get()->playSound(item_drop_sound_);
|
||||||
|
} else {
|
||||||
|
createItem(DROPPED_ITEM, players_[INDEX]->getPosX(), 0);
|
||||||
|
coffee_machine_enabled_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mueve las balas activas
|
// Mueve las balas activas
|
||||||
void Game::moveBullets() {
|
void Game::moveBullets() {
|
||||||
for (auto *bullet : bullets_) {
|
for (auto *bullet : bullets_) {
|
||||||
@@ -2422,145 +2452,136 @@ void Game::updateMenace() {
|
|||||||
void Game::checkGameInput() {
|
void Game::checkGameInput() {
|
||||||
demo_.keys.left = 0;
|
demo_.keys.left = 0;
|
||||||
demo_.keys.right = 0;
|
demo_.keys.right = 0;
|
||||||
demo_.keys.noInput = 0;
|
demo_.keys.no_input = 0;
|
||||||
demo_.keys.fire = 0;
|
demo_.keys.fire = 0;
|
||||||
demo_.keys.fireLeft = 0;
|
demo_.keys.fire_left = 0;
|
||||||
demo_.keys.fireRight = 0;
|
demo_.keys.fire_right = 0;
|
||||||
|
|
||||||
// Atalls globals (zoom finestra, fullscreen, shaders, presets, ...)
|
// Atalls globals (zoom finestra, fullscreen, shaders, presets, ...)
|
||||||
GlobalInputs::handle();
|
GlobalInputs::handle();
|
||||||
|
|
||||||
// Modo Demo activo
|
|
||||||
if (demo_.enabled) {
|
if (demo_.enabled) {
|
||||||
const int INDEX = 0;
|
processDemoInput();
|
||||||
if (demo_.data_file[demo_.counter].left == 1) {
|
} else {
|
||||||
players_[INDEX]->setInput(input_left);
|
processLiveInput();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (demo_.data_file[demo_.counter].right == 1) {
|
// Rama de checkGameInput: reproduce el input grabado en data_file
|
||||||
players_[INDEX]->setInput(input_right);
|
void Game::processDemoInput() {
|
||||||
}
|
const int INDEX = 0;
|
||||||
|
const DemoKeys &keys = demo_.data_file[demo_.counter];
|
||||||
|
|
||||||
if (demo_.data_file[demo_.counter].noInput == 1) {
|
if (keys.left == 1) {
|
||||||
players_[INDEX]->setInput(input_null);
|
players_[INDEX]->setInput(LEFT);
|
||||||
}
|
}
|
||||||
|
if (keys.right == 1) {
|
||||||
|
players_[INDEX]->setInput(RIGHT);
|
||||||
|
}
|
||||||
|
if (keys.no_input == 1) {
|
||||||
|
players_[INDEX]->setInput(INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
if (demo_.data_file[demo_.counter].fire == 1) {
|
if (keys.fire == 1 && players_[INDEX]->canFire()) {
|
||||||
if (players_[INDEX]->canFire()) {
|
players_[INDEX]->setInput(FIRE_CENTER);
|
||||||
players_[INDEX]->setInput(input_fire_center);
|
createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::UP, players_[INDEX]->isPowerUp(), INDEX);
|
||||||
createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::UP, players_[INDEX]->isPowerUp(), INDEX);
|
players_[INDEX]->setFireCooldown(10);
|
||||||
players_[INDEX]->setFireCooldown(10);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demo_.data_file[demo_.counter].fireLeft == 1) {
|
if (keys.fire_left == 1 && players_[INDEX]->canFire()) {
|
||||||
if (players_[INDEX]->canFire()) {
|
players_[INDEX]->setInput(FIRE_LEFT);
|
||||||
players_[INDEX]->setInput(input_fire_left);
|
createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::LEFT, players_[INDEX]->isPowerUp(), INDEX);
|
||||||
createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::LEFT, players_[INDEX]->isPowerUp(), INDEX);
|
players_[INDEX]->setFireCooldown(10);
|
||||||
players_[INDEX]->setFireCooldown(10);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demo_.data_file[demo_.counter].fireRight == 1) {
|
if (keys.fire_right == 1 && players_[INDEX]->canFire()) {
|
||||||
if (players_[INDEX]->canFire()) {
|
players_[INDEX]->setInput(FIRE_RIGHT);
|
||||||
players_[INDEX]->setInput(input_fire_right);
|
createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::RIGHT, players_[INDEX]->isPowerUp(), INDEX);
|
||||||
createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::RIGHT, players_[INDEX]->isPowerUp(), INDEX);
|
players_[INDEX]->setFireCooldown(10);
|
||||||
players_[INDEX]->setFireCooldown(10);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si se pulsa cualquier tecla, se sale del modo demo
|
// Si se pulsa cualquier tecla, se sale del modo demo
|
||||||
if (Input::get()->checkAnyInput()) {
|
if (Input::get()->checkAnyInput()) {
|
||||||
section_->name = SECTION_PROG_TITLE;
|
section_->name = SECTION_PROG_TITLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incrementa el contador de la demo
|
// Incrementa el contador de la demo
|
||||||
if (demo_.counter < TOTAL_DEMO_DATA) {
|
if (demo_.counter < TOTAL_DEMO_DATA) {
|
||||||
demo_.counter++;
|
demo_.counter++;
|
||||||
} else {
|
} else {
|
||||||
section_->name = SECTION_PROG_TITLE;
|
section_->name = SECTION_PROG_TITLE;
|
||||||
section_->subsection = SUBSECTION_TITLE_INSTRUCTIONS;
|
section_->subsection = SUBSECTION_TITLE_INSTRUCTIONS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rama de checkGameInput: lee inputs reales del teclado/gamepad por jugador
|
||||||
|
void Game::processLiveInput() {
|
||||||
|
int i = 0;
|
||||||
|
for (auto *player : players_) {
|
||||||
|
if (player->isAlive()) {
|
||||||
|
processPlayerLiveInput(player, i);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Modo Demo no activo
|
}
|
||||||
else {
|
|
||||||
int i = 0;
|
|
||||||
for (auto *player : players_) {
|
|
||||||
if (player->isAlive()) {
|
|
||||||
// Input a la izquierda
|
|
||||||
if (Input::get()->checkInput(input_left, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) {
|
|
||||||
player->setInput(input_left);
|
|
||||||
demo_.keys.left = 1;
|
|
||||||
} else {
|
|
||||||
// Input a la derecha
|
|
||||||
if (Input::get()->checkInput(input_right, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) {
|
|
||||||
player->setInput(input_right);
|
|
||||||
demo_.keys.right = 1;
|
|
||||||
} else {
|
|
||||||
// Ninguno de los dos inputs anteriores
|
|
||||||
player->setInput(input_null);
|
|
||||||
demo_.keys.noInput = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Comprueba el input de disparar al centro
|
|
||||||
if (Input::get()->checkInput(input_fire_center, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) {
|
|
||||||
if (player->canFire()) {
|
|
||||||
player->setInput(input_fire_center);
|
|
||||||
createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::UP, player->isPowerUp(), i);
|
|
||||||
player->setFireCooldown(10);
|
|
||||||
|
|
||||||
// Reproduce el sonido de disparo
|
// Cuerpo per-player de processLiveInput
|
||||||
Audio::get()->playSound(bullet_sound_);
|
void Game::processPlayerLiveInput(Player *player, int i) {
|
||||||
|
auto *input = Input::get();
|
||||||
|
const auto &device = Options::inputs[i];
|
||||||
|
|
||||||
demo_.keys.fire = 1;
|
// Movimiento izquierda / derecha / nada
|
||||||
}
|
if (input->checkInput(LEFT, REPEAT_TRUE, device.device_type, device.id)) {
|
||||||
}
|
player->setInput(LEFT);
|
||||||
|
demo_.keys.left = 1;
|
||||||
|
} else if (input->checkInput(RIGHT, REPEAT_TRUE, device.device_type, device.id)) {
|
||||||
|
player->setInput(RIGHT);
|
||||||
|
demo_.keys.right = 1;
|
||||||
|
} else {
|
||||||
|
player->setInput(INVALID);
|
||||||
|
demo_.keys.no_input = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Comprueba el input de disparar a la izquierda
|
// Disparo al centro
|
||||||
if (Input::get()->checkInput(input_fire_left, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) {
|
if (input->checkInput(FIRE_CENTER, REPEAT_TRUE, device.device_type, device.id) && player->canFire()) {
|
||||||
if (player->canFire()) {
|
player->setInput(FIRE_CENTER);
|
||||||
player->setInput(input_fire_left);
|
createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::UP, player->isPowerUp(), i);
|
||||||
createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::LEFT, player->isPowerUp(), i);
|
player->setFireCooldown(10);
|
||||||
player->setFireCooldown(10);
|
Audio::get()->playSound(bullet_sound_);
|
||||||
|
demo_.keys.fire = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Reproduce el sonido de disparo
|
// Disparo a la izquierda
|
||||||
Audio::get()->playSound(bullet_sound_);
|
if (input->checkInput(FIRE_LEFT, REPEAT_TRUE, device.device_type, device.id) && player->canFire()) {
|
||||||
|
player->setInput(FIRE_LEFT);
|
||||||
|
createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::LEFT, player->isPowerUp(), i);
|
||||||
|
player->setFireCooldown(10);
|
||||||
|
Audio::get()->playSound(bullet_sound_);
|
||||||
|
demo_.keys.fire_left = 1;
|
||||||
|
}
|
||||||
|
|
||||||
demo_.keys.fireLeft = 1;
|
// Disparo a la derecha
|
||||||
}
|
if (input->checkInput(FIRE_RIGHT, REPEAT_TRUE, device.device_type, device.id) && player->canFire()) {
|
||||||
}
|
player->setInput(FIRE_RIGHT);
|
||||||
|
createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::RIGHT, player->isPowerUp(), i);
|
||||||
|
player->setFireCooldown(10);
|
||||||
|
Audio::get()->playSound(bullet_sound_);
|
||||||
|
demo_.keys.fire_right = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Comprueba el input de disparar a la derecha
|
// Pausa
|
||||||
if (Input::get()->checkInput(input_fire_right, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) {
|
if (input->checkInput(PAUSE, REPEAT_FALSE, device.device_type, device.id)) {
|
||||||
if (player->canFire()) {
|
section_->subsection = SUBSECTION_GAME_PAUSE;
|
||||||
player->setInput(input_fire_right);
|
}
|
||||||
createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::RIGHT, player->isPowerUp(), i);
|
|
||||||
player->setFireCooldown(10);
|
|
||||||
|
|
||||||
// Reproduce el sonido de disparo
|
// Grabación de demo
|
||||||
Audio::get()->playSound(bullet_sound_);
|
if (demo_.counter < TOTAL_DEMO_DATA) {
|
||||||
|
if (demo_.recording) {
|
||||||
demo_.keys.fireRight = 1;
|
demo_.data_file[demo_.counter] = demo_.keys;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprueba el input de pausa
|
|
||||||
if (Input::get()->checkInput(input_pause, REPEAT_FALSE, Options::inputs[i].deviceType, Options::inputs[i].id)) {
|
|
||||||
section_->subsection = SUBSECTION_GAME_PAUSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (demo_.counter < TOTAL_DEMO_DATA) {
|
|
||||||
if (demo_.recording) {
|
|
||||||
demo_.data_file[demo_.counter] = demo_.keys;
|
|
||||||
}
|
|
||||||
demo_.counter++;
|
|
||||||
} else if (demo_.recording) {
|
|
||||||
section_->name = SECTION_PROG_QUIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
demo_.counter++;
|
||||||
|
} else if (demo_.recording) {
|
||||||
|
section_->name = SECTION_PROG_QUIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2767,60 +2788,67 @@ void Game::run() {
|
|||||||
|
|
||||||
// Actualiza las variables del menu de pausa del juego
|
// Actualiza las variables del menu de pausa del juego
|
||||||
void Game::updatePausedGame() {
|
void Game::updatePausedGame() {
|
||||||
// Calcula la lógica de los objetos
|
if (SDL_GetTicks() - ticks_ <= ticks_speed_) {
|
||||||
if (SDL_GetTicks() - ticks_ > ticks_speed_) {
|
return;
|
||||||
// Actualiza el contador de ticks
|
}
|
||||||
ticks_ = SDL_GetTicks();
|
ticks_ = SDL_GetTicks();
|
||||||
|
|
||||||
// Atalls globals (zoom finestra, fullscreen, shaders, presets, ...)
|
// Atalls globals (zoom finestra, fullscreen, shaders, presets, ...)
|
||||||
GlobalInputs::handle();
|
GlobalInputs::handle();
|
||||||
|
|
||||||
if (leaving_pause_menu_) {
|
if (leaving_pause_menu_) {
|
||||||
if (pause_counter_ > 0) { // El contador está descendiendo
|
updateLeavingPauseMenu();
|
||||||
const bool A = pause_counter_ == 90;
|
} else {
|
||||||
const bool B = pause_counter_ == 60;
|
updatePauseMenuUI();
|
||||||
const bool C = pause_counter_ == 30;
|
}
|
||||||
if (A || B || C) {
|
}
|
||||||
Audio::get()->playSound(clock_sound_);
|
|
||||||
}
|
|
||||||
pause_counter_--;
|
|
||||||
} else { // Ha finalizado el contador
|
|
||||||
section_->name = SECTION_PROG_GAME;
|
|
||||||
section_->subsection = num_players_ == 1 ? SUBSECTION_GAME_PLAY_1P : SUBSECTION_GAME_PLAY_2P;
|
|
||||||
|
|
||||||
if (Audio::getRealMusicState() == Audio::MusicState::PAUSED) {
|
// Rama de updatePausedGame: cuenta atrás de salida y vuelta al juego
|
||||||
Audio::get()->resumeMusic();
|
void Game::updateLeavingPauseMenu() {
|
||||||
}
|
if (pause_counter_ > 0) { // El contador está descendiendo
|
||||||
}
|
const bool A = pause_counter_ == 90;
|
||||||
} else { // Actualiza la lógica del menu de pausa
|
const bool B = pause_counter_ == 60;
|
||||||
pause_menu_->update();
|
const bool C = pause_counter_ == 30;
|
||||||
|
if (A || B || C) {
|
||||||
// Comprueba las entradas para el menu
|
Audio::get()->playSound(clock_sound_);
|
||||||
pause_menu_->checkInput();
|
|
||||||
|
|
||||||
// Comprueba si se ha seleccionado algún item del menú
|
|
||||||
switch (pause_menu_->getItemSelected()) {
|
|
||||||
case 1:
|
|
||||||
leaving_pause_menu_ = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
fade_->setFadeType(FADE_CENTER);
|
|
||||||
fade_->activateFade();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actualiza el fade
|
|
||||||
fade_->update();
|
|
||||||
if (fade_->hasEnded()) {
|
|
||||||
section_->name = SECTION_PROG_TITLE;
|
|
||||||
section_->subsection = SUBSECTION_TITLE_1;
|
|
||||||
Audio::get()->stopMusic();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pause_counter_--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ha finalizado el contador
|
||||||
|
section_->name = SECTION_PROG_GAME;
|
||||||
|
section_->subsection = num_players_ == 1 ? SUBSECTION_GAME_PLAY_1P : SUBSECTION_GAME_PLAY_2P;
|
||||||
|
|
||||||
|
if (Audio::getRealMusicState() == Audio::MusicState::PAUSED) {
|
||||||
|
Audio::get()->resumeMusic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rama de updatePausedGame: lógica del menú de pausa
|
||||||
|
void Game::updatePauseMenuUI() {
|
||||||
|
pause_menu_->update();
|
||||||
|
pause_menu_->checkInput();
|
||||||
|
|
||||||
|
switch (pause_menu_->getItemSelected()) {
|
||||||
|
case 1:
|
||||||
|
leaving_pause_menu_ = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
fade_->setFadeType(FADE_CENTER);
|
||||||
|
fade_->activateFade();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fade_->update();
|
||||||
|
if (fade_->hasEnded()) {
|
||||||
|
section_->name = SECTION_PROG_TITLE;
|
||||||
|
section_->subsection = SUBSECTION_TITLE_1;
|
||||||
|
Audio::get()->stopMusic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3027,7 +3055,7 @@ void Game::initPaths() {
|
|||||||
|
|
||||||
// Letrero de STAGE #
|
// Letrero de STAGE #
|
||||||
const int FIRST_PART = STAGE_COUNTER / 4; // 50
|
const int FIRST_PART = STAGE_COUNTER / 4; // 50
|
||||||
const int SECOND_PART = FIRST_PART * 3; // 150
|
const int SECOND_PART = FIRST_PART * 3; // 150
|
||||||
const int CENTER_POINT = PLAY_AREA_CENTER_Y - (BLOCK * 2);
|
const int CENTER_POINT = PLAY_AREA_CENTER_Y - (BLOCK * 2);
|
||||||
const int DISTANCE = (PLAY_AREA_BOTTOM) - (PLAY_AREA_CENTER_Y - 16);
|
const int DISTANCE = (PLAY_AREA_BOTTOM) - (PLAY_AREA_CENTER_Y - 16);
|
||||||
|
|
||||||
|
|||||||
@@ -283,6 +283,12 @@ class Game {
|
|||||||
// Inicializa las formaciones enemigas
|
// Inicializa las formaciones enemigas
|
||||||
void initEnemyFormations();
|
void initEnemyFormations();
|
||||||
|
|
||||||
|
// Helpers de initEnemyFormations
|
||||||
|
void initEnemyFormationsZero();
|
||||||
|
void initEnemyFormationsLinear();
|
||||||
|
void initEnemyFormationsSymmetric();
|
||||||
|
void initEnemyFormationsHexagonsAndTest();
|
||||||
|
|
||||||
// Inicializa los conjuntos de formaciones
|
// Inicializa los conjuntos de formaciones
|
||||||
void initEnemyPools();
|
void initEnemyPools();
|
||||||
|
|
||||||
@@ -370,6 +376,9 @@ class Game {
|
|||||||
// Comprueba la colisión entre las balas y los globos
|
// Comprueba la colisión entre las balas y los globos
|
||||||
void checkBulletBalloonCollision();
|
void checkBulletBalloonCollision();
|
||||||
|
|
||||||
|
// Resuelve un impacto bala-globo (helper de checkBulletBalloonCollision)
|
||||||
|
void resolveBulletBalloonHit(Bullet *bullet, Balloon *balloon);
|
||||||
|
|
||||||
// Mueve las balas activas
|
// Mueve las balas activas
|
||||||
void moveBullets();
|
void moveBullets();
|
||||||
|
|
||||||
@@ -457,6 +466,11 @@ class Game {
|
|||||||
// Gestiona la entrada durante el juego
|
// Gestiona la entrada durante el juego
|
||||||
void checkGameInput();
|
void checkGameInput();
|
||||||
|
|
||||||
|
// Helpers de checkGameInput
|
||||||
|
void processDemoInput();
|
||||||
|
void processLiveInput();
|
||||||
|
void processPlayerLiveInput(Player *player, int i);
|
||||||
|
|
||||||
// Pinta diferentes mensajes en la pantalla
|
// Pinta diferentes mensajes en la pantalla
|
||||||
void renderMessages();
|
void renderMessages();
|
||||||
|
|
||||||
@@ -481,6 +495,10 @@ class Game {
|
|||||||
// Actualiza las variables del menu de pausa del juego
|
// Actualiza las variables del menu de pausa del juego
|
||||||
void updatePausedGame();
|
void updatePausedGame();
|
||||||
|
|
||||||
|
// Helpers de updatePausedGame
|
||||||
|
void updateLeavingPauseMenu();
|
||||||
|
void updatePauseMenuUI();
|
||||||
|
|
||||||
// Dibuja el menu de pausa del juego
|
// Dibuja el menu de pausa del juego
|
||||||
void renderPausedGame();
|
void renderPausedGame();
|
||||||
|
|
||||||
|
|||||||
@@ -161,9 +161,9 @@ namespace Options {
|
|||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (const auto &entry : ins) {
|
for (const auto &entry : ins) {
|
||||||
if (i >= inputs.size()) { break; }
|
if (i >= inputs.size()) { break; }
|
||||||
int device_type_int = inputs[i].deviceType;
|
int device_type_int = inputs[i].device_type;
|
||||||
if (tryGet<int>(entry, "device_type", device_type_int)) {
|
if (tryGet<int>(entry, "device_type", device_type_int)) {
|
||||||
inputs[i].deviceType = static_cast<Uint8>(device_type_int);
|
inputs[i].device_type = static_cast<Uint8>(device_type_int);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
@@ -200,13 +200,13 @@ namespace Options {
|
|||||||
InputDevice kb;
|
InputDevice kb;
|
||||||
kb.id = 0;
|
kb.id = 0;
|
||||||
kb.name = "KEYBOARD";
|
kb.name = "KEYBOARD";
|
||||||
kb.deviceType = INPUT_USE_KEYBOARD;
|
kb.device_type = INPUT_USE_KEYBOARD;
|
||||||
inputs.push_back(kb);
|
inputs.push_back(kb);
|
||||||
|
|
||||||
InputDevice gc;
|
InputDevice gc;
|
||||||
gc.id = 0;
|
gc.id = 0;
|
||||||
gc.name = "GAME CONTROLLER";
|
gc.name = "GAME CONTROLLER";
|
||||||
gc.deviceType = INPUT_USE_GAMECONTROLLER;
|
gc.device_type = INPUT_USE_GAMECONTROLLER;
|
||||||
inputs.push_back(gc);
|
inputs.push_back(gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +328,7 @@ namespace Options {
|
|||||||
file << "input:\n";
|
file << "input:\n";
|
||||||
for (size_t i = 0; i < inputs.size(); ++i) {
|
for (size_t i = 0; i < inputs.size(); ++i) {
|
||||||
file << " - slot: " << i << "\n";
|
file << " - slot: " << i << "\n";
|
||||||
file << " device_type: " << static_cast<int>(inputs[i].deviceType) << "\n";
|
file << " device_type: " << static_cast<int>(inputs[i].device_type) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ void Instructions::checkEvents() {
|
|||||||
// Comprueba las entradas
|
// Comprueba las entradas
|
||||||
void Instructions::checkInput() {
|
void Instructions::checkInput() {
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(EXIT, REPEAT_FALSE)) {
|
||||||
quit_requested_ = true;
|
quit_requested_ = true;
|
||||||
finished_ = true;
|
finished_ = true;
|
||||||
return;
|
return;
|
||||||
@@ -219,7 +219,7 @@ void Instructions::checkInput() {
|
|||||||
#endif
|
#endif
|
||||||
if (GlobalInputs::handle()) { return; }
|
if (GlobalInputs::handle()) { return; }
|
||||||
|
|
||||||
if (Input::get()->checkInput(input_pause, REPEAT_FALSE) || Input::get()->checkInput(input_accept, REPEAT_FALSE) || Input::get()->checkInput(input_fire_left, REPEAT_FALSE) || Input::get()->checkInput(input_fire_center, REPEAT_FALSE) || Input::get()->checkInput(input_fire_right, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(PAUSE, REPEAT_FALSE) || Input::get()->checkInput(ACCEPT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_LEFT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_CENTER, REPEAT_FALSE) || Input::get()->checkInput(FIRE_RIGHT, REPEAT_FALSE)) {
|
||||||
if (mode_ == Mode::AUTO) {
|
if (mode_ == Mode::AUTO) {
|
||||||
finished_ = true;
|
finished_ = true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -167,14 +167,14 @@ Intro::~Intro() {
|
|||||||
// Comprueba las entradas
|
// Comprueba las entradas
|
||||||
void Intro::checkInput() {
|
void Intro::checkInput() {
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(EXIT, REPEAT_FALSE)) {
|
||||||
section_->name = SECTION_PROG_QUIT;
|
section_->name = SECTION_PROG_QUIT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (GlobalInputs::handle()) { return; }
|
if (GlobalInputs::handle()) { return; }
|
||||||
|
|
||||||
if (Input::get()->checkInput(input_pause, REPEAT_FALSE) || Input::get()->checkInput(input_accept, REPEAT_FALSE) || Input::get()->checkInput(input_fire_left, REPEAT_FALSE) || Input::get()->checkInput(input_fire_center, REPEAT_FALSE) || Input::get()->checkInput(input_fire_right, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(PAUSE, REPEAT_FALSE) || Input::get()->checkInput(ACCEPT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_LEFT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_CENTER, REPEAT_FALSE) || Input::get()->checkInput(FIRE_RIGHT, REPEAT_FALSE)) {
|
||||||
Audio::get()->stopMusic();
|
Audio::get()->stopMusic();
|
||||||
section_->name = SECTION_PROG_TITLE;
|
section_->name = SECTION_PROG_TITLE;
|
||||||
section_->subsection = SUBSECTION_TITLE_1;
|
section_->subsection = SUBSECTION_TITLE_1;
|
||||||
|
|||||||
@@ -59,14 +59,14 @@ void Logo::checkLogoEnd() {
|
|||||||
// Comprueba las entradas
|
// Comprueba las entradas
|
||||||
void Logo::checkInput() {
|
void Logo::checkInput() {
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(EXIT, REPEAT_FALSE)) {
|
||||||
section_->name = SECTION_PROG_QUIT;
|
section_->name = SECTION_PROG_QUIT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (GlobalInputs::handle()) { return; }
|
if (GlobalInputs::handle()) { return; }
|
||||||
|
|
||||||
if (Input::get()->checkInput(input_pause, REPEAT_FALSE) || Input::get()->checkInput(input_accept, REPEAT_FALSE) || Input::get()->checkInput(input_fire_left, REPEAT_FALSE) || Input::get()->checkInput(input_fire_center, REPEAT_FALSE) || Input::get()->checkInput(input_fire_right, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(PAUSE, REPEAT_FALSE) || Input::get()->checkInput(ACCEPT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_LEFT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_CENTER, REPEAT_FALSE) || Input::get()->checkInput(FIRE_RIGHT, REPEAT_FALSE)) {
|
||||||
section_->name = SECTION_PROG_TITLE;
|
section_->name = SECTION_PROG_TITLE;
|
||||||
section_->subsection = SUBSECTION_TITLE_1;
|
section_->subsection = SUBSECTION_TITLE_1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,12 +115,12 @@ void Title::init() {
|
|||||||
InputDevice inp;
|
InputDevice inp;
|
||||||
inp.id = 0;
|
inp.id = 0;
|
||||||
inp.name = "KEYBOARD";
|
inp.name = "KEYBOARD";
|
||||||
inp.deviceType = INPUT_USE_KEYBOARD;
|
inp.device_type = INPUT_USE_KEYBOARD;
|
||||||
Options::inputs.push_back(inp);
|
Options::inputs.push_back(inp);
|
||||||
|
|
||||||
inp.id = 0;
|
inp.id = 0;
|
||||||
inp.name = "GAME CONTROLLER";
|
inp.name = "GAME CONTROLLER";
|
||||||
inp.deviceType = INPUT_USE_GAMECONTROLLER;
|
inp.device_type = INPUT_USE_GAMECONTROLLER;
|
||||||
Options::inputs.push_back(inp);
|
Options::inputs.push_back(inp);
|
||||||
|
|
||||||
// Comprueba si hay mandos conectados
|
// Comprueba si hay mandos conectados
|
||||||
@@ -135,7 +135,7 @@ void Title::init() {
|
|||||||
if (Input::get()->gameControllerFound()) {
|
if (Input::get()->gameControllerFound()) {
|
||||||
Options::inputs[1].id = available_input_devices_[device_index_[1]].id;
|
Options::inputs[1].id = available_input_devices_[device_index_[1]].id;
|
||||||
Options::inputs[1].name = available_input_devices_[device_index_[1]].name;
|
Options::inputs[1].name = available_input_devices_[device_index_[1]].name;
|
||||||
Options::inputs[1].deviceType = available_input_devices_[device_index_[1]].deviceType;
|
Options::inputs[1].device_type = available_input_devices_[device_index_[1]].device_type;
|
||||||
} else { // Si no ha encontrado un mando, deshabilita la opción de jugar a 2 jugadores
|
} else { // Si no ha encontrado un mando, deshabilita la opción de jugar a 2 jugadores
|
||||||
menu_.title->setSelectable(1, false);
|
menu_.title->setSelectable(1, false);
|
||||||
menu_.title->setGreyed(1, true);
|
menu_.title->setGreyed(1, true);
|
||||||
@@ -625,7 +625,7 @@ void Title::render() {
|
|||||||
// Comprueba las entradas
|
// Comprueba las entradas
|
||||||
void Title::checkInput() {
|
void Title::checkInput() {
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(EXIT, REPEAT_FALSE)) {
|
||||||
section_->name = SECTION_PROG_QUIT;
|
section_->name = SECTION_PROG_QUIT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -678,7 +678,7 @@ void Title::updateMenuLabels() const {
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
// PLAYER 1 CONTROLS - OPTIONS
|
// PLAYER 1 CONTROLS - OPTIONS
|
||||||
switch (Options::inputs[0].deviceType) {
|
switch (Options::inputs[0].device_type) {
|
||||||
case INPUT_USE_KEYBOARD:
|
case INPUT_USE_KEYBOARD:
|
||||||
menu_.options->setItemCaption(i, Lang::get()->getText(69)); // KEYBOARD
|
menu_.options->setItemCaption(i, Lang::get()->getText(69)); // KEYBOARD
|
||||||
menu_.options->setGreyed(i, false);
|
menu_.options->setGreyed(i, false);
|
||||||
@@ -705,7 +705,7 @@ void Title::updateMenuLabels() const {
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
// PLAYER 2 CONTROLS - OPTIONS
|
// PLAYER 2 CONTROLS - OPTIONS
|
||||||
switch (Options::inputs[1].deviceType) {
|
switch (Options::inputs[1].device_type) {
|
||||||
case INPUT_USE_KEYBOARD:
|
case INPUT_USE_KEYBOARD:
|
||||||
menu_.options->setItemCaption(i, Lang::get()->getText(69)); // KEYBOARD
|
menu_.options->setItemCaption(i, Lang::get()->getText(69)); // KEYBOARD
|
||||||
menu_.options->setGreyed(i, false);
|
menu_.options->setGreyed(i, false);
|
||||||
@@ -966,11 +966,11 @@ auto Title::updatePlayerInputs(int num_player) -> bool {
|
|||||||
|
|
||||||
Options::inputs[0].id = -1;
|
Options::inputs[0].id = -1;
|
||||||
Options::inputs[0].name = "KEYBOARD";
|
Options::inputs[0].name = "KEYBOARD";
|
||||||
Options::inputs[0].deviceType = INPUT_USE_KEYBOARD;
|
Options::inputs[0].device_type = INPUT_USE_KEYBOARD;
|
||||||
|
|
||||||
Options::inputs[1].id = 0;
|
Options::inputs[1].id = 0;
|
||||||
Options::inputs[1].name = "GAME CONTROLLER";
|
Options::inputs[1].name = "GAME CONTROLLER";
|
||||||
Options::inputs[1].deviceType = INPUT_USE_GAMECONTROLLER;
|
Options::inputs[1].device_type = INPUT_USE_GAMECONTROLLER;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // Si hay mas de un dispositivo, se recorre el vector
|
} // Si hay mas de un dispositivo, se recorre el vector
|
||||||
@@ -1062,7 +1062,7 @@ void Title::checkInputDevices() {
|
|||||||
for (int i = 0; i < NUM_CONTROLLERS; ++i) {
|
for (int i = 0; i < NUM_CONTROLLERS; ++i) {
|
||||||
temp.id = i;
|
temp.id = i;
|
||||||
temp.name = Input::get()->getControllerName(i);
|
temp.name = Input::get()->getControllerName(i);
|
||||||
temp.deviceType = INPUT_USE_GAMECONTROLLER;
|
temp.device_type = INPUT_USE_GAMECONTROLLER;
|
||||||
available_input_devices_.push_back(temp);
|
available_input_devices_.push_back(temp);
|
||||||
if (Options::settings.console) {
|
if (Options::settings.console) {
|
||||||
std::cout << "Device " << (int)available_input_devices_.size() << " - " << temp.name.c_str() << '\n';
|
std::cout << "Device " << (int)available_input_devices_.size() << " - " << temp.name.c_str() << '\n';
|
||||||
@@ -1073,7 +1073,7 @@ void Title::checkInputDevices() {
|
|||||||
// Añade el teclado al final
|
// Añade el teclado al final
|
||||||
temp.id = -1;
|
temp.id = -1;
|
||||||
temp.name = "KEYBOARD";
|
temp.name = "KEYBOARD";
|
||||||
temp.deviceType = INPUT_USE_KEYBOARD;
|
temp.device_type = INPUT_USE_KEYBOARD;
|
||||||
available_input_devices_.push_back(temp);
|
available_input_devices_.push_back(temp);
|
||||||
if (Options::settings.console) {
|
if (Options::settings.console) {
|
||||||
std::cout << "Device " << (int)available_input_devices_.size() << " - " << temp.name.c_str() << '\n';
|
std::cout << "Device " << (int)available_input_devices_.size() << " - " << temp.name.c_str() << '\n';
|
||||||
|
|||||||
@@ -775,28 +775,28 @@ void Menu::setDefaultActionWhenCancel(int item) {
|
|||||||
|
|
||||||
// Gestiona la entrada de teclado y mando durante el menu
|
// Gestiona la entrada de teclado y mando durante el menu
|
||||||
void Menu::checkInput() {
|
void Menu::checkInput() {
|
||||||
if (Input::get()->checkInput(input_up, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(UP, REPEAT_FALSE)) {
|
||||||
decreaseSelectorIndex();
|
decreaseSelectorIndex();
|
||||||
if (soundMove != nullptr) {
|
if (soundMove != nullptr) {
|
||||||
Audio::get()->playSound(soundMove);
|
Audio::get()->playSound(soundMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input::get()->checkInput(input_down, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(DOWN, REPEAT_FALSE)) {
|
||||||
increaseSelectorIndex();
|
increaseSelectorIndex();
|
||||||
if (soundMove != nullptr) {
|
if (soundMove != nullptr) {
|
||||||
Audio::get()->playSound(soundMove);
|
Audio::get()->playSound(soundMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input::get()->checkInput(input_accept, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(ACCEPT, REPEAT_FALSE)) {
|
||||||
itemSelected = selector.index;
|
itemSelected = selector.index;
|
||||||
if (soundAccept != nullptr) {
|
if (soundAccept != nullptr) {
|
||||||
Audio::get()->playSound(soundAccept);
|
Audio::get()->playSound(soundAccept);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input::get()->checkInput(input_cancel, REPEAT_FALSE)) {
|
if (Input::get()->checkInput(CANCEL, REPEAT_FALSE)) {
|
||||||
itemSelected = defaultActionWhenCancel;
|
itemSelected = defaultActionWhenCancel;
|
||||||
if (soundCancel != nullptr) {
|
if (soundCancel != nullptr) {
|
||||||
Audio::get()->playSound(soundCancel);
|
Audio::get()->playSound(soundCancel);
|
||||||
|
|||||||
+59
-81
@@ -7,47 +7,47 @@
|
|||||||
|
|
||||||
// Calcula el cuadrado de la distancia entre dos puntos
|
// Calcula el cuadrado de la distancia entre dos puntos
|
||||||
auto distanceSquared(int x1, int y1, int x2, int y2) -> double {
|
auto distanceSquared(int x1, int y1, int x2, int y2) -> double {
|
||||||
const int deltaX = x2 - x1;
|
const int DELTA_X = x2 - x1;
|
||||||
const int deltaY = y2 - y1;
|
const int DELTA_Y = y2 - y1;
|
||||||
return (deltaX * deltaX) + (deltaY * deltaY);
|
return (DELTA_X * DELTA_X) + (DELTA_Y * DELTA_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detector de colisiones entre dos circulos
|
// Detector de colisiones entre dos circulos
|
||||||
auto checkCollision(const Circle &a, const Circle &b) -> bool {
|
auto checkCollision(const Circle &a, const Circle &b) -> bool {
|
||||||
// Calcula el radio total al cuadrado
|
// Calcula el radio total al cuadrado
|
||||||
int totalRadiusSquared = a.r + b.r;
|
int total_radius_squared = a.r + b.r;
|
||||||
totalRadiusSquared = totalRadiusSquared * totalRadiusSquared;
|
total_radius_squared = total_radius_squared * total_radius_squared;
|
||||||
|
|
||||||
// Han colisionat si la distancia entre centres és inferior a la suma de radis
|
// Han colisionat si la distancia entre centres és inferior a la suma de radis
|
||||||
return distanceSquared(a.x, a.y, b.x, b.y) < totalRadiusSquared;
|
return distanceSquared(a.x, a.y, b.x, b.y) < total_radius_squared;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detector de colisiones entre un circulo y un rectangulo
|
// Detector de colisiones entre un circulo y un rectangulo
|
||||||
auto checkCollision(const Circle &a, const SDL_Rect &b) -> bool {
|
auto checkCollision(const Circle &a, const SDL_Rect &b) -> bool {
|
||||||
// Closest point on collision box
|
// Closest point on collision box
|
||||||
int cX;
|
int c_x;
|
||||||
int cY;
|
int c_y;
|
||||||
|
|
||||||
// Find closest x offset
|
// Find closest x offset
|
||||||
if (a.x < b.x) {
|
if (a.x < b.x) {
|
||||||
cX = b.x;
|
c_x = b.x;
|
||||||
} else if (a.x > b.x + b.w) {
|
} else if (a.x > b.x + b.w) {
|
||||||
cX = b.x + b.w;
|
c_x = b.x + b.w;
|
||||||
} else {
|
} else {
|
||||||
cX = a.x;
|
c_x = a.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find closest y offset
|
// Find closest y offset
|
||||||
if (a.y < b.y) {
|
if (a.y < b.y) {
|
||||||
cY = b.y;
|
c_y = b.y;
|
||||||
} else if (a.y > b.y + b.h) {
|
} else if (a.y > b.y + b.h) {
|
||||||
cY = b.y + b.h;
|
c_y = b.y + b.h;
|
||||||
} else {
|
} else {
|
||||||
cY = a.y;
|
c_y = a.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the closest point is inside the Circle
|
// If the closest point is inside the Circle
|
||||||
if (distanceSquared(a.x, a.y, cX, cY) < a.r * a.r) {
|
if (distanceSquared(a.x, a.y, c_x, c_y) < a.r * a.r) {
|
||||||
// This box and the Circle have collided
|
// This box and the Circle have collided
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -59,31 +59,31 @@ auto checkCollision(const Circle &a, const SDL_Rect &b) -> bool {
|
|||||||
// Detector de colisiones entre dos rectangulos
|
// Detector de colisiones entre dos rectangulos
|
||||||
auto checkCollision(const SDL_Rect &a, const SDL_Rect &b) -> bool {
|
auto checkCollision(const SDL_Rect &a, const SDL_Rect &b) -> bool {
|
||||||
// Calcula las caras del rectangulo a
|
// Calcula las caras del rectangulo a
|
||||||
const int leftA = a.x;
|
const int LEFT_A = a.x;
|
||||||
const int rightA = a.x + a.w;
|
const int RIGHT_A = a.x + a.w;
|
||||||
const int topA = a.y;
|
const int TOP_A = a.y;
|
||||||
const int bottomA = a.y + a.h;
|
const int BOTTOM_A = a.y + a.h;
|
||||||
|
|
||||||
// Calcula las caras del rectangulo b
|
// Calcula las caras del rectangulo b
|
||||||
const int leftB = b.x;
|
const int LEFT_B = b.x;
|
||||||
const int rightB = b.x + b.w;
|
const int RIGHT_B = b.x + b.w;
|
||||||
const int topB = b.y;
|
const int TOP_B = b.y;
|
||||||
const int bottomB = b.y + b.h;
|
const int BOTTOM_B = b.y + b.h;
|
||||||
|
|
||||||
// Si cualquiera de las caras de a está fuera de b
|
// Si cualquiera de las caras de a está fuera de b
|
||||||
if (bottomA <= topB) {
|
if (BOTTOM_A <= TOP_B) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topA >= bottomB) {
|
if (TOP_A >= BOTTOM_B) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rightA <= leftB) {
|
if (RIGHT_A <= LEFT_B) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leftA >= rightB) {
|
if (LEFT_A >= RIGHT_B) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,91 +197,69 @@ auto checkCollision(const HorizontalLine &l, const SDL_Point &p) -> bool {
|
|||||||
|
|
||||||
// Detector de colisiones entre dos lineas
|
// Detector de colisiones entre dos lineas
|
||||||
auto checkCollision(const Line &l1, const Line &l2) -> SDL_Point {
|
auto checkCollision(const Line &l1, const Line &l2) -> SDL_Point {
|
||||||
const float x1 = l1.x1;
|
const float X1 = l1.x1;
|
||||||
const float y1 = l1.y1;
|
const float Y1 = l1.y1;
|
||||||
const float x2 = l1.x2;
|
const float X2 = l1.x2;
|
||||||
const float y2 = l1.y2;
|
const float Y2 = l1.y2;
|
||||||
|
|
||||||
const float x3 = l2.x1;
|
const float X3 = l2.x1;
|
||||||
const float y3 = l2.y1;
|
const float Y3 = l2.y1;
|
||||||
const float x4 = l2.x2;
|
const float X4 = l2.x2;
|
||||||
const float y4 = l2.y2;
|
const float Y4 = l2.y2;
|
||||||
|
|
||||||
// calculate the direction of the lines
|
// calculate the direction of the lines
|
||||||
float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
|
float u_a = ((X4 - X3) * (Y1 - Y3) - (Y4 - Y3) * (X1 - X3)) / ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1));
|
||||||
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
|
float u_b = ((X2 - X1) * (Y1 - Y3) - (Y2 - Y1) * (X1 - X3)) / ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1));
|
||||||
|
|
||||||
// if uA and uB are between 0-1, lines are colliding
|
// if uA and uB are between 0-1, lines are colliding
|
||||||
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
|
if (u_a >= 0 && u_a <= 1 && u_b >= 0 && u_b <= 1) {
|
||||||
// Calcula la intersección
|
// Calcula la intersección
|
||||||
const float x = x1 + (uA * (x2 - x1));
|
const float X = X1 + (u_a * (X2 - X1));
|
||||||
const float y = y1 + (uA * (y2 - y1));
|
const float Y = Y1 + (u_a * (Y2 - Y1));
|
||||||
|
|
||||||
return {(int)std::round(x), (int)std::round(y)};
|
return {(int)std::round(X), (int)std::round(Y)};
|
||||||
}
|
}
|
||||||
return {-1, -1};
|
return {-1, -1};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detector de colisiones entre dos lineas
|
// Detector de colisiones entre dos lineas
|
||||||
auto checkCollision(const DiagonalLine &l1, const VerticalLine &l2) -> SDL_Point {
|
auto checkCollision(const DiagonalLine &l1, const VerticalLine &l2) -> SDL_Point {
|
||||||
const float x1 = l1.x1;
|
const float X1 = l1.x1;
|
||||||
const float y1 = l1.y1;
|
const float Y1 = l1.y1;
|
||||||
const float x2 = l1.x2;
|
const float X2 = l1.x2;
|
||||||
const float y2 = l1.y2;
|
const float Y2 = l1.y2;
|
||||||
|
|
||||||
const float x3 = l2.x;
|
const float X3 = l2.x;
|
||||||
const float y3 = l2.y1;
|
const float Y3 = l2.y1;
|
||||||
const float x4 = l2.x;
|
const float X4 = l2.x;
|
||||||
const float y4 = l2.y2;
|
const float Y4 = l2.y2;
|
||||||
|
|
||||||
// calculate the direction of the lines
|
// calculate the direction of the lines
|
||||||
float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
|
float u_a = ((X4 - X3) * (Y1 - Y3) - (Y4 - Y3) * (X1 - X3)) / ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1));
|
||||||
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
|
float u_b = ((X2 - X1) * (Y1 - Y3) - (Y2 - Y1) * (X1 - X3)) / ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1));
|
||||||
|
|
||||||
// if uA and uB are between 0-1, lines are colliding
|
// if uA and uB are between 0-1, lines are colliding
|
||||||
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
|
if (u_a >= 0 && u_a <= 1 && u_b >= 0 && u_b <= 1) {
|
||||||
// Calcula la intersección
|
// Calcula la intersección
|
||||||
const float x = x1 + (uA * (x2 - x1));
|
const float X = X1 + (u_a * (X2 - X1));
|
||||||
const float y = y1 + (uA * (y2 - y1));
|
const float Y = Y1 + (u_a * (Y2 - Y1));
|
||||||
|
|
||||||
return {(int)x, (int)y};
|
return {(int)X, (int)Y};
|
||||||
}
|
}
|
||||||
return {-1, -1};
|
return {-1, -1};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detector de colisiones entre una linea diagonal y una vertical
|
|
||||||
/*bool checkCollision(DiagonalLine &l1, VerticalLine &l2)
|
|
||||||
{
|
|
||||||
// Normaliza la linea diagonal
|
|
||||||
normalizeLine(l1);
|
|
||||||
|
|
||||||
// Comprueba si la linea vertical esta a la izquierda de la linea diagonal
|
|
||||||
if (l2.x < l1.x1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprueba si la linea vertical esta a la derecha de la linea diagonal
|
|
||||||
if (l2.x > l1.x2)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inacabada
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Normaliza una linea diagonal
|
// Normaliza una linea diagonal
|
||||||
void normalizeLine(DiagonalLine &l) {
|
void normalizeLine(DiagonalLine &l) {
|
||||||
// Las lineas diagonales van de izquierda a derecha
|
// Las lineas diagonales van de izquierda a derecha
|
||||||
// x2 mayor que x1
|
// x2 mayor que x1
|
||||||
if (l.x2 < l.x1) {
|
if (l.x2 < l.x1) {
|
||||||
const int x = l.x1;
|
const int X = l.x1;
|
||||||
const int y = l.y1;
|
const int Y = l.y1;
|
||||||
l.x1 = l.x2;
|
l.x1 = l.x2;
|
||||||
l.y1 = l.y2;
|
l.y1 = l.y2;
|
||||||
l.x2 = x;
|
l.x2 = X;
|
||||||
l.y2 = y;
|
l.y2 = Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <string> // for string, basic_string
|
#include <string> // for string, basic_string
|
||||||
#include <vector> // for vector
|
|
||||||
|
|
||||||
// Dificultad del juego
|
// Dificultad del juego
|
||||||
constexpr int DIFFICULTY_EASY = 0;
|
constexpr int DIFFICULTY_EASY = 0;
|
||||||
@@ -63,17 +62,17 @@ struct Section {
|
|||||||
struct DemoKeys {
|
struct DemoKeys {
|
||||||
Uint8 left;
|
Uint8 left;
|
||||||
Uint8 right;
|
Uint8 right;
|
||||||
Uint8 noInput;
|
Uint8 no_input;
|
||||||
Uint8 fire;
|
Uint8 fire;
|
||||||
Uint8 fireLeft;
|
Uint8 fire_left;
|
||||||
Uint8 fireRight;
|
Uint8 fire_right;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Estructura para albergar métodos de control
|
// Estructura para albergar métodos de control
|
||||||
struct InputDevice {
|
struct InputDevice {
|
||||||
int id; // Identificador en el vector de mandos
|
int id; // Identificador en el vector de mandos
|
||||||
std::string name; // Nombre del dispositivo
|
std::string name; // Nombre del dispositivo
|
||||||
Uint8 deviceType; // Tipo de dispositivo (teclado o mando)
|
Uint8 device_type; // Tipo de dispositivo (teclado o mando)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calcula el cuadrado de la distancia entre dos puntos
|
// Calcula el cuadrado de la distancia entre dos puntos
|
||||||
|
|||||||
Reference in New Issue
Block a user