gitignore no ha deixat versionar cap fitxer de core

afegida gestió de ratolí
This commit is contained in:
2025-12-03 09:42:45 +01:00
parent aa66dd41c1
commit 9f0dfc4e24
39 changed files with 2983 additions and 3 deletions

View File

@@ -0,0 +1,68 @@
// color_oscillator.cpp - Implementació d'oscil·lació de color
// © 2025 Port a C++20 amb SDL3
#include "core/rendering/color_oscillator.hpp"
#include <cmath>
#include "core/defaults.hpp"
namespace Rendering {
ColorOscillator::ColorOscillator()
: accumulated_time_(0.0f) {
// Inicialitzar amb el color mínim
current_line_color_ = {Defaults::Color::LINE_MIN_R,
Defaults::Color::LINE_MIN_G,
Defaults::Color::LINE_MIN_B,
255};
current_background_color_ = {Defaults::Color::BACKGROUND_MIN_R,
Defaults::Color::BACKGROUND_MIN_G,
Defaults::Color::BACKGROUND_MIN_B,
255};
}
void ColorOscillator::update(float delta_time) {
accumulated_time_ += delta_time;
float factor =
calculateOscillationFactor(accumulated_time_, Defaults::Color::FREQUENCY);
// Interpolar colors de línies
SDL_Color line_min = {Defaults::Color::LINE_MIN_R,
Defaults::Color::LINE_MIN_G,
Defaults::Color::LINE_MIN_B,
255};
SDL_Color line_max = {Defaults::Color::LINE_MAX_R,
Defaults::Color::LINE_MAX_G,
Defaults::Color::LINE_MAX_B,
255};
current_line_color_ = interpolateColor(line_min, line_max, factor);
// Interpolar colors de fons
SDL_Color bg_min = {Defaults::Color::BACKGROUND_MIN_R,
Defaults::Color::BACKGROUND_MIN_G,
Defaults::Color::BACKGROUND_MIN_B,
255};
SDL_Color bg_max = {Defaults::Color::BACKGROUND_MAX_R,
Defaults::Color::BACKGROUND_MAX_G,
Defaults::Color::BACKGROUND_MAX_B,
255};
current_background_color_ = interpolateColor(bg_min, bg_max, factor);
}
float ColorOscillator::calculateOscillationFactor(float time, float frequency) {
// Oscil·lació senoïdal: sin(t * freq * 2π)
// Mapejar de [-1, 1] a [0, 1]
float radians = time * frequency * 2.0f * Defaults::Math::PI;
return (std::sin(radians) + 1.0f) / 2.0f;
}
SDL_Color ColorOscillator::interpolateColor(SDL_Color min, SDL_Color max, float factor) {
return {static_cast<uint8_t>(min.r + (max.r - min.r) * factor),
static_cast<uint8_t>(min.g + (max.g - min.g) * factor),
static_cast<uint8_t>(min.b + (max.b - min.b) * factor),
255};
}
} // namespace Rendering

View File

@@ -0,0 +1,29 @@
// color_oscillator.hpp - Sistema d'oscil·lació de color per efecte CRT
// © 2025 Port a C++20 amb SDL3
#pragma once
#include <SDL3/SDL.h>
namespace Rendering {
class ColorOscillator {
public:
ColorOscillator();
void update(float delta_time);
SDL_Color getCurrentLineColor() const { return current_line_color_; }
SDL_Color getCurrentBackgroundColor() const {
return current_background_color_;
}
private:
float accumulated_time_;
SDL_Color current_line_color_;
SDL_Color current_background_color_;
static float calculateOscillationFactor(float time, float frequency);
static SDL_Color interpolateColor(SDL_Color min, SDL_Color max, float factor);
};
} // namespace Rendering

View File

@@ -0,0 +1,11 @@
// coordinate_transform.cpp - Inicialització de variables globals
// © 2025 Port a C++20 amb SDL3
#include "core/rendering/coordinate_transform.hpp"
namespace Rendering {
// Factor d'escala global (inicialitzat a 1.0 per defecte)
float g_current_scale_factor = 1.0f;
} // namespace Rendering

View File

@@ -0,0 +1,31 @@
// coordinate_transform.hpp - Transformació de coordenades lògiques a físiques
// © 2025 Port a C++20 amb SDL3
#pragma once
#include <cmath>
namespace Rendering {
// Factor d'escala global (actualitzat cada frame per SDLManager)
extern float g_current_scale_factor;
// Transforma coordenada lògica a física amb arrodoniment
inline int transform_x(int logical_x, float scale) {
return static_cast<int>(std::round(logical_x * scale));
}
inline int transform_y(int logical_y, float scale) {
return static_cast<int>(std::round(logical_y * scale));
}
// Variant que usa el factor d'escala global
inline int transform_x(int logical_x) {
return transform_x(logical_x, g_current_scale_factor);
}
inline int transform_y(int logical_y) {
return transform_y(logical_y, g_current_scale_factor);
}
} // namespace Rendering

View File

@@ -0,0 +1,101 @@
// line_renderer.cpp - Implementació de renderitzat de línies
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
#include "core/rendering/line_renderer.hpp"
#include <cmath>
#include "core/rendering/coordinate_transform.hpp"
namespace Rendering {
// [NUEVO] Color global compartit (actualitzat per ColorOscillator via
// SDLManager)
SDL_Color g_current_line_color = {255, 255, 255, 255}; // Blanc inicial
bool linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, bool dibuixar, float brightness) {
// Algorisme de Bresenham per dibuixar línies
// Basat en el codi Pascal original
// Helper function: retorna el signe d'un nombre
auto sign = [](int x) -> int {
if (x < 0)
return -1;
if (x > 0)
return 1;
return 0;
};
// Variables per a l'algorisme (no utilitzades fins Fase 10 - detecció de
// col·lisions) int x = x1, y = y1; int xs = x2 - x1; int ys = y2 - y1; int
// xm = sign(xs); int ym = sign(ys); xs = std::abs(xs); ys = std::abs(ys);
// Suprimir warning de variable no usada
(void)sign;
// Detecció de col·lisió (TODO per Fase 10)
// El codi Pascal original llegia pixels del framebuffer bit-packed
// i comptava col·lisions. Per ara, usem SDL_RenderDrawLine i retornem false.
bool colisio = false;
// Dibuixar amb SDL3 (més eficient que Bresenham píxel a píxel)
if (dibuixar && renderer) {
// Transformar coordenades lògiques (640x480) a físiques (resolució real)
float scale = g_current_scale_factor;
int px1 = transform_x(x1, scale);
int py1 = transform_y(y1, scale);
int px2 = transform_x(x2, scale);
int py2 = transform_y(y2, scale);
// Aplicar brightness al color oscil·lat global
SDL_Color color_final;
color_final.r = static_cast<uint8_t>(g_current_line_color.r * brightness);
color_final.g = static_cast<uint8_t>(g_current_line_color.g * brightness);
color_final.b = static_cast<uint8_t>(g_current_line_color.b * brightness);
color_final.a = 255;
SDL_SetRenderDrawColor(renderer, color_final.r, color_final.g, color_final.b, 255);
// Renderitzar amb coordenades físiques
SDL_RenderLine(renderer, static_cast<float>(px1), static_cast<float>(py1),
static_cast<float>(px2), static_cast<float>(py2));
}
// Algorisme de Bresenham original (conservat per a futura detecció de
// col·lisió)
/*
if (xs > ys) {
// Línia plana (<45 graus)
int count = -(xs / 2);
while (x != x2) {
count = count + ys;
x = x + xm;
if (count > 0) {
y = y + ym;
count = count - xs;
}
// Aquí aniria la detecció de col·lisió píxel a píxel
}
} else {
// Línia pronunciada (>=45 graus)
int count = -(ys / 2);
while (y != y2) {
count = count + xs;
y = y + ym;
if (count > 0) {
x = x + xm;
count = count - ys;
}
// Aquí aniria la detecció de col·lisió píxel a píxel
}
}
*/
return colisio;
}
// [NUEVO] Establir el color global de les línies
void setLineColor(SDL_Color color) { g_current_line_color = color; }
} // namespace Rendering

View File

@@ -0,0 +1,16 @@
// line_renderer.hpp - Renderitzat de línies
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
#pragma once
#include <SDL3/SDL.h>
namespace Rendering {
// Algorisme de Bresenham per dibuixar línies
// Retorna true si hi ha col·lisió (per Fase 10)
// brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
bool linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, bool dibuixar, float brightness = 1.0f);
// [NUEVO] Establir el color global de les línies (oscil·lació)
void setLineColor(SDL_Color color);
} // namespace Rendering

View File

@@ -0,0 +1,86 @@
// polygon_renderer.cpp - Implementació de renderitzat de polígons
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
//
// ==============================================================================
// DEPRECATED: Use core/rendering/shape_renderer.cpp instead
// ==============================================================================
#include "core/rendering/polygon_renderer.hpp"
#include <array>
#include <cmath>
#include "core/defaults.hpp"
#include "core/rendering/line_renderer.hpp"
namespace Rendering {
void rota_tri(SDL_Renderer* renderer, const Triangle& tri, float angul, float velocitat, bool dibuixar) {
// Rotar i dibuixar triangle (nau)
// Conversió de coordenades polars a cartesianes amb rotació
// Basat en el codi Pascal original: lines 271-284
// Convertir cada punt polar a cartesià
// x = (r + velocitat) * cos(angle_punt + angle_nau) + centre.x
// y = (r + velocitat) * sin(angle_punt + angle_nau) + centre.y
int x1 = static_cast<int>(std::round((tri.p1.r + velocitat) *
std::cos(tri.p1.angle + angul))) +
tri.centre.x;
int y1 = static_cast<int>(std::round((tri.p1.r + velocitat) *
std::sin(tri.p1.angle + angul))) +
tri.centre.y;
int x2 = static_cast<int>(std::round((tri.p2.r + velocitat) *
std::cos(tri.p2.angle + angul))) +
tri.centre.x;
int y2 = static_cast<int>(std::round((tri.p2.r + velocitat) *
std::sin(tri.p2.angle + angul))) +
tri.centre.y;
int x3 = static_cast<int>(std::round((tri.p3.r + velocitat) *
std::cos(tri.p3.angle + angul))) +
tri.centre.x;
int y3 = static_cast<int>(std::round((tri.p3.r + velocitat) *
std::sin(tri.p3.angle + angul))) +
tri.centre.y;
// Dibuixar les 3 línies que formen el triangle
linea(renderer, x1, y1, x2, y2, dibuixar);
linea(renderer, x1, y1, x3, y3, dibuixar);
linea(renderer, x3, y3, x2, y2, dibuixar);
}
void rota_pol(SDL_Renderer* renderer, const Poligon& pol, float angul, bool dibuixar) {
// Rotar i dibuixar polígon (enemics i bales)
// Conversió de coordenades polars a cartesianes amb rotació
// Basat en el codi Pascal original: lines 286-296
// Array temporal per emmagatzemar punts convertits a cartesianes
std::array<Punt, Defaults::Entities::MAX_IPUNTS> xy;
// Convertir cada punt polar a cartesià
for (uint8_t i = 0; i < pol.n; i++) {
xy[i].x = static_cast<int>(std::round(
pol.ipuntx[i].r * std::cos(pol.ipuntx[i].angle + angul))) +
pol.centre.x;
xy[i].y = static_cast<int>(std::round(
pol.ipuntx[i].r * std::sin(pol.ipuntx[i].angle + angul))) +
pol.centre.y;
}
// Dibuixar línies entre punts consecutius
for (uint8_t i = 0; i < pol.n - 1; i++) {
linea(renderer, xy[i].x, xy[i].y, xy[i + 1].x, xy[i + 1].y, dibuixar);
}
// Tancar el polígon (últim punt → primer punt)
linea(renderer, xy[pol.n - 1].x, xy[pol.n - 1].y, xy[0].x, xy[0].y, dibuixar);
}
} // namespace Rendering

View File

@@ -0,0 +1,22 @@
// polygon_renderer.hpp - Renderitzat de polígons polars
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
//
// ==============================================================================
// DEPRECATED: Use core/rendering/shape_renderer.hpp instead
// ==============================================================================
// This file is kept temporarily for chatarra_cosmica_ (Phase 10: explosions)
// TODO Phase 10: Replace with particle system or remove completely
#pragma once
#include <SDL3/SDL.h>
#include "core/types.hpp"
namespace Rendering {
// Rotar i dibuixar triangle (nau)
void rota_tri(SDL_Renderer* renderer, const Triangle& tri, float angul, float velocitat, bool dibuixar);
// Rotar i dibuixar polígon (enemics i bales)
void rota_pol(SDL_Renderer* renderer, const Poligon& pol, float angul, bool dibuixar);
} // namespace Rendering

View File

@@ -0,0 +1,66 @@
// primitives.cpp - Implementació de funcions geomètriques
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
//
// ==============================================================================
// DEPRECATED: Use Shape system instead (.shp files + ShapeLoader)
// ==============================================================================
#include "primitives.hpp"
#include <cmath>
#include "core/defaults.hpp"
float modul(const Punt& p) {
// Càlcul de la magnitud d'un vector: sqrt(x² + y²)
return std::sqrt(p.x * p.x + p.y * p.y);
}
void diferencia(const Punt& o, const Punt& d, Punt& p) {
// Resta de vectors (origen - destí)
p.x = o.x - d.x;
p.y = o.y - d.y;
}
int distancia(const Punt& o, const Punt& d) {
// Distància entre dos punts
Punt p;
diferencia(o, d, p);
return static_cast<int>(std::round(modul(p)));
}
float angle_punt(const Punt& p) {
// Càlcul de l'angle d'un punt (arctan)
if (p.y != 0) {
return std::atan(p.x / p.y);
}
return 0.0f;
}
void 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 * Defaults::Math::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 = Defaults::Physics::ENEMY_SPEED * 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;
}

View File

@@ -0,0 +1,32 @@
// primitives.hpp - Funcions geomètriques bàsiques
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
//
// ==============================================================================
// DEPRECATED: Use Shape system instead (.shp files + ShapeLoader)
// ==============================================================================
// This file is kept temporarily for chatarra_cosmica_ (Phase 10: explosions)
// TODO Phase 10: Replace with particle system or remove completely
#pragma once
#include <cstdint>
#include "core/types.hpp"
// Funcions matemàtiques geomètriques pures (sense dependències d'estat)
// Càlcul de la magnitud d'un vector
float modul(const Punt& p);
// Diferència entre dos punts (vector origen - destí)
void diferencia(const Punt& o, const Punt& d, Punt& p);
// Distància entre dos punts
int distancia(const Punt& o, const Punt& d);
// Càlcul de l'angle d'un punt
float angle_punt(const Punt& p);
// Creació de polígons regulars
void crear_poligon_regular(Poligon& pol, uint8_t n, float r);

View File

@@ -8,6 +8,7 @@
#include <iostream>
#include "core/defaults.hpp"
#include "core/input/mouse.hpp"
#include "core/rendering/coordinate_transform.hpp"
#include "core/rendering/line_renderer.hpp"
#include "game/options.hpp"
@@ -147,6 +148,9 @@ SDLManager::SDLManager(int width, int height, bool fullscreen)
std::cout << " [FULLSCREEN]";
}
std::cout << std::endl;
// Inicialitzar mòdul Mouse amb l'estat actual de fullscreen
Mouse::setForceHidden(is_fullscreen_);
}
SDLManager::~SDLManager() {
@@ -356,6 +360,10 @@ void SDLManager::toggleFullscreen() {
}
Options::window.fullscreen = is_fullscreen_;
// Notificar al mòdul Mouse: Fullscreen requereix ocultació permanent del cursor.
// Quan es surt de fullscreen, restaurar el comportament normal d'auto-ocultació.
Mouse::setForceHidden(is_fullscreen_);
}
bool SDLManager::handleWindowEvent(const SDL_Event& event) {

View File

@@ -0,0 +1,80 @@
// shape_renderer.cpp - Implementació del renderitzat de formes
// © 2025 Port a C++20 amb SDL3
#include "core/rendering/shape_renderer.hpp"
#include <cmath>
#include "core/defaults.hpp"
#include "core/rendering/line_renderer.hpp"
namespace Rendering {
// Helper: transformar un punt amb rotació, escala i trasllació
static Punt transform_point(const Punt& point, const Punt& shape_centre, const Punt& posicio, float angle, float escala) {
// 1. Centrar el punt respecte al centre de la forma
float centered_x = point.x - shape_centre.x;
float centered_y = point.y - shape_centre.y;
// 2. Aplicar escala al punt centrat
float scaled_x = centered_x * escala;
float scaled_y = centered_y * escala;
// 3. Aplicar rotació
// IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no dreta)
// Per això usem (angle - PI/2) per compensar
// Però aquí angle ja ve en el sistema correcte del joc
float cos_a = std::cos(angle);
float sin_a = std::sin(angle);
float rotated_x = scaled_x * cos_a - scaled_y * sin_a;
float rotated_y = scaled_x * sin_a + scaled_y * cos_a;
// 4. Aplicar trasllació a posició mundial
return {rotated_x + posicio.x, rotated_y + posicio.y};
}
void render_shape(SDL_Renderer* renderer,
const std::shared_ptr<Graphics::Shape>& shape,
const Punt& posicio,
float angle,
float escala,
bool dibuixar,
float progress,
float brightness) {
// Verificar que la forma és vàlida
if (!shape || !shape->es_valida()) {
return;
}
// Si progress < 1.0, no dibuixar (tot o res)
if (progress < 1.0f) {
return;
}
// Obtenir el centre de la forma per a transformacions
const Punt& shape_centre = shape->get_centre();
// Iterar sobre totes les primitives
for (const auto& primitive : shape->get_primitives()) {
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
// POLYLINE: connectar punts consecutius
for (size_t i = 0; i < primitive.points.size() - 1; i++) {
Punt p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala);
Punt p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala);
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y), static_cast<int>(p2.x), static_cast<int>(p2.y), dibuixar, brightness);
}
} else { // PrimitiveType::LINE
// LINE: exactament 2 punts
if (primitive.points.size() >= 2) {
Punt p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala);
Punt p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala);
linea(renderer, static_cast<int>(p1.x), static_cast<int>(p1.y), static_cast<int>(p2.x), static_cast<int>(p2.y), dibuixar, brightness);
}
}
}
}
} // namespace Rendering

View File

@@ -0,0 +1,33 @@
// shape_renderer.hpp - Renderitzat de formes vectorials
// © 2025 Port a C++20 amb SDL3
#pragma once
#include <SDL3/SDL.h>
#include <memory>
#include "core/graphics/shape.hpp"
#include "core/types.hpp"
namespace Rendering {
// Renderitzar forma amb transformacions
// - renderer: SDL renderer
// - shape: forma vectorial a dibuixar
// - posicio: posició del centre en coordenades mundials
// - angle: rotació en radians (0 = amunt, sentit horari)
// - escala: factor d'escala (1.0 = mida original)
// - dibuixar: flag per dibuixar (false per col·lisions futures)
// - progress: progrés de l'animació (0.0-1.0, default 1.0 = tot visible)
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
void render_shape(SDL_Renderer* renderer,
const std::shared_ptr<Graphics::Shape>& shape,
const Punt& posicio,
float angle,
float escala = 1.0f,
bool dibuixar = true,
float progress = 1.0f,
float brightness = 1.0f);
} // namespace Rendering