From 45b763791a5bb5348b62eb6f3346bb28379c2bf8 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 23 Mar 2025 22:56:10 +0100 Subject: [PATCH] migrat a SDL3 --- CMakeLists.txt | 55 ++++++++++++++++++++++++++++++++ Makefile | 25 +++++---------- source/ball.cpp | 10 +++--- source/ball.h | 2 +- source/defines.h | 26 +++++++++------- source/main.cpp | 61 ++++++++++++++++-------------------- source/sprite.cpp | 47 +++++++++++++--------------- source/sprite.h | 20 ++++++------ source/texture.cpp | 78 ++++++++++++++++++++++------------------------ source/texture.h | 14 ++++----- 10 files changed, 186 insertions(+), 152 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ba80ab7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.20) +project(demo4_sprites) + +# Establecer el estándar de C++ +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Opciones comunes de compilación +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Os") + +# Buscar SDL3 automáticamente +find_package(SDL3 REQUIRED) + +# Si no se encuentra SDL3, generar un error +if (NOT SDL3_FOUND) + message(FATAL_ERROR "SDL3 no encontrado. Por favor, verifica su instalación.") +endif() + +# Archivos fuente +file(GLOB SOURCE_FILES source/*.cpp) + +# Comprobar si se encontraron archivos fuente +if(NOT SOURCE_FILES) + message(FATAL_ERROR "No se encontraron archivos fuente en el directorio 'source/'. Verifica la ruta.") +endif() + +# Nombre del ejecutable +set(EXECUTABLE_NAME demo4_sprites) + +# Detectar la plataforma y configuraciones específicas +if(WIN32) + set(PLATFORM windows) + set(LINK_LIBS ${SDL3_LIBRARIES} mingw32 ws2_32) + set(EXECUTABLE_EXTENSION ".exe") +elseif(UNIX AND NOT APPLE) + set(PLATFORM linux) + set(LINK_LIBS ${SDL3_LIBRARIES}) + set(EXECUTABLE_EXTENSION ".out") +elseif(APPLE) + set(PLATFORM macos) + set(LINK_LIBS ${SDL3_LIBRARIES}) + set(EXECUTABLE_EXTENSION ".out") +endif() + +# Incluir directorios de SDL3 +include_directories(${SDL3_INCLUDE_DIRS}) + +# Añadir el ejecutable +add_executable(${EXECUTABLE_NAME}${EXECUTABLE_EXTENSION} ${SOURCE_FILES}) + +# Especificar la ubicación del ejecutable (en la raíz del proyecto) +set_target_properties(${EXECUTABLE_NAME}${EXECUTABLE_EXTENSION} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) + +# Enlazar las bibliotecas necesarias +target_link_libraries(${EXECUTABLE_NAME}${EXECUTABLE_EXTENSION} ${LINK_LIBS}) diff --git a/Makefile b/Makefile index 2d2f3c3..02aa2d2 100644 --- a/Makefile +++ b/Makefile @@ -1,31 +1,22 @@ # Variables comunes source := source/*.cpp -executable_name := demo_pelotas1 -CXX := g++ # Cambiar a clang++ si prefieres -CXXFLAGS := -std=c++11 -Wall # Opciones comunes de compilación -LDFLAGS := -lSDL2 # Flags de enlace comunes +executable_name := demo4_sprites +CXXFLAGS := -std=c++20 -Wall -Os # Opciones comunes de compilación +LDFLAGS := -lSDL2 # Flags de enlace comunes +OUTPUT_EXT := -# Detectar plataforma +# Detectar plataforma y configurar ifeq ($(OS),Windows_NT) - PLATFORM := windows LDFLAGS += -lmingw32 -lws2_32 -lSDL2main OUTPUT_EXT := .exe else - PLATFORM := unix # Unificación para macOS y Linux OUTPUT_EXT := .out endif -# Regla principal: compilar según la plataforma detectada -all: $(PLATFORM) - -# Compilación para Windows -windows: - $(CXX) $(source) $(CXXFLAGS) $(LDFLAGS) -o $(executable_name)$(OUTPUT_EXT) - -# Compilación para Unix (Linux y macOS) -unix: +# Regla principal: compilar el ejecutable +all: $(CXX) $(source) $(CXXFLAGS) $(LDFLAGS) -o $(executable_name)$(OUTPUT_EXT) # Regla para limpiar archivos generados clean: - rm -f $(executable_name)* \ No newline at end of file + rm -f $(executable_name)$(OUTPUT_EXT) \ No newline at end of file diff --git a/source/ball.cpp b/source/ball.cpp index 75c2a28..b415daf 100644 --- a/source/ball.cpp +++ b/source/ball.cpp @@ -12,7 +12,7 @@ Ball::Ball(int x, int y, int w, int h, int vx, int vy, Texture *texture) sprite = new Sprite(texture); sprite->setPos({x, y}); sprite->setSize(w, h); - sprite->setClip({0, 0, w, h}); + sprite->setClip({0, 0, static_cast(w), static_cast(h)}); color = {(rand() % 192) + 32, (rand() % 192) + 32, (rand() % 192) + 32}; } @@ -45,9 +45,9 @@ void Ball::update() collision = true; } - if (x + w > SCREEN_WIDTH) + if (x + w > DEMO_WIDTH) { - x = SCREEN_WIDTH - w; + x = DEMO_WIDTH - w; vx = -luckyX; collision = true; } @@ -59,9 +59,9 @@ void Ball::update() collision = true; } - if (y + h > SCREEN_HEIGHT) + if (y + h > DEMO_HEIGHT) { - y = SCREEN_HEIGHT - h; + y = DEMO_HEIGHT - h; vy = -luckyY; collision = true; } diff --git a/source/ball.h b/source/ball.h index 12266d8..1e58580 100644 --- a/source/ball.h +++ b/source/ball.h @@ -13,7 +13,7 @@ private: int w; // Ancho int h; // Alto int vx, vy; // Velocidad - color_t color; // Color de la pelota + Color color; // Color de la pelota public: // Constructor diff --git a/source/defines.h b/source/defines.h index 666a295..f73e084 100644 --- a/source/defines.h +++ b/source/defines.h @@ -1,19 +1,21 @@ #pragma once -#include "SDL2/SDL.h" -#include /* srand, rand */ +constexpr Uint64 DEMO_SPEED = 1000/60; -#define SCREEN_WIDTH 480 -#define SCREEN_HEIGHT 360 -#define NUM_BALLS 100 -#define BALL_SIZE 36 -#define NUM_FRAMES 4 -#define BG_R 96 -#define BG_G 96 -#define BG_B 96 -#define TEXTURE_FILE "resources/soccer_ball.png" +constexpr int DEMO_WIDTH = 480; +constexpr int DEMO_HEIGHT = 360; +constexpr int WINDOW_ZOOM = 2; +constexpr int NUM_BALLS = 100; +constexpr int BALL_SIZE = 36; +constexpr int NUM_FRAMES = 4; -struct color_t +constexpr int BG_R = 96; +constexpr int BG_G = 96; +constexpr int BG_B = 96; + +constexpr char TEXTURE_FILE[] = "resources/soccer_ball.png"; + +struct Color { int r, g, b; }; \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 910e1bc..d1bc459 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -2,15 +2,15 @@ #include "ball.h" #include "defines.h" #include +#include -SDL_Window *window = NULL; -SDL_Renderer *renderer = NULL; -SDL_Event *event; +SDL_Window *window = nullptr; +SDL_Renderer *renderer = nullptr; Texture *texture = nullptr; Ball *ball[NUM_BALLS]; -bool shouldExit = false; -Uint32 ticks = 0; +bool should_exit = false; +Uint64 ticks = 0; bool init() { @@ -18,7 +18,7 @@ bool init() bool success = true; // Initialize SDL - if (SDL_Init(SDL_INIT_VIDEO) < 0) + if (SDL_Init(SDL_INIT_VIDEO)) { printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError()); success = false; @@ -26,7 +26,7 @@ bool init() else { // Create window - window = SDL_CreateWindow("demo_pelotas1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2, SDL_WINDOW_SHOWN); + window = SDL_CreateWindow("demo_pelotas1", DEMO_WIDTH * WINDOW_ZOOM, DEMO_HEIGHT * WINDOW_ZOOM, SDL_WINDOW_OPENGL); if (window == NULL) { printf("Window could not be created! SDL Error: %s\n", SDL_GetError()); @@ -35,7 +35,7 @@ bool init() else { // Create renderer for window - renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + renderer = SDL_CreateRenderer(window, nullptr); if (renderer == NULL) { printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); @@ -46,26 +46,24 @@ bool init() // Initialize renderer color SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); + SDL_SetRenderLogicalPresentation(renderer, DEMO_WIDTH, DEMO_HEIGHT, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE); } } } - event = new SDL_Event(); - texture = new Texture(renderer, TEXTURE_FILE); for (int i = 0; i < NUM_BALLS; ++i) { - const int vx = rand() % 2 == 0 ? 1 : -1; - const int vy = rand() % 2 == 0 ? 1 : -1; - const int x = rand() % SCREEN_WIDTH; - const int y = rand() % SCREEN_HEIGHT; - const int size = BALL_SIZE; - ball[i] = new Ball(x, y, size, size, vx, vy, texture); + const int VX = rand() % 2 == 0 ? 1 : -1; + const int VY = rand() % 2 == 0 ? 1 : -1; + const int X = rand() % DEMO_WIDTH; + const int Y = rand() % DEMO_HEIGHT; + constexpr int SIZE = BALL_SIZE; + ball[i] = new Ball(X, Y, SIZE, SIZE, VX, VY, texture); } ticks = SDL_GetTicks(); - srand(time(NULL)); + srand(time(nullptr)); return success; } @@ -75,13 +73,6 @@ void close() // Destroy window SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); - window = NULL; - renderer = NULL; - - if (event) - { - delete event; - } if (texture) { @@ -102,24 +93,26 @@ void close() void checkEvents() { + SDL_Event event; + // Comprueba los eventos que hay en la cola - while (SDL_PollEvent(event) != 0) + while (SDL_PollEvent(&event) != 0) { // Evento de salida de la aplicación - if (event->type == SDL_QUIT) + if (event.type == SDL_EVENT_QUIT) { - shouldExit = true; + should_exit = true; break; } - if (event->type == SDL_KEYDOWN && event->key.repeat == 0) + if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat == 0) { - switch (event->key.keysym.sym) + switch (event.key.key) { case SDLK_ESCAPE: - shouldExit = true; + should_exit = true; break; - + default: break; } @@ -129,7 +122,7 @@ void checkEvents() void update() { - if (SDL_GetTicks() - ticks > 15) + if (SDL_GetTicks() - ticks > DEMO_SPEED) { ticks = SDL_GetTicks(); @@ -157,7 +150,7 @@ int main(int argc, char *args[]) { init(); - while (!shouldExit) + while (!should_exit) { update(); checkEvents(); diff --git a/source/sprite.cpp b/source/sprite.cpp index 5d00818..e98b1a2 100644 --- a/source/sprite.cpp +++ b/source/sprite.cpp @@ -3,72 +3,67 @@ // Constructor Sprite::Sprite(Texture *texture) { - this->texture = texture; - pos = {0, 0, 0, 0}; - clip = {0, 0, 0, 0}; - frame = 0; - numFrames = NUM_FRAMES; - animationSpeed = 20; - animationCounter = 0; -} - -// Destructor -Sprite::~Sprite() -{ + texture_ = texture; + pos_ = {0, 0, 0, 0}; + clip_ = {0, 0, 0, 0}; + frame_ = 0; + num_frames_ = NUM_FRAMES; + animation_speed_ = 20; + animation_counter_ = 0; } // Establece la posición del sprite void Sprite::setPos(SDL_Point pos) { - this->pos.x = pos.x; - this->pos.y = pos.y; + pos_.x = pos.x; + pos_.y = pos.y; } // Pinta el sprite void Sprite::render() { - texture->render(&clip, &pos); + texture_->render(&clip_, &pos_); } // Actualiza la lógica de la clase void Sprite::update() { - animationCounter++; - if (animationCounter % animationSpeed == 0) + animation_counter_++; + if (animation_counter_ % animation_speed_ == 0) { animate(); } } // Establece el rectangulo de la textura que se va a pintar -void Sprite::setClip(SDL_Rect clip) +void Sprite::setClip(SDL_FRect clip) { - this->clip = clip; + clip_ = clip; } // Establece el tamaño del sprite void Sprite::setSize(int w, int h) { - this->pos.w = w; - this->pos.h = h; + pos_.w = w; + pos_.h = h; } // Anima el sprite void Sprite::animate() { - frame = (frame + 1) % numFrames; - clip.x = frame * pos.w; + frame_ = (frame_ + 1) % num_frames_; + clip_.x = frame_ * pos_.w; } // Modulación de color void Sprite::setColor(int r, int g, int b) { - texture->setColor(r, g, b); + texture_->setColor(r, g, b); } // Cambia la velocidad de la animación void Sprite::setAnimationSpeed(int value) { - animationSpeed = value; - animationCounter = 0; + animation_speed_ = value; + animation_counter_ = 0; } \ No newline at end of file diff --git a/source/sprite.h b/source/sprite.h index d57dfd6..5211be9 100644 --- a/source/sprite.h +++ b/source/sprite.h @@ -6,23 +6,23 @@ class Sprite { private: - Texture *texture; // Textura con los gráficos del sprite - SDL_Rect pos; // Posición y tamaño del sprite - SDL_Rect clip; // Parte de la textura que se va a dibujar - int frame; // Frame a dibujar de la textura definido en clip - int numFrames; // Numero total de frames - int animationSpeed; // Velocidad de animación - int animationCounter; // Contador para la animación + Texture *texture_; // Textura con los gráficos del sprite + SDL_FRect pos_; // Posición y tamaño del sprite + SDL_FRect clip_; // Parte de la textura que se va a dibujar + int frame_; // Frame a dibujar de la textura definido en clip + int num_frames_; // Numero total de frames + int animation_speed_; // Velocidad de animación + int animation_counter_; // Contador para la animación // Anima el sprite void animate(); public: // Constructor - Sprite(Texture *texture); + explicit Sprite(Texture *texture); // Destructor - ~Sprite(); + ~Sprite() = default; // Establece la posición del sprite void setPos(SDL_Point pos); @@ -34,7 +34,7 @@ public: void update(); // Establece el rectangulo de la textura que se va a pintar - void setClip(SDL_Rect clip); + void setClip(SDL_FRect clip); // Establece el tamaño del sprite void setSize(int w, int h); diff --git a/source/texture.cpp b/source/texture.cpp index ea7eed8..d4824d9 100644 --- a/source/texture.cpp +++ b/source/texture.cpp @@ -6,19 +6,19 @@ Texture::Texture(SDL_Renderer *renderer) { - this->renderer = renderer; - texture = NULL; - width = 0; - height = 0; + renderer_ = renderer; + texture_ = nullptr; + width_ = 0; + height_ = 0; } -Texture::Texture(SDL_Renderer *renderer, std::string filepath) +Texture::Texture(SDL_Renderer *renderer, std::string file_path) { - this->renderer = renderer; - texture = NULL; - width = 0; - height = 0; - loadFromFile(filepath); + renderer_ = renderer; + texture_ = nullptr; + width_ = 0; + height_ = 0; + loadFromFile(file_path); } Texture::~Texture() @@ -26,12 +26,12 @@ Texture::~Texture() free(); } -bool Texture::loadFromFile(std::string path) +bool Texture::loadFromFile(std::string file_path) { - const std::string filename = path.substr(path.find_last_of("\\/") + 1); + const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1); int req_format = STBI_rgb_alpha; int width, height, orig_format; - unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format); + unsigned char *data = stbi_load(file_path.c_str(), &width, &height, &orig_format, req_format); if (data == nullptr) { SDL_Log("Loading image failed: %s", stbi_failure_reason()); @@ -39,20 +39,18 @@ bool Texture::loadFromFile(std::string path) } else { - std::cout << "Image loaded: " << filename.c_str() << std::endl; + std::cout << "Image loaded: " << filename.c_str() << std::endl; } - int depth, pitch; - Uint32 pixel_format; + int pitch; + SDL_PixelFormat pixel_format; if (req_format == STBI_rgb) { - depth = 24; pitch = 3 * width; // 3 bytes por pixel * pixels por linea pixel_format = SDL_PIXELFORMAT_RGB24; } else { // STBI_rgb_alpha (RGBA) - depth = 32; pitch = 4 * width; pixel_format = SDL_PIXELFORMAT_RGBA32; } @@ -61,69 +59,69 @@ bool Texture::loadFromFile(std::string path) free(); // La textura final - SDL_Texture *newTexture = nullptr; + SDL_Texture *new_texture = nullptr; // Carga la imagen desde una ruta específica - SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format); - if (loadedSurface == nullptr) + SDL_Surface *loaded_surface = SDL_CreateSurfaceFrom(width, height, pixel_format, (void *)data, pitch); + if (loaded_surface == nullptr) { - std::cout << "Unable to load image " << path.c_str() << std::endl; + std::cout << "Unable to load image " << file_path.c_str() << std::endl; } else { // Crea la textura desde los pixels de la surface - newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); - if (newTexture == nullptr) + new_texture = SDL_CreateTextureFromSurface(renderer_, loaded_surface); + if (new_texture == nullptr) { - std::cout << "Unable to create texture from " << path.c_str() << "! SDL Error: " << SDL_GetError() << std::endl; + std::cout << "Unable to create texture from " << file_path.c_str() << "! SDL Error: " << SDL_GetError() << std::endl; } else { // Obtiene las dimensiones de la imagen - this->width = loadedSurface->w; - this->height = loadedSurface->h; + width_ = loaded_surface->w; + height_ = loaded_surface->h; } // Elimina la textura cargada - SDL_FreeSurface(loadedSurface); + SDL_DestroySurface(loaded_surface); } // Return success stbi_image_free(data); - texture = newTexture; - return texture != nullptr; + texture_ = new_texture; + return texture_ != nullptr; } void Texture::free() { // Free texture if it exists - if (texture != NULL) + if (texture_ != NULL) { - SDL_DestroyTexture(texture); - texture = NULL; - width = 0; - height = 0; + SDL_DestroyTexture(texture_); + texture_ = NULL; + width_ = 0; + height_ = 0; } } -void Texture::render(SDL_Rect *src, SDL_Rect *dst) +void Texture::render(SDL_FRect *src, SDL_FRect *dst) { // Render to screen - SDL_RenderCopy(renderer, texture, src, dst); + SDL_RenderTexture(renderer_, texture_, src, dst); } int Texture::getWidth() { - return width; + return width_; } int Texture::getHeight() { - return height; + return height_; } // Modulación de color void Texture::setColor(int r, int g, int b) { - SDL_SetTextureColorMod(texture, r, g, b); + SDL_SetTextureColorMod(texture_, r, g, b); } diff --git a/source/texture.h b/source/texture.h index efc85ab..4989369 100644 --- a/source/texture.h +++ b/source/texture.h @@ -1,23 +1,23 @@ #pragma once -#include +#include #include // Texture wrapper class class Texture { private: - SDL_Renderer *renderer; - SDL_Texture *texture; + SDL_Renderer *renderer_; + SDL_Texture *texture_; // Image dimensions - int width; - int height; + int width_; + int height_; public: // Initializes variables Texture(SDL_Renderer *renderer); - Texture(SDL_Renderer *renderer, std::string filepath); + Texture(SDL_Renderer *renderer, std::string file_path); // Deallocates memory ~Texture(); @@ -29,7 +29,7 @@ public: void free(); // Renders texture at given point - void render(SDL_Rect *src = nullptr, SDL_Rect *dst = nullptr); + void render(SDL_FRect *src = nullptr, SDL_FRect *dst = nullptr); // Gets image dimensions int getWidth();