corregides cridades a SDL3 i migrat casi tot de int a float. Falta jail_shader

This commit is contained in:
2025-10-15 12:16:50 +02:00
parent 7c102e42cc
commit e4a08d2ec7
52 changed files with 879 additions and 823 deletions

View File

@@ -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;

View File

@@ -1,61 +1,55 @@
#include "debug.h"
#include <algorithm> // Para max
#include <memory> // 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()
{
void Debug::init() {
Debug::debug_ = new Debug();
}
// [SINGLETON] Destruiremos el objeto con esta función estática
void Debug::destroy()
{
void Debug::destroy() {
delete Debug::debug_;
}
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
Debug *Debug::get()
{
Debug* Debug::get() {
return Debug::debug_;
}
// Dibuja en pantalla
void Debug::render()
{
void Debug::render() {
auto text = Resource::get()->getText("debug");
int y = y_;
int w = 0;
for (const auto &s : slot_)
{
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())
{
if (y > 192 - text->getCharacterSize()) {
y = y_;
x_ += w * text->getCharacterSize() + 2;
}
}
y = 0;
for (const auto &l : log_)
{
for (const auto& l : log_) {
text->writeColored(x_ + 10, y, l, static_cast<Uint8>(PaletteColor::WHITE));
y += text->getCharacterSize() + 1;
}
}
// Establece la posición donde se colocará la información de debug
void Debug::setPos(SDL_Point p)
{
void Debug::setPos(SDL_FPoint p) {
x_ = p.x;
y_ = p.y;
}

View File

@@ -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_; }

View File

@@ -13,21 +13,21 @@
#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 "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
@@ -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<unsigned int>(SDL_GetTicks()));
// Establece el filtro de la textura a nearest
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(static_cast<int>(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);
}
}
}

View File

@@ -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<SDL_RendererFlip>(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<SDL_FlipMode>(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_;
}

View File

@@ -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();
};

View File

@@ -1,211 +1,244 @@
#include "external/jail_audio.h"
#ifndef JA_USESDLMIXER
#include "jail_audio.h"
#include <SDL3/SDL.h>
#include <stdint.h> // Para uint8_t, uint32_t
#include <stdio.h> // Para NULL, fseek, fclose, fopen, fread, ftell
#include <SDL3/SDL.h> // 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 <stdint.h> // Para uint32_t, uint8_t
#include <stdio.h> // Para NULL, fseek, printf, fclose, fopen, fread, ftell, FILE, SEEK_END, SEEK_SET
#include <stdlib.h> // Para free, malloc
#include <string.h> // 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_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; i<JA_MAX_SIMULTANEOUS_CHANNELS; ++i) channels[i].state = JA_CHANNEL_FREE;
for (int i=0; i<JA_MAX_GROUPS; ++i) JA_soundVolume[i] = 0.5f;
//SDL_PauseAudioDevice(sdlAudioDevice);
//JA_timerID = SDL_AddTimer(30, JA_UpdateCallback, nullptr);
}
void JA_Quit() {
SDL_PauseAudioDevice(sdlAudioDevice, 1);
if (sdlAudioDevice != 0)
SDL_CloseAudioDevice(sdlAudioDevice);
void JA_Quit()
{
//if (JA_timerID) SDL_RemoveTimer(JA_timerID);
if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = 0;
}
JA_Music_t* JA_LoadMusic(Uint8* buffer, Uint32 length) {
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length)
{
JA_Music_t *music = new JA_Music_t();
int chan, samplerate;
JA_Music_t* music = new JA_Music_t();
short *output;
music->length = 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(&current_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;
//SDL_PauseAudioStreamDevice(channels[i].stream);
SDL_UnbindAudioStream(channels[i].stream);
}
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
}
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
{
if (channels[channel].state == JA_CHANNEL_PLAYING)
{
channels[channel].state = JA_CHANNEL_PAUSED;
//SDL_PauseAudioStreamDevice(channels[channel].stream);
SDL_UnbindAudioStream(channels[channel].stream);
}
}
}
void JA_ResumeChannel(const int channel) {
if (!JA_soundEnabled)
return;
void JA_ResumeChannel(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_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) {
}
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;
void JA_StopChannel(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_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;
}
#endif

View File

@@ -1,55 +1,44 @@
#pragma once
#include <SDL3/SDL.h>
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);

View File

@@ -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__

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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<int>(input)).button = button;
}
@@ -66,20 +66,20 @@ bool Input::checkInput(InputAction input, bool repeat, InputDeviceToUse device,
const int input_index = static_cast<int>(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) {
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 std::string name = SDL_GameControllerNameForIndex(i);
std::cout << "#" << i << ": " << name << std::endl;
controller_names_.push_back(name);
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<int>(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;

View File

@@ -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<SDL_GameController*> connected_controllers_; // Vector con todos los mandos conectados
std::vector<SDL_Gamepad*> connected_controllers_; // Vector con todos los mandos conectados
std::vector<SDL_Joystick*> joysticks_; // Vector con todos los joysticks conectados
std::vector<KeyBindings> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<std::vector<ControllerBindings>> 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;

View File

@@ -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;
}

View File

@@ -37,7 +37,7 @@ class Item {
// Variables
std::vector<Uint8> 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);

View File

@@ -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++;

View File

@@ -7,10 +7,10 @@
struct ItemTrackerData {
std::string name; // Nombre de la habitación donde se encuentra el objeto
std::vector<SDL_Point> pos; // Lista de objetos cogidos de la habitación
std::vector<SDL_FPoint> 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);
};

View File

@@ -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;
}
}

View File

@@ -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<int>(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<int>(DEFAULT_VIDEO_FILTER));
if (val == static_cast<int>(ScreenFilter::NEAREST) || val == static_cast<int>(ScreenFilter::LINEAR)) {

View File

@@ -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) {}
};

View File

@@ -217,7 +217,7 @@ void Player::applyGravity() {
// Recalcula la posición del jugador y su animación
void Player::move() {
last_position_ = {static_cast<int>(x_), static_cast<int>(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<int>(x_ + vx_);
proj.y = static_cast<int>(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<int>(x_) + WIDTH_;
proj.y = static_cast<int>(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<int>(x_);
proj.y = static_cast<int>(y_ + vy_);
proj.h = static_cast<int>(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<int>(x_);
proj.y = static_cast<int>(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<Uint8>(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<int>(x_), static_cast<int>(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<Uint8>(PaletteColor::BRIGHT_MAGENTA));
// Pinta rectangulo del jugador
SDL_Rect rect = getRect();
SDL_FRect rect = getRect();
surface->drawRectBorder(&rect, static_cast<Uint8>(PaletteColor::BRIGHT_CYAN));
// Pinta el rectangulo de movimiento

View File

@@ -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),
@@ -80,10 +80,10 @@ class Player {
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<SDL_Point> collider_points_; // Puntos de colisión con el mapa
std::vector<SDL_Point> under_feet_; // Contiene los puntos que hay bajo cada pie del jugador
std::vector<SDL_Point> feet_; // Contiene los puntos que hay en el pie del jugador
SDL_FRect collider_box_; // Caja de colisión con los enemigos u objetos
std::vector<SDL_FPoint> collider_points_; // Puntos de colisión con el mapa
std::vector<SDL_FPoint> under_feet_; // Contiene los puntos que hay bajo cada pie del jugador
std::vector<SDL_FPoint> 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
@@ -91,7 +91,7 @@ class Player {
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
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<JA_Sound_t*> jumping_sound_; // Vecor con todos los sonidos del salto
std::vector<JA_Sound_t*> falling_sound_; // Vecor con todos los sonidos de la caída
@@ -99,10 +99,10 @@ class Player {
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
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_Point debug_point_; // Punto para debug
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<int>(x_), static_cast<int>(y_), WIDTH_, HEIGHT_}; }
SDL_FRect getRect() { return {static_cast<int>(x_), static_cast<int>(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()}; }

View File

@@ -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<Uint8>(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<Uint8>(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<Uint8>(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;

View File

@@ -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<int>(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<int>(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;

View File

@@ -2,7 +2,6 @@
#include <SDL3/SDL.h>
#include <memory> // Para shared_ptr
#include <string> // Para string
#include <vector> // 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; };

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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<Uint8>(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<Surface>(options.game.width, options.game.height);
@@ -100,7 +99,7 @@ Screen::Screen(SDL_Window* window, SDL_Renderer* renderer)
renderer_surface_ = std::make_shared<std::shared_ptr<Surface>>(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);
@@ -250,17 +249,16 @@ void Screen::adjustWindowSize() {
// Ajusta el tamaño lógico del renderizador
void Screen::adjustRenderLogicalSize() {
SDL_SetRenderLogicalPresentation(renderer_, window_width_, window_height_);
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<Surface> Screen::getRendererSurface() { return (*renderer_surface_); }

View File

@@ -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<std::string> 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();

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -343,20 +343,20 @@ void Ending2::renderTexts() {
// Coloca los sprites en su sito
void Ending2::placeSprites() {
for (int i = 0; i < static_cast<int>(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<int>(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<int>(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<Surface>(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<SMovingSprite>(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<Surface>(w, h);
auto surface = std::make_shared<Surface>(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<SMovingSprite>(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<Surface>(w, h);
auto surface = std::make_shared<Surface>(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<SMovingSprite>(surface, pos));
texts_.back()->setVelY(SPRITE_DESP_SPEED_);
Screen::get()->setRendererSurface(previuos_renderer);

View File

@@ -70,8 +70,8 @@ class Ending2 {
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
std::vector<std::string> sprite_list_; // Lista con todos los sprites a dibujar
std::vector<Uint8> 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

View File

@@ -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<Uint8>(PaletteColor::BLACK));
// Pinta la rejilla

View File

@@ -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();

View File

@@ -22,7 +22,7 @@ class LoadingScreen {
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
SDL_FRect load_rect_ = {0, 0, 52, 1}; // Rectangulo para dibujar la pantalla de carga
// Actualiza las variables
void update();

View File

@@ -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_);
}

View File

@@ -38,7 +38,7 @@ class Title {
std::vector<TitleLetter> 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

View File

@@ -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);

View File

@@ -11,7 +11,7 @@ class Surface; // lines 9-9
struct AnimationData {
std::string name; // Nombre de la animacion
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
std::vector<SDL_FRect> 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

View File

@@ -3,13 +3,13 @@
#include "surface.h" // Para Surface
// Constructor
SMovingSprite::SMovingSprite(std::shared_ptr<Surface> surface, SDL_Rect pos, SDL_RendererFlip flip)
SMovingSprite::SMovingSprite(std::shared_ptr<Surface> 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> surface, SDL_Rect pos)
SMovingSprite::SMovingSprite(std::shared_ptr<Surface> 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<float>(rect.x);
y_ = static_cast<float>(rect.y);

View File

@@ -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> surface, SDL_Rect pos, SDL_RendererFlip flip);
SMovingSprite(std::shared_ptr<Surface> surface, SDL_Rect pos);
SMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos, SDL_FlipMode flip);
SMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos);
explicit SMovingSprite(std::shared_ptr<Surface> 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);

View File

@@ -3,19 +3,19 @@
#include "surface.h" // Para Surface
// Constructor
SSprite::SSprite(std::shared_ptr<Surface> surface, int x, int y, int w, int h)
SSprite::SSprite(std::shared_ptr<Surface> 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> surface, SDL_Rect rect)
SSprite::SSprite(std::shared_ptr<Surface> 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_(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;
}

View File

@@ -10,13 +10,13 @@ class SSprite {
protected:
// Variables
std::shared_ptr<Surface> 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<Surface>, int x, int y, int w, int h);
SSprite(std::shared_ptr<Surface>, SDL_Rect rect);
SSprite(std::shared_ptr<Surface>, float x, float y, float w, float h);
SSprite(std::shared_ptr<Surface>, SDL_FRect rect);
explicit SSprite(std::shared_ptr<Surface>);
// 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<Surface> getSurface() const { return surface_; }

View File

@@ -1,5 +1,6 @@
// IWYU pragma: no_include <bits/std_abs.h>
#include "surface.h"
#include <SDL3/SDL.h>
#include <algorithm> // 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<int>(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<int>(surface_data_->width));
int y_end = std::min(rect->y + rect->h, static_cast<int>(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<int>(surface_data_->width));
int y_end = std::min(rect->y + rect->h, static_cast<int>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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<size_t>(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<void**>(&pixels), &pitch) != 0) {
SDL_Rect lockRect;
if (destRect) {
lockRect.x = static_cast<int>(destRect->x);
lockRect.y = static_cast<int>(destRect->y);
lockRect.w = static_cast<int>(destRect->w);
lockRect.h = static_cast<int>(destRect->h);
}
// Usa lockRect solo si destRect no es nulo
if (SDL_LockTexture(texture, destRect ? &lockRect : nullptr, reinterpret_cast<void**>(&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()));
}
}

View File

@@ -22,8 +22,8 @@ Palette readPalFile(const std::string& file_path);
struct SurfaceData {
std::shared_ptr<Uint8[]> 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<Uint8[]>(new Uint8[w * h](), std::default_delete<Uint8[]>())),
SurfaceData(float w, float h)
: data(std::shared_ptr<Uint8[]>(new Uint8[static_cast<size_t>(w * h)](), std::default_delete<Uint8[]>())),
width(w),
height(h) {}
// Constructor para inicializar directamente con datos
SurfaceData(Uint16 w, Uint16 h, std::shared_ptr<Uint8[]> pixels)
SurfaceData(float w, float h, std::shared_ptr<Uint8[]> 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<SurfaceData> getSurfaceData() const { return surface_data_; }
void setSurfaceData(std::shared_ptr<SurfaceData> 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_; }

View File

@@ -88,7 +88,7 @@ Text::Text(std::shared_ptr<Surface> surface, const std::string& text_file) {
}
// Crea los objetos
sprite_ = std::make_unique<SSprite>(surface, (SDL_Rect){0, 0, box_width_, box_height_});
sprite_ = std::make_unique<SSprite>(surface, (SDL_FRect){0, 0, box_width_, box_height_});
// Inicializa variables
fixed_width_ = false;
@@ -106,7 +106,7 @@ Text::Text(std::shared_ptr<Surface> surface, std::shared_ptr<TextFile> text_file
}
// Crea los objetos
sprite_ = std::make_unique<SSprite>(surface, (SDL_Rect){0, 0, box_width_, box_height_});
sprite_ = std::make_unique<SSprite>(surface, (SDL_FRect){0, 0, box_width_, box_height_});
// Inicializa variables
fixed_width_ = false;

View File

@@ -194,7 +194,7 @@ void Notifier::show(std::vector<std::string> 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<std::string> 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<Uint8>(PaletteColor::CYAN));
}
// Dibuja el icono de la notificación
if (has_icons_ && icon >= 0 && texts.size() >= 2) {
auto sp = std::make_unique<SSprite>(icon_surface_, (SDL_Rect){0, 0, ICON_SIZE_, ICON_SIZE_});
auto sp = std::make_unique<SSprite>(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();

View File

@@ -46,7 +46,7 @@ class Notifier {
std::vector<std::string> 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

View File

@@ -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;

View File

@@ -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);