From e4a08d2ec7a65f10ced8dad14f2cfb5d651f3e71 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 15 Oct 2025 12:16:50 +0200 Subject: [PATCH] corregides cridades a SDL3 i migrat casi tot de int a float. Falta jail_shader --- source/cheevos.cpp | 8 +- source/debug.cpp | 74 ++- source/debug.h | 2 +- source/director.cpp | 122 ++-- source/enemy.cpp | 10 +- source/enemy.h | 8 +- source/external/jail_audio.cpp | 552 ++++++++++-------- source/external/jail_audio.h | 49 +- source/external/jail_shader.cpp | 4 +- .../external/{stb_vorbis.c => stb_vorbis.h} | 0 source/global_events.cpp | 4 +- source/global_inputs.cpp | 7 +- source/input.cpp | 91 +-- source/input.h | 12 +- source/item.cpp | 4 +- source/item.h | 8 +- source/item_tracker.cpp | 50 +- source/item_tracker.h | 14 +- source/mouse.cpp | 6 +- source/options.cpp | 13 +- source/options.h | 22 +- source/player.cpp | 22 +- source/player.h | 60 +- source/resource.cpp | 22 +- source/room.cpp | 40 +- source/room.h | 27 +- source/scoreboard.cpp | 2 +- source/scoreboard.h | 2 +- source/screen.cpp | 58 +- source/screen.h | 7 +- source/sections/credits.cpp | 4 +- source/sections/ending.cpp | 10 +- source/sections/ending2.cpp | 60 +- source/sections/ending2.h | 4 +- source/sections/game.cpp | 2 +- source/sections/game.h | 2 +- source/sections/loading_screen.h | 14 +- source/sections/title.cpp | 8 +- source/sections/title.h | 2 +- source/sprite/surface_animated_sprite.cpp | 2 +- source/sprite/surface_animated_sprite.h | 14 +- source/sprite/surface_moving_sprite.cpp | 6 +- source/sprite/surface_moving_sprite.h | 12 +- source/sprite/surface_sprite.cpp | 16 +- source/sprite/surface_sprite.h | 44 +- source/surface.cpp | 116 ++-- source/surface.h | 30 +- source/text.cpp | 4 +- source/ui/notifier.cpp | 6 +- source/ui/notifier.h | 2 +- source/utils.cpp | 18 +- source/utils.h | 26 +- 52 files changed, 879 insertions(+), 823 deletions(-) rename source/external/{stb_vorbis.c => stb_vorbis.h} (100%) diff --git a/source/cheevos.cpp b/source/cheevos.cpp index c34c7fb..0ae1201 100644 --- a/source/cheevos.cpp +++ b/source/cheevos.cpp @@ -140,15 +140,15 @@ void Cheevos::loadFromFile() { // Guarda el estado de los logros en un fichero void Cheevos::saveToFile() { // Abre el fichero en modo escritura (binario) - SDL_RWops* file = SDL_RWFromFile(this->file_.c_str(), "w+b"); - if (file != NULL) { + SDL_IOStream* file = SDL_IOFromFile(this->file_.c_str(), "w+b"); + if (file != nullptr) { // Guarda la información for (int i = 0; i < (int)cheevos_list_.size(); ++i) { - SDL_RWwrite(file, &cheevos_list_[i].completed, sizeof(bool), 1); + SDL_WriteIO(file, &cheevos_list_[i].completed, sizeof(bool)); } // Cierra el fichero - SDL_RWclose(file); + SDL_CloseIO(file); } else { if (options.console) { std::cout << "Error: Unable to save file! " << SDL_GetError() << std::endl; diff --git a/source/debug.cpp b/source/debug.cpp index 9452933..fa1e282 100644 --- a/source/debug.cpp +++ b/source/debug.cpp @@ -1,61 +1,55 @@ #include "debug.h" + #include // Para max -#include // Para __shared_ptr_access, shared_ptr -#include "resource.h" // Para Resource -#include "text.h" // Para Text -#include "utils.h" // Para Color +#include // Para __shared_ptr_access, shared_ptr + +#include "resource.h" // Para Resource +#include "text.h" // Para Text +#include "utils.h" // Para Color // [SINGLETON] -Debug *Debug::debug_ = nullptr; +Debug* Debug::debug_ = nullptr; // [SINGLETON] Crearemos el objeto con esta función estática -void Debug::init() -{ - Debug::debug_ = new Debug(); +void Debug::init() { + Debug::debug_ = new Debug(); } // [SINGLETON] Destruiremos el objeto con esta función estática -void Debug::destroy() -{ - delete Debug::debug_; +void Debug::destroy() { + delete Debug::debug_; } // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él -Debug *Debug::get() -{ - return Debug::debug_; +Debug* Debug::get() { + return Debug::debug_; } // Dibuja en pantalla -void Debug::render() -{ - auto text = Resource::get()->getText("debug"); - int y = y_; - int w = 0; +void Debug::render() { + auto text = Resource::get()->getText("debug"); + int y = y_; + int w = 0; - for (const auto &s : slot_) - { - text->write(x_, y, s); - w = (std::max(w, (int)s.length())); - y += text->getCharacterSize() + 1; - if (y > 192 - text->getCharacterSize()) - { - y = y_; - x_ += w * text->getCharacterSize() + 2; - } - } + for (const auto& s : slot_) { + text->write(x_, y, s); + w = (std::max(w, (int)s.length())); + y += text->getCharacterSize() + 1; + if (y > 192 - text->getCharacterSize()) { + y = y_; + x_ += w * text->getCharacterSize() + 2; + } + } - y = 0; - for (const auto &l : log_) - { - text->writeColored(x_ + 10, y, l, static_cast(PaletteColor::WHITE)); - y += text->getCharacterSize() + 1; - } + y = 0; + for (const auto& l : log_) { + text->writeColored(x_ + 10, y, l, static_cast(PaletteColor::WHITE)); + y += text->getCharacterSize() + 1; + } } // Establece la posición donde se colocará la información de debug -void Debug::setPos(SDL_Point p) -{ - x_ = p.x; - y_ = p.y; +void Debug::setPos(SDL_FPoint p) { + x_ = p.x; + y_ = p.y; } \ No newline at end of file diff --git a/source/debug.h b/source/debug.h index 729aae5..eb29de8 100644 --- a/source/debug.h +++ b/source/debug.h @@ -38,7 +38,7 @@ class Debug { void render(); // Establece la posición donde se colocará la información de debug - void setPos(SDL_Point p); + void setPos(SDL_FPoint p); // Getters bool getEnabled() { return enabled_; } diff --git a/source/director.cpp b/source/director.cpp index 879977d..7019c98 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -11,24 +11,24 @@ #include // Para make_unique, unique_ptr #include // Para operator+, allocator, char_traits -#include "asset.h" // Para Asset, AssetType -#include "cheevos.h" // Para Cheevos -#include "credits.h" // Para Credits -#include "debug.h" // Para Debug -#include "defines.h" // Para WINDOW_CAPTION -#include "ending.h" // Para Ending -#include "ending2.h" // Para Ending2 -#include "external/jail_audio.h" // Para JA_SetMusicVolume, JA_SetSoundV... -#include "game.h" // Para Game, GameMode -#include "game_over.h" // Para GameOver -#include "input.h" // Para Input, InputAction -#include "loading_screen.h" // Para LoadingScreen -#include "logo.h" // Para Logo -#include "options.h" // Para Options, options, OptionsVideo -#include "resource.h" // Para Resource -#include "screen.h" // Para Screen -#include "title.h" // Para Title -#include "ui/notifier.h" // Para Notifier +#include "asset.h" // Para Asset, AssetType +#include "cheevos.h" // Para Cheevos +#include "debug.h" // Para Debug +#include "defines.h" // Para WINDOW_CAPTION +#include "external/jail_audio.h" // Para JA_SetMusicVolume, JA_SetSoundV... +#include "input.h" // Para Input, InputAction +#include "options.h" // Para Options, options, OptionsVideo +#include "resource.h" // Para Resource +#include "screen.h" // Para Screen +#include "sections/credits.h" // Para Credits +#include "sections/ending.h" // Para Ending +#include "sections/ending2.h" // Para Ending2 +#include "sections/game.h" // Para Game, GameMode +#include "sections/game_over.h" // Para GameOver +#include "sections/loading_screen.h" // Para LoadingScreen +#include "sections/logo.h" // Para Logo +#include "sections/title.h" // Para Title +#include "ui/notifier.h" // Para Notifier #ifndef _WIN32 #include @@ -67,7 +67,7 @@ Director::Director(int argc, const char* argv[]) { // Crea los objetos Screen::init(window_, renderer_); - SDL_ShowCursor(SDL_DISABLE); + SDL_HideCursor(); Resource::init(); Notifier::init("", "8bithud"); Screen::get()->setNotificationsEnabled(true); @@ -220,29 +220,29 @@ void Director::initInput() { const int NUM_GAMEPADS = Input::get()->getNumControllers(); for (int i = 0; i < NUM_GAMEPADS; ++i) { // Movimiento - Input::get()->bindGameControllerButton(i, InputAction::JUMP, SDL_CONTROLLER_BUTTON_B); - Input::get()->bindGameControllerButton(i, InputAction::LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT); - Input::get()->bindGameControllerButton(i, InputAction::RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); + Input::get()->bindGameControllerButton(i, InputAction::JUMP, SDL_GAMEPAD_BUTTON_SOUTH); + Input::get()->bindGameControllerButton(i, InputAction::LEFT, SDL_GAMEPAD_BUTTON_DPAD_LEFT); + Input::get()->bindGameControllerButton(i, InputAction::RIGHT, SDL_GAMEPAD_BUTTON_DPAD_RIGHT); // Otros - Input::get()->bindGameControllerButton(i, InputAction::ACCEPT, SDL_CONTROLLER_BUTTON_B); - Input::get()->bindGameControllerButton(i, InputAction::CANCEL, SDL_CONTROLLER_BUTTON_A); + Input::get()->bindGameControllerButton(i, InputAction::ACCEPT, SDL_GAMEPAD_BUTTON_SOUTH); + Input::get()->bindGameControllerButton(i, InputAction::CANCEL, SDL_GAMEPAD_BUTTON_EAST); #ifdef GAME_CONSOLE - Input::get()->bindGameControllerButton(i, InputAction::input_pause, SDL_CONTROLLER_BUTTON_BACK); - Input::get()->bindGameControllerButton(i, InputAction::input_exit, SDL_CONTROLLER_BUTTON_START); + Input::get()->bindGameControllerButton(i, InputAction::input_pause, SDL_GAMEPAD_BUTTON_BACK); + Input::get()->bindGameControllerButton(i, InputAction::input_exit, SDL_GAMEPAD_BUTTON_START); #else - Input::get()->bindGameControllerButton(i, InputAction::PAUSE, SDL_CONTROLLER_BUTTON_START); - Input::get()->bindGameControllerButton(i, InputAction::EXIT, SDL_CONTROLLER_BUTTON_BACK); + Input::get()->bindGameControllerButton(i, InputAction::PAUSE, SDL_GAMEPAD_BUTTON_START); + Input::get()->bindGameControllerButton(i, InputAction::EXIT, SDL_GAMEPAD_BUTTON_BACK); #endif - Input::get()->bindGameControllerButton(i, InputAction::NEXT_PALETTE, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); - Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_MUSIC, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); - Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_BORDER, SDL_CONTROLLER_BUTTON_X); + Input::get()->bindGameControllerButton(i, InputAction::NEXT_PALETTE, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER); + Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_MUSIC, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER); + Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_BORDER, SDL_GAMEPAD_BUTTON_NORTH); } } // Inicializa JailAudio void Director::initJailAudio() { - JA_Init(48000, AUDIO_S16, 2); + JA_Init(48000, SDL_AUDIO_S16LE, 2); if (options.audio.enabled) { JA_SetMusicVolume(options.audio.music.volume); JA_SetSoundVolume(options.audio.sound.volume); @@ -258,7 +258,7 @@ bool Director::initSDL() { bool success = true; // Inicializa SDL - if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { + if (!SDL_Init(SDL_INIT_VIDEO)) { if (options.console) { std::cout << "SDL could not initialize!\nSDL Error: " << SDL_GetError() << std::endl; } @@ -267,23 +267,24 @@ bool Director::initSDL() { // Inicia el generador de numeros aleatorios std::srand(static_cast(SDL_GetTicks())); - // Establece el filtro de la textura a nearest - if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(static_cast(options.video.filter)).c_str())) { - if (options.console) { - std::cout << "Warning: Nearest texture filtering not enabled!\n"; - } - } - // Activa el render OpenGL if (!SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl")) { std::cout << "Warning: opengl not enabled!\n"; } // Crea la ventana - const auto window_width = options.video.border.enabled ? options.game.width + options.video.border.width * 2 : options.game.width; - const auto window_height = options.video.border.enabled ? options.game.height + options.video.border.height * 2 : options.game.height; + const auto WINDOW_WIDTH = options.video.border.enabled ? options.game.width + options.video.border.width * 2 : options.game.width; + const auto WINDOW_HEIGHT = options.video.border.enabled ? options.game.height + options.video.border.height * 2 : options.game.height; - window_ = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_width * options.window.zoom, window_height * options.window.zoom, SDL_WINDOW_HIDDEN); +#ifdef __APPLE__ + SDL_WindowFlags window_flags = SDL_WINDOW_METAL; +#else + SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL; +#endif + if (options.video.fullscreen) { + window_flags |= SDL_WINDOW_FULLSCREEN; + } + window_ = SDL_CreateWindow(WINDOW_CAPTION, WINDOW_WIDTH * options.window.zoom, WINDOW_HEIGHT * options.window.zoom, window_flags); if (window_ == nullptr) { if (options.console) { std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl; @@ -291,28 +292,27 @@ bool Director::initSDL() { success = false; } else { // Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones - Uint32 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; - if (options.video.vertical_sync) { - flags = flags | SDL_RENDERER_PRESENTVSYNC; - } - renderer_ = SDL_CreateRenderer(window_, -1, flags); - + renderer_ = SDL_CreateRenderer(window_, nullptr); if (renderer_ == nullptr) { - if (options.console) { - std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << std::endl; - } - success = false; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "FATAL: Failed to create renderer! SDL Error: %s", + SDL_GetError()); + SDL_DestroyWindow(window_); + window_ = nullptr; + SDL_Quit(); + return false; } else { - // Inicializa el color de renderizado + // Configurar renderer + const int EXTRA_WIDTH = options.video.border.enabled ? options.video.border.width * 2 : 0; + const int EXTRA_HEIGHT = options.video.border.enabled ? options.video.border.height * 2 : 0; + SDL_SetRenderLogicalPresentation( + renderer_, + options.game.width + EXTRA_WIDTH, + options.game.height + EXTRA_HEIGHT, + options.video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX); SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF); - - // Modifica el tamaño del renderizador - const int extra_width = options.video.border.enabled ? options.video.border.width * 2 : 0; - const int extra_height = options.video.border.enabled ? options.video.border.height * 2 : 0; - SDL_RenderSetLogicalSize(renderer_, options.game.width + extra_width, options.game.height + extra_height); - - // Establece el modo de mezcla SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); + SDL_SetRenderVSync(renderer_, options.video.vertical_sync ? 1 : SDL_RENDERER_VSYNC_DISABLED); } } } diff --git a/source/enemy.cpp b/source/enemy.cpp index 5dfaefc..98f4f08 100644 --- a/source/enemy.cpp +++ b/source/enemy.cpp @@ -25,9 +25,9 @@ Enemy::Enemy(const EnemyData& enemy) sprite_->setWidth(enemy.w); sprite_->setHeight(enemy.h); - const SDL_RendererFlip FLIP = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; - const SDL_RendererFlip MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE; - sprite_->setFlip(static_cast(FLIP | MIRROR)); + const SDL_FlipMode FLIP = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; + const SDL_FlipMode MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE; + sprite_->setFlip(static_cast(FLIP | MIRROR)); collider_ = getRect(); @@ -87,11 +87,11 @@ void Enemy::checkPath() { } // Devuelve el rectangulo que contiene al enemigo -SDL_Rect Enemy::getRect() { +SDL_FRect Enemy::getRect() { return sprite_->getRect(); } // Obtiene el rectangulo de colision del enemigo -SDL_Rect& Enemy::getCollider() { +SDL_FRect& Enemy::getCollider() { return collider_; } \ No newline at end of file diff --git a/source/enemy.h b/source/enemy.h index 18d64a7..7f668dd 100644 --- a/source/enemy.h +++ b/source/enemy.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include // Para shared_ptr #include // Para string @@ -38,7 +38,7 @@ class Enemy { int x2_; // Limite derecho de la ruta en el eje X int y1_; // Limite superior de la ruta en el eje Y int y2_; // Limite inferior de la ruta en el eje Y - SDL_Rect collider_; // Caja de colisión + SDL_FRect collider_; // Caja de colisión bool should_flip_; // Indica si el enemigo hace flip al terminar su ruta bool should_mirror_; // Indica si el enemigo se dibuja volteado verticalmente @@ -59,8 +59,8 @@ class Enemy { void update(); // Devuelve el rectangulo que contiene al enemigo - SDL_Rect getRect(); + SDL_FRect getRect(); // Obtiene el rectangulo de colision del enemigo - SDL_Rect& getCollider(); + SDL_FRect& getCollider(); }; diff --git a/source/external/jail_audio.cpp b/source/external/jail_audio.cpp index d699f07..ba7f6c1 100644 --- a/source/external/jail_audio.cpp +++ b/source/external/jail_audio.cpp @@ -1,211 +1,244 @@ -#include "external/jail_audio.h" +#ifndef JA_USESDLMIXER +#include "jail_audio.h" -#include -#include // Para uint8_t, uint32_t -#include // Para NULL, fseek, fclose, fopen, fread, ftell -#include // Para free, malloc +#include // Para SDL_AudioFormat, SDL_BindAudioStream, SDL_SetAudioStreamGain, SDL_PutAudioStreamData, SDL_DestroyAudioStream, SDL_GetAudioStreamAvailable, Uint8, SDL_CreateAudioStream, SDL_UnbindAudioStream, Uint32, SDL_CloseAudioDevice, SDL_GetTicks, SDL_Log, SDL_free, SDL_AudioSpec, SDL_AudioStream, SDL_IOFromMem, SDL_LoadWAV, SDL_LoadWAV_IO, SDL_OpenAudioDevice, SDL_clamp, SDL_malloc, SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, SDL_AudioDeviceID, SDL_memcpy +#include // Para uint32_t, uint8_t +#include // Para NULL, fseek, printf, fclose, fopen, fread, ftell, FILE, SEEK_END, SEEK_SET +#include // Para free, malloc +#include // Para strcpy, strlen -#include "stb_vorbis.c" // Para stb_vorbis_decode_memory +#include "stb_vorbis.h" // Para stb_vorbis_decode_memory -constexpr int JA_MAX_SIMULTANEOUS_CHANNELS = 20; +#define JA_MAX_SIMULTANEOUS_CHANNELS 20 +#define JA_MAX_GROUPS 2 -struct JA_Sound_t { - Uint32 length{0}; - Uint8* buffer{NULL}; +struct JA_Sound_t +{ + SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 }; + Uint32 length { 0 }; + Uint8 *buffer { NULL }; }; -struct JA_Channel_t { - JA_Sound_t* sound; - int pos{0}; - int times{0}; - JA_Channel_state state{JA_CHANNEL_FREE}; +struct JA_Channel_t +{ + JA_Sound_t *sound { nullptr }; + int pos { 0 }; + int times { 0 }; + int group { 0 }; + SDL_AudioStream *stream { nullptr }; + JA_Channel_state state { JA_CHANNEL_FREE }; }; -struct JA_Music_t { - int samples{0}; - Uint32 length{0}; - int pos{0}; - int times{0}; - short* output{NULL}; - JA_Music_state state{JA_MUSIC_INVALID}; +struct JA_Music_t +{ + SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 }; + Uint32 length { 0 }; + Uint8 *buffer { nullptr }; + char *filename { nullptr }; + + int pos { 0 }; + int times { 0 }; + SDL_AudioStream *stream { nullptr }; + JA_Music_state state { JA_MUSIC_INVALID }; }; -JA_Music_t* current_music{NULL}; -JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; +JA_Music_t *current_music { nullptr }; +JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; -int JA_freq{48000}; -SDL_AudioFormat JA_format{AUDIO_S16}; -Uint8 JA_channels{2}; -int JA_musicVolume = 128; -int JA_soundVolume = 64; -bool JA_musicEnabled = true; -bool JA_soundEnabled = true; -SDL_AudioDeviceID sdlAudioDevice = 0; +SDL_AudioSpec JA_audioSpec { SDL_AUDIO_S16, 2, 48000 }; +float JA_musicVolume { 1.0f }; +float JA_soundVolume[JA_MAX_GROUPS]; +bool JA_musicEnabled { true }; +bool JA_soundEnabled { true }; +SDL_AudioDeviceID sdlAudioDevice { 0 }; +//SDL_TimerID JA_timerID { 0 }; bool fading = false; int fade_start_time; int fade_duration; int fade_initial_volume; -void audioCallback(void* userdata, uint8_t* stream, int len) { - SDL_memset(stream, 0, len); - if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) { - int volume = JA_musicVolume; + +void JA_Update() +{ + if (JA_musicEnabled && current_music && current_music->state == JA_MUSIC_PLAYING) + { if (fading) { int time = SDL_GetTicks(); - if (time > (fade_start_time + fade_duration)) { + if (time > (fade_start_time+fade_duration)) { fading = false; - current_music->pos = 0; - current_music->state = JA_MUSIC_STOPPED; - volume = 0; + JA_StopMusic(); + return; } else { const int time_passed = time - fade_start_time; const float percent = (float)time_passed / (float)fade_duration; - volume = JA_musicVolume * (1.0 - percent); + SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume*(1.0 - percent)); } } - const int size = SDL_min(len, current_music->length - current_music->pos); - SDL_MixAudioFormat(stream, (Uint8*)(current_music->output) + current_music->pos, AUDIO_S16, size, volume); - current_music->pos += size; - if (size < len) { - if (current_music->times != 0) { - SDL_MixAudioFormat(stream + size, (Uint8*)current_music->output, AUDIO_S16, len - size, volume); - current_music->pos = len - size; - if (current_music->times > 0) - current_music->times--; - } else { - current_music->pos = 0; - current_music->state = JA_MUSIC_STOPPED; + + if (current_music->times != 0) + { + if ((Uint32)SDL_GetAudioStreamAvailable(current_music->stream) < (current_music->length/2)) { + SDL_PutAudioStreamData(current_music->stream, current_music->buffer, current_music->length); } + if (current_music->times>0) current_music->times--; + } + else + { + if (SDL_GetAudioStreamAvailable(current_music->stream) == 0) JA_StopMusic(); } } - // Mixar els channels mi amol - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].state == JA_CHANNEL_PLAYING) { - const int size = SDL_min(len, channels[i].sound->length - channels[i].pos); - SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume); - channels[i].pos += size; - if (size < len) { - if (channels[i].times != 0) { - SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len - size, JA_soundVolume); - channels[i].pos = len - size; - if (channels[i].times > 0) - channels[i].times--; - } else { - JA_StopChannel(i); + + if (JA_soundEnabled) + { + for (int i=0; i < JA_MAX_SIMULTANEOUS_CHANNELS; ++i) + if (channels[i].state == JA_CHANNEL_PLAYING) + { + if (channels[i].times != 0) + { + if ((Uint32)SDL_GetAudioStreamAvailable(channels[i].stream) < (channels[i].sound->length/2)) { + SDL_PutAudioStreamData(channels[i].stream, channels[i].sound->buffer, channels[i].sound->length); + if (channels[i].times>0) channels[i].times--; + } + } + else + { + if (SDL_GetAudioStreamAvailable(channels[i].stream) == 0) JA_StopChannel(i); } } - } + } + + return; } -void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) { - JA_freq = freq; - JA_format = format; - JA_channels = channels; - SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL}; - if (sdlAudioDevice != 0) - SDL_CloseAudioDevice(sdlAudioDevice); - sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0); - SDL_PauseAudioDevice(sdlAudioDevice, 0); +void JA_Init(const int freq, const SDL_AudioFormat format, const int num_channels) +{ + #ifdef DEBUG + SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG); + #endif + + SDL_Log("Iniciant JailAudio..."); + JA_audioSpec = {format, num_channels, freq }; + if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice); + sdlAudioDevice = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &JA_audioSpec); + SDL_Log( (sdlAudioDevice==0) ? "Failed to initialize SDL audio!\n" : "OK!\n"); + for (int i=0; ilength = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &output) * chan * 2; - music->samples = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &music->output); - - SDL_AudioCVT cvt; - SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq); - if (cvt.needed) { - cvt.len = music->samples * chan * 2; - music->length = cvt.len; - cvt.buf = (Uint8*)SDL_malloc(cvt.len * cvt.len_mult); - SDL_memcpy(cvt.buf, music->output, cvt.len); - SDL_ConvertAudio(&cvt); - free(music->output); - music->output = (short*)cvt.buf; - } - music->length = music->samples * chan * 2; + music->spec.channels = chan; + music->spec.freq = samplerate; + music->spec.format = SDL_AUDIO_S16; + music->buffer = (Uint8*)SDL_malloc(music->length); + SDL_memcpy(music->buffer, output, music->length); + free(output); music->pos = 0; music->state = JA_MUSIC_STOPPED; return music; } -JA_Music_t* JA_LoadMusic(const char* filename) { +JA_Music_t *JA_LoadMusic(const char* filename) +{ // [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid. - FILE* f = fopen(filename, "rb"); + FILE *f = fopen(filename, "rb"); fseek(f, 0, SEEK_END); long fsize = ftell(f); fseek(f, 0, SEEK_SET); - Uint8* buffer = (Uint8*)malloc(fsize + 1); - if (fread(buffer, fsize, 1, f) != 1) - return NULL; + Uint8 *buffer = (Uint8*)malloc(fsize + 1); + if (fread(buffer, fsize, 1, f)!=1) return NULL; fclose(f); - JA_Music_t* music = JA_LoadMusic(buffer, fsize); + JA_Music_t *music = JA_LoadMusic(buffer, fsize); + music->filename = (char*)malloc(strlen(filename)+1); + strcpy(music->filename, filename); free(buffer); return music; } -void JA_PlayMusic(JA_Music_t* music, const int loop) { - if (!JA_musicEnabled) - return; +void JA_PlayMusic(JA_Music_t *music, const int loop) +{ + if (!JA_musicEnabled) return; + + JA_StopMusic(); - if (current_music != NULL) { - current_music->pos = 0; - current_music->state = JA_MUSIC_STOPPED; - } current_music = music; current_music->pos = 0; current_music->state = JA_MUSIC_PLAYING; current_music->times = loop; + + current_music->stream = SDL_CreateAudioStream(¤t_music->spec, &JA_audioSpec); + if (!SDL_PutAudioStreamData(current_music->stream, current_music->buffer, current_music->length)) printf("[ERROR] SDL_PutAudioStreamData failed!\n"); + SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume); + if (!SDL_BindAudioStream(sdlAudioDevice, current_music->stream)) printf("[ERROR] SDL_BindAudioStream failed!\n"); + //SDL_ResumeAudioStreamDevice(current_music->stream); } -void JA_PauseMusic() { - if (!JA_musicEnabled) - return; +char *JA_GetMusicFilename(JA_Music_t *music) +{ + if (!music) music = current_music; + return music->filename; +} + +void JA_PauseMusic() +{ + if (!JA_musicEnabled) return; + if (!current_music || current_music->state == JA_MUSIC_INVALID) return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) - return; current_music->state = JA_MUSIC_PAUSED; + //SDL_PauseAudioStreamDevice(current_music->stream); + SDL_UnbindAudioStream(current_music->stream); } -void JA_ResumeMusic() { - if (!JA_musicEnabled) - return; +void JA_ResumeMusic() +{ + if (!JA_musicEnabled) return; + if (!current_music || current_music->state == JA_MUSIC_INVALID) return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) - return; current_music->state = JA_MUSIC_PLAYING; + //SDL_ResumeAudioStreamDevice(current_music->stream); + SDL_BindAudioStream(sdlAudioDevice, current_music->stream); } -void JA_StopMusic() { - if (!JA_musicEnabled) - return; +void JA_StopMusic() +{ + if (!JA_musicEnabled) return; + if (!current_music || current_music->state == JA_MUSIC_INVALID) return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) - return; current_music->pos = 0; current_music->state = JA_MUSIC_STOPPED; + //SDL_PauseAudioStreamDevice(current_music->stream); + SDL_DestroyAudioStream(current_music->stream); + current_music->stream = nullptr; + free(current_music->filename); + current_music->filename = nullptr; } -void JA_FadeOutMusic(const int milliseconds) { - if (!JA_musicEnabled) - return; - if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) - return; +void JA_FadeOutMusic(const int milliseconds) +{ + if (!JA_musicEnabled) return; + if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; fading = true; fade_start_time = SDL_GetTicks(); @@ -213,204 +246,237 @@ void JA_FadeOutMusic(const int milliseconds) { fade_initial_volume = JA_musicVolume; } -JA_Music_state JA_GetMusicState() { - if (!JA_musicEnabled) - return JA_MUSIC_DISABLED; +JA_Music_state JA_GetMusicState() +{ + if (!JA_musicEnabled) return JA_MUSIC_DISABLED; + if (!current_music) return JA_MUSIC_INVALID; - if (current_music == NULL) - return JA_MUSIC_INVALID; return current_music->state; } -void JA_DeleteMusic(JA_Music_t* music) { - if (current_music == music) - current_music = NULL; - free(music->output); +void JA_DeleteMusic(JA_Music_t *music) +{ + if (current_music == music) current_music = nullptr; + SDL_free(music->buffer); + if (music->stream) SDL_DestroyAudioStream(music->stream); delete music; } -int JA_SetMusicVolume(int volume) { - JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 - : volume; +float JA_SetMusicVolume(float volume) +{ + JA_musicVolume = SDL_clamp( volume, 0.0f, 1.0f ); + if (current_music) SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume); return JA_musicVolume; } -void JA_SetMusicPosition(float value) { - if (!current_music) - return; - current_music->pos = value * JA_freq; +void JA_SetMusicPosition(float value) +{ + if (!current_music) return; + current_music->pos = value * current_music->spec.freq; } -float JA_GetMusicPosition() { - if (!current_music) - return 0; - return float(current_music->pos) / float(JA_freq); +float JA_GetMusicPosition() +{ + if (!current_music) return 0; + return float(current_music->pos)/float(current_music->spec.freq); } -void JA_EnableMusic(const bool value) { - if (!value && current_music != NULL && current_music->state == JA_MUSIC_PLAYING) - JA_StopMusic(); +void JA_EnableMusic(const bool value) +{ + if ( !value && current_music && (current_music->state==JA_MUSIC_PLAYING) ) JA_StopMusic(); JA_musicEnabled = value; } -JA_Sound_t* JA_NewSound(Uint8* buffer, Uint32 length) { - JA_Sound_t* sound = new JA_Sound_t(); + + + + +JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) +{ + JA_Sound_t *sound = new JA_Sound_t(); sound->buffer = buffer; sound->length = length; return sound; } -JA_Sound_t* JA_LoadSound(uint8_t* buffer, uint32_t size) { - JA_Sound_t* sound = new JA_Sound_t(); - SDL_AudioSpec wavSpec; - SDL_LoadWAV_RW(SDL_RWFromMem(buffer, size), 1, &wavSpec, &sound->buffer, &sound->length); - - SDL_AudioCVT cvt; - SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq); - cvt.len = sound->length; - cvt.buf = (Uint8*)SDL_malloc(cvt.len * cvt.len_mult); - SDL_memcpy(cvt.buf, sound->buffer, sound->length); - SDL_ConvertAudio(&cvt); - SDL_FreeWAV(sound->buffer); - sound->buffer = cvt.buf; - sound->length = cvt.len_cvt; +JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size) +{ + JA_Sound_t *sound = new JA_Sound_t(); + SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size),1, &sound->spec, &sound->buffer, &sound->length); return sound; } -JA_Sound_t* JA_LoadSound(const char* filename) { - JA_Sound_t* sound = new JA_Sound_t(); - SDL_AudioSpec wavSpec; - SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length); - - SDL_AudioCVT cvt; - SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq); - cvt.len = sound->length; - cvt.buf = (Uint8*)SDL_malloc(cvt.len * cvt.len_mult); - SDL_memcpy(cvt.buf, sound->buffer, sound->length); - SDL_ConvertAudio(&cvt); - SDL_FreeWAV(sound->buffer); - sound->buffer = cvt.buf; - sound->length = cvt.len_cvt; +JA_Sound_t *JA_LoadSound(const char* filename) +{ + JA_Sound_t *sound = new JA_Sound_t(); + SDL_LoadWAV(filename, &sound->spec, &sound->buffer, &sound->length); return sound; } -int JA_PlaySound(JA_Sound_t* sound, const int loop) { - if (!JA_soundEnabled) - return -1; +int JA_PlaySound(JA_Sound_t *sound, const int loop, const int group) +{ + if (!JA_soundEnabled) return -1; int channel = 0; - while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { - channel++; - } - if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) - channel = 0; + while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } + if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0; + JA_StopChannel(channel); channels[channel].sound = sound; channels[channel].times = loop; channels[channel].pos = 0; channels[channel].state = JA_CHANNEL_PLAYING; + channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &JA_audioSpec); + SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length); + SDL_SetAudioStreamGain(channels[channel].stream, JA_soundVolume[group]); + SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream); + return channel; } -int JA_PlaySoundOnChannel(JA_Sound_t* sound, const int channel, const int loop) { - if (!JA_soundEnabled) - return -1; +int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop, const int group) +{ + if (!JA_soundEnabled) return -1; - if (channel >= JA_MAX_SIMULTANEOUS_CHANNELS) - return -1; + if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return -1; + JA_StopChannel(channel); channels[channel].sound = sound; channels[channel].times = loop; channels[channel].pos = 0; channels[channel].state = JA_CHANNEL_PLAYING; + channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &JA_audioSpec); + SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length); + SDL_SetAudioStreamGain(channels[channel].stream, JA_soundVolume[group]); + SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream); + return channel; } -void JA_DeleteSound(JA_Sound_t* sound) { +void JA_DeleteSound(JA_Sound_t *sound) +{ for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].sound == sound) - JA_StopChannel(i); + if (channels[i].sound == sound) JA_StopChannel(i); } SDL_free(sound->buffer); delete sound; } -void JA_PauseChannel(const int channel) { - if (!JA_soundEnabled) - return; +void JA_PauseChannel(const int channel) +{ + if (!JA_soundEnabled) return; - if (channel == -1) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { + if (channel == -1) + { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) if (channels[i].state == JA_CHANNEL_PLAYING) + { channels[i].state = JA_CHANNEL_PAUSED; - } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { + //SDL_PauseAudioStreamDevice(channels[i].stream); + SDL_UnbindAudioStream(channels[i].stream); + } + } + else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) + { if (channels[channel].state == JA_CHANNEL_PLAYING) + { channels[channel].state = JA_CHANNEL_PAUSED; - } -} - -void JA_ResumeChannel(const int channel) { - if (!JA_soundEnabled) - return; - - if (channel == -1) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].state == JA_CHANNEL_PAUSED) - channels[i].state = JA_CHANNEL_PLAYING; + //SDL_PauseAudioStreamDevice(channels[channel].stream); + SDL_UnbindAudioStream(channels[channel].stream); } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { - if (channels[channel].state == JA_CHANNEL_PAUSED) - channels[channel].state = JA_CHANNEL_PLAYING; } } -void JA_StopChannel(const int channel) { - if (!JA_soundEnabled) - return; +void JA_ResumeChannel(const int channel) +{ + if (!JA_soundEnabled) return; - if (channel == -1) { + if (channel == -1) + { + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) + if (channels[i].state == JA_CHANNEL_PAUSED) + { + channels[i].state = JA_CHANNEL_PLAYING; + //SDL_ResumeAudioStreamDevice(channels[i].stream); + SDL_BindAudioStream(sdlAudioDevice, channels[i].stream); + } + } + else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) + { + if (channels[channel].state == JA_CHANNEL_PAUSED) + { + channels[channel].state = JA_CHANNEL_PLAYING; + //SDL_ResumeAudioStreamDevice(channels[channel].stream); + SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream); + } + } +} + +void JA_StopChannel(const int channel) +{ + if (!JA_soundEnabled) return; + + if (channel == -1) + { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { + if (channels[i].state != JA_CHANNEL_FREE) SDL_DestroyAudioStream(channels[i].stream); + channels[i].stream = nullptr; channels[i].state = JA_CHANNEL_FREE; channels[i].pos = 0; channels[i].sound = NULL; } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { + } + else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) + { + if (channels[channel].state != JA_CHANNEL_FREE) SDL_DestroyAudioStream(channels[channel].stream); + channels[channel].stream = nullptr; channels[channel].state = JA_CHANNEL_FREE; channels[channel].pos = 0; channels[channel].sound = NULL; } } -JA_Channel_state JA_GetChannelState(const int channel) { - if (!JA_soundEnabled) - return JA_SOUND_DISABLED; +JA_Channel_state JA_GetChannelState(const int channel) +{ + if (!JA_soundEnabled) return JA_SOUND_DISABLED; + + if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID; - if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) - return JA_CHANNEL_INVALID; return channels[channel].state; } -int JA_SetSoundVolume(int volume) { - JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 - : volume; - return JA_soundVolume; +float JA_SetSoundVolume(float volume, const int group) +{ + const float v = SDL_clamp( volume, 0.0f, 1.0f ); + for (int i = 0; i < JA_MAX_GROUPS; ++i) { + if (group==-1 || group==i) JA_soundVolume[i]=v; + } + + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) + if ( ((channels[i].state == JA_CHANNEL_PLAYING) || (channels[i].state == JA_CHANNEL_PAUSED)) && + ((group==-1) || (channels[i].group==group)) ) + SDL_SetAudioStreamGain(channels[i].stream, JA_soundVolume[i]); + + return v; } -void JA_EnableSound(const bool value) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].state == JA_CHANNEL_PLAYING) - JA_StopChannel(i); +void JA_EnableSound(const bool value) +{ + for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) + { + if (channels[i].state == JA_CHANNEL_PLAYING) JA_StopChannel(i); } JA_soundEnabled = value; } -int JA_SetVolume(int volume) { - JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 - : volume; - JA_soundVolume = JA_musicVolume / 2; +float JA_SetVolume(float volume) +{ + JA_SetSoundVolume(JA_SetMusicVolume(volume) / 2.0f); + return JA_musicVolume; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/source/external/jail_audio.h b/source/external/jail_audio.h index a242bae..6cf3335 100644 --- a/source/external/jail_audio.h +++ b/source/external/jail_audio.h @@ -1,55 +1,44 @@ #pragma once #include -struct JA_Music_t; // lines 5-5 -struct JA_Sound_t; // lines 6-6 -enum JA_Channel_state { - JA_CHANNEL_INVALID, - JA_CHANNEL_FREE, - JA_CHANNEL_PLAYING, - JA_CHANNEL_PAUSED, - JA_SOUND_DISABLED -}; -enum JA_Music_state { - JA_MUSIC_INVALID, - JA_MUSIC_PLAYING, - JA_MUSIC_PAUSED, - JA_MUSIC_STOPPED, - JA_MUSIC_DISABLED -}; +enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED, JA_SOUND_DISABLED }; +enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED }; struct JA_Sound_t; struct JA_Music_t; -void JA_Init(const int freq, const SDL_AudioFormat format, const int channels); +void JA_Update(); + +void JA_Init(const int freq, const SDL_AudioFormat format, const int num_channels); void JA_Quit(); -JA_Music_t* JA_LoadMusic(const char* filename); -JA_Music_t* JA_LoadMusic(Uint8* buffer, Uint32 length); -void JA_PlayMusic(JA_Music_t* music, const int loop = -1); +JA_Music_t *JA_LoadMusic(const char* filename); +JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length); +void JA_PlayMusic(JA_Music_t *music, const int loop = -1); +char *JA_GetMusicFilename(JA_Music_t *music = nullptr); void JA_PauseMusic(); void JA_ResumeMusic(); void JA_StopMusic(); void JA_FadeOutMusic(const int milliseconds); JA_Music_state JA_GetMusicState(); -void JA_DeleteMusic(JA_Music_t* music); -int JA_SetMusicVolume(int volume); +void JA_DeleteMusic(JA_Music_t *music); +float JA_SetMusicVolume(float volume); void JA_SetMusicPosition(float value); float JA_GetMusicPosition(); void JA_EnableMusic(const bool value); -JA_Sound_t* JA_NewSound(Uint8* buffer, Uint32 length); -JA_Sound_t* JA_LoadSound(Uint8* buffer, Uint32 length); -JA_Sound_t* JA_LoadSound(const char* filename); -int JA_PlaySound(JA_Sound_t* sound, const int loop = 0); -int JA_PlaySoundOnChannel(JA_Sound_t* sound, const int channel, const int loop = 0); +JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length); +JA_Sound_t *JA_LoadSound(Uint8* buffer, Uint32 length); +JA_Sound_t *JA_LoadSound(const char* filename); +int JA_PlaySound(JA_Sound_t *sound, const int loop = 0, const int group=0); +int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop = 0, const int group=0); void JA_PauseChannel(const int channel); void JA_ResumeChannel(const int channel); void JA_StopChannel(const int channel); JA_Channel_state JA_GetChannelState(const int channel); -void JA_DeleteSound(JA_Sound_t* sound); -int JA_SetSoundVolume(int volume); +void JA_DeleteSound(JA_Sound_t *sound); +float JA_SetSoundVolume(float volume, const int group=0); void JA_EnableSound(const bool value); -int JA_SetVolume(int volume); +float JA_SetVolume(float volume); diff --git a/source/external/jail_shader.cpp b/source/external/jail_shader.cpp index 0c89e0e..1861745 100644 --- a/source/external/jail_shader.cpp +++ b/source/external/jail_shader.cpp @@ -25,8 +25,8 @@ SDL_Window* win = nullptr; SDL_Renderer* renderer = nullptr; GLuint programId = 0; SDL_Texture* backBuffer = nullptr; -SDL_Point win_size = {320 * 4, 256 * 4}; -SDL_Point tex_size = {320, 256}; +SDL_FPoint win_size = {320 * 4, 256 * 4}; +SDL_FPoint tex_size = {320, 256}; bool usingOpenGL = false; #ifndef __APPLE__ diff --git a/source/external/stb_vorbis.c b/source/external/stb_vorbis.h similarity index 100% rename from source/external/stb_vorbis.c rename to source/external/stb_vorbis.h diff --git a/source/global_events.cpp b/source/global_events.cpp index f005925..01b732e 100644 --- a/source/global_events.cpp +++ b/source/global_events.cpp @@ -8,13 +8,13 @@ namespace globalEvents void check(const SDL_Event &event) { // Evento de salida de la aplicación - if (event.type == SDL_QUIT) + if (event.type == SDL_EVENT_QUIT) { options.section.section = Section::QUIT; return; } - if (event.type == SDL_RENDER_DEVICE_RESET || event.type == SDL_RENDER_TARGETS_RESET) + if (event.type == SDL_EVENT_RENDER_DEVICE_RESET || event.type == SDL_EVENT_RENDER_TARGETS_RESET) { // reLoadTextures(); } diff --git a/source/global_inputs.cpp b/source/global_inputs.cpp index a50c7fd..a010a99 100644 --- a/source/global_inputs.cpp +++ b/source/global_inputs.cpp @@ -60,7 +60,7 @@ void check() { else if (Input::get()->checkInput(InputAction::TOGGLE_VIDEOMODE, INPUT_DO_NOT_ALLOW_REPEAT)) { Screen::get()->toggleVideoMode(); - Notifier::get()->show({"FULLSCREEN " + std::string(options.video.mode == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER); + Notifier::get()->show({"FULLSCREEN " + std::string(options.video.fullscreen == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER); } else if (Input::get()->checkInput(InputAction::WINDOW_DEC_ZOOM, INPUT_DO_NOT_ALLOW_REPEAT)) { @@ -91,9 +91,8 @@ void check() { } else if (Input::get()->checkInput(InputAction::TOGGLE_INTEGER_SCALE, INPUT_DO_NOT_ALLOW_REPEAT)) { - options.video.integer_scale = !options.video.integer_scale; - SDL_RenderSetIntegerScale(Screen::get()->getRenderer(), options.video.integer_scale ? SDL_TRUE : SDL_FALSE); - Screen::get()->setVideoMode(options.video.mode); + Screen::get()->toggleIntegerScale(); + Screen::get()->setVideoMode(options.video.fullscreen); Notifier::get()->show({"INTEGER SCALE " + std::string(options.video.integer_scale ? "ENABLED" : "DISABLED")}, NotificationText::CENTER); } diff --git a/source/input.cpp b/source/input.cpp index 0b1ad35..1cac197 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -46,7 +46,7 @@ void Input::bindKey(InputAction input, SDL_Scancode code) { } // Asigna inputs a botones del mando -void Input::bindGameControllerButton(int controller_index, InputAction input, SDL_GameControllerButton button) { +void Input::bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button) { if (controller_index < num_gamepads_) { controller_bindings_.at(controller_index).at(static_cast(input)).button = button; } @@ -66,20 +66,20 @@ bool Input::checkInput(InputAction input, bool repeat, InputDeviceToUse device, const int input_index = static_cast(input); if (device == InputDeviceToUse::KEYBOARD || device == InputDeviceToUse::ANY) { - const Uint8* keyStates = SDL_GetKeyboardState(nullptr); + auto key_states = SDL_GetKeyboardState(nullptr); if (repeat) { - success_keyboard = keyStates[key_bindings_[input_index].scancode] != 0; + success_keyboard = key_states[key_bindings_[input_index].scancode] != 0; } else { if (!key_bindings_[input_index].active) { - if (keyStates[key_bindings_[input_index].scancode] != 0) { + if (key_states[key_bindings_[input_index].scancode] != 0) { key_bindings_[input_index].active = true; success_keyboard = true; } else { success_keyboard = false; } } else { - if (keyStates[key_bindings_[input_index].scancode] == 0) { + if (key_states[key_bindings_[input_index].scancode] == 0) { key_bindings_[input_index].active = false; } success_keyboard = false; @@ -93,17 +93,17 @@ bool Input::checkInput(InputAction input, bool repeat, InputDeviceToUse device, if (!success_controller) { if (repeat) { - success_controller = SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0; + success_controller = SDL_GetGamepadButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0; } else { if (!controller_bindings_.at(controller_index).at(input_index).active) { - if (SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0) { + if (SDL_GetGamepadButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0) { controller_bindings_.at(controller_index).at(input_index).active = true; success_controller = true; } else { success_controller = false; } } else { - if (SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) == 0) { + if (SDL_GetGamepadButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) == 0) { controller_bindings_.at(controller_index).at(input_index).active = false; } success_controller = false; @@ -119,10 +119,10 @@ bool Input::checkInput(InputAction input, bool repeat, InputDeviceToUse device, // Comprueba si hay almenos un input activo bool Input::checkAnyInput(InputDeviceToUse device, int controller_index) { if (device == InputDeviceToUse::KEYBOARD || device == InputDeviceToUse::ANY) { - const Uint8* mKeystates = SDL_GetKeyboardState(nullptr); + const bool *key_states = SDL_GetKeyboardState(nullptr); for (int i = 0; i < (int)key_bindings_.size(); ++i) { - if (mKeystates[key_bindings_[i].scancode] != 0 && !key_bindings_[i].active) { + if (key_states[key_bindings_[i].scancode] != 0 && !key_bindings_[i].active) { key_bindings_[i].active = true; return true; } @@ -132,7 +132,7 @@ bool Input::checkAnyInput(InputDeviceToUse device, int controller_index) { if (gameControllerFound()) { if (device == InputDeviceToUse::CONTROLLER || device == InputDeviceToUse::ANY) { for (int i = 0; i < (int)controller_bindings_.size(); ++i) { - if (SDL_GameControllerGetButton(connected_controllers_[controller_index], controller_bindings_[controller_index][i].button) != 0 && !controller_bindings_[controller_index][i].active) { + if (SDL_GetGamepadButton(connected_controllers_[controller_index], controller_bindings_[controller_index][i].button) != 0 && !controller_bindings_[controller_index][i].active) { controller_bindings_[controller_index][i].active = true; return true; } @@ -147,23 +147,32 @@ bool Input::checkAnyInput(InputDeviceToUse device, int controller_index) { bool Input::discoverGameControllers() { bool found = false; - if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1) { - SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); + // Asegúrate de que el subsistema de gamepads está inicializado + if (SDL_WasInit(SDL_INIT_GAMEPAD) != 1) { + SDL_InitSubSystem(SDL_INIT_GAMEPAD); } - if (SDL_GameControllerAddMappingsFromFile(game_controller_db_path_.c_str()) < 0) { - std::cout << "Error, could not load " << game_controller_db_path_.c_str() << " file: " << SDL_GetError() << std::endl; + // Carga el mapping de mandos desde archivo + if (SDL_AddGamepadMappingsFromFile(game_controller_db_path_.c_str()) < 0) { + std::cout << "Error, could not load " << game_controller_db_path_.c_str() + << " file: " << SDL_GetError() << std::endl; } - num_joysticks_ = SDL_NumJoysticks(); + // En SDL3 ya no existe SDL_NumJoysticks() + // Ahora se obtiene un array dinámico de IDs + int num_joysticks = 0; + SDL_JoystickID* joystick_ids = SDL_GetJoysticks(&num_joysticks); + + num_joysticks_ = num_joysticks; num_gamepads_ = 0; - - // Cuenta el número de mandos joysticks_.clear(); + + // Recorremos todos los joysticks detectados for (int i = 0; i < num_joysticks_; ++i) { - auto joy = SDL_JoystickOpen(i); + SDL_Joystick* joy = SDL_OpenJoystick(joystick_ids[i]); joysticks_.push_back(joy); - if (SDL_IsGameController(i)) { + + if (SDL_IsGamepad(joystick_ids[i])) { num_gamepads_++; } } @@ -179,26 +188,32 @@ bool Input::discoverGameControllers() { if (num_gamepads_ > 0) { found = true; - for (int i = 0; i < num_gamepads_; i++) { - // Abre el mando y lo añade a la lista - auto pad = SDL_GameControllerOpen(i); - if (SDL_GameControllerGetAttached(pad) == 1) { - connected_controllers_.push_back(pad); - const std::string name = SDL_GameControllerNameForIndex(i); - std::cout << "#" << i << ": " << name << std::endl; - controller_names_.push_back(name); - } else { - std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl; + for (int i = 0; i < num_joysticks_; i++) { + if (SDL_IsGamepad(joystick_ids[i])) { + SDL_Gamepad* pad = SDL_OpenGamepad(joystick_ids[i]); + if (pad && SDL_GamepadConnected(pad)) { + connected_controllers_.push_back(pad); + + const char* name = SDL_GetGamepadName(pad); + std::cout << "#" << i << ": " << (name ? name : "Unknown") << std::endl; + controller_names_.push_back(name ? name : "Unknown"); + } else { + std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl; + } } } - SDL_GameControllerEventState(SDL_ENABLE); + // En SDL3 ya no hace falta SDL_GameControllerEventState() + // Los eventos de gamepad están siempre habilitados } + SDL_free(joystick_ids); + std::cout << "\n** FINISHED LOOKING FOR GAME CONTROLLERS" << std::endl; return found; } + // Comprueba si hay algun mando conectado bool Input::gameControllerFound() { return num_gamepads_ > 0 ? true : false; } @@ -211,15 +226,15 @@ int Input::getNumControllers() const { return num_gamepads_; } // Obtiene el indice del controlador a partir de un event.id int Input::getJoyIndex(int id) const { for (int i = 0; i < num_joysticks_; ++i) { - if (SDL_JoystickInstanceID(joysticks_[i]) == id) { + if (SDL_GetJoystickID(joysticks_[i]) == id) { return i; } } return -1; } -// Obtiene el SDL_GameControllerButton asignado a un input -SDL_GameControllerButton Input::getControllerBinding(int controller_index, InputAction input) const { +// Obtiene el SDL_GamepadButton asignado a un input +SDL_GamepadButton Input::getControllerBinding(int controller_index, InputAction input) const { return controller_bindings_[controller_index][static_cast(input)].button; } @@ -237,16 +252,16 @@ bool Input::checkAxisInput(InputAction input, int controller_index, bool repeat) switch (input) { case InputAction::LEFT: - axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTX) < -threshold; + axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) < -threshold; break; case InputAction::RIGHT: - axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTX) > threshold; + axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) > threshold; break; case InputAction::UP: - axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTY) < -threshold; + axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) < -threshold; break; case InputAction::DOWN: - axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTY) > threshold; + axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) > threshold; break; default: return false; diff --git a/source/input.h b/source/input.h index 194804b..f4a61ec 100644 --- a/source/input.h +++ b/source/input.h @@ -61,19 +61,19 @@ class Input { }; struct ControllerBindings { - SDL_GameControllerButton button; // GameControllerButton asociado + SDL_GamepadButton button; // GameControllerButton asociado bool active; // Indica si está activo bool axis_active; // Estado del eje // Constructor - explicit ControllerBindings(SDL_GameControllerButton btn = SDL_CONTROLLER_BUTTON_INVALID, bool act = false, bool axis_act = false) + explicit ControllerBindings(SDL_GamepadButton btn = SDL_GAMEPAD_BUTTON_INVALID, bool act = false, bool axis_act = false) : button(btn), active(act), axis_active(axis_act) {} }; // Variables - std::vector connected_controllers_; // Vector con todos los mandos conectados + std::vector connected_controllers_; // Vector con todos los mandos conectados std::vector joysticks_; // Vector con todos los joysticks conectados std::vector key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos std::vector> controller_bindings_; // Vector con los botones asociadas a los inputs predefinidos para cada mando @@ -106,7 +106,7 @@ class Input { void bindKey(InputAction input, SDL_Scancode code); // Asigna inputs a botones del mando - void bindGameControllerButton(int controller_index, InputAction input, SDL_GameControllerButton button); + void bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button); void bindGameControllerButton(int controller_index, InputAction inputTarget, InputAction inputSource); // Comprueba si un input esta activo @@ -130,8 +130,8 @@ class Input { // Obtiene el indice del controlador a partir de un event.id int getJoyIndex(int id) const; - // Obtiene el SDL_GameControllerButton asignado a un input - SDL_GameControllerButton getControllerBinding(int controller_index, InputAction input) const; + // Obtiene el SDL_GamepadButton asignado a un input + SDL_GamepadButton getControllerBinding(int controller_index, InputAction input) const; // Obtiene el indice a partir del nombre del mando int getIndexByName(const std::string& name) const; diff --git a/source/item.cpp b/source/item.cpp index 0dd88d6..b9d4b6f 100644 --- a/source/item.cpp +++ b/source/item.cpp @@ -27,8 +27,8 @@ void Item::render() { } // Obtiene su ubicación -SDL_Point Item::getPos() { - const SDL_Point p = {sprite_->getX(), sprite_->getY()}; +SDL_FPoint Item::getPos() { + const SDL_FPoint p = {sprite_->getX(), sprite_->getY()}; return p; } diff --git a/source/item.h b/source/item.h index 943cd46..3c33422 100644 --- a/source/item.h +++ b/source/item.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include // Para shared_ptr #include // Para string @@ -37,7 +37,7 @@ class Item { // Variables std::vector color_; // Vector con los colores del objeto int counter_; // Contador interno - SDL_Rect collider_; // Rectangulo de colisión + SDL_FRect collider_; // Rectangulo de colisión int change_color_speed; // Cuanto mas alto, mas tarda en cambiar de color public: @@ -54,10 +54,10 @@ class Item { void update() { counter_++; } // Obtiene el rectangulo de colision del objeto - SDL_Rect& getCollider() { return collider_; } + SDL_FRect& getCollider() { return collider_; } // Obtiene su ubicación - SDL_Point getPos(); + SDL_FPoint getPos(); // Asigna los colores del objeto void setColors(Uint8 col1, Uint8 col2); diff --git a/source/item_tracker.cpp b/source/item_tracker.cpp index 0a43a5a..43a8141 100644 --- a/source/item_tracker.cpp +++ b/source/item_tracker.cpp @@ -1,35 +1,29 @@ #include "item_tracker.h" // [SINGLETON] -ItemTracker *ItemTracker::item_tracker_ = nullptr; +ItemTracker* ItemTracker::item_tracker_ = nullptr; // [SINGLETON] Crearemos el objeto con esta función estática -void ItemTracker::init() -{ +void ItemTracker::init() { ItemTracker::item_tracker_ = new ItemTracker(); } // [SINGLETON] Destruiremos el objeto con esta función estática -void ItemTracker::destroy() -{ +void ItemTracker::destroy() { delete ItemTracker::item_tracker_; } // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él -ItemTracker *ItemTracker::get() -{ +ItemTracker* ItemTracker::get() { return ItemTracker::item_tracker_; } // Comprueba si el objeto ya ha sido cogido -bool ItemTracker::hasBeenPicked(const std::string &name, SDL_Point pos) -{ +bool ItemTracker::hasBeenPicked(const std::string& name, SDL_FPoint pos) { // Primero busca si ya hay una entrada con ese nombre - if (const int index = findByName(name); index != -1) - { + if (const int index = findByName(name); index != -1) { // Luego busca si existe ya una entrada con esa posición - if (findByPos(index, pos) != -1) - { + if (findByPos(index, pos) != -1) { return true; } } @@ -38,33 +32,26 @@ bool ItemTracker::hasBeenPicked(const std::string &name, SDL_Point pos) } // Añade el objeto a la lista de objetos cogidos -void ItemTracker::addItem(const std::string &name, SDL_Point pos) -{ +void ItemTracker::addItem(const std::string& name, SDL_FPoint pos) { // Comprueba si el objeto no ha sido recogido con anterioridad - if (!hasBeenPicked(name, pos)) - { + if (!hasBeenPicked(name, pos)) { // Primero busca si ya hay una entrada con ese nombre - if (const int index = findByName(name); index != -1) - { + if (const int index = findByName(name); index != -1) { item_list_.at(index).pos.push_back(pos); } // En caso contrario crea la entrada - else - { + else { item_list_.emplace_back(name, pos); } } } // Busca una entrada en la lista por nombre -int ItemTracker::findByName(const std::string &name) -{ +int ItemTracker::findByName(const std::string& name) { int i = 0; - for (const auto &l : item_list_) - { - if (l.name == name) - { + for (const auto& l : item_list_) { + if (l.name == name) { return i; } i++; @@ -74,14 +61,11 @@ int ItemTracker::findByName(const std::string &name) } // Busca una entrada en la lista por posición -int ItemTracker::findByPos(int index, SDL_Point pos) -{ +int ItemTracker::findByPos(int index, SDL_FPoint pos) { int i = 0; - for (const auto &l : item_list_[index].pos) - { - if ((l.x == pos.x) && (l.y == pos.y)) - { + for (const auto& l : item_list_[index].pos) { + if ((l.x == pos.x) && (l.y == pos.y)) { return i; } i++; diff --git a/source/item_tracker.h b/source/item_tracker.h index db4f69d..6f2b94d 100644 --- a/source/item_tracker.h +++ b/source/item_tracker.h @@ -1,16 +1,16 @@ #pragma once -#include +#include #include // Para string, basic_string #include // Para vector struct ItemTrackerData { - std::string name; // Nombre de la habitación donde se encuentra el objeto - std::vector pos; // Lista de objetos cogidos de la habitación + std::string name; // Nombre de la habitación donde se encuentra el objeto + std::vector pos; // Lista de objetos cogidos de la habitación // Constructor - ItemTrackerData(const std::string& name, const SDL_Point& position) + ItemTrackerData(const std::string& name, const SDL_FPoint& position) : name(name) { pos.push_back(position); } @@ -28,7 +28,7 @@ class ItemTracker { int findByName(const std::string& name); // Busca una entrada en la lista por posición - int findByPos(int index, SDL_Point pos); + int findByPos(int index, SDL_FPoint pos); // Constructor ItemTracker() = default; @@ -47,8 +47,8 @@ class ItemTracker { static ItemTracker* get(); // Comprueba si el objeto ya ha sido cogido - bool hasBeenPicked(const std::string& name, SDL_Point pos); + bool hasBeenPicked(const std::string& name, SDL_FPoint pos); // Añade el objeto a la lista de objetos cogidos - void addItem(const std::string& name, SDL_Point pos); + void addItem(const std::string& name, SDL_FPoint pos); }; \ No newline at end of file diff --git a/source/mouse.cpp b/source/mouse.cpp index 7169b8a..dea2f6f 100644 --- a/source/mouse.cpp +++ b/source/mouse.cpp @@ -7,10 +7,10 @@ Uint32 last_mouse_move_time = 0; // Última vez que el ratón se movió bool cursor_visible = true; // Estado del cursor void handleEvent(const SDL_Event& event) { - if (event.type == SDL_MOUSEMOTION) { + if (event.type == SDL_EVENT_MOUSE_MOTION) { last_mouse_move_time = SDL_GetTicks(); if (!cursor_visible) { - SDL_ShowCursor(SDL_ENABLE); + SDL_ShowCursor(); cursor_visible = true; } } @@ -19,7 +19,7 @@ void handleEvent(const SDL_Event& event) { void updateCursorVisibility() { Uint32 current_time = SDL_GetTicks(); if (cursor_visible && (current_time - last_mouse_move_time > cursor_hide_time)) { - SDL_ShowCursor(SDL_DISABLE); + SDL_HideCursor(); cursor_visible = false; } } diff --git a/source/options.cpp b/source/options.cpp index 16634c7..2b88632 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -1,6 +1,6 @@ #include "options.h" -#include +#include #include // Para find_if #include // Para isspace @@ -131,7 +131,7 @@ bool saveOptionsToFile(const std::string& file_path) { file << "\n## VIDEO\n"; file << "# Modo de video: 0 = Ventana, 1 = Pantalla completa, 2 = Pantalla completa (escritorio)\n"; - file << "video.mode " << options.video.mode << "\n\n"; + file << "video.mode " << options.video.fullscreen << "\n\n"; file << "# Filtro de pantalla: 0 = Nearest, 1 = Linear\n"; file << "video.filter " << static_cast(options.video.filter) << "\n\n"; file << "# Shaders: 1 = Activado, 0 = Desactivado\n"; @@ -176,14 +176,7 @@ bool setOptions(const std::string& var, const std::string& value) { options.window.zoom = DEFAULT_WINDOW_ZOOM; } }}, - {"video.mode", [](const std::string& v) { - int val = safeStoi(v, 0); - if (val == 0 || val == SDL_WINDOW_FULLSCREEN_DESKTOP) { - options.video.mode = val; - } else { - options.video.mode = 0; - } - }}, + {"video.mode", [](const std::string& v) { options.video.fullscreen = stringToBool(v); }}, {"video.filter", [](const std::string& v) { int val = safeStoi(v, static_cast(DEFAULT_VIDEO_FILTER)); if (val == static_cast(ScreenFilter::NEAREST) || val == static_cast(ScreenFilter::LINEAR)) { diff --git a/source/options.h b/source/options.h index 2b1e575..9dd3e90 100644 --- a/source/options.h +++ b/source/options.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include // Para string, basic_string @@ -58,7 +58,7 @@ enum class ControlScheme { constexpr int DEFAULT_GAME_WIDTH = 256; // Ancho de la ventana por defecto constexpr int DEFAULT_GAME_HEIGHT = 192; // Alto de la ventana por defecto constexpr int DEFAULT_WINDOW_ZOOM = 2; // Zoom de la ventana por defecto -constexpr int DEFAULT_VIDEO_MODE = 0; // Modo de pantalla completa por defecto +constexpr bool DEFAULT_VIDEO_MODE = false; // Modo de pantalla completa por defecto constexpr ScreenFilter DEFAULT_VIDEO_FILTER = ScreenFilter::NEAREST; // Filtro por defecto constexpr bool DEFAULT_VIDEO_VERTICAL_SYNC = true; // Vsync activado por defecto constexpr bool DEFAULT_VIDEO_SHADERS = false; // Shaders desactivados por defecto @@ -225,8 +225,8 @@ struct OptionsWindow { // Estructura para gestionar el borde de la pantalla struct Border { bool enabled; // Indica si se ha de mostrar el borde - int width; // Ancho del borde - int height; // Alto del borde + float width; // Ancho del borde + float height; // Alto del borde // Constructor por defecto Border() @@ -235,7 +235,7 @@ struct Border { height(DEFAULT_BORDER_HEIGHT) {} // Constructor - Border(bool e, int w, int h) + Border(bool e, float w, float h) : enabled(e), width(w), height(h) {} @@ -243,7 +243,7 @@ struct Border { // Estructura para las opciones de video struct OptionsVideo { - Uint32 mode; // Contiene el valor del modo de pantalla completa + bool fullscreen; // Contiene el valor del modo de pantalla completa ScreenFilter filter; // Filtro usado para el escalado de la imagen bool vertical_sync; // Indica si se quiere usar vsync o no bool shaders; // Indica si se van a usar shaders o no @@ -254,7 +254,7 @@ struct OptionsVideo { // Constructor por defecto OptionsVideo() - : mode(DEFAULT_VIDEO_MODE), + : fullscreen(DEFAULT_VIDEO_MODE), filter(DEFAULT_VIDEO_FILTER), vertical_sync(DEFAULT_VIDEO_VERTICAL_SYNC), shaders(DEFAULT_VIDEO_SHADERS), @@ -265,7 +265,7 @@ struct OptionsVideo { // Constructor OptionsVideo(Uint32 m, ScreenFilter f, bool vs, bool s, bool is, bool ka, Border b, const std::string& p) - : mode(m), + : fullscreen(m), filter(f), vertical_sync(vs), shaders(s), @@ -353,8 +353,8 @@ struct OptionsAudio { // Estructura para las opciones de juego struct OptionsGame { - int width; // Ancho de la resolucion del juego - int height; // Alto de la resolucion del juego + float width; // Ancho de la resolucion del juego + float height; // Alto de la resolucion del juego // Constructor por defecto OptionsGame() @@ -362,7 +362,7 @@ struct OptionsGame { height(DEFAULT_GAME_HEIGHT) {} // Constructor - OptionsGame(int w, int h) + OptionsGame(float w, float h) : width(w), height(h) {} }; diff --git a/source/player.cpp b/source/player.cpp index 04ab49d..2e965ef 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -217,7 +217,7 @@ void Player::applyGravity() { // Recalcula la posición del jugador y su animación void Player::move() { - last_position_ = {static_cast(x_), static_cast(y_)}; // Guarda la posicion actual antes de modificarla + last_position_ = {x_, y_}; // Guarda la posicion actual antes de modificarla applyGravity(); // Aplica gravedad al jugador checkState(); // Comprueba el estado del jugador @@ -228,7 +228,7 @@ void Player::move() { // Se mueve hacia la izquierda if (vx_ < 0.0f) { // Crea el rectangulo de proyección en el eje X para ver si colisiona - SDL_Rect proj; + SDL_FRect proj; proj.x = static_cast(x_ + vx_); proj.y = static_cast(y_); proj.h = HEIGHT_; @@ -268,7 +268,7 @@ void Player::move() { // Se mueve hacia la derecha else if (vx_ > 0.0f) { // Crea el rectangulo de proyección en el eje X para ver si colisiona - SDL_Rect proj; + SDL_FRect proj; proj.x = static_cast(x_) + WIDTH_; proj.y = static_cast(y_); proj.h = HEIGHT_; @@ -322,7 +322,7 @@ void Player::move() { // Se mueve hacia arriba if (vy_ < 0.0f) { // Crea el rectangulo de proyección en el eje Y para ver si colisiona - SDL_Rect proj; + SDL_FRect proj; proj.x = static_cast(x_); proj.y = static_cast(y_ + vy_); proj.h = static_cast(std::ceil(std::fabs(vy_))); // Para evitar que tenga una altura de 0 pixels @@ -349,7 +349,7 @@ void Player::move() { // Se mueve hacia abajo else if (vy_ > 0.0f) { // Crea el rectangulo de proyección en el eje Y para ver si colisiona - SDL_Rect proj; + SDL_FRect proj; proj.x = static_cast(x_); proj.y = static_cast(y_) + HEIGHT_; proj.h = ceil(vy_); // Para evitar que tenga una altura de 0 pixels @@ -360,7 +360,7 @@ void Player::move() { #endif // Comprueba la colisión con las superficies normales y las automáticas - const int POS = std::max(room_->checkTopSurfaces(&proj), room_->checkAutoSurfaces(&proj)); + const float POS = std::max(room_->checkTopSurfaces(&proj), room_->checkAutoSurfaces(&proj)); if (POS > -1) { // Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie y_ = POS - HEIGHT_; @@ -373,7 +373,7 @@ void Player::move() { if (state_ != PlayerState::JUMPING) { // Las rampas no se miran si se está saltando const LineVertical LEFT_SIDE = {proj.x, proj.y, proj.y + proj.h - 1}; const LineVertical RIGHT_SIDE = {proj.x + proj.w - 1, proj.y, proj.y + proj.h - 1}; - const int POINT = std::max(room_->checkRightSlopes(&RIGHT_SIDE), room_->checkLeftSlopes(&LEFT_SIDE)); + const float POINT = std::max(room_->checkRightSlopes(&RIGHT_SIDE), room_->checkLeftSlopes(&LEFT_SIDE)); if (POINT > -1) { // No está saltando y hay colisión con una rampa // Calcula la nueva posición @@ -381,7 +381,7 @@ void Player::move() { setState(PlayerState::STANDING); #ifdef DEBUG debug_color_ = static_cast(PaletteColor::YELLOW); - debug_point_ = {(int)x_ + (WIDTH_ / 2), POINT}; + debug_point_ = {x_ + (WIDTH_ / 2), POINT}; #endif } else { // No está saltando y no hay colisón con una rampa @@ -559,7 +559,7 @@ void Player::setColor() { // Actualiza los puntos de colisión void Player::updateColliderPoints() { - const SDL_Rect rect = getRect(); + const SDL_FRect rect = getRect(); collider_points_[0] = {rect.x, rect.y}; collider_points_[1] = {rect.x + 7, rect.y}; collider_points_[2] = {rect.x + 7, rect.y + 7}; @@ -572,7 +572,7 @@ void Player::updateColliderPoints() { // Actualiza los puntos de los pies void Player::updateFeet() { - const SDL_Point p = {static_cast(x_), static_cast(y_)}; + const SDL_FPoint p = {x_, y_}; under_feet_[0] = {p.x, p.y + HEIGHT_}; under_feet_[1] = {p.x + 7, p.y + HEIGHT_}; @@ -637,7 +637,7 @@ void Player::renderDebugInfo() { surface->putPixel(under_feet_[1].x, under_feet_[1].y, static_cast(PaletteColor::BRIGHT_MAGENTA)); // Pinta rectangulo del jugador - SDL_Rect rect = getRect(); + SDL_FRect rect = getRect(); surface->drawRectBorder(&rect, static_cast(PaletteColor::BRIGHT_CYAN)); // Pinta el rectangulo de movimiento diff --git a/source/player.h b/source/player.h index 49f8e50..00637e6 100644 --- a/source/player.h +++ b/source/player.h @@ -25,7 +25,7 @@ struct PlayerSpawn { float vy; int jump_init_pos; PlayerState state; - SDL_RendererFlip flip; + SDL_FlipMode flip; // Constructor por defecto PlayerSpawn() @@ -38,7 +38,7 @@ struct PlayerSpawn { flip(SDL_FLIP_NONE) {} // Constructor - PlayerSpawn(float x, float y, float vx, float vy, int jump_init_pos, PlayerState state, SDL_RendererFlip flip) + PlayerSpawn(float x, float y, float vx, float vy, int jump_init_pos, PlayerState state, SDL_FlipMode flip) : x(x), y(y), vx(vx), @@ -75,34 +75,34 @@ class Player { std::shared_ptr sprite_; // Sprite del jugador // Variables - float x_; // Posición del jugador en el eje X - float y_; // Posición del jugador en el eje Y - float vx_; // Velocidad/desplazamiento del jugador en el eje X - float vy_; // Velocidad/desplazamiento del jugador en el eje Y - Uint8 color_; // Color del jugador - SDL_Rect collider_box_; // Caja de colisión con los enemigos u objetos - std::vector collider_points_; // Puntos de colisión con el mapa - std::vector under_feet_; // Contiene los puntos que hay bajo cada pie del jugador - std::vector feet_; // Contiene los puntos que hay en el pie del jugador - PlayerState state_; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo - PlayerState previous_state_; // Estado previo en el que se encontraba el jugador - bool is_on_border_ = false; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla - bool is_alive_ = true; // Indica si el jugador esta vivo o no - bool is_paused_ = false; // Indica si el jugador esta en modo pausa - bool auto_movement_ = false; // Indica si esta siendo arrastrado por una superficie automatica - RoomBorder border_ = RoomBorder::TOP; // Indica en cual de los cuatro bordes se encuentra - SDL_Rect last_position_; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento - int jump_init_pos_; // Valor del eje Y en el que se inicia el salto - std::vector jumping_sound_; // Vecor con todos los sonidos del salto - std::vector falling_sound_; // Vecor con todos los sonidos de la caída - int jumping_counter_ = 0; // Cuenta el tiempo de salto - int falling_counter_ = 0; // Cuenta el tiempo de caida + float x_; // Posición del jugador en el eje X + float y_; // Posición del jugador en el eje Y + float vx_; // Velocidad/desplazamiento del jugador en el eje X + float vy_; // Velocidad/desplazamiento del jugador en el eje Y + Uint8 color_; // Color del jugador + SDL_FRect collider_box_; // Caja de colisión con los enemigos u objetos + std::vector collider_points_; // Puntos de colisión con el mapa + std::vector under_feet_; // Contiene los puntos que hay bajo cada pie del jugador + std::vector feet_; // Contiene los puntos que hay en el pie del jugador + PlayerState state_; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo + PlayerState previous_state_; // Estado previo en el que se encontraba el jugador + bool is_on_border_ = false; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla + bool is_alive_ = true; // Indica si el jugador esta vivo o no + bool is_paused_ = false; // Indica si el jugador esta en modo pausa + bool auto_movement_ = false; // Indica si esta siendo arrastrado por una superficie automatica + RoomBorder border_ = RoomBorder::TOP; // Indica en cual de los cuatro bordes se encuentra + SDL_FRect last_position_; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento + int jump_init_pos_; // Valor del eje Y en el que se inicia el salto + std::vector jumping_sound_; // Vecor con todos los sonidos del salto + std::vector falling_sound_; // Vecor con todos los sonidos de la caída + int jumping_counter_ = 0; // Cuenta el tiempo de salto + int falling_counter_ = 0; // Cuenta el tiempo de caida #ifdef DEBUG - SDL_Rect debug_rect_x_; // Rectangulo de desplazamiento para el modo debug - SDL_Rect debug_rect_y_; // Rectangulo de desplazamiento para el modo debug - Uint8 debug_color_; // Color del recuadro de debug del jugador - SDL_Point debug_point_; // Punto para debug + SDL_FRect debug_rect_x_; // Rectangulo de desplazamiento para el modo debug + SDL_FRect debug_rect_y_; // Rectangulo de desplazamiento para el modo debug + Uint8 debug_color_; // Color del recuadro de debug del jugador + SDL_FPoint debug_point_; // Punto para debug #endif // Comprueba las entradas y modifica variables @@ -193,10 +193,10 @@ class Player { void switchBorders(); // Obtiene el rectangulo que delimita al jugador - SDL_Rect getRect() { return {static_cast(x_), static_cast(y_), WIDTH_, HEIGHT_}; } + SDL_FRect getRect() { return {static_cast(x_), static_cast(y_), WIDTH_, HEIGHT_}; } // Obtiene el rectangulo de colision del jugador - SDL_Rect& getCollider() { return collider_box_; } + SDL_FRect& getCollider() { return collider_box_; } // Obtiene el estado de reaparición del jugador PlayerSpawn getSpawnParams() { return {x_, y_, vx_, vy_, jump_init_pos_, state_, sprite_->getFlip()}; } diff --git a/source/resource.cpp b/source/resource.cpp index ed8acd9..dabe87a 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -373,20 +373,20 @@ void Resource::calculateTotal() { // Muestra el progreso de carga void Resource::renderProgress() { - constexpr int X_PADDING = 10; - constexpr int Y_PADDING = 10; - constexpr int BAR_HEIGHT = 10; - const int bar_position = options.game.height - BAR_HEIGHT - Y_PADDING; + constexpr float X_PADDING = 10; + constexpr float Y_PADDING = 10; + constexpr float BAR_HEIGHT = 10; + const float bar_position = options.game.height - BAR_HEIGHT - Y_PADDING; Screen::get()->start(); Screen::get()->clearSurface(static_cast(PaletteColor::BLACK)); auto surface = Screen::get()->getRendererSurface(); - const int wired_bar_width = options.game.width - (X_PADDING * 2); - SDL_Rect rect_wired = {X_PADDING, bar_position, wired_bar_width, X_PADDING}; + const float WIRED_BAR_WIDTH = options.game.width - (X_PADDING * 2); + SDL_FRect rect_wired = {X_PADDING, bar_position, WIRED_BAR_WIDTH, X_PADDING}; surface->drawRectBorder(&rect_wired, static_cast(PaletteColor::WHITE)); - const int full_bar_width = wired_bar_width * count_.getPercentage(); - SDL_Rect rect_full = {X_PADDING, bar_position, full_bar_width, X_PADDING}; + const float FULL_BAR_WIDTH = WIRED_BAR_WIDTH * count_.getPercentage(); + SDL_FRect rect_full = {X_PADDING, bar_position, FULL_BAR_WIDTH, X_PADDING}; surface->fillRect(&rect_full, static_cast(PaletteColor::WHITE)); Screen::get()->render(); @@ -397,11 +397,11 @@ void Resource::checkEvents() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { - case SDL_QUIT: + case SDL_EVENT_QUIT: exit(0); break; - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_ESCAPE) { + case SDL_EVENT_KEY_DOWN: + if (event.key.key == SDLK_ESCAPE) { exit(0); } break; diff --git a/source/room.cpp b/source/room.cpp index f7fc555..5355451 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -338,7 +338,7 @@ void Room::initializeRoom(const RoomData& room) { // Crear los items for (const auto& item : room.items) { - const SDL_Point itemPos = {item.x, item.y}; + const SDL_FPoint itemPos = {item.x, item.y}; if (!ItemTracker::get()->hasBeenPicked(room.name, itemPos)) { // Crear una copia local de los datos del item @@ -361,7 +361,7 @@ void Room::fillMapTexture() { // Los tileSetFiles son de 20x20 tiles. El primer tile es el 0. Cuentan hacia la derecha y hacia abajo - SDL_Rect clip = {0, 0, TILE_SIZE_, TILE_SIZE_}; + SDL_FRect clip = {0, 0, TILE_SIZE_, TILE_SIZE_}; for (int y = 0; y < MAP_HEIGHT_; ++y) for (int x = 0; x < MAP_WIDTH_; ++x) { // Tiled pone los tiles vacios del mapa como cero y empieza a contar de 1 a n. @@ -439,7 +439,7 @@ void Room::fillMapTexture() { // Dibuja el mapa en pantalla void Room::renderMap() { // Dibuja la textura con el mapa en pantalla - SDL_Rect dest = {0, 0, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT}; + SDL_FRect dest = {0, 0, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT}; map_surface_->render(nullptr, &dest); // Dibuja los tiles animados @@ -516,7 +516,7 @@ std::string Room::getRoom(RoomBorder border) { } // Devuelve el tipo de tile que hay en ese pixel -TileType Room::getTile(SDL_Point point) { +TileType Room::getTile(SDL_FPoint point) { const int pos = ((point.y / TILE_SIZE_) * MAP_WIDTH_) + (point.x / TILE_SIZE_); return getTile(pos); } @@ -562,7 +562,7 @@ TileType Room::getTile(int index) { } // Indica si hay colision con un enemigo a partir de un rectangulo -bool Room::enemyCollision(SDL_Rect& rect) { +bool Room::enemyCollision(SDL_FRect& rect) { for (const auto& enemy : enemies_) { if (checkCollision(rect, enemy->getCollider())) { return true; @@ -572,7 +572,7 @@ bool Room::enemyCollision(SDL_Rect& rect) { } // Indica si hay colision con un objeto a partir de un rectangulo -bool Room::itemCollision(SDL_Rect& rect) { +bool Room::itemCollision(SDL_FRect& rect) { for (int i = 0; i < static_cast(items_.size()); ++i) { if (checkCollision(rect, items_.at(i)->getCollider())) { ItemTracker::get()->addItem(name_, items_.at(i)->getPos()); @@ -588,7 +588,7 @@ bool Room::itemCollision(SDL_Rect& rect) { } // Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile -int Room::getSlopeHeight(SDL_Point p, TileType slope) { +int Room::getSlopeHeight(SDL_FPoint p, TileType slope) { // Calcula la base del tile int base = ((p.y / TILE_SIZE_) * TILE_SIZE_) + TILE_SIZE_; #ifdef DEBUG @@ -596,7 +596,7 @@ int Room::getSlopeHeight(SDL_Point p, TileType slope) { #endif // Calcula cuanto se ha entrado en el tile horizontalmente - const int pos = (p.x % TILE_SIZE_); // Esto da un valor entre 0 y 7 + const int pos = (static_cast(p.x) % TILE_SIZE_); // Esto da un valor entre 0 y 7 #ifdef DEBUG Debug::get()->add("POS = " + std::to_string(pos)); #endif @@ -950,7 +950,7 @@ void Room::updateAnimatedTiles() { } for (auto& a : animated_tiles_) { - SDL_Rect rect = a.sprite->getClip(); + SDL_FRect rect = a.sprite->getClip(); rect.x = a.x_orig + offset; a.sprite->setClip(rect); } @@ -964,7 +964,7 @@ void Room::renderAnimatedTiles() { } // Comprueba las colisiones -int Room::checkRightSurfaces(SDL_Rect* rect) { +int Room::checkRightSurfaces(SDL_FRect* rect) { for (const auto& s : right_walls_) { if (checkCollision(s, *rect)) { return s.x; @@ -975,7 +975,7 @@ int Room::checkRightSurfaces(SDL_Rect* rect) { } // Comprueba las colisiones -int Room::checkLeftSurfaces(SDL_Rect* rect) { +int Room::checkLeftSurfaces(SDL_FRect* rect) { for (const auto& s : left_walls_) { if (checkCollision(s, *rect)) { return s.x; @@ -986,7 +986,7 @@ int Room::checkLeftSurfaces(SDL_Rect* rect) { } // Comprueba las colisiones -int Room::checkTopSurfaces(SDL_Rect* rect) { +int Room::checkTopSurfaces(SDL_FRect* rect) { for (const auto& s : top_floors_) { if (checkCollision(s, *rect)) { return s.y; @@ -997,7 +997,7 @@ int Room::checkTopSurfaces(SDL_Rect* rect) { } // Comprueba las colisiones -int Room::checkBottomSurfaces(SDL_Rect* rect) { +int Room::checkBottomSurfaces(SDL_FRect* rect) { for (const auto& s : bottom_floors_) { if (checkCollision(s, *rect)) { return s.y; @@ -1008,7 +1008,7 @@ int Room::checkBottomSurfaces(SDL_Rect* rect) { } // Comprueba las colisiones -int Room::checkAutoSurfaces(SDL_Rect* rect) { +int Room::checkAutoSurfaces(SDL_FRect* rect) { for (const auto& s : conveyor_belt_floors_) { if (checkCollision(s, *rect)) { return s.y; @@ -1019,7 +1019,7 @@ int Room::checkAutoSurfaces(SDL_Rect* rect) { } // Comprueba las colisiones -bool Room::checkTopSurfaces(SDL_Point* p) { +bool Room::checkTopSurfaces(SDL_FPoint* p) { for (const auto& s : top_floors_) { if (checkCollision(s, *p)) { return true; @@ -1030,7 +1030,7 @@ bool Room::checkTopSurfaces(SDL_Point* p) { } // Comprueba las colisiones -bool Room::checkAutoSurfaces(SDL_Point* p) { +bool Room::checkAutoSurfaces(SDL_FPoint* p) { for (const auto& s : conveyor_belt_floors_) { if (checkCollision(s, *p)) { return true; @@ -1043,7 +1043,7 @@ bool Room::checkAutoSurfaces(SDL_Point* p) { // Comprueba las colisiones int Room::checkLeftSlopes(const LineVertical* line) { for (const auto& slope : left_slopes_) { - const SDL_Point p = checkCollision(slope, *line); + const SDL_FPoint p = checkCollision(slope, *line); if (p.x != -1) { return p.y; } @@ -1053,7 +1053,7 @@ int Room::checkLeftSlopes(const LineVertical* line) { } // Comprueba las colisiones -bool Room::checkLeftSlopes(SDL_Point* p) { +bool Room::checkLeftSlopes(SDL_FPoint* p) { for (const auto& slope : left_slopes_) { if (checkCollision(*p, slope)) { return true; @@ -1066,7 +1066,7 @@ bool Room::checkLeftSlopes(SDL_Point* p) { // Comprueba las colisiones int Room::checkRightSlopes(const LineVertical* line) { for (const auto& slope : right_slopes_) { - const SDL_Point p = checkCollision(slope, *line); + const SDL_FPoint p = checkCollision(slope, *line); if (p.x != -1) { return p.y; } @@ -1076,7 +1076,7 @@ int Room::checkRightSlopes(const LineVertical* line) { } // Comprueba las colisiones -bool Room::checkRightSlopes(SDL_Point* p) { +bool Room::checkRightSlopes(SDL_FPoint* p) { for (const auto& slope : right_slopes_) { if (checkCollision(*p, slope)) { return true; diff --git a/source/room.h b/source/room.h index 6112f21..61d6181 100644 --- a/source/room.h +++ b/source/room.h @@ -2,7 +2,6 @@ #include - #include // Para shared_ptr #include // Para string #include // Para vector @@ -187,52 +186,52 @@ class Room { std::string getRoom(RoomBorder border); // Devuelve el tipo de tile que hay en ese pixel - TileType getTile(SDL_Point point); + TileType getTile(SDL_FPoint point); // Indica si hay colision con un enemigo a partir de un rectangulo - bool enemyCollision(SDL_Rect& rect); + bool enemyCollision(SDL_FRect& rect); // Indica si hay colision con un objeto a partir de un rectangulo - bool itemCollision(SDL_Rect& rect); + bool itemCollision(SDL_FRect& rect); // Obten el tamaño del tile int getTileSize() const { return TILE_SIZE_; } // Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile - int getSlopeHeight(SDL_Point p, TileType slope); + int getSlopeHeight(SDL_FPoint p, TileType slope); // Comprueba las colisiones - int checkRightSurfaces(SDL_Rect* rect); + int checkRightSurfaces(SDL_FRect* rect); // Comprueba las colisiones - int checkLeftSurfaces(SDL_Rect* rect); + int checkLeftSurfaces(SDL_FRect* rect); // Comprueba las colisiones - int checkTopSurfaces(SDL_Rect* rect); + int checkTopSurfaces(SDL_FRect* rect); // Comprueba las colisiones - int checkBottomSurfaces(SDL_Rect* rect); + int checkBottomSurfaces(SDL_FRect* rect); // Comprueba las colisiones - int checkAutoSurfaces(SDL_Rect* rect); + int checkAutoSurfaces(SDL_FRect* rect); // Comprueba las colisiones - bool checkTopSurfaces(SDL_Point* p); + bool checkTopSurfaces(SDL_FPoint* p); // Comprueba las colisiones - bool checkAutoSurfaces(SDL_Point* p); + bool checkAutoSurfaces(SDL_FPoint* p); // Comprueba las colisiones int checkLeftSlopes(const LineVertical* line); // Comprueba las colisiones - bool checkLeftSlopes(SDL_Point* p); + bool checkLeftSlopes(SDL_FPoint* p); // Comprueba las colisiones int checkRightSlopes(const LineVertical* line); // Comprueba las colisiones - bool checkRightSlopes(SDL_Point* p); + bool checkRightSlopes(SDL_FPoint* p); // Pone el mapa en modo pausa void setPaused(bool value) { is_paused_ = value; }; diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index 6ab3761..710c6bb 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -141,7 +141,7 @@ void Scoreboard::fillTexture() { // Muestra si suena la música if (data_->music) { const Uint8 c = data_->color; - SDL_Rect clip = {0, 8, 8, 8}; + SDL_FRect clip = {0, 8, 8, 8}; item_surface_->renderWithColorReplace(20 * BLOCK, LINE2, 1, c, &clip); } diff --git a/source/scoreboard.h b/source/scoreboard.h index 118d9ca..9fc5212 100644 --- a/source/scoreboard.h +++ b/source/scoreboard.h @@ -76,7 +76,7 @@ class Scoreboard { Uint32 paused_time_elapsed_; // Tiempo acumulado en pausa ClockData clock_; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida Uint8 items_color_; // Color de la cantidad de items recogidos - SDL_Rect surface_dest_; // Rectangulo donde dibujar la surface del marcador + SDL_FRect surface_dest_; // Rectangulo donde dibujar la surface del marcador // Obtiene el tiempo transcurrido de partida ClockData getTime(); diff --git a/source/screen.cpp b/source/screen.cpp index fa2a5b8..59d8d0d 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -42,9 +42,8 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer) renderer_(renderer), palettes_(Asset::get()->getListByType(AssetType::PALETTE)) { // Inicializa variables - SDL_DisplayMode DM; - SDL_GetCurrentDisplayMode(0, &DM); - info_resolution_ = std::to_string(DM.w) + " X " + std::to_string(DM.h) + " AT " + std::to_string(DM.refresh_rate) + " HZ"; + auto display_mode = SDL_GetCurrentDisplayMode(0); + info_resolution_ = std::to_string(display_mode->w) + " X " + std::to_string(display_mode->h) + " AT " + std::to_string(display_mode->refresh_rate) + " HZ"; // Ajusta los tamaños game_surface_dstrect_ = {options.video.border.width, options.video.border.height, options.game.width, options.game.height}; @@ -54,9 +53,6 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer) // Define el color del borde para el modo de pantalla completa border_color_ = static_cast(PaletteColor::BLACK); - // Establece el modo de escalado - SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE); - // Crea la textura donde se dibujan los graficos del juego game_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width, options.game.height); if (!game_texture_) { @@ -65,6 +61,7 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer) std::cerr << "Error: game_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } } + SDL_SetTextureScaleMode(game_texture_, SDL_SCALEMODE_NEAREST); // Crea la textura donde se dibuja el borde que rodea el area de juego border_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2); @@ -74,8 +71,9 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer) std::cerr << "Error: border_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } } + SDL_SetTextureScaleMode(border_texture_, SDL_SCALEMODE_NEAREST); - // Crea la textura donde se dibuja el borde que rodea el area de juego + // Crea la textura para los shaders const int EXTRA_WIDTH = options.video.border.enabled ? options.video.border.width * 2 : 0; const int EXTRA_HEIGHT = options.video.border.enabled ? options.video.border.height * 2 : 0; shaders_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width + EXTRA_WIDTH, options.game.height + EXTRA_HEIGHT); @@ -85,6 +83,7 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer) std::cerr << "Error: shaders_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } } + SDL_SetTextureScaleMode(shaders_texture_, SDL_SCALEMODE_NEAREST); // Crea la surface donde se dibujan los graficos del juego game_surface_ = std::make_shared(options.game.width, options.game.height); @@ -100,7 +99,7 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer) renderer_surface_ = std::make_shared>(game_surface_); // Establece el modo de video - setVideoMode(options.video.mode); + setVideoMode(options.video.fullscreen); // Muestra la ventana show(); @@ -141,12 +140,12 @@ void Screen::render() { } // Establece el modo de video -void Screen::setVideoMode(int mode) { +void Screen::setVideoMode(bool mode) { // Actualiza las opciones - options.video.mode = mode; + options.video.fullscreen = mode; // Configura el modo de pantalla y ajusta la ventana - SDL_SetWindowFullscreen(window_, options.video.mode); + SDL_SetWindowFullscreen(window_, options.video.fullscreen); adjustWindowSize(); adjustRenderLogicalSize(); @@ -156,19 +155,19 @@ void Screen::setVideoMode(int mode) { // Camibia entre pantalla completa y ventana void Screen::toggleVideoMode() { - options.video.mode = (options.video.mode == 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; - setVideoMode(options.video.mode); + options.video.fullscreen = !options.video.fullscreen; + setVideoMode(options.video.fullscreen); } // Reduce el tamaño de la ventana bool Screen::decWindowZoom() { - if (options.video.mode == 0) { + if (options.video.fullscreen == 0) { const int PREVIOUS_ZOOM = options.window.zoom; --options.window.zoom; options.window.zoom = std::max(options.window.zoom, 1); if (options.window.zoom != PREVIOUS_ZOOM) { - setVideoMode(options.video.mode); + setVideoMode(options.video.fullscreen); return true; } } @@ -178,13 +177,13 @@ bool Screen::decWindowZoom() { // Aumenta el tamaño de la ventana bool Screen::incWindowZoom() { - if (options.video.mode == 0) { + if (options.video.fullscreen == 0) { const int PREVIOUS_ZOOM = options.window.zoom; ++options.window.zoom; options.window.zoom = std::min(options.window.zoom, options.window.max_zoom); if (options.window.zoom != PREVIOUS_ZOOM) { - setVideoMode(options.video.mode); + setVideoMode(options.video.fullscreen); return true; } } @@ -202,7 +201,7 @@ void Screen::setBorderColor(Uint8 color) { void Screen::toggleBorder() { options.video.border.enabled = !options.video.border.enabled; createShadersTexture(); - setVideoMode(options.video.mode); + setVideoMode(options.video.fullscreen); } // Dibuja las notificaciones @@ -215,7 +214,7 @@ void Screen::renderNotifications() { // Cambia el estado de los shaders void Screen::toggleShaders() { options.video.shaders = !options.video.shaders; - setVideoMode(options.video.mode); + setVideoMode(options.video.fullscreen); } // Actualiza la lógica de la clase @@ -233,7 +232,7 @@ void Screen::adjustWindowSize() { options.window.max_zoom = getMaxZoom(); // Establece el nuevo tamaño - if (options.video.mode == 0) { + if (options.video.fullscreen == 0) { int old_width, old_height; SDL_GetWindowSize(window_, &old_width, &old_height); @@ -249,18 +248,17 @@ void Screen::adjustWindowSize() { } // Ajusta el tamaño lógico del renderizador -void Screen::adjustRenderLogicalSize() { - SDL_SetRenderLogicalPresentation(renderer_, window_width_, window_height_); +void Screen::adjustRenderLogicalSize() { + SDL_SetRenderLogicalPresentation(renderer_, window_width_, window_height_, options.video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX); } // Obtiene el tamaño máximo de zoom posible para la ventana int Screen::getMaxZoom() { // Obtiene información sobre la pantalla - SDL_DisplayMode DM; - SDL_GetCurrentDisplayMode(0, &DM); + auto display_mode = SDL_GetCurrentDisplayMode(0); // Calcula el máximo factor de zoom que se puede aplicar a la pantalla - const int MAX_ZOOM = std::min(DM.w / window_width_, (DM.h - WINDOWS_DECORATIONS_) / window_height_); + const int MAX_ZOOM = std::min(display_mode->w / window_width_, (display_mode->h - WINDOWS_DECORATIONS_) / window_height_); // Normaliza los valores de zoom options.window.zoom = std::min(options.window.zoom, MAX_ZOOM); @@ -345,14 +343,14 @@ void Screen::textureToRenderer() { if (options.video.shaders) { SDL_SetRenderTarget(renderer_, shaders_texture_); - SDL_RenderCopy(renderer_, texture_to_render, nullptr, nullptr); + SDL_RenderTexture(renderer_, texture_to_render, nullptr, nullptr); SDL_SetRenderTarget(renderer_, nullptr); shader::render(); } else { SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF); SDL_RenderClear(renderer_); - SDL_RenderCopy(renderer_, texture_to_render, nullptr, nullptr); + SDL_RenderTexture(renderer_, texture_to_render, nullptr, nullptr); SDL_RenderPresent(renderer_); } } @@ -432,6 +430,12 @@ void Screen::setNotificationsEnabled(bool value) { notifications_enabled_ = valu // Activa / desactiva la información de debug void Screen::toggleDebugInfo() { show_debug_info_ = !show_debug_info_; } +// Alterna entre activar y desactivar el escalado entero +void Screen::toggleIntegerScale() { + options.video.integer_scale = !options.video.integer_scale; + SDL_SetRenderLogicalPresentation(renderer_, options.game.width, options.game.height, options.video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX); +} + // Getters SDL_Renderer* Screen::getRenderer() { return renderer_; } std::shared_ptr Screen::getRendererSurface() { return (*renderer_surface_); } diff --git a/source/screen.h b/source/screen.h index 8894dba..2872cff 100644 --- a/source/screen.h +++ b/source/screen.h @@ -66,7 +66,7 @@ class Screen { // Variables int window_width_; // Ancho de la pantalla o ventana int window_height_; // Alto de la pantalla o ventana - SDL_Rect game_surface_dstrect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana + SDL_FRect game_surface_dstrect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana Uint8 border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla std::vector palettes_; // Listado de los ficheros de paletta disponibles Uint8 current_palette_ = 0; // Indice para el vector de paletas @@ -145,11 +145,14 @@ class Screen { void update(); // Establece el modo de video - void setVideoMode(int mode); + void setVideoMode(bool mode); // Camibia entre pantalla completa y ventana void toggleVideoMode(); + // Alterna entre activar y desactivar el escalado entero + void toggleIntegerScale(); + // Reduce el tamaño de la ventana bool decWindowZoom(); diff --git a/source/sections/credits.cpp b/source/sections/credits.cpp index eb32d48..97a3202 100644 --- a/source/sections/credits.cpp +++ b/source/sections/credits.cpp @@ -174,7 +174,7 @@ void Credits::fillTexture() { } // El resto se rellena de color sólido - SDL_Rect rect = {0, 8, 256, 192}; + SDL_FRect rect = {0, 8, 256, 192}; cover_surface_->fillRect(&rect, color); } @@ -236,7 +236,7 @@ void Credits::render() { // Dibuja la textura que cubre el texto const int offset = std::min(counter_ / 8, 192 / 2); - SDL_Rect srcRect = {0, 0, 256, 192 - (offset * 2)}; + SDL_FRect srcRect = {0, 0, 256, 192 - (offset * 2)}; cover_surface_->render(0, offset * 2, &srcRect); // Dibuja el sprite con el brillo diff --git a/source/sections/ending.cpp b/source/sections/ending.cpp index 62b0887..c995e25 100644 --- a/source/sections/ending.cpp +++ b/source/sections/ending.cpp @@ -190,7 +190,7 @@ void Ending::iniTexts() { } // El resto se rellena de color sólido - SDL_Rect rect = {0, 8, WIDTH, HEIGHT}; + SDL_FRect rect = {0, 8, WIDTH, HEIGHT}; surface->fillRect(&rect, color); // Crea el sprite @@ -256,7 +256,7 @@ void Ending::iniPics() { } // El resto se rellena de color sólido - SDL_Rect rect = {0, 8, WIDTH, HEIGHT}; + SDL_FRect rect = {0, 8, WIDTH, HEIGHT}; surface->fillRect(&rect, color); // Crea el sprite @@ -453,7 +453,7 @@ void Ending::fillCoverTexture() { } // El resto se rellena de color sólido - SDL_Rect rect = {0, 0, 256, options.game.height}; + SDL_FRect rect = {0, 0, 256, options.game.height}; surface->fillRect(&rect, color); Screen::get()->setRendererSurface(previuos_renderer); @@ -464,8 +464,8 @@ void Ending::renderCoverTexture() { if (cover_counter_ > 0) { // Dibuja la textura que cubre el texto const int OFFSET = std::min(cover_counter_, 100); - SDL_Rect srcRect = {0, 200 - (cover_counter_ * 2), 256, OFFSET * 2}; - SDL_Rect dstRect = {0, 0, 256, OFFSET * 2}; + SDL_FRect srcRect = {0, 200 - (cover_counter_ * 2), 256, OFFSET * 2}; + SDL_FRect dstRect = {0, 0, 256, OFFSET * 2}; cover_surface_->render(&srcRect, &dstRect); } } diff --git a/source/sections/ending2.cpp b/source/sections/ending2.cpp index b27fa57..9639a96 100644 --- a/source/sections/ending2.cpp +++ b/source/sections/ending2.cpp @@ -343,20 +343,20 @@ void Ending2::renderTexts() { // Coloca los sprites en su sito void Ending2::placeSprites() { for (int i = 0; i < static_cast(sprites_.size()); ++i) { - const int X = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_; - const int Y = (i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT_ + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE_) + options.game.height + 40; - const int W = sprites_.at(i)->getWidth(); - const int H = sprites_.at(i)->getHeight(); - const int DX = -(W / 2); - const int DY = sprite_max_height_ - H; + const float X = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_; + const float Y = (i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT_ + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE_) + options.game.height + 40; + const float W = sprites_.at(i)->getWidth(); + const float H = sprites_.at(i)->getHeight(); + const float DX = -(W / 2); + const float DY = sprite_max_height_ - H; sprites_.at(i)->setPos({X + DX, Y + DY, W, H}); sprites_.at(i)->setVelY(SPRITE_DESP_SPEED_); } // Recoloca el sprite del jugador, que es el último de la lista - const int X = (options.game.width - sprites_.back()->getWidth()) / 2; - const int Y = sprites_.back()->getPosY() + sprite_max_height_ * 2; + const float X = (options.game.width - sprites_.back()->getWidth()) / 2; + const float Y = sprites_.back()->getPosY() + sprite_max_height_ * 2; sprites_.back()->setPos(X, Y); sprites_.back()->setCurrentAnimation("walk"); } @@ -364,7 +364,7 @@ void Ending2::placeSprites() { // Crea los sprites con las texturas con los textos void Ending2::createSpriteTexts() { // Crea los sprites de texto a partir de la lista - for (int i = 0; i < static_cast(sprite_list_.size()); ++i) { + for (size_t i = 0; i < sprite_list_.size(); ++i) { auto text = Resource::get()->getText("smb2"); // Procesa y ajusta el texto del sprite actual @@ -375,16 +375,16 @@ void Ending2::createSpriteTexts() { } // Calcula las dimensiones del texto - const int W = text->lenght(txt, 1); - const int H = text->getCharacterSize(); + const float W = text->lenght(txt, 1); + const float H = text->getCharacterSize(); // Determina la columna y la posición X del texto - const int X = (i == static_cast(sprite_list_.size()) - 1) + const float X = (i == sprite_list_.size() - 1) ? (GAMECANVAS_CENTER_X - (W / 2)) : ((i % 2 == 0 ? FIRST_COL_ : SECOND_COL_) - (W / 2)); // Calcula la posición Y del texto en base a la posición y altura del sprite - const int Y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + DIST_SPRITE_TEXT_; + const float Y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + DIST_SPRITE_TEXT_; // Crea la surface auto surface = std::make_shared(W, H); @@ -393,7 +393,7 @@ void Ending2::createSpriteTexts() { text->write(0, 0, txt); // Crea el sprite - SDL_Rect pos = {X, Y, W, H}; + SDL_FRect pos = {X, Y, W, H}; sprite_texts_.emplace_back(std::make_shared(surface, pos)); sprite_texts_.back()->setVelY(SPRITE_DESP_SPEED_); Screen::get()->setRendererSurface(previuos_renderer); @@ -409,22 +409,22 @@ void Ending2::createTexts() { auto text = Resource::get()->getText("smb2"); // Crea los sprites de texto a partir de la lista - for (int i = 0; i < (int)list.size(); ++i) { + for (size_t i = 0; i < list.size(); ++i) { // Calcula constantes - const int w = text->lenght(list[i], 1); - const int h = text->getCharacterSize(); - const int x = GAMECANVAS_CENTER_X; - const int dx = -(w / 2); - const int y = options.game.height + (text->getCharacterSize() * (i * 2)); + const float W = text->lenght(list[i], 1); + const float H = text->getCharacterSize(); + const float X = GAMECANVAS_CENTER_X; + const float DX = -(W / 2); + const float Y = options.game.height + (text->getCharacterSize() * (i * 2)); // Crea la surface - auto surface = std::make_shared(w, h); + auto surface = std::make_shared(W, H); auto previuos_renderer = Screen::get()->getRendererSurface(); Screen::get()->setRendererSurface(surface); text->write(0, 0, list[i]); // Crea el sprite - SDL_Rect pos = {x + dx, y, w, h}; + SDL_FRect pos = {X + DX, Y, W, H}; texts_.emplace_back(std::make_shared(surface, pos)); texts_.back()->setVelY(SPRITE_DESP_SPEED_); Screen::get()->setRendererSurface(previuos_renderer); @@ -438,22 +438,22 @@ void Ending2::createTexts() { list.push_back("FOR PLAYING!"); // Crea los sprites de texto a partir de la lista - for (int i = 0; i < (int)list.size(); ++i) { + for (size_t i = 0; i < list.size(); ++i) { // Calcula constantes - const int w = text->lenght(list[i], 1); - const int h = text->getCharacterSize(); - const int x = GAMECANVAS_CENTER_X; - const int dx = -(w / 2); - const int y = START + (text->getCharacterSize() * (i * 2)); + const float W = text->lenght(list[i], 1); + const float H = text->getCharacterSize(); + const float X = GAMECANVAS_CENTER_X; + const float DX = -(W / 2); + const float Y = START + (text->getCharacterSize() * (i * 2)); // Crea la surface - auto surface = std::make_shared(w, h); + auto surface = std::make_shared(W, H); auto previuos_renderer = Screen::get()->getRendererSurface(); Screen::get()->setRendererSurface(surface); text->write(0, 0, list[i]); // Crea el sprite - SDL_Rect pos = {x + dx, y, w, h}; + SDL_FRect pos = {X + DX, Y, W, H}; texts_.emplace_back(std::make_shared(surface, pos)); texts_.back()->setVelY(SPRITE_DESP_SPEED_); Screen::get()->setRendererSurface(previuos_renderer); diff --git a/source/sections/ending2.h b/source/sections/ending2.h index 1a4b48f..a2c4607 100644 --- a/source/sections/ending2.h +++ b/source/sections/ending2.h @@ -70,8 +70,8 @@ class Ending2 { Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa std::vector sprite_list_; // Lista con todos los sprites a dibujar std::vector colors_; // Vector con los colores para el fade - int sprite_max_width_ = 0; // El valor de ancho del sprite mas ancho - int sprite_max_height_ = 0; // El valor de alto del sprite mas alto + float sprite_max_width_ = 0; // El valor de ancho del sprite mas ancho + float sprite_max_height_ = 0; // El valor de alto del sprite mas alto State state_; // Controla el estado de la clase // Actualiza el objeto diff --git a/source/sections/game.cpp b/source/sections/game.cpp index 835a66d..aa16f47 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -193,7 +193,7 @@ void Game::renderDebugInfo() { auto surface = Screen::get()->getRendererSurface(); // Borra el marcador - SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT}; + SDL_FRect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT}; surface->fillRect(&rect, static_cast(PaletteColor::BLACK)); // Pinta la rejilla diff --git a/source/sections/game.h b/source/sections/game.h index 4036cf5..36a8ca8 100644 --- a/source/sections/game.h +++ b/source/sections/game.h @@ -63,7 +63,7 @@ class Game { bool black_screen_ = false; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador int black_screen_counter_ = 0; // Contador para temporizar la pantalla en negro int total_items_; // Cantidad total de items que hay en el mapeado del juego - SDL_Rect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación + SDL_FRect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación // Actualiza el juego, las variables, comprueba la entrada, etc. void update(); diff --git a/source/sections/loading_screen.h b/source/sections/loading_screen.h index 8c79c79..5702209 100644 --- a/source/sections/loading_screen.h +++ b/source/sections/loading_screen.h @@ -16,13 +16,13 @@ class LoadingScreen { std::shared_ptr screen_surface_; // Surface para dibujar la pantalla de carga // Variables - int pre_counter_ = 0; // Contador previo para realizar una pausa inicial - int counter_ = 0; // Contador - Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa - int load_counter_ = 0; // Contador para controlar las cargas - bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra - int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga - SDL_Rect load_rect_ = {0, 0, 52, 1}; // Rectangulo para dibujar la pantalla de carga + int pre_counter_ = 0; // Contador previo para realizar una pausa inicial + int counter_ = 0; // Contador + Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa + int load_counter_ = 0; // Contador para controlar las cargas + bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra + int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga + SDL_FRect load_rect_ = {0, 0, 52, 1}; // Rectangulo para dibujar la pantalla de carga // Actualiza las variables void update(); diff --git a/source/sections/title.cpp b/source/sections/title.cpp index 4c5c992..52bd22f 100644 --- a/source/sections/title.cpp +++ b/source/sections/title.cpp @@ -64,9 +64,9 @@ void Title::checkEvents() { globalEvents::check(event); // Solo se comprueban estas teclas si no está activo el menu de logros - if (event.type == SDL_KEYDOWN) { + if (event.type == SDL_EVENT_KEY_DOWN) { if (!show_cheevos_) { - switch (event.key.keysym.scancode) { + switch (event.key.key) { case SDL_SCANCODE_1: options.section.section = Section::GAME; options.section.subsection = Subsection::NONE; @@ -242,8 +242,8 @@ void Title::moveCheevosList(int direction) { cheevos_surface_view_.y = direction == 0 ? cheevos_surface_view_.y - SPEED : cheevos_surface_view_.y + SPEED; // Ajusta los limites - const int BOTTOM = cheevos_surface_->getHeight() - cheevos_surface_view_.h; - cheevos_surface_view_.y = std::clamp(cheevos_surface_view_.y, 0, BOTTOM); + const float BOTTOM = cheevos_surface_->getHeight() - cheevos_surface_view_.h; + cheevos_surface_view_.y = std::clamp(cheevos_surface_view_.y, 0.0F, BOTTOM); cheevos_sprite_->setClip(cheevos_surface_view_); } diff --git a/source/sections/title.h b/source/sections/title.h index d35f779..b93f7c5 100644 --- a/source/sections/title.h +++ b/source/sections/title.h @@ -38,7 +38,7 @@ class Title { std::vector letters_; // Vector con las letras de la marquesina int marquee_speed_ = 2; // Velocidad de desplazamiento de la marquesina bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros - SDL_Rect cheevos_surface_view_; // Zona visible de la surface con el listado de logros + SDL_FRect cheevos_surface_view_; // Zona visible de la surface con el listado de logros TitleState state_; // Estado en el que se encuentra el bucle principal // Actualiza las variables diff --git a/source/sprite/surface_animated_sprite.cpp b/source/sprite/surface_animated_sprite.cpp index 6854b82..6987f71 100644 --- a/source/sprite/surface_animated_sprite.cpp +++ b/source/sprite/surface_animated_sprite.cpp @@ -190,7 +190,7 @@ void SAnimatedSprite::setAnimations(const Animations& animations) { // Se introducen los valores separados por comas en un vector std::stringstream ss(value); std::string tmp; - SDL_Rect rect = {0, 0, frame_width, frame_height}; + SDL_FRect rect = {0, 0, frame_width, frame_height}; while (getline(ss, tmp, ',')) { // Comprueba que el tile no sea mayor que el maximo indice permitido const int num_tile = std::stoi(tmp); diff --git a/source/sprite/surface_animated_sprite.h b/source/sprite/surface_animated_sprite.h index 0fd65f7..b089604 100644 --- a/source/sprite/surface_animated_sprite.h +++ b/source/sprite/surface_animated_sprite.h @@ -10,13 +10,13 @@ class Surface; // lines 9-9 struct AnimationData { - std::string name; // Nombre de la animacion - std::vector frames; // Cada uno de los frames que componen la animación - int speed; // Velocidad de la animación - int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva - bool completed; // Indica si ha finalizado la animación - int current_frame; // Frame actual - int counter; // Contador para las animaciones + std::string name; // Nombre de la animacion + std::vector frames; // Cada uno de los frames que componen la animación + int speed; // Velocidad de la animación + int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva + bool completed; // Indica si ha finalizado la animación + int current_frame; // Frame actual + int counter; // Contador para las animaciones AnimationData() : name(std::string()), diff --git a/source/sprite/surface_moving_sprite.cpp b/source/sprite/surface_moving_sprite.cpp index 7ed57cb..b4138b6 100644 --- a/source/sprite/surface_moving_sprite.cpp +++ b/source/sprite/surface_moving_sprite.cpp @@ -3,13 +3,13 @@ #include "surface.h" // Para Surface // Constructor -SMovingSprite::SMovingSprite(std::shared_ptr surface, SDL_Rect pos, SDL_RendererFlip flip) +SMovingSprite::SMovingSprite(std::shared_ptr surface, SDL_FRect pos, SDL_FlipMode flip) : SSprite(surface, pos), x_(pos.x), y_(pos.y), flip_(flip) { SSprite::pos_ = pos; } -SMovingSprite::SMovingSprite(std::shared_ptr surface, SDL_Rect pos) +SMovingSprite::SMovingSprite(std::shared_ptr surface, SDL_FRect pos) : SSprite(surface, pos), x_(pos.x), y_(pos.y), @@ -65,7 +65,7 @@ void SMovingSprite::render(Uint8 source_color, Uint8 target_color) { } // Establece la posición y_ el tamaño del objeto -void SMovingSprite::setPos(SDL_Rect rect) { +void SMovingSprite::setPos(SDL_FRect rect) { x_ = static_cast(rect.x); y_ = static_cast(rect.y); diff --git a/source/sprite/surface_moving_sprite.h b/source/sprite/surface_moving_sprite.h index 87d6626..0bc2b00 100644 --- a/source/sprite/surface_moving_sprite.h +++ b/source/sprite/surface_moving_sprite.h @@ -20,15 +20,15 @@ class SMovingSprite : public SSprite { float ax_ = 0.0f; // Aceleración en el eje X. Variación de la velocidad float ay_ = 0.0f; // Aceleración en el eje Y. Variación de la velocidad - SDL_RendererFlip flip_; // Indica como se voltea el sprite + SDL_FlipMode flip_; // Indica como se voltea el sprite // Mueve el sprite void move(); public: // Constructor - SMovingSprite(std::shared_ptr surface, SDL_Rect pos, SDL_RendererFlip flip); - SMovingSprite(std::shared_ptr surface, SDL_Rect pos); + SMovingSprite(std::shared_ptr surface, SDL_FRect pos, SDL_FlipMode flip); + SMovingSprite(std::shared_ptr surface, SDL_FRect pos); explicit SMovingSprite(std::shared_ptr surface); // Destructor @@ -59,16 +59,16 @@ class SMovingSprite : public SSprite { void setAccelY(float value) { ay_ = value; } // Establece el valor de la variable - void setFlip(SDL_RendererFlip flip) { flip_ = flip; } + void setFlip(SDL_FlipMode flip) { flip_ = flip; } // Gira el sprite horizontalmente void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; } // Obtiene el valor de la variable - SDL_RendererFlip getFlip() { return flip_; } + SDL_FlipMode getFlip() { return flip_; } // Establece la posición y_ el tamaño del objeto - void setPos(SDL_Rect rect); + void setPos(SDL_FRect rect); // Establece el valor de las variables void setPos(float x, float y); diff --git a/source/sprite/surface_sprite.cpp b/source/sprite/surface_sprite.cpp index c28b6eb..74cd496 100644 --- a/source/sprite/surface_sprite.cpp +++ b/source/sprite/surface_sprite.cpp @@ -3,19 +3,19 @@ #include "surface.h" // Para Surface // Constructor -SSprite::SSprite(std::shared_ptr surface, int x, int y, int w, int h) +SSprite::SSprite(std::shared_ptr surface, float x, float y, float w, float h) : surface_(surface), - pos_((SDL_Rect){x, y, w, h}), - clip_((SDL_Rect){0, 0, pos_.w, pos_.h}) {} + pos_((SDL_FRect){x, y, w, h}), + clip_((SDL_FRect){0.0F, 0.0F, pos_.w, pos_.h}) {} -SSprite::SSprite(std::shared_ptr surface, SDL_Rect rect) +SSprite::SSprite(std::shared_ptr surface, SDL_FRect rect) : surface_(surface), pos_(rect), - clip_((SDL_Rect){0, 0, pos_.w, pos_.h}) {} + clip_((SDL_FRect){0, 0, pos_.w, pos_.h}) {} SSprite::SSprite(std::shared_ptr surface) : surface_(surface), - pos_({0, 0, surface_->getWidth(), surface_->getHeight()}), + pos_((SDL_FRect){0.0F, 0.0F, surface_->getWidth(), surface_->getHeight()}), clip_(pos_) {} // Muestra el sprite por pantalla @@ -28,13 +28,13 @@ void SSprite::render(Uint8 source_color, Uint8 target_color) { } // Establece la posición del objeto -void SSprite::setPosition(int x, int y) { +void SSprite::setPosition(float x, float y) { pos_.x = x; pos_.y = y; } // Establece la posición del objeto -void SSprite::setPosition(SDL_Point p) { +void SSprite::setPosition(SDL_FPoint p) { pos_.x = p.x; pos_.y = p.y; } diff --git a/source/sprite/surface_sprite.h b/source/sprite/surface_sprite.h index e0d8213..e0d1943 100644 --- a/source/sprite/surface_sprite.h +++ b/source/sprite/surface_sprite.h @@ -10,13 +10,13 @@ class SSprite { protected: // Variables std::shared_ptr surface_; // Surface donde estan todos los dibujos del sprite - SDL_Rect pos_; // Posición y tamaño donde dibujar el sprite - SDL_Rect clip_; // Rectangulo de origen de la surface que se dibujará en pantalla + SDL_FRect pos_; // Posición y tamaño donde dibujar el sprite + SDL_FRect clip_; // Rectangulo de origen de la surface que se dibujará en pantalla public: // Constructor - SSprite(std::shared_ptr, int x, int y, int w, int h); - SSprite(std::shared_ptr, SDL_Rect rect); + SSprite(std::shared_ptr, float x, float y, float w, float h); + SSprite(std::shared_ptr, SDL_FRect rect); explicit SSprite(std::shared_ptr); // Destructor @@ -30,36 +30,36 @@ class SSprite { virtual void clear(); // Obtiene la posición y el tamaño - int getX() const { return pos_.x; } - int getY() const { return pos_.y; } - int getWidth() const { return pos_.w; } - int getHeight() const { return pos_.h; } + float getX() const { return pos_.x; } + float getY() const { return pos_.y; } + float getWidth() const { return pos_.w; } + float getHeight() const { return pos_.h; } // Devuelve el rectangulo donde está el sprite - SDL_Rect getPosition() const { return pos_; } - SDL_Rect& getRect() { return pos_; } + SDL_FRect getPosition() const { return pos_; } + SDL_FRect& getRect() { return pos_; } // Establece la posición y el tamaño - void setX(int x) { pos_.x = x; } - void setY(int y) { pos_.y = y; } - void setWidth(int w) { pos_.w = w; } - void setHeight(int h) { pos_.h = h; } + void setX(float x) { pos_.x = x; } + void setY(float y) { pos_.y = y; } + void setWidth(float w) { pos_.w = w; } + void setHeight(float h) { pos_.h = h; } // Establece la posición del objeto - void setPosition(int x, int y); - void setPosition(SDL_Point p); - void setPosition(SDL_Rect r) { pos_ = r; } + void setPosition(float x, float y); + void setPosition(SDL_FPoint p); + void setPosition(SDL_FRect r) { pos_ = r; } // Aumenta o disminuye la posición - void incX(int value) { pos_.x += value; } - void incY(int value) { pos_.y += value; } + void incX(float value) { pos_.x += value; } + void incY(float value) { pos_.y += value; } // Obtiene el rectangulo que se dibuja de la surface - SDL_Rect getClip() const { return clip_; } + SDL_FRect getClip() const { return clip_; } // Establece el rectangulo que se dibuja de la surface - void setClip(SDL_Rect rect) { clip_ = rect; } - void setClip(int x, int y, int w, int h) { clip_ = (SDL_Rect){x, y, w, h}; } + void setClip(SDL_FRect rect) { clip_ = rect; } + void setClip(float x, float y, float w, float h) { clip_ = (SDL_FRect){x, y, w, h}; } // Obtiene un puntero a la surface std::shared_ptr getSurface() const { return surface_; } diff --git a/source/surface.cpp b/source/surface.cpp index 183e3d2..781d94b 100644 --- a/source/surface.cpp +++ b/source/surface.cpp @@ -1,5 +1,6 @@ // IWYU pragma: no_include #include "surface.h" + #include #include // Para min, max, copy_n, fill @@ -177,32 +178,32 @@ void Surface::putPixel(int x, int y, Uint8 color) { } // Obtiene el color de un pixel de la surface_data -Uint8 Surface::getPixel(int x, int y) { return surface_data_->data.get()[x + y * surface_data_->width]; } +Uint8 Surface::getPixel(int x, int y) { return surface_data_->data.get()[x + y * static_cast(surface_data_->width)]; } // Dibuja un rectangulo relleno -void Surface::fillRect(const SDL_Rect* rect, Uint8 color) { +void Surface::fillRect(const SDL_FRect* rect, Uint8 color) { // Limitar los valores del rectángulo al tamaño de la superficie - int x_start = std::max(0, rect->x); - int y_start = std::max(0, rect->y); - int x_end = std::min(rect->x + rect->w, static_cast(surface_data_->width)); - int y_end = std::min(rect->y + rect->h, static_cast(surface_data_->height)); + float x_start = std::max(0.0F, rect->x); + float y_start = std::max(0.0F, rect->y); + float x_end = std::min(rect->x + rect->w, surface_data_->width); + float y_end = std::min(rect->y + rect->h, surface_data_->height); // Recorrer cada píxel dentro del rectángulo directamente for (int y = y_start; y < y_end; ++y) { for (int x = x_start; x < x_end; ++x) { - const int index = x + y * surface_data_->width; - surface_data_->data.get()[index] = color; + const int INDEX = x + y * surface_data_->width; + surface_data_->data.get()[INDEX] = color; } } } // Dibuja el borde de un rectangulo -void Surface::drawRectBorder(const SDL_Rect* rect, Uint8 color) { +void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) { // Limitar los valores del rectángulo al tamaño de la superficie - int x_start = std::max(0, rect->x); - int y_start = std::max(0, rect->y); - int x_end = std::min(rect->x + rect->w, static_cast(surface_data_->width)); - int y_end = std::min(rect->y + rect->h, static_cast(surface_data_->height)); + float x_start = std::max(0.0F, rect->x); + float y_start = std::max(0.0F, rect->y); + float x_end = std::min(rect->x + rect->w, surface_data_->width); + float y_end = std::min(rect->y + rect->h, surface_data_->height); // Dibujar bordes horizontales for (int x = x_start; x < x_end; ++x) { @@ -218,31 +219,31 @@ void Surface::drawRectBorder(const SDL_Rect* rect, Uint8 color) { // Dibujar bordes verticales for (int y = y_start; y < y_end; ++y) { // Borde izquierdo - const int left_index = x_start + y * surface_data_->width; - surface_data_->data.get()[left_index] = color; + const int LEFT_INDEX = x_start + y * surface_data_->width; + surface_data_->data.get()[LEFT_INDEX] = color; // Borde derecho - const int right_index = (x_end - 1) + y * surface_data_->width; - surface_data_->data.get()[right_index] = color; + const int RIGHT_INDEX = (x_end - 1) + y * surface_data_->width; + surface_data_->data.get()[RIGHT_INDEX] = color; } } // Dibuja una linea -void Surface::drawLine(int x1, int y1, int x2, int y2, Uint8 color) { +void Surface::drawLine(float x1, float y1, float x2, float y2, Uint8 color) { // Calcula las diferencias - int dx = std::abs(x2 - x1); - int dy = std::abs(y2 - y1); + float dx = std::abs(x2 - x1); + float dy = std::abs(y2 - y1); // Determina la dirección del incremento - int sx = (x1 < x2) ? 1 : -1; - int sy = (y1 < y2) ? 1 : -1; + float sx = (x1 < x2) ? 1 : -1; + float sy = (y1 < y2) ? 1 : -1; - int err = dx - dy; + float err = dx - dy; while (true) { // Asegúrate de no dibujar fuera de los límites de la superficie if (x1 >= 0 && x1 < surface_data_->width && y1 >= 0 && y1 < surface_data_->height) { - surface_data_->data.get()[x1 + y1 * surface_data_->width] = color; + surface_data_->data.get()[static_cast(x1 + y1 * surface_data_->width)] = color; } // Si alcanzamos el punto final, salimos @@ -261,7 +262,7 @@ void Surface::drawLine(int x1, int y1, int x2, int y2, Uint8 color) { } } -void Surface::render(int dx, int dy, int sx, int sy, int w, int h) { +void Surface::render(float dx, float dy, float sx, float sy, float w, float h) { auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData(); // Limitar la región para evitar accesos fuera de rango en origen @@ -280,9 +281,9 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h) { int src_x = sx + ix; int src_y = sy + iy; - Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width]; + Uint8 color = surface_data_->data.get()[static_cast(src_x + src_y * surface_data_->width)]; if (color != transparent_color_) { - surface_data->data.get()[dest_x + dest_y * surface_data->width] = sub_palette_[color]; + surface_data->data.get()[static_cast(dest_x + dest_y * surface_data->width)] = sub_palette_[color]; } } } @@ -290,14 +291,14 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h) { } } -void Surface::render(int x, int y, SDL_Rect* srcRect, SDL_RendererFlip flip) { +void Surface::render(int x, int y, SDL_FRect* srcRect, SDL_FlipMode flip) { auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData(); // Determina la región de origen (clip) a renderizar - int sx = (srcRect) ? srcRect->x : 0; - int sy = (srcRect) ? srcRect->y : 0; - int w = (srcRect) ? srcRect->w : surface_data_->width; - int h = (srcRect) ? srcRect->h : surface_data_->height; + float sx = (srcRect) ? srcRect->x : 0; + float sy = (srcRect) ? srcRect->y : 0; + float w = (srcRect) ? srcRect->w : surface_data_->width; + float h = (srcRect) ? srcRect->h : surface_data_->height; // Limitar la región para evitar accesos fuera de rango en origen w = std::min(w, surface_data_->width - sx); @@ -323,7 +324,7 @@ void Surface::render(int x, int y, SDL_Rect* srcRect, SDL_RendererFlip flip) { // Verificar que las coordenadas de destino están dentro de los límites if (dest_x >= 0 && dest_x < surface_data_dest->width && dest_y >= 0 && dest_y < surface_data_dest->height) { // Copia el píxel si no es transparente - Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width]; + Uint8 color = surface_data_->data.get()[static_cast(src_x + src_y * surface_data_->width)]; if (color != transparent_color_) { surface_data_dest->data[dest_x + dest_y * surface_data_dest->width] = sub_palette_[color]; } @@ -333,20 +334,20 @@ void Surface::render(int x, int y, SDL_Rect* srcRect, SDL_RendererFlip flip) { } // Copia una región de la superficie de origen a la de destino -void Surface::render(SDL_Rect* srcRect, SDL_Rect* dstRect, SDL_RendererFlip flip) { +void Surface::render(SDL_FRect* srcRect, SDL_FRect* dstRect, SDL_FlipMode flip) { auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData(); // Si srcRect es nullptr, tomar toda la superficie fuente - int sx = (srcRect) ? srcRect->x : 0; - int sy = (srcRect) ? srcRect->y : 0; - int sw = (srcRect) ? srcRect->w : surface_data_->width; - int sh = (srcRect) ? srcRect->h : surface_data_->height; + float sx = (srcRect) ? srcRect->x : 0; + float sy = (srcRect) ? srcRect->y : 0; + float sw = (srcRect) ? srcRect->w : surface_data_->width; + float sh = (srcRect) ? srcRect->h : surface_data_->height; // Si dstRect es nullptr, asignar las mismas dimensiones que srcRect - int dx = (dstRect) ? dstRect->x : 0; - int dy = (dstRect) ? dstRect->y : 0; - int dw = (dstRect) ? dstRect->w : sw; - int dh = (dstRect) ? dstRect->h : sh; + float dx = (dstRect) ? dstRect->x : 0; + float dy = (dstRect) ? dstRect->y : 0; + float dw = (dstRect) ? dstRect->w : sw; + float dh = (dstRect) ? dstRect->h : sh; // Asegurarse de que srcRect y dstRect tienen las mismas dimensiones if (sw != dw || sh != dh) { @@ -374,7 +375,7 @@ void Surface::render(SDL_Rect* srcRect, SDL_Rect* dstRect, SDL_RendererFlip flip if (int dest_x = dx + ix; dest_x >= 0 && dest_x < surface_data->width) { if (int dest_y = dy + iy; dest_y >= 0 && dest_y < surface_data->height) { // Copiar el píxel si no es transparente - Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width]; + Uint8 color = surface_data_->data.get()[static_cast(src_x + src_y * surface_data_->width)]; if (color != transparent_color_) { surface_data->data[dest_x + dest_y * surface_data->width] = sub_palette_[color]; } @@ -385,14 +386,14 @@ void Surface::render(SDL_Rect* srcRect, SDL_Rect* dstRect, SDL_RendererFlip flip } // Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro -void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, SDL_Rect* srcRect, SDL_RendererFlip flip) { +void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, SDL_FRect* srcRect, SDL_FlipMode flip) { auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData(); // Determina la región de origen (clip) a renderizar - int sx = (srcRect) ? srcRect->x : 0; - int sy = (srcRect) ? srcRect->y : 0; - int w = (srcRect) ? srcRect->w : surface_data_->width; - int h = (srcRect) ? srcRect->h : surface_data_->height; + float sx = (srcRect) ? srcRect->x : 0; + float sy = (srcRect) ? srcRect->y : 0; + float w = (srcRect) ? srcRect->w : surface_data_->width; + float h = (srcRect) ? srcRect->h : surface_data_->height; // Limitar la región para evitar accesos fuera de rango w = std::min(w, surface_data_->width - sx); @@ -415,7 +416,7 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar } // Copia el píxel si no es transparente - Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width]; + Uint8 color = surface_data_->data.get()[static_cast(src_x + src_y * surface_data_->width)]; if (color != transparent_color_) { surface_data->data[dest_x + dest_y * surface_data->width] = (color == source_color) ? target_color : color; @@ -458,13 +459,13 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) { SDL_UnlockTexture(texture); // Desbloquea la textura // Renderiza la textura en la pantalla completa - if (SDL_RenderCopy(renderer, texture, nullptr, nullptr) != 0) { + if (SDL_RenderTexture(renderer, texture, nullptr, nullptr) != 0) { throw std::runtime_error("Failed to copy texture to renderer: " + std::string(SDL_GetError())); } } // Vuelca la superficie a una textura -void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Rect* srcRect, SDL_Rect* destRect) { +void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FRect* srcRect, SDL_FRect* destRect) { if (!renderer || !texture || !surface_data_) { throw std::runtime_error("Renderer or texture is null."); } @@ -476,7 +477,16 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Re Uint32* pixels = nullptr; int pitch = 0; - if (SDL_LockTexture(texture, destRect, reinterpret_cast(&pixels), &pitch) != 0) { + SDL_Rect lockRect; + if (destRect) { + lockRect.x = static_cast(destRect->x); + lockRect.y = static_cast(destRect->y); + lockRect.w = static_cast(destRect->w); + lockRect.h = static_cast(destRect->h); + } + + // Usa lockRect solo si destRect no es nulo + if (SDL_LockTexture(texture, destRect ? &lockRect : nullptr, reinterpret_cast(&pixels), &pitch) != 0) { throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError())); } @@ -494,7 +504,7 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Re SDL_UnlockTexture(texture); // Renderiza la textura con los rectángulos especificados - if (SDL_RenderCopy(renderer, texture, srcRect, destRect) != 0) { + if (SDL_RenderTexture(renderer, texture, srcRect, destRect) != 0) { throw std::runtime_error("Failed to copy texture to renderer: " + std::string(SDL_GetError())); } } diff --git a/source/surface.h b/source/surface.h index 3d75b6c..e993467 100644 --- a/source/surface.h +++ b/source/surface.h @@ -22,8 +22,8 @@ Palette readPalFile(const std::string& file_path); struct SurfaceData { std::shared_ptr data; // Usa std::shared_ptr para gestión automática - Uint16 width; // Ancho de la imagen - Uint16 height; // Alto de la imagen + float width; // Ancho de la imagen + float height; // Alto de la imagen // Constructor por defecto SurfaceData() @@ -32,13 +32,13 @@ struct SurfaceData { height(0) {} // Constructor que inicializa dimensiones y asigna memoria - SurfaceData(Uint16 w, Uint16 h) - : data(std::shared_ptr(new Uint8[w * h](), std::default_delete())), + SurfaceData(float w, float h) + : data(std::shared_ptr(new Uint8[static_cast(w * h)](), std::default_delete())), width(w), height(h) {} // Constructor para inicializar directamente con datos - SurfaceData(Uint16 w, Uint16 h, std::shared_ptr pixels) + SurfaceData(float w, float h, std::shared_ptr pixels) : data(std::move(pixels)), width(w), height(h) {} @@ -77,12 +77,12 @@ class Surface { void loadPalette(Palette palette); // Copia una región de la SurfaceData de origen a la SurfaceData de destino - void render(int dx, int dy, int sx, int sy, int w, int h); - void render(int x, int y, SDL_Rect* clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE); - void render(SDL_Rect* srcRect = nullptr, SDL_Rect* dstRect = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE); + void render(float dx, float dy, float sx, float sy, float w, float h); + void render(int x, int y, SDL_FRect* clip = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); + void render(SDL_FRect* srcRect = nullptr, SDL_FRect* dstRect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro - void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_Rect* srcRect = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE); + void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_FRect* srcRect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Establece un color en la paleta void setColor(int index, Uint32 color); @@ -92,7 +92,7 @@ class Surface { // Vuelca la SurfaceData a una textura void copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture); - void copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Rect* srcRect, SDL_Rect* destRect); + void copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FRect* srcRect, SDL_FRect* destRect); // Realiza un efecto de fundido en las paletas bool fadePalette(); @@ -105,21 +105,21 @@ class Surface { Uint8 getPixel(int x, int y); // Dibuja un rectangulo relleno - void fillRect(const SDL_Rect* rect, Uint8 color); + void fillRect(const SDL_FRect* rect, Uint8 color); // Dibuja el borde de un rectangulo - void drawRectBorder(const SDL_Rect* rect, Uint8 color); + void drawRectBorder(const SDL_FRect* rect, Uint8 color); // Dibuja una linea - void drawLine(int x1, int y1, int x2, int y2, Uint8 color); + void drawLine(float x1, float y1, float x2, float y2, Uint8 color); // Metodos para gestionar surface_data_ std::shared_ptr getSurfaceData() const { return surface_data_; } void setSurfaceData(std::shared_ptr new_data) { surface_data_ = new_data; } // Obtien ancho y alto - int getWidth() const { return surface_data_->width; } - int getHeight() const { return surface_data_->height; } + float getWidth() const { return surface_data_->width; } + float getHeight() const { return surface_data_->height; } // Color transparente Uint8 getTransparentColor() const { return transparent_color_; } diff --git a/source/text.cpp b/source/text.cpp index 0ec1093..7a0de79 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -88,7 +88,7 @@ Text::Text(std::shared_ptr surface, const std::string& text_file) { } // Crea los objetos - sprite_ = std::make_unique(surface, (SDL_Rect){0, 0, box_width_, box_height_}); + sprite_ = std::make_unique(surface, (SDL_FRect){0, 0, box_width_, box_height_}); // Inicializa variables fixed_width_ = false; @@ -106,7 +106,7 @@ Text::Text(std::shared_ptr surface, std::shared_ptr text_file } // Crea los objetos - sprite_ = std::make_unique(surface, (SDL_Rect){0, 0, box_width_, box_height_}); + sprite_ = std::make_unique(surface, (SDL_FRect){0, 0, box_width_, box_height_}); // Inicializa variables fixed_width_ = false; diff --git a/source/ui/notifier.cpp b/source/ui/notifier.cpp index 1be8eed..e8cb1d7 100644 --- a/source/ui/notifier.cpp +++ b/source/ui/notifier.cpp @@ -194,7 +194,7 @@ void Notifier::show(std::vector texts, NotificationText text_is, Ui Screen::get()->setRendererSurface(n.surface); // Dibuja el fondo de la notificación - SDL_Rect rect; + SDL_FRect rect; if (SHAPE == NotificationShape::ROUNDED) { rect = {4, 0, WIDTH - (4 * 2), HEIGHT}; n.surface->fillRect(&rect, bg_color_); @@ -211,13 +211,13 @@ void Notifier::show(std::vector texts, NotificationText text_is, Ui else if (SHAPE == NotificationShape::SQUARED) { n.surface->clear(bg_color_); - SDL_Rect squared_rect = {0, 0, n.surface->getWidth(), n.surface->getHeight()}; + SDL_FRect squared_rect = {0, 0, n.surface->getWidth(), n.surface->getHeight()}; n.surface->drawRectBorder(&squared_rect, static_cast(PaletteColor::CYAN)); } // Dibuja el icono de la notificación if (has_icons_ && icon >= 0 && texts.size() >= 2) { - auto sp = std::make_unique(icon_surface_, (SDL_Rect){0, 0, ICON_SIZE_, ICON_SIZE_}); + auto sp = std::make_unique(icon_surface_, (SDL_FRect){0, 0, ICON_SIZE_, ICON_SIZE_}); sp->setPosition({PADDING_IN_H, PADDING_IN_V, ICON_SIZE_, ICON_SIZE_}); sp->setClip({ICON_SIZE_ * (icon % 10), ICON_SIZE_ * (icon / 10), ICON_SIZE_, ICON_SIZE_}); sp->render(); diff --git a/source/ui/notifier.h b/source/ui/notifier.h index b46a01d..d601cf4 100644 --- a/source/ui/notifier.h +++ b/source/ui/notifier.h @@ -46,7 +46,7 @@ class Notifier { std::vector texts; // Lista de textos incluidos en la notificación NotificationStatus state; // Estado actual de la notificación (RISING, SHOWING, etc.) NotificationShape shape; // Forma de la notificación (ej. SQUARED o ROUNDED) - SDL_Rect rect; // Dimensiones y posición de la notificación en pantalla + SDL_FRect rect; // Dimensiones y posición de la notificación en pantalla int y; // Posición actual en el eje Y int travel_dist; // Distancia a recorrer (por ejemplo, en animaciones) std::string code; // Código identificador único para esta notificación diff --git a/source/utils.cpp b/source/utils.cpp index 9625188..78507b9 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -39,7 +39,7 @@ bool checkCollision(const Circle& a, const Circle& b) { } // Detector de colisiones entre un circulo y un rectangulo -bool checkCollision(const Circle& a, const SDL_Rect& b) { +bool checkCollision(const Circle& a, const SDL_FRect& b) { // Closest point on collision box int cX, cY; @@ -72,7 +72,7 @@ bool checkCollision(const Circle& a, const SDL_Rect& b) { } // Detector de colisiones entre dos rectangulos -bool checkCollision(const SDL_Rect& a, const SDL_Rect& b) { +bool checkCollision(const SDL_FRect& a, const SDL_FRect& b) { // Calcula las caras del rectangulo a const int leftA = a.x; const int rightA = a.x + a.w; @@ -107,7 +107,7 @@ bool checkCollision(const SDL_Rect& a, const SDL_Rect& b) { } // Detector de colisiones entre un punto y un rectangulo -bool checkCollision(const SDL_Point& p, const SDL_Rect& r) { +bool checkCollision(const SDL_FPoint& p, const SDL_FRect& r) { // Comprueba si el punto está a la izquierda del rectangulo if (p.x < r.x) { return false; @@ -133,7 +133,7 @@ bool checkCollision(const SDL_Point& p, const SDL_Rect& r) { } // Detector de colisiones entre una linea horizontal y un rectangulo -bool checkCollision(const LineHorizontal& l, const SDL_Rect& r) { +bool checkCollision(const LineHorizontal& l, const SDL_FRect& r) { // Comprueba si la linea esta por encima del rectangulo if (l.y < r.y) { return false; @@ -159,7 +159,7 @@ bool checkCollision(const LineHorizontal& l, const SDL_Rect& r) { } // Detector de colisiones entre una linea vertical y un rectangulo -bool checkCollision(const LineVertical& l, const SDL_Rect& r) { +bool checkCollision(const LineVertical& l, const SDL_FRect& r) { // Comprueba si la linea esta por la izquierda del rectangulo if (l.x < r.x) { return false; @@ -185,7 +185,7 @@ bool checkCollision(const LineVertical& l, const SDL_Rect& r) { } // Detector de colisiones entre una linea horizontal y un punto -bool checkCollision(const LineHorizontal& l, const SDL_Point& p) { +bool checkCollision(const LineHorizontal& l, const SDL_FPoint& p) { // Comprueba si el punto esta sobre la linea if (p.y > l.y) { return false; @@ -211,7 +211,7 @@ bool checkCollision(const LineHorizontal& l, const SDL_Point& p) { } // Detector de colisiones entre dos lineas -SDL_Point checkCollision(const Line& l1, const Line& l2) { +SDL_FPoint checkCollision(const Line& l1, const Line& l2) { const float x1 = l1.x1; const float y1 = l1.y1; const float x2 = l1.x2; @@ -238,7 +238,7 @@ SDL_Point checkCollision(const Line& l1, const Line& l2) { } // Detector de colisiones entre dos lineas -SDL_Point checkCollision(const LineDiagonal& l1, const LineVertical& l2) { +SDL_FPoint checkCollision(const LineDiagonal& l1, const LineVertical& l2) { const float x1 = l1.x1; const float y1 = l1.y1; const float x2 = l1.x2; @@ -279,7 +279,7 @@ void normalizeLine(LineDiagonal& l) { } // Detector de colisiones entre un punto y una linea diagonal -bool checkCollision(const SDL_Point& p, const LineDiagonal& l) { +bool checkCollision(const SDL_FPoint& p, const LineDiagonal& l) { // Comprueba si el punto está en alineado con la linea if (abs(p.x - l.x1) != abs(p.y - l.y1)) { return false; diff --git a/source/utils.h b/source/utils.h index 0948a08..3041f07 100644 --- a/source/utils.h +++ b/source/utils.h @@ -42,22 +42,22 @@ struct Circle { // Estructura para definir una linea horizontal struct LineHorizontal { - int x1, x2, y; + float x1, x2, y; }; // Estructura para definir una linea vertical struct LineVertical { - int x, y1, y2; + float x, y1, y2; }; // Estructura para definir una linea diagonal struct LineDiagonal { - int x1, y1, x2, y2; + float x1, y1, x2, y2; }; // Estructura para definir una linea struct Line { - int x1, y1, x2, y2; + float x1, y1, x2, y2; }; // Estructura para definir un color @@ -86,31 +86,31 @@ double distanceSquared(int x1, int y1, int x2, int y2); bool checkCollision(const Circle& a, const Circle& b); // Detector de colisiones entre un circulo y un rectangulo -bool checkCollision(const Circle& a, const SDL_Rect& b); +bool checkCollision(const Circle& a, const SDL_FRect& b); // Detector de colisiones entre un dos rectangulos -bool checkCollision(const SDL_Rect& a, const SDL_Rect& b); +bool checkCollision(const SDL_FRect& a, const SDL_FRect& b); // Detector de colisiones entre un punto y un rectangulo -bool checkCollision(const SDL_Point& p, const SDL_Rect& r); +bool checkCollision(const SDL_FPoint& p, const SDL_FRect& r); // Detector de colisiones entre una linea horizontal y un rectangulo -bool checkCollision(const LineHorizontal& l, const SDL_Rect& r); +bool checkCollision(const LineHorizontal& l, const SDL_FRect& r); // Detector de colisiones entre una linea vertical y un rectangulo -bool checkCollision(const LineVertical& l, const SDL_Rect& r); +bool checkCollision(const LineVertical& l, const SDL_FRect& r); // Detector de colisiones entre una linea horizontal y un punto -bool checkCollision(const LineHorizontal& l, const SDL_Point& p); +bool checkCollision(const LineHorizontal& l, const SDL_FPoint& p); // Detector de colisiones entre dos lineas -SDL_Point checkCollision(const Line& l1, const Line& l2); +SDL_FPoint checkCollision(const Line& l1, const Line& l2); // Detector de colisiones entre dos lineas -SDL_Point checkCollision(const LineDiagonal& l1, const LineVertical& l2); +SDL_FPoint checkCollision(const LineDiagonal& l1, const LineVertical& l2); // Detector de colisiones entre un punto y una linea diagonal -bool checkCollision(const SDL_Point& p, const LineDiagonal& l); +bool checkCollision(const SDL_FPoint& p, const LineDiagonal& l); // Normaliza una linea diagonal void normalizeLine(LineDiagonal& l);