creat project.h

This commit is contained in:
2025-11-27 21:47:08 +01:00
parent 0d69af667d
commit 2b1311042f
18 changed files with 708 additions and 338 deletions

View File

@@ -0,0 +1,212 @@
// sdl_manager.cpp - Implementació del gestor SDL3
// © 2025 Port a C++20 amb SDL3
#include "sdl_manager.hpp"
#include "core/defaults.hpp"
#include "project.h"
#include <iostream>
#include <algorithm>
#include <format>
SDLManager::SDLManager()
: finestra_(nullptr)
, renderer_(nullptr)
, current_width_(Defaults::Window::WIDTH)
, current_height_(Defaults::Window::HEIGHT)
, is_fullscreen_(false)
, max_width_(1920)
, max_height_(1080)
{
// Inicialitzar SDL3
if (!SDL_Init(SDL_INIT_VIDEO)) {
std::cerr << "Error inicialitzant SDL3: " << SDL_GetError() << std::endl;
return;
}
// Calcular mida màxima des del display
calculateMaxWindowSize();
// Construir títol dinàmic igual que en pollo
std::string window_title = std::format("{} v{} ({})",
Project::LONG_NAME,
Project::VERSION,
Project::COPYRIGHT
);
// Crear finestra CENTRADA (SDL ho fa automàticament amb CENTERED)
finestra_ = SDL_CreateWindow(
window_title.c_str(),
current_width_,
current_height_,
SDL_WINDOW_RESIZABLE // Permetre resize manual també
);
if (!finestra_) {
std::cerr << "Error creant finestra: " << SDL_GetError() << std::endl;
SDL_Quit();
return;
}
// IMPORTANT: Centrar explícitament la finestra
SDL_SetWindowPosition(finestra_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
// Crear renderer amb acceleració
renderer_ = SDL_CreateRenderer(finestra_, nullptr);
if (!renderer_) {
std::cerr << "Error creant renderer: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(finestra_);
SDL_Quit();
return;
}
// CRÍTIC: Configurar viewport scaling
updateLogicalPresentation();
std::cout << "SDL3 inicialitzat: " << current_width_ << "x" << current_height_
<< " (logic: " << Defaults::Game::WIDTH << "x" << Defaults::Game::HEIGHT << ")" << std::endl;
}
SDLManager::~SDLManager() {
if (renderer_) {
SDL_DestroyRenderer(renderer_);
renderer_ = nullptr;
}
if (finestra_) {
SDL_DestroyWindow(finestra_);
finestra_ = nullptr;
}
SDL_Quit();
std::cout << "SDL3 netejat correctament" << std::endl;
}
void SDLManager::calculateMaxWindowSize() {
SDL_DisplayID display = SDL_GetPrimaryDisplay();
const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(display);
if (mode) {
// Deixar marge de 100px per a decoracions de l'OS
max_width_ = mode->w - 100;
max_height_ = mode->h - 100;
std::cout << "Display detectat: " << mode->w << "x" << mode->h
<< " (max finestra: " << max_width_ << "x" << max_height_ << ")" << std::endl;
} else {
// Fallback conservador
max_width_ = 1920;
max_height_ = 1080;
std::cerr << "No s'ha pogut detectar el display, usant fallback: "
<< max_width_ << "x" << max_height_ << std::endl;
}
}
void SDLManager::updateLogicalPresentation() {
// AIXÒ ÉS LA MÀGIA: El joc SEMPRE dibuixa en 640x480,
// SDL escala automàticament a la mida física de la finestra
SDL_SetRenderLogicalPresentation(
renderer_,
Defaults::Game::WIDTH, // 640 (lògic)
Defaults::Game::HEIGHT, // 480 (lògic)
SDL_LOGICAL_PRESENTATION_LETTERBOX // Mantenir aspect ratio 4:3
);
}
void SDLManager::increaseWindowSize() {
if (is_fullscreen_) return; // No operar en fullscreen
int new_width = current_width_ + Defaults::Window::SIZE_INCREMENT;
int new_height = current_height_ + Defaults::Window::SIZE_INCREMENT;
// Clamp a màxim
new_width = std::min(new_width, max_width_);
new_height = std::min(new_height, max_height_);
if (new_width != current_width_ || new_height != current_height_) {
applyWindowSize(new_width, new_height);
std::cout << "F2: Finestra augmentada a " << new_width << "x" << new_height << std::endl;
}
}
void SDLManager::decreaseWindowSize() {
if (is_fullscreen_) return;
int new_width = current_width_ - Defaults::Window::SIZE_INCREMENT;
int new_height = current_height_ - Defaults::Window::SIZE_INCREMENT;
// Clamp a mínim
new_width = std::max(new_width, Defaults::Window::MIN_WIDTH);
new_height = std::max(new_height, Defaults::Window::MIN_HEIGHT);
if (new_width != current_width_ || new_height != current_height_) {
applyWindowSize(new_width, new_height);
std::cout << "F1: Finestra reduïda a " << new_width << "x" << new_height << std::endl;
}
}
void SDLManager::applyWindowSize(int new_width, int new_height) {
// Obtenir posició actual ABANS del resize
int old_x, old_y;
SDL_GetWindowPosition(finestra_, &old_x, &old_y);
int old_width = current_width_;
int old_height = current_height_;
// Actualitzar mida
SDL_SetWindowSize(finestra_, new_width, new_height);
current_width_ = new_width;
current_height_ = new_height;
// CENTRADO INTEL·LIGENT (algoritme de pollo)
// Calcular nova posició per mantenir la finestra centrada sobre si mateixa
int delta_width = old_width - new_width;
int delta_height = old_height - new_height;
int new_x = old_x + (delta_width / 2);
int new_y = old_y + (delta_height / 2);
// Evitar que la finestra surti de la pantalla
constexpr int TITLEBAR_HEIGHT = 35; // Alçada aproximada de la barra de títol
new_x = std::max(new_x, 0);
new_y = std::max(new_y, TITLEBAR_HEIGHT);
SDL_SetWindowPosition(finestra_, new_x, new_y);
// NO cal actualitzar el logical presentation aquí,
// SDL ho maneja automàticament
}
void SDLManager::toggleFullscreen() {
is_fullscreen_ = !is_fullscreen_;
SDL_SetWindowFullscreen(finestra_, is_fullscreen_);
std::cout << "F3: Fullscreen " << (is_fullscreen_ ? "activat" : "desactivat") << std::endl;
// En fullscreen, SDL gestiona tot automàticament
// En sortir, restaura la mida anterior
}
bool SDLManager::handleWindowEvent(const SDL_Event& event) {
if (event.type == SDL_EVENT_WINDOW_RESIZED) {
// Usuari ha redimensionat manualment (arrossegar vora)
// Actualitzar el nostre tracking
SDL_GetWindowSize(finestra_, &current_width_, &current_height_);
std::cout << "Finestra redimensionada manualment a "
<< current_width_ << "x" << current_height_ << std::endl;
return true;
}
return false;
}
void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) {
if (!renderer_) return;
SDL_SetRenderDrawColor(renderer_, r, g, b, 255);
SDL_RenderClear(renderer_);
}
void SDLManager::presenta() {
if (!renderer_) return;
SDL_RenderPresent(renderer_);
}

View File

@@ -0,0 +1,49 @@
// sdl_manager.hpp - Gestor d'inicialització de SDL3
// © 2025 Port a C++20 amb SDL3
#ifndef SDL_MANAGER_HPP
#define SDL_MANAGER_HPP
#include <SDL3/SDL.h>
#include <cstdint>
class SDLManager {
public:
SDLManager();
~SDLManager();
// No permetre còpia ni assignació
SDLManager(const SDLManager&) = delete;
SDLManager& operator=(const SDLManager&) = delete;
// [NUEVO] Gestió de finestra dinàmica
void increaseWindowSize(); // F2: +100px
void decreaseWindowSize(); // F1: -100px
void toggleFullscreen(); // F3
bool handleWindowEvent(const SDL_Event& event); // Per a SDL_EVENT_WINDOW_RESIZED
// Funcions principals (renderitzat)
void neteja(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0);
void presenta();
// Getters
SDL_Renderer* obte_renderer() { return renderer_; }
private:
SDL_Window* finestra_;
SDL_Renderer* renderer_;
// [NUEVO] Estat de la finestra
int current_width_; // Mida física actual
int current_height_;
bool is_fullscreen_;
int max_width_; // Calculat des del display
int max_height_;
// [NUEVO] Funcions internes
void calculateMaxWindowSize(); // Llegir resolució del display
void applyWindowSize(int width, int height); // Canviar mida + centrar
void updateLogicalPresentation(); // Actualitzar viewport
};
#endif // SDL_MANAGER_HPP

26
source/game/constants.hpp Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#include "core/defaults.hpp"
// Aliases per a backward compatibility amb codi existent
// Permet usar Constants::MARGE_ESQ en lloc de Defaults::Game::MARGIN_LEFT
namespace Constants {
// Marges de l'àrea de joc
constexpr int MARGE_DALT = Defaults::Game::MARGIN_TOP;
constexpr int MARGE_BAIX = Defaults::Game::MARGIN_BOTTOM;
constexpr int MARGE_ESQ = Defaults::Game::MARGIN_LEFT;
constexpr int MARGE_DRET = Defaults::Game::MARGIN_RIGHT;
// Límits de polígons i objectes
constexpr int MAX_IPUNTS = Defaults::Entities::MAX_IPUNTS;
constexpr int MAX_ORNIS = Defaults::Entities::MAX_ORNIS;
constexpr int MAX_BALES = Defaults::Entities::MAX_BALES;
// Velocitats (valors legacy del codi Pascal)
constexpr int VELOCITAT = static_cast<int>(Defaults::Physics::ENEMY_SPEED);
constexpr int VELOCITAT_MAX = static_cast<int>(Defaults::Physics::BULLET_SPEED);
// Matemàtiques
constexpr float PI = Defaults::Math::PI;
}

View File

@@ -3,6 +3,7 @@
// © 2025 Port a C++20 amb SDL3
#include "joc_asteroides.hpp"
#include "core/rendering/primitives.hpp"
#include <cmath>
#include <iostream>
#include <cstdlib>
@@ -122,18 +123,6 @@ void JocAsteroides::actualitzar(float delta_time) {
}
}
// DEBUG: Mostrar info de la nau (temporal)
static float time_accumulator = 0.0f;
time_accumulator += delta_time;
if (time_accumulator >= 1.0f) { // Cada segon
std::cout << "Nau: pos(" << nau_.centre.x << "," << nau_.centre.y
<< ") vel=" << static_cast<int>(nau_.velocitat) << " px/s"
<< " angle=" << static_cast<int>(nau_.angle * 180.0f / Constants::PI) << "°"
<< " dt=" << static_cast<int>(delta_time * 1000.0f) << "ms"
<< std::endl;
time_accumulator -= 1.0f;
}
// Actualitzar moviment i rotació dels enemics (ORNIs)
// Basat en el codi Pascal original: lines 429-432
@@ -224,60 +213,7 @@ void JocAsteroides::processar_input(const SDL_Event& event) {
}
}
// Funcions utilitàries - Geometria i matemàtiques
// Basades en el codi Pascal original
float JocAsteroides::modul(const Punt& p) const {
// Càlcul de la magnitud d'un vector: sqrt(x² + y²)
return std::sqrt(static_cast<float>(p.x * p.x + p.y * p.y));
}
void JocAsteroides::diferencia(const Punt& o, const Punt& d, Punt& p) const {
// Resta de vectors (origen - destí)
p.x = o.x - d.x;
p.y = o.y - d.y;
}
int JocAsteroides::distancia(const Punt& o, const Punt& d) const {
// Distància entre dos punts
Punt p;
diferencia(o, d, p);
return static_cast<int>(std::round(modul(p)));
}
float JocAsteroides::angle_punt(const Punt& p) const {
// Càlcul de l'angle d'un punt (arctan)
if (p.y != 0) {
return std::atan(static_cast<float>(p.x) / static_cast<float>(p.y));
}
return 0.0f;
}
void JocAsteroides::crear_poligon_regular(Poligon& pol, uint8_t n, float r) {
// Crear un polígon regular amb n costats i radi r
// Distribueix els punts uniformement al voltant d'un cercle
float interval = 2.0f * Constants::PI / n;
float act = 0.0f;
for (uint8_t i = 0; i < n; i++) {
pol.ipuntx[i].r = r;
pol.ipuntx[i].angle = act;
act += interval;
}
// Inicialitzar propietats del polígon
pol.centre.x = 320.0f;
pol.centre.y = 200.0f;
pol.angle = 0.0f;
// Convertir velocitat de px/frame a px/s: 2 px/frame × 20 FPS = 40 px/s
pol.velocitat = static_cast<float>(Constants::VELOCITAT) * 20.0f;
pol.n = n;
// Convertir rotació de rad/frame a rad/s: 0.0785 rad/frame × 20 FPS = 1.57 rad/s (~90°/s)
pol.drotacio = 0.078539816f * 20.0f;
pol.rotacio = 0.0f;
pol.esta = true;
}
// Funcions de dibuix
bool JocAsteroides::linea(int x1, int y1, int x2, int y2, bool dibuixar) {
// Algorisme de Bresenham per dibuixar línies
@@ -418,38 +354,46 @@ void JocAsteroides::rota_pol(const Poligon& pol, float angul, bool dibuixar) {
void JocAsteroides::mou_orni(Poligon& orni, float delta_time) {
// Moviment autònom d'ORNI (enemic pentàgon)
// Basat en el codi Pascal original: procedure mou_orni
// Basat EXACTAMENT en el codi Pascal original: ASTEROID.PAS lines 279-293
//
// IMPORTANT: El Pascal original NO té canvi aleatori continu!
// Només ajusta l'angle quan toca una paret.
// Cambio aleatori d'angle (5% probabilitat per crida)
// En el Pascal original: if (random<0.05) then orni.angle:=random*2*pi
float random_val = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
if (random_val < 0.05f) {
// Assignar un angle completament aleatori (0-360°)
orni.angle = (static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX))
* 2.0f * Constants::PI;
}
// Calcular nova posició (moviment polar time-based)
// velocitat ja està en px/s (40 px/s), només cal multiplicar per delta_time
// Calcular nova posició PROPUESTA (time-based, però lògica Pascal)
// velocitat ja està en px/s (40 px/s), multiplicar per delta_time
float velocitat_efectiva = orni.velocitat * delta_time;
// Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt)
float dy = velocitat_efectiva * std::sin(orni.angle - Constants::PI / 2.0f);
float dx = velocitat_efectiva * std::cos(orni.angle - Constants::PI / 2.0f);
// Acumulació directa amb precisió subpíxel
orni.centre.y += dy;
orni.centre.x += dx;
float new_y = orni.centre.y + dy;
float new_x = orni.centre.x + dx;
// Boundary checking amb rebot (reflexió d'angle)
// Si toca paret esquerra/dreta: angle = PI - angle
if (orni.centre.x < Constants::MARGE_ESQ || orni.centre.x > Constants::MARGE_DRET) {
orni.angle = Constants::PI - orni.angle;
// Lògica Pascal: Actualitza Y si dins, sinó ajusta angle aleatòriament
// if (dy>marge_dalt) and (dy<marge_baix) then orni.centre.y:=round(Dy)
// else orni.angle:=orni.angle+(random(256)/512)*(random(3)-1);
if (new_y > Constants::MARGE_DALT && new_y < Constants::MARGE_BAIX) {
orni.centre.y = new_y;
} else {
// Pequeño ajuste aleatorio: (random(256)/512)*(random(3)-1)
// random(256) = 0..255, /512 = 0..0.498
// random(3) = 0,1,2, -1 = -1,0,1
// Resultado: ±0.5 rad aprox
float rand1 = (static_cast<float>(std::rand() % 256) / 512.0f);
int rand2 = (std::rand() % 3) - 1; // -1, 0, o 1
orni.angle += rand1 * static_cast<float>(rand2);
}
// Si toca paret dalt/baix: angle = 2*PI - angle
if (orni.centre.y < Constants::MARGE_DALT || orni.centre.y > Constants::MARGE_BAIX) {
orni.angle = 2.0f * Constants::PI - orni.angle;
// Lògica Pascal: Actualitza X si dins, sinó ajusta angle aleatòriament
// if (dx>marge_esq) and (dx<marge_dret) then orni.centre.x:=round(Dx)
// else orni.angle:=orni.angle+(random(256)/512)*(random(3)-1);
if (new_x > Constants::MARGE_ESQ && new_x < Constants::MARGE_DRET) {
orni.centre.x = new_x;
} else {
float rand1 = (static_cast<float>(std::rand() % 256) / 512.0f);
int rand2 = (std::rand() % 3) - 1;
orni.angle += rand1 * static_cast<float>(rand2);
}
// Nota: La rotació visual (orni.rotacio += orni.drotacio) ja es fa a actualitzar()

View File

@@ -0,0 +1,46 @@
// joc_asteroides.hpp - Lògica principal del joc
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
#ifndef JOC_ASTEROIDES_HPP
#define JOC_ASTEROIDES_HPP
#include <SDL3/SDL.h>
#include <array>
#include <cstdint>
#include "core/types.hpp"
#include "game/constants.hpp"
// Classe principal del joc
class JocAsteroides {
public:
JocAsteroides(SDL_Renderer* renderer);
~JocAsteroides() = default;
void inicialitzar();
void actualitzar(float delta_time);
void dibuixar();
void processar_input(const SDL_Event& event);
private:
SDL_Renderer* renderer_;
// Estat del joc
Triangle nau_;
std::array<Poligon, Constants::MAX_ORNIS> orni_;
std::array<Poligon, Constants::MAX_BALES> bales_;
Poligon chatarra_cosmica_;
uint16_t itocado_;
// Funcions de dibuix
bool linea(int x1, int y1, int x2, int y2, bool dibuixar);
void rota_tri(const Triangle& tri, float angul, float velocitat, bool dibuixar);
void rota_pol(const Poligon& pol, float angul, bool dibuixar);
// Moviment
void mou_orni(Poligon& orni, float delta_time);
void mou_bales(Poligon& bala, float delta_time);
void tocado();
};
#endif // JOC_ASTEROIDES_HPP

View File

@@ -1,94 +0,0 @@
// joc_asteroides.hpp - Lògica principal del joc
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
#ifndef JOC_ASTEROIDES_HPP
#define JOC_ASTEROIDES_HPP
#include <SDL3/SDL.h>
#include <array>
#include <cstdint>
// Espai de noms per a les constants del joc
namespace Constants {
constexpr int MARGE_DALT = 20;
constexpr int MARGE_BAIX = 460;
constexpr int MARGE_ESQ = 20;
constexpr int MARGE_DRET = 620;
constexpr int MAX_IPUNTS = 30;
constexpr int MAX_ORNIS = 15;
constexpr int VELOCITAT = 2;
constexpr int VELOCITAT_MAX = 6;
constexpr int MAX_BALES = 3;
constexpr float PI = 3.14159265359f;
}
// Estructures de dades (coordenades polars i cartesianes)
struct IPunt {
float r;
float angle;
};
struct Punt {
float x;
float y;
};
struct Triangle {
IPunt p1, p2, p3;
Punt centre;
float angle;
float velocitat;
};
struct Poligon {
std::array<IPunt, Constants::MAX_IPUNTS> ipuntx;
Punt centre;
float angle;
float velocitat;
uint8_t n;
float drotacio;
float rotacio;
bool esta;
};
// Classe principal del joc
class JocAsteroides {
public:
JocAsteroides(SDL_Renderer* renderer);
~JocAsteroides() = default;
void inicialitzar();
void actualitzar(float delta_time);
void dibuixar();
void processar_input(const SDL_Event& event);
private:
SDL_Renderer* renderer_;
// Estat del joc
Triangle nau_;
std::array<Poligon, Constants::MAX_ORNIS> orni_;
std::array<Poligon, Constants::MAX_BALES> bales_;
Poligon chatarra_cosmica_;
uint16_t itocado_;
// Funcions utilitàries (geometria)
void crear_poligon_regular(Poligon& pol, uint8_t n, float r);
float modul(const Punt& p) const;
void diferencia(const Punt& o, const Punt& d, Punt& p) const;
int distancia(const Punt& o, const Punt& d) const;
float angle_punt(const Punt& p) const;
// Funcions de dibuix
bool linea(int x1, int y1, int x2, int y2, bool dibuixar);
void rota_tri(const Triangle& tri, float angul, float velocitat, bool dibuixar);
void rota_pol(const Poligon& pol, float angul, bool dibuixar);
// Moviment
void mou_orni(Poligon& orni, float delta_time);
void mou_bales(Poligon& bala, float delta_time);
void tocado();
};
#endif // JOC_ASTEROIDES_HPP

View File

@@ -2,12 +2,12 @@
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
#include "sdl_manager.hpp"
#include "joc_asteroides.hpp"
#include "core/rendering/sdl_manager.hpp"
#include "game/joc_asteroides.hpp"
int main(int argc, char* argv[]) {
// Crear gestor SDL amb finestra de 640x480
SDLManager sdl(640, 480, "Asteroides - BETA 2.2");
// Crear gestor SDL (finestra centrada 640x480 per defecte)
SDLManager sdl;
// Crear instància del joc
JocAsteroides joc(sdl.obte_renderer());
@@ -33,7 +33,27 @@ int main(int argc, char* argv[]) {
// Processar events SDL
while (SDL_PollEvent(&event)) {
// Processar input del joc
// [NUEVO] Manejo de ventana ANTES de lógica del juego
if (sdl.handleWindowEvent(event)) {
continue; // Evento procesado, siguiente
}
// [NUEVO] Teclas globales de ventana
if (event.type == SDL_EVENT_KEY_DOWN) {
switch (event.key.key) {
case SDLK_F1:
sdl.decreaseWindowSize();
continue;
case SDLK_F2:
sdl.increaseWindowSize();
continue;
case SDLK_F3:
sdl.toggleFullscreen();
continue;
}
}
// Procesamiento normal del juego
joc.processar_input(event);
// Detectar tancament de finestra o ESC

9
source/project.h.in Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
namespace Project {
constexpr const char* NAME = "@PROJECT_NAME@";
constexpr const char* LONG_NAME = "@PROJECT_LONG_NAME@";
constexpr const char* VERSION = "@PROJECT_VERSION@";
constexpr const char* COPYRIGHT = "@PROJECT_COPYRIGHT@";
constexpr const char* GIT_HASH = "@GIT_HASH@";
} // namespace Project

View File

@@ -1,91 +0,0 @@
// sdl_manager.cpp - Implementació del gestor SDL3
// © 2025 Port a C++20 amb SDL3
#include "sdl_manager.hpp"
#include <iostream>
SDLManager::SDLManager(int amplada, int alcada, const char* titol)
: finestra_(nullptr), renderer_(nullptr), inicialitzat_(false) {
// Inicialitzar SDL3
if (!SDL_Init(SDL_INIT_VIDEO)) {
std::cerr << "Error inicialitzant SDL3: " << SDL_GetError() << std::endl;
return;
}
// Crear finestra
finestra_ = SDL_CreateWindow(
titol,
amplada, alcada,
SDL_WINDOW_RESIZABLE
);
if (!finestra_) {
std::cerr << "Error creant finestra: " << SDL_GetError() << std::endl;
SDL_Quit();
return;
}
// Crear renderer amb acceleració i vsync
// En SDL3, els flags són diferents o s'especifiquen diferent
renderer_ = SDL_CreateRenderer(finestra_, nullptr);
if (!renderer_) {
std::cerr << "Error creant renderer: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(finestra_);
SDL_Quit();
return;
}
inicialitzat_ = true;
std::cout << "SDL3 inicialitzat correctament" << std::endl;
}
SDLManager::~SDLManager() {
if (renderer_) {
SDL_DestroyRenderer(renderer_);
renderer_ = nullptr;
}
if (finestra_) {
SDL_DestroyWindow(finestra_);
finestra_ = nullptr;
}
SDL_Quit();
std::cout << "SDL3 netejat correctament" << std::endl;
}
void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) {
if (!renderer_) return;
SDL_SetRenderDrawColor(renderer_, r, g, b, 255);
SDL_RenderClear(renderer_);
}
void SDLManager::presenta() {
if (!renderer_) return;
SDL_RenderPresent(renderer_);
}
bool SDLManager::processar_events() {
if (!inicialitzat_) return false;
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_QUIT:
return false;
case SDL_EVENT_KEY_DOWN:
// En SDL3, la tecla està en event.key.key en lloc de event.key.keysym.sym
if (event.key.key == SDLK_ESCAPE) {
return false;
}
break;
}
}
return true;
}

View File

@@ -1,33 +0,0 @@
// sdl_manager.hpp - Gestor d'inicialització de SDL3
// © 2025 Port a C++20 amb SDL3
#ifndef SDL_MANAGER_HPP
#define SDL_MANAGER_HPP
#include <SDL3/SDL.h>
#include <cstdint>
class SDLManager {
public:
SDLManager(int amplada, int alcada, const char* titol);
~SDLManager();
// No permetre còpia ni assignació
SDLManager(const SDLManager&) = delete;
SDLManager& operator=(const SDLManager&) = delete;
// Funcions principals
void neteja(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0);
void presenta();
bool processar_events();
// Getters
SDL_Renderer* obte_renderer() { return renderer_; }
private:
SDL_Window* finestra_;
SDL_Renderer* renderer_;
bool inicialitzat_;
};
#endif // SDL_MANAGER_HPP