treball en curs: correccions de tidy

This commit is contained in:
2026-05-16 17:19:40 +02:00
parent 3421f34a84
commit ee2dd0bc2c
30 changed files with 1220 additions and 1479 deletions
+13 -7
View File
@@ -30,19 +30,19 @@ Lang::Lang() = default;
Lang::~Lang() = default; Lang::~Lang() = default;
// Inicializa los textos del juego en el idioma seleccionado // Inicializa los textos del juego en el idioma seleccionado
auto Lang::setLang(Uint8 lang) -> bool { auto Lang::setLang(Code lang) -> bool {
std::string file; std::string file;
switch (lang) { switch (lang) {
case es_ES: case Code::ES_ES:
file = Asset::get()->get("es_ES.txt"); file = Asset::get()->get("es_ES.txt");
break; break;
case en_UK: case Code::EN_UK:
file = Asset::get()->get("en_UK.txt"); file = Asset::get()->get("en_UK.txt");
break; break;
case ba_BA: case Code::BA_BA:
file = Asset::get()->get("ba_BA.txt"); file = Asset::get()->get("ba_BA.txt");
break; break;
@@ -51,7 +51,7 @@ auto Lang::setLang(Uint8 lang) -> bool {
break; break;
} }
for (auto &mTextString : mTextStrings) { for (auto &mTextString : text_strings_) {
mTextString = ""; mTextString = "";
} }
@@ -80,7 +80,7 @@ auto Lang::setLang(Uint8 lang) -> bool {
if (index >= MAX_TEXT_STRINGS) { if (index >= MAX_TEXT_STRINGS) {
break; break;
} }
mTextStrings[index] = line; text_strings_[index] = line;
index++; index++;
} }
} }
@@ -90,5 +90,11 @@ auto Lang::setLang(Uint8 lang) -> bool {
// Obtiene la cadena de texto del indice // Obtiene la cadena de texto del indice
auto Lang::getText(int index) -> std::string { auto Lang::getText(int index) -> std::string {
return mTextStrings[index]; return text_strings_[index];
}
// Devuelve el siguiente idioma del ciclo (wrap-around)
auto Lang::nextLanguage(Code c) -> Code {
const int NEXT = (static_cast<int>(c) + 1) % MAX_LANGUAGES;
return static_cast<Code>(NEXT);
} }
+23 -24
View File
@@ -2,40 +2,39 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <cstdint> // for uint8_t
#include <string> // for string, basic_string #include <string> // for string, basic_string
// Códigos de idioma
constexpr int es_ES = 0;
constexpr int ba_BA = 1;
constexpr int en_UK = 2;
constexpr int MAX_LANGUAGES = 3;
// Textos
constexpr int MAX_TEXT_STRINGS = 100;
// Clase Lang // Clase Lang
class Lang { class Lang {
private:
std::string mTextStrings[MAX_TEXT_STRINGS]; // Vector con los textos
// Constructor privado (usar Lang::init)
Lang();
// Instancia única
static Lang *instance;
public: public:
// Códigos de idioma (basados en la convención IETF de los ficheros de locale)
enum class Code : std::uint8_t {
ES_ES = 0,
BA_BA = 1,
EN_UK = 2,
};
static constexpr int MAX_LANGUAGES = 3; // Número total de idiomas disponibles
// Singleton API // Singleton API
static void init(); // Crea la instancia static void init(); // Crea la instancia
static void destroy(); // Libera la instancia static void destroy(); // Libera la instancia
static auto get() -> Lang *; // Obtiene el puntero a la instancia static auto get() -> Lang *; // Obtiene el puntero a la instancia
// Destructor ~Lang(); // Destructor
~Lang();
// Inicializa los textos del juego en el idioma seleccionado auto setLang(Code lang) -> bool; // Inicializa los textos del juego en el idioma seleccionado
auto setLang(Uint8 lang) -> bool; auto getText(int index) -> std::string; // Obtiene la cadena de texto del indice
// Obtiene la cadena de texto del indice static auto nextLanguage(Code c) -> Code; // Devuelve el siguiente idioma del ciclo
auto getText(int index) -> std::string;
private:
static constexpr int MAX_TEXT_STRINGS = 100;
std::string text_strings_[MAX_TEXT_STRINGS]; // Vector con los textos
static Lang *instance; // Instancia única
Lang(); // Constructor privado (usar Lang::init)
}; };
+62 -62
View File
@@ -36,7 +36,7 @@ static auto parseAnimationStream(std::istream &file, Texture *texture, const std
buffer.speed = 0; buffer.speed = 0;
buffer.loop = -1; buffer.loop = -1;
buffer.counter = 0; buffer.counter = 0;
buffer.currentFrame = 0; buffer.current_frame = 0;
buffer.completed = false; buffer.completed = false;
do { do {
@@ -98,9 +98,9 @@ static auto parseAnimationStream(std::istream &file, Texture *texture, const std
} }
// Carga la animación desde un fichero (vía ResourceHelper: pack si està inicialitzat, filesystem si no) // Carga la animación desde un fichero (vía ResourceHelper: pack si està inicialitzat, filesystem si no)
auto loadAnimationFromFile(Texture *texture, const std::string &filePath, bool verbose) -> AnimatedSpriteData { auto loadAnimationFromFile(Texture *texture, const std::string &file_path, bool verbose) -> AnimatedSpriteData {
const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1); const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1);
auto bytes = ResourceHelper::loadFile(filePath); auto bytes = ResourceHelper::loadFile(file_path);
if (bytes.empty()) { if (bytes.empty()) {
if (verbose) { if (verbose) {
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << '\n'; std::cout << "Warning: Unable to open " << filename.c_str() << " file" << '\n';
@@ -113,7 +113,7 @@ auto loadAnimationFromFile(Texture *texture, const std::string &filePath, bool v
} }
// Carga la animación desde bytes en memoria // Carga la animación desde bytes en memoria
auto loadAnimationFromMemory(Texture *texture, const std::vector<uint8_t> &bytes, const std::string &nameForLogs, bool verbose) -> AnimatedSpriteData { auto loadAnimationFromMemory(Texture *texture, const std::vector<uint8_t> &bytes, const std::string &name_for_logs, bool verbose) -> AnimatedSpriteData {
if (bytes.empty()) { if (bytes.empty()) {
AnimatedSpriteData as; AnimatedSpriteData as;
as.texture = texture; as.texture = texture;
@@ -121,12 +121,12 @@ auto loadAnimationFromMemory(Texture *texture, const std::vector<uint8_t> &bytes
} }
std::string content(reinterpret_cast<const char *>(bytes.data()), bytes.size()); std::string content(reinterpret_cast<const char *>(bytes.data()), bytes.size());
std::stringstream ss(content); std::stringstream ss(content);
return parseAnimationStream(ss, texture, nameForLogs, verbose); return parseAnimationStream(ss, texture, name_for_logs, verbose);
} }
// Constructor // Constructor
AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, const std::string &file, std::vector<std::string> *buffer) AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, const std::string &file, std::vector<std::string> *buffer)
: currentAnimation(0) { : current_animation_(0) {
// Copia los punteros // Copia los punteros
setTexture(texture); setTexture(texture);
setRenderer(renderer); setRenderer(renderer);
@@ -136,7 +136,7 @@ AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, const s
AnimatedSpriteData as = loadAnimationFromFile(texture, file); AnimatedSpriteData as = loadAnimationFromFile(texture, file);
// Copia los datos de las animaciones // Copia los datos de las animaciones
animation.insert(animation.end(), as.animations.begin(), as.animations.end()); animation_.insert(animation_.end(), as.animations.begin(), as.animations.end());
} }
else if (buffer != nullptr) { else if (buffer != nullptr) {
@@ -145,29 +145,29 @@ AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, const s
} }
// Constructor // Constructor
AnimatedSprite::AnimatedSprite(SDL_Renderer *renderer, AnimatedSpriteData *animation) AnimatedSprite::AnimatedSprite(SDL_Renderer *renderer, AnimatedSpriteData *data)
: currentAnimation(0) { : current_animation_(0) {
// Copia los punteros // Copia los punteros
setTexture(animation->texture); setTexture(data->texture);
setRenderer(renderer); setRenderer(renderer);
// Copia los datos de las animaciones // Copia los datos de las animaciones
this->animation.insert(this->animation.end(), animation->animations.begin(), animation->animations.end()); this->animation_.insert(this->animation_.end(), data->animations.begin(), data->animations.end());
} }
// Destructor // Destructor
AnimatedSprite::~AnimatedSprite() { AnimatedSprite::~AnimatedSprite() {
for (auto &a : animation) { for (auto &a : animation_) {
a.frames.clear(); a.frames.clear();
} }
animation.clear(); animation_.clear();
} }
// Obtiene el indice de la animación a partir del nombre // Obtiene el indice de la animación a partir del nombre
auto AnimatedSprite::getIndex(const std::string &name) -> int { auto AnimatedSprite::getIndex(const std::string &name) -> int {
int index = -1; int index = -1;
for (const auto &a : animation) { for (const auto &a : animation_) {
index++; index++;
if (a.name == name) { if (a.name == name) {
return index; return index;
@@ -181,102 +181,102 @@ auto AnimatedSprite::getIndex(const std::string &name) -> int {
// Calcula el frame correspondiente a la animación // Calcula el frame correspondiente a la animación
void AnimatedSprite::animate() { void AnimatedSprite::animate() {
if (!enabled || animation[currentAnimation].speed == 0) { if (!enabled_ || animation_[current_animation_].speed == 0) {
return; return;
} }
// Calcula el frame actual a partir del contador // Calcula el frame actual a partir del contador
animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed; animation_[current_animation_].current_frame = animation_[current_animation_].counter / animation_[current_animation_].speed;
// Si alcanza el final de la animación, reinicia el contador de la animación // Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame // en función de la variable loop y coloca el nuevo frame
if (animation[currentAnimation].currentFrame >= (int)animation[currentAnimation].frames.size()) { if (animation_[current_animation_].current_frame >= (int)animation_[current_animation_].frames.size()) {
if (animation[currentAnimation].loop == -1) { // Si no hay loop, deja el último frame if (animation_[current_animation_].loop == -1) { // Si no hay loop, deja el último frame
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size(); animation_[current_animation_].current_frame = animation_[current_animation_].frames.size();
animation[currentAnimation].completed = true; animation_[current_animation_].completed = true;
} else { // Si hay loop, vuelve al frame indicado } else { // Si hay loop, vuelve al frame indicado
animation[currentAnimation].counter = 0; animation_[current_animation_].counter = 0;
animation[currentAnimation].currentFrame = animation[currentAnimation].loop; animation_[current_animation_].current_frame = animation_[current_animation_].loop;
} }
} }
// En caso contrario // En caso contrario
else { else {
// Escoge el frame correspondiente de la animación // Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]); setSpriteClip(animation_[current_animation_].frames[animation_[current_animation_].current_frame]);
// Incrementa el contador de la animacion // Incrementa el contador de la animacion
animation[currentAnimation].counter++; animation_[current_animation_].counter++;
} }
} }
// Obtiene el numero de frames de la animación actual // Obtiene el numero de frames de la animación actual
auto AnimatedSprite::getNumFrames() -> int { auto AnimatedSprite::getNumFrames() -> int {
return (int)animation[currentAnimation].frames.size(); return (int)animation_[current_animation_].frames.size();
} }
// Establece el frame actual de la animación // Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(int num) { void AnimatedSprite::setCurrentFrame(int num) {
// Descarta valores fuera de rango // Descarta valores fuera de rango
if (num >= (int)animation[currentAnimation].frames.size()) { if (num >= (int)animation_[current_animation_].frames.size()) {
num = 0; num = 0;
} }
// Cambia el valor de la variable // Cambia el valor de la variable
animation[currentAnimation].currentFrame = num; animation_[current_animation_].current_frame = num;
animation[currentAnimation].counter = 0; animation_[current_animation_].counter = 0;
// Escoge el frame correspondiente de la animación // Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]); setSpriteClip(animation_[current_animation_].frames[animation_[current_animation_].current_frame]);
} }
// Establece el valor del contador // Establece el valor del contador
void AnimatedSprite::setAnimationCounter(const std::string &name, int num) { void AnimatedSprite::setAnimationCounter(const std::string &name, int num) {
animation[getIndex(name)].counter = num; animation_[getIndex(name)].counter = num;
} }
// Establece la velocidad de una animación // Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(const std::string &name, int speed) { void AnimatedSprite::setAnimationSpeed(const std::string &name, int speed) {
animation[getIndex(name)].counter = speed; animation_[getIndex(name)].counter = speed;
} }
// Establece la velocidad de una animación // Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(int index, int speed) { void AnimatedSprite::setAnimationSpeed(int index, int speed) {
animation[index].counter = speed; animation_[index].counter = speed;
} }
// Establece si la animación se reproduce en bucle // Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(const std::string &name, int loop) { void AnimatedSprite::setAnimationLoop(const std::string &name, int loop) {
animation[getIndex(name)].loop = loop; animation_[getIndex(name)].loop = loop;
} }
// Establece si la animación se reproduce en bucle // Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(int index, int loop) { void AnimatedSprite::setAnimationLoop(int index, int loop) {
animation[index].loop = loop; animation_[index].loop = loop;
} }
// Establece el valor de la variable // Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(const std::string &name, bool value) { void AnimatedSprite::setAnimationCompleted(const std::string &name, bool value) {
animation[getIndex(name)].completed = value; animation_[getIndex(name)].completed = value;
} }
// OLD - Establece el valor de la variable // OLD - Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(int index, bool value) { void AnimatedSprite::setAnimationCompleted(int index, bool value) {
animation[index].completed = value; animation_[index].completed = value;
} }
// Comprueba si ha terminado la animación // Comprueba si ha terminado la animación
auto AnimatedSprite::animationIsCompleted() -> bool { auto AnimatedSprite::animationIsCompleted() -> bool {
return animation[currentAnimation].completed; return animation_[current_animation_].completed;
} }
// Devuelve el rectangulo de una animación y frame concreto // Devuelve el rectangulo de una animación y frame concreto
auto AnimatedSprite::getAnimationClip(const std::string &name, Uint8 index) -> SDL_Rect { auto AnimatedSprite::getAnimationClip(const std::string &name, Uint8 index) -> SDL_Rect {
return animation[getIndex(name)].frames[index]; return animation_[getIndex(name)].frames[index];
} }
// Devuelve el rectangulo de una animación y frame concreto // Devuelve el rectangulo de una animación y frame concreto
auto AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF) -> SDL_Rect { auto AnimatedSprite::getAnimationClip(int index_a, Uint8 index_f) -> SDL_Rect {
return animation[indexA].frames[indexF]; return animation_[index_a].frames[index_f];
} }
// Carga la animación desde un vector // Carga la animación desde un vector
@@ -297,13 +297,13 @@ auto AnimatedSprite::loadFromVector(std::vector<std::string> *source) -> bool {
// Lee desde el vector // Lee desde el vector
line = source->at(index); line = source->at(index);
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación // Si la linea contiene el texto [animation_] se realiza el proceso de carga de una animación
if (line == "[animation]") { if (line == "[animation]") {
Animation buffer; Animation buffer;
buffer.speed = 0; buffer.speed = 0;
buffer.loop = -1; buffer.loop = -1;
buffer.counter = 0; buffer.counter = 0;
buffer.currentFrame = 0; buffer.current_frame = 0;
buffer.completed = false; buffer.completed = false;
do { do {
@@ -350,7 +350,7 @@ auto AnimatedSprite::loadFromVector(std::vector<std::string> *source) -> bool {
} while (line != "[/animation]"); } while (line != "[/animation]");
// Añade la animación al vector de animaciones // Añade la animación al vector de animaciones
animation.push_back(buffer); animation_.push_back(buffer);
} }
// En caso contrario se parsea el fichero para buscar las variables y los valores // En caso contrario se parsea el fichero para buscar las variables y los valores
@@ -379,12 +379,12 @@ auto AnimatedSprite::loadFromVector(std::vector<std::string> *source) -> bool {
// Normaliza valores // Normaliza valores
if (framesPerRow == 0 && frameWidth > 0) { if (framesPerRow == 0 && frameWidth > 0) {
framesPerRow = texture->getWidth() / frameWidth; framesPerRow = texture_->getWidth() / frameWidth;
} }
if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0) { if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0) {
const int w = texture->getWidth() / frameWidth; const int w = texture_->getWidth() / frameWidth;
const int h = texture->getHeight() / frameHeight; const int h = texture_->getHeight() / frameHeight;
maxTiles = w * h; maxTiles = w * h;
} }
} }
@@ -403,22 +403,22 @@ auto AnimatedSprite::loadFromVector(std::vector<std::string> *source) -> bool {
// Establece la animacion actual // Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(const std::string &name) { void AnimatedSprite::setCurrentAnimation(const std::string &name) {
const int newAnimation = getIndex(name); const int newAnimation = getIndex(name);
if (currentAnimation != newAnimation) { if (current_animation_ != newAnimation) {
currentAnimation = newAnimation; current_animation_ = newAnimation;
animation[currentAnimation].currentFrame = 0; animation_[current_animation_].current_frame = 0;
animation[currentAnimation].counter = 0; animation_[current_animation_].counter = 0;
animation[currentAnimation].completed = false; animation_[current_animation_].completed = false;
} }
} }
// Establece la animacion actual // Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(int index) { void AnimatedSprite::setCurrentAnimation(int index) {
const int newAnimation = index; const int newAnimation = index;
if (currentAnimation != newAnimation) { if (current_animation_ != newAnimation) {
currentAnimation = newAnimation; current_animation_ = newAnimation;
animation[currentAnimation].currentFrame = 0; animation_[current_animation_].current_frame = 0;
animation[currentAnimation].counter = 0; animation_[current_animation_].counter = 0;
animation[currentAnimation].completed = false; animation_[current_animation_].completed = false;
} }
} }
@@ -430,19 +430,19 @@ void AnimatedSprite::update() {
// Establece el rectangulo para un frame de una animación // Establece el rectangulo para un frame de una animación
void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h) { void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h) {
animation[index_animation].frames.push_back({x, y, w, h}); animation_[index_animation].frames.push_back({x, y, w, h});
} }
// OLD - Establece el contador para todas las animaciones // OLD - Establece el contador para todas las animaciones
void AnimatedSprite::setAnimationCounter(int value) { void AnimatedSprite::setAnimationCounter(int value) {
for (auto &a : animation) { for (auto &a : animation_) {
a.counter = value; a.counter = value;
} }
} }
// Reinicia la animación // Reinicia la animación
void AnimatedSprite::resetAnimation() { void AnimatedSprite::resetAnimation() {
animation[currentAnimation].currentFrame = 0; animation_[current_animation_].current_frame = 0;
animation[currentAnimation].counter = 0; animation_[current_animation_].counter = 0;
animation[currentAnimation].completed = false; animation_[current_animation_].completed = false;
} }
+27 -50
View File
@@ -15,7 +15,7 @@ struct Animation {
int speed; // Velocidad de 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 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 bool completed; // Indica si ha finalizado la animación
int currentFrame; // Frame actual int current_frame; // Frame actual
int counter; // Contador para las animaciones int counter; // Contador para las animaciones
}; };
@@ -25,75 +25,52 @@ struct AnimatedSpriteData {
}; };
// Carga la animación desde un fichero // Carga la animación desde un fichero
auto loadAnimationFromFile(Texture *texture, const std::string &filePath, bool verbose = false) -> AnimatedSpriteData; auto loadAnimationFromFile(Texture *texture, const std::string &file_path, bool verbose = false) -> AnimatedSpriteData;
// Carga la animación desde bytes en memoria // Carga la animación desde bytes en memoria
auto loadAnimationFromMemory(Texture *texture, const std::vector<uint8_t> &bytes, const std::string &nameForLogs = "", bool verbose = false) -> AnimatedSpriteData; auto loadAnimationFromMemory(Texture *texture, const std::vector<uint8_t> &bytes, const std::string &name_for_logs = "", bool verbose = false) -> AnimatedSpriteData;
class AnimatedSprite : public MovingSprite { class AnimatedSprite : public MovingSprite {
private:
// Variables
std::vector<Animation> animation; // Vector con las diferentes animaciones
int currentAnimation; // Animacion activa
public: public:
// Constructor explicit AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, const std::string &file = "", std::vector<std::string> *buffer = nullptr); // Constructor
explicit AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, const std::string &file = "", std::vector<std::string> *buffer = nullptr); AnimatedSprite(SDL_Renderer *renderer, AnimatedSpriteData *data);
AnimatedSprite(SDL_Renderer *renderer, AnimatedSpriteData *animation);
// Destructor ~AnimatedSprite() override; // Destructor
~AnimatedSprite() override;
// Calcula el frame correspondiente a la animación actual void animate(); // Calcula el frame correspondiente a la animación actual
void animate(); auto getNumFrames() -> int; // Obtiene el numero de frames de la animación actual
void setCurrentFrame(int num); // Establece el frame actual de la animación
void setAnimationCounter(const std::string &name, int num); // Establece el valor del contador
// Obtiene el numero de frames de la animación actual void setAnimationSpeed(const std::string &name, int speed); // Establece la velocidad de una animación
auto getNumFrames() -> int;
// Establece el frame actual de la animación
void setCurrentFrame(int num);
// Establece el valor del contador
void setAnimationCounter(const std::string &name, int num);
// Establece la velocidad de una animación
void setAnimationSpeed(const std::string &name, int speed);
void setAnimationSpeed(int index, int speed); void setAnimationSpeed(int index, int speed);
// Establece el frame al que vuelve la animación al finalizar void setAnimationLoop(const std::string &name, int loop); // Establece el frame al que vuelve la animación al finalizar
void setAnimationLoop(const std::string &name, int loop);
void setAnimationLoop(int index, int loop); void setAnimationLoop(int index, int loop);
// Establece el valor de la variable void setAnimationCompleted(const std::string &name, bool value); // Establece el valor de la variable
void setAnimationCompleted(const std::string &name, bool value);
void setAnimationCompleted(int index, bool value); void setAnimationCompleted(int index, bool value);
// Comprueba si ha terminado la animación auto animationIsCompleted() -> bool; // Comprueba si ha terminado la animación
auto animationIsCompleted() -> bool;
// Devuelve el rectangulo de una animación y frame concreto auto getAnimationClip(const std::string &name = "default", Uint8 index = 0) -> SDL_Rect; // Devuelve el rectangulo de una animación y frame concreto
auto getAnimationClip(const std::string &name = "default", Uint8 index = 0) -> SDL_Rect; auto getAnimationClip(int index_a = 0, Uint8 index_f = 0) -> SDL_Rect;
auto getAnimationClip(int indexA = 0, Uint8 indexF = 0) -> SDL_Rect;
// Obtiene el indice de la animación a partir del nombre auto getIndex(const std::string &name) -> int; // Obtiene el indice de la animación a partir del nombre
auto getIndex(const std::string &name) -> int; auto loadFromVector(std::vector<std::string> *source) -> bool; // Carga la animación desde un vector
// Carga la animación desde un vector void setCurrentAnimation(const std::string &name = "default"); // Establece la animacion actual
auto loadFromVector(std::vector<std::string> *source) -> bool;
// Establece la animacion actual
void setCurrentAnimation(const std::string &name = "default");
void setCurrentAnimation(int index = 0); void setCurrentAnimation(int index = 0);
// Actualiza las variables del objeto void update() override; // Actualiza las variables del objeto
void update() override;
// OLD - Establece el rectangulo para un frame de una animación void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h); // OLD - Establece el rectangulo para un frame de una animación
void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h); void setAnimationCounter(int value); // OLD - Establece el contador para todas las animaciones
// OLD - Establece el contador para todas las animaciones void resetAnimation(); // Reinicia la animación
void setAnimationCounter(int value);
// Reinicia la animación private:
void resetAnimation(); // Variables
std::vector<Animation> animation_; // Vector con las diferentes animaciones
int current_animation_; // Animacion activa
}; };
+70 -70
View File
@@ -9,70 +9,70 @@
// Constructor // Constructor
Fade::Fade(SDL_Renderer *renderer) Fade::Fade(SDL_Renderer *renderer)
: mRenderer(renderer) { : renderer_(renderer) {
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (mBackbuffer != nullptr) { if (backbuffer_ != nullptr) {
SDL_SetTextureScaleMode(mBackbuffer, SDL_SCALEMODE_NEAREST); SDL_SetTextureScaleMode(backbuffer_, SDL_SCALEMODE_NEAREST);
} }
if (mBackbuffer == nullptr) { if (backbuffer_ == nullptr) {
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << '\n'; std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << '\n';
} }
} }
// Destructor // Destructor
Fade::~Fade() { Fade::~Fade() {
SDL_DestroyTexture(mBackbuffer); SDL_DestroyTexture(backbuffer_);
mBackbuffer = nullptr; backbuffer_ = nullptr;
} }
// Inicializa las variables // Inicializa las variables
void Fade::init(Uint8 r, Uint8 g, Uint8 b) { void Fade::init(Uint8 r, Uint8 g, Uint8 b) {
mFadeType = FADE_CENTER; fade_type_ = FADE_CENTER;
mEnabled = false; enabled_ = false;
mFinished = false; finished_ = false;
mCounter = 0; counter_ = 0;
mR = r; r_ = r;
mG = g; g_ = g;
mB = b; b_ = b;
mROriginal = r; r_original_ = r;
mGOriginal = g; g_original_ = g;
mBOriginal = b; b_original_ = b;
mLastSquareTicks = 0; last_square_ticks_ = 0;
mSquaresDrawn = 0; squares_drawn_ = 0;
mFullscreenDone = false; fullscreen_done_ = false;
} }
// Pinta una transición en pantalla // Pinta una transición en pantalla
void Fade::render() { void Fade::render() {
if (mEnabled && !mFinished) { if (enabled_ && !finished_) {
switch (mFadeType) { switch (fade_type_) {
case FADE_FULLSCREEN: { case FADE_FULLSCREEN: {
if (!mFullscreenDone) { if (!fullscreen_done_) {
SDL_FRect fRect1 = {0, 0, (float)GAMECANVAS_WIDTH, (float)GAMECANVAS_HEIGHT}; SDL_FRect fRect1 = {0, 0, (float)GAMECANVAS_WIDTH, (float)GAMECANVAS_HEIGHT};
int alpha = mCounter * 4; int alpha = counter_ * 4;
if (alpha >= 255) { if (alpha >= 255) {
mFullscreenDone = true; fullscreen_done_ = true;
// Deja todos los buffers del mismo color // Deja todos los buffers del mismo color
SDL_SetRenderTarget(mRenderer, mBackbuffer); SDL_SetRenderTarget(renderer_, backbuffer_);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_SetRenderDrawColor(renderer_, r_, g_, b_, 255);
SDL_RenderClear(mRenderer); SDL_RenderClear(renderer_);
SDL_SetRenderTarget(mRenderer, nullptr); SDL_SetRenderTarget(renderer_, nullptr);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_SetRenderDrawColor(renderer_, r_, g_, b_, 255);
SDL_RenderClear(mRenderer); SDL_RenderClear(renderer_);
mFinished = true; finished_ = true;
} else { } else {
// Dibujamos sobre el renderizador // Dibujamos sobre el renderizador
SDL_SetRenderTarget(mRenderer, nullptr); SDL_SetRenderTarget(renderer_, nullptr);
// Copia el backbuffer con la imagen que había al renderizador // Copia el backbuffer con la imagen que había al renderizador
SDL_RenderTexture(mRenderer, mBackbuffer, nullptr, nullptr); SDL_RenderTexture(renderer_, backbuffer_, nullptr, nullptr);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, alpha); SDL_SetRenderDrawColor(renderer_, r_, g_, b_, alpha);
SDL_RenderFillRect(mRenderer, &fRect1); SDL_RenderFillRect(renderer_, &fRect1);
} }
} }
break; break;
@@ -82,26 +82,26 @@ void Fade::render() {
SDL_FRect fR1 = {0, 0, (float)GAMECANVAS_WIDTH, 0}; SDL_FRect fR1 = {0, 0, (float)GAMECANVAS_WIDTH, 0};
SDL_FRect fR2 = {0, 0, (float)GAMECANVAS_WIDTH, 0}; SDL_FRect fR2 = {0, 0, (float)GAMECANVAS_WIDTH, 0};
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64); SDL_SetRenderDrawColor(renderer_, r_, g_, b_, 64);
for (int i = 0; i < mCounter; i++) { for (int i = 0; i < counter_; i++) {
fR1.h = fR2.h = (float)(i * 4); fR1.h = fR2.h = (float)(i * 4);
fR2.y = (float)(GAMECANVAS_HEIGHT - (i * 4)); fR2.y = (float)(GAMECANVAS_HEIGHT - (i * 4));
SDL_RenderFillRect(mRenderer, &fR1); SDL_RenderFillRect(renderer_, &fR1);
SDL_RenderFillRect(mRenderer, &fR2); SDL_RenderFillRect(renderer_, &fR2);
} }
if ((mCounter * 4) > GAMECANVAS_HEIGHT) { if ((counter_ * 4) > GAMECANVAS_HEIGHT) {
mFinished = true; finished_ = true;
} }
break; break;
} }
case FADE_RANDOM_SQUARE: { case FADE_RANDOM_SQUARE: {
Uint32 now = SDL_GetTicks(); Uint32 now = SDL_GetTicks();
if (mSquaresDrawn < 50 && now - mLastSquareTicks >= 100) { if (squares_drawn_ < 50 && now - last_square_ticks_ >= 100) {
mLastSquareTicks = now; last_square_ticks_ = now;
SDL_FRect fRs = {0, 0, 32, 32}; SDL_FRect fRs = {0, 0, 32, 32};
@@ -109,26 +109,26 @@ void Fade::render() {
Uint8 r = 255 * (rand() % 2); Uint8 r = 255 * (rand() % 2);
Uint8 g = 255 * (rand() % 2); Uint8 g = 255 * (rand() % 2);
Uint8 b = 255 * (rand() % 2); Uint8 b = 255 * (rand() % 2);
SDL_SetRenderDrawColor(mRenderer, r, g, b, 64); SDL_SetRenderDrawColor(renderer_, r, g, b, 64);
// Dibujamos sobre el backbuffer // Dibujamos sobre el backbuffer
SDL_SetRenderTarget(mRenderer, mBackbuffer); SDL_SetRenderTarget(renderer_, backbuffer_);
fRs.x = (float)(rand() % (GAMECANVAS_WIDTH - 32)); fRs.x = (float)(rand() % (GAMECANVAS_WIDTH - 32));
fRs.y = (float)(rand() % (GAMECANVAS_HEIGHT - 32)); fRs.y = (float)(rand() % (GAMECANVAS_HEIGHT - 32));
SDL_RenderFillRect(mRenderer, &fRs); SDL_RenderFillRect(renderer_, &fRs);
// Volvemos a usar el renderizador de forma normal // Volvemos a usar el renderizador de forma normal
SDL_SetRenderTarget(mRenderer, nullptr); SDL_SetRenderTarget(renderer_, nullptr);
mSquaresDrawn++; squares_drawn_++;
} }
// Copiamos el backbuffer al renderizador // Copiamos el backbuffer al renderizador
SDL_RenderTexture(mRenderer, mBackbuffer, nullptr, nullptr); SDL_RenderTexture(renderer_, backbuffer_, nullptr, nullptr);
if (mSquaresDrawn >= 50) { if (squares_drawn_ >= 50) {
mFinished = true; finished_ = true;
} }
break; break;
} }
@@ -138,43 +138,43 @@ void Fade::render() {
} }
} }
if (mFinished) { if (finished_) {
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_SetRenderDrawColor(renderer_, r_, g_, b_, 255);
SDL_RenderClear(mRenderer); SDL_RenderClear(renderer_);
} }
} }
// Actualiza las variables internas // Actualiza las variables internas
void Fade::update() { void Fade::update() {
if (mEnabled) { if (enabled_) {
mCounter++; counter_++;
} }
} }
// Activa el fade // Activa el fade
void Fade::activateFade() { void Fade::activateFade() {
mEnabled = true; enabled_ = true;
mFinished = false; finished_ = false;
mCounter = 0; counter_ = 0;
mSquaresDrawn = 0; squares_drawn_ = 0;
mLastSquareTicks = 0; last_square_ticks_ = 0;
mFullscreenDone = false; fullscreen_done_ = false;
mR = mROriginal; r_ = r_original_;
mG = mGOriginal; g_ = g_original_;
mB = mBOriginal; b_ = b_original_;
} }
// Comprueba si está activo // Comprueba si está activo
auto Fade::isEnabled() const -> bool { auto Fade::isEnabled() const -> bool {
return mEnabled; return enabled_;
} }
// Comprueba si ha terminado la transicion // Comprueba si ha terminado la transicion
auto Fade::hasEnded() const -> bool { auto Fade::hasEnded() const -> bool {
return mFinished; return finished_;
} }
// Establece el tipo de fade // Establece el tipo de fade
void Fade::setFadeType(Uint8 fadeType) { void Fade::setFadeType(Uint8 fade_type) {
mFadeType = fadeType; fade_type_ = fade_type;
} }
+23 -37
View File
@@ -9,46 +9,32 @@ constexpr int FADE_RANDOM_SQUARE = 2;
// Clase Fade // Clase Fade
class Fade { class Fade {
private:
SDL_Renderer *mRenderer = nullptr; // El renderizador de la ventana
SDL_Texture *mBackbuffer = nullptr; // Textura para usar como backbuffer
Uint8 mFadeType = FADE_FULLSCREEN; // Tipo de fade a realizar
Uint16 mCounter = 0; // Contador interno
bool mEnabled = false; // Indica si el fade está activo
bool mFinished = false; // Indica si ha terminado la transición
Uint8 mR = 0, mG = 0, mB = 0; // Colores para el fade
Uint8 mROriginal = 0, mGOriginal = 0, mBOriginal = 0; // Colores originales para FADE_RANDOM_SQUARE
Uint32 mLastSquareTicks = 0; // Ticks del último cuadrado dibujado (FADE_RANDOM_SQUARE)
Uint16 mSquaresDrawn = 0; // Número de cuadrados dibujados (FADE_RANDOM_SQUARE)
bool mFullscreenDone = false; // Indica si el fade fullscreen ha terminado la fase de fundido
SDL_Rect mRect1{}; // Rectangulo usado para crear los efectos de transición
SDL_Rect mRect2{}; // Rectangulo usado para crear los efectos de transición
public: public:
// Constructor explicit Fade(SDL_Renderer *renderer); // Constructor
explicit Fade(SDL_Renderer *renderer); ~Fade(); // Destructor
// Destructor void init(Uint8 r, Uint8 g, Uint8 b); // Inicializa las variables
~Fade(); void render(); // Pinta una transición en pantalla
void update(); // Actualiza las variables internas
void activateFade(); // Activa el fade
// Inicializa las variables [[nodiscard]] auto hasEnded() const -> bool; // Comprueba si ha terminado la transicion
void init(Uint8 r, Uint8 g, Uint8 b); [[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activo
// Pinta una transición en pantalla void setFadeType(Uint8 fade_type); // Establece el tipo de fade
void render();
// Actualiza las variables internas private:
void update(); SDL_Renderer *renderer_ = nullptr; // El renderizador de la ventana
SDL_Texture *backbuffer_ = nullptr; // Textura para usar como backbuffer
// Activa el fade Uint8 fade_type_ = FADE_FULLSCREEN; // Tipo de fade a realizar
void activateFade(); Uint16 counter_ = 0; // Contador interno
bool enabled_ = false; // Indica si el fade está activo
// Comprueba si ha terminado la transicion bool finished_ = false; // Indica si ha terminado la transición
[[nodiscard]] auto hasEnded() const -> bool; Uint8 r_ = 0, g_ = 0, b_ = 0; // Colores para el fade
Uint8 r_original_ = 0, g_original_ = 0, b_original_ = 0; // Colores originales para FADE_RANDOM_SQUARE
// Comprueba si está activo Uint32 last_square_ticks_ = 0; // Ticks del último cuadrado dibujado (FADE_RANDOM_SQUARE)
[[nodiscard]] auto isEnabled() const -> bool; Uint16 squares_drawn_ = 0; // Número de cuadrados dibujados (FADE_RANDOM_SQUARE)
bool fullscreen_done_ = false; // Indica si el fade fullscreen ha terminado la fase de fundido
// Establece el tipo de fade SDL_Rect rect1_{}; // Rectangulo usado para crear los efectos de transición
void setFadeType(Uint8 fadeType); SDL_Rect rect2_{}; // Rectangulo usado para crear los efectos de transición
}; };
+82 -82
View File
@@ -5,187 +5,187 @@
// Constructor // Constructor
MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, Texture *texture, SDL_Renderer *renderer) MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, Texture *texture, SDL_Renderer *renderer)
: Sprite(0, 0, w, h, texture, renderer), : Sprite(0, 0, w, h, texture, renderer),
x(x), x_(x),
y(y), y_(y),
xPrev(x), x_prev_(x),
yPrev(y), y_prev_(y),
vx(velx), vx_(velx),
vy(vely), vy_(vely),
ax(accelx), ax_(accelx),
ay(accely) { ay_(accely) {
} }
// Reinicia todas las variables // Reinicia todas las variables
void MovingSprite::clear() { void MovingSprite::clear() {
x = 0.0F; // Posición en el eje X x_ = 0.0F;
y = 0.0F; // Posición en el eje Y y_ = 0.0F;
vx = 0.0F; // Velocidad en el eje X. Cantidad de pixeles a desplazarse vx_ = 0.0F;
vy = 0.0F; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse vy_ = 0.0F;
ax = 0.0F; // Aceleración en el eje X. Variación de la velocidad ax_ = 0.0F;
ay = 0.0F; // Aceleración en el eje Y. Variación de la velocidad ay_ = 0.0F;
zoomW = 1.0F; // Zoom aplicado a la anchura zoom_w_ = 1.0F;
zoomH = 1.0F; // Zoom aplicado a la altura zoom_h_ = 1.0F;
angle = 0.0; // Angulo para dibujarlo angle_ = 0.0;
rotateEnabled = false; // Indica si ha de rotar rotate_enabled_ = false;
center = nullptr; // Centro de rotación center_ = nullptr;
rotateSpeed = 0; // Velocidad de giro rotate_speed_ = 0;
rotateAmount = 0.0; // Cantidad de grados a girar en cada iteración rotate_amount_ = 0.0;
counter = 0; // Contador interno counter_ = 0;
currentFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite current_flip_ = SDL_FLIP_NONE;
} }
// Mueve el sprite // Mueve el sprite
void MovingSprite::move() { void MovingSprite::move() {
if (enabled) { if (enabled_) {
xPrev = x; x_prev_ = x_;
yPrev = y; y_prev_ = y_;
x += vx; x_ += vx_;
y += vy; y_ += vy_;
vx += ax; vx_ += ax_;
vy += ay; vy_ += ay_;
} }
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void MovingSprite::render() { void MovingSprite::render() {
if (enabled) { if (enabled_) {
texture->render(renderer, (int)x, (int)y, &spriteClip, zoomW, zoomH, angle, center, currentFlip); texture_->render(renderer_, (int)x_, (int)y_, &sprite_clip_, zoom_w_, zoom_h_, angle_, center_, current_flip_);
} }
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
// cppcheck-suppress duplInheritedMember // cppcheck-suppress duplInheritedMember
auto MovingSprite::getPosX() const -> float { auto MovingSprite::getPosX() const -> float {
return x; return x_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
// cppcheck-suppress duplInheritedMember // cppcheck-suppress duplInheritedMember
auto MovingSprite::getPosY() const -> float { auto MovingSprite::getPosY() const -> float {
return y; return y_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getVelX() const -> float { auto MovingSprite::getVelX() const -> float {
return vx; return vx_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getVelY() const -> float { auto MovingSprite::getVelY() const -> float {
return vy; return vy_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getAccelX() const -> float { auto MovingSprite::getAccelX() const -> float {
return ax; return ax_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getAccelY() const -> float { auto MovingSprite::getAccelY() const -> float {
return ay; return ay_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getZoomW() const -> float { auto MovingSprite::getZoomW() const -> float {
return zoomW; return zoom_w_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getZoomH() const -> float { auto MovingSprite::getZoomH() const -> float {
return zoomH; return zoom_h_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getAngle() const -> double { auto MovingSprite::getAngle() const -> double {
return angle; return angle_;
} }
// Establece la posición y el tamaño del objeto // Establece la posición y el tamaño del objeto
void MovingSprite::setRect(SDL_Rect rect) { void MovingSprite::setRect(SDL_Rect rect) {
x = (float)rect.x; x_ = (float)rect.x;
y = (float)rect.y; y_ = (float)rect.y;
w = rect.w; w_ = rect.w;
h = rect.h; h_ = rect.h;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setPosX(float value) { void MovingSprite::setPosX(float value) {
x = value; x_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setPosY(float value) { void MovingSprite::setPosY(float value) {
y = value; y_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setVelX(float value) { void MovingSprite::setVelX(float value) {
vx = value; vx_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setVelY(float value) { void MovingSprite::setVelY(float value) {
vy = value; vy_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAccelX(float value) { void MovingSprite::setAccelX(float value) {
ax = value; ax_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAccelY(float value) { void MovingSprite::setAccelY(float value) {
ay = value; ay_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setZoomW(float value) { void MovingSprite::setZoomW(float value) {
zoomW = value; zoom_w_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setZoomH(float value) { void MovingSprite::setZoomH(float value) {
zoomH = value; zoom_h_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAngle(double value) { void MovingSprite::setAngle(double value) {
angle = value; angle_ = value;
} }
// Incrementa el valor de la variable // Incrementa el valor de la variable
void MovingSprite::incAngle(double value) { void MovingSprite::incAngle(double value) {
angle += value; angle_ += value;
} }
// Decrementa el valor de la variable // Decrementa el valor de la variable
void MovingSprite::decAngle(double value) { void MovingSprite::decAngle(double value) {
angle -= value; angle_ -= value;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getRotate() const -> bool { auto MovingSprite::getRotate() const -> bool {
return rotateEnabled; return rotate_enabled_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getRotateSpeed() const -> Uint16 { auto MovingSprite::getRotateSpeed() const -> Uint16 {
return rotateSpeed; return rotate_speed_;
} }
// Establece la rotacion // Establece la rotacion
void MovingSprite::rotate() { void MovingSprite::rotate() {
if (enabled) { if (enabled_) {
if (rotateEnabled) { if (rotate_enabled_) {
if (counter % rotateSpeed == 0) { if (counter_ % rotate_speed_ == 0) {
incAngle(rotateAmount); incAngle(rotate_amount_);
} }
} }
} }
@@ -193,27 +193,27 @@ void MovingSprite::rotate() {
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotate(bool value) { void MovingSprite::setRotate(bool value) {
rotateEnabled = value; rotate_enabled_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotateSpeed(int value) { void MovingSprite::setRotateSpeed(int value) {
if (value < 1) { if (value < 1) {
rotateSpeed = 1; rotate_speed_ = 1;
} else { } else {
rotateSpeed = value; rotate_speed_ = value;
} }
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotateAmount(double value) { void MovingSprite::setRotateAmount(double value) {
rotateAmount = value; rotate_amount_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::disableRotate() { void MovingSprite::disableRotate() {
rotateEnabled = false; rotate_enabled_ = false;
angle = (double)0; angle_ = (double)0;
} }
// Actualiza las variables internas del objeto // Actualiza las variables internas del objeto
@@ -221,59 +221,59 @@ void MovingSprite::update() {
move(); move();
rotate(); rotate();
if (enabled) { if (enabled_) {
++counter %= 60000; ++counter_ %= 60000;
} }
} }
// Cambia el sentido de la rotación // Cambia el sentido de la rotación
void MovingSprite::switchRotate() { void MovingSprite::switchRotate() {
rotateAmount *= -1; rotate_amount_ *= -1;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setFlip(SDL_FlipMode flip) { void MovingSprite::setFlip(SDL_FlipMode flip) {
currentFlip = flip; current_flip_ = flip;
} }
// Gira el sprite horizontalmente // Gira el sprite horizontalmente
void MovingSprite::flip() { void MovingSprite::flip() {
currentFlip = (currentFlip == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; current_flip_ = (current_flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto MovingSprite::getFlip() -> SDL_FlipMode { auto MovingSprite::getFlip() -> SDL_FlipMode {
return currentFlip; return current_flip_;
} }
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
auto MovingSprite::getRect() -> SDL_Rect { auto MovingSprite::getRect() -> SDL_Rect {
const SDL_Rect rect = {(int)x, (int)y, w, h}; const SDL_Rect RECT = {(int)x_, (int)y_, w_, h_};
return rect; return RECT;
} }
// Deshace el último movimiento // Deshace el último movimiento
void MovingSprite::undoMove() { void MovingSprite::undoMove() {
x = xPrev; x_ = x_prev_;
y = yPrev; y_ = y_prev_;
} }
// Deshace el último movimiento en el eje X // Deshace el último movimiento en el eje X
void MovingSprite::undoMoveX() { void MovingSprite::undoMoveX() {
x = xPrev; x_ = x_prev_;
} }
// Deshace el último movimiento en el eje Y // Deshace el último movimiento en el eje Y
void MovingSprite::undoMoveY() { void MovingSprite::undoMoveY() {
y = yPrev; y_ = y_prev_;
} }
// Pone a cero las velocidades de desplacamiento // Pone a cero las velocidades de desplacamiento
void MovingSprite::clearVel() { void MovingSprite::clearVel() {
vx = vy = 0.0F; vx_ = vy_ = 0.0F;
} }
// Devuelve el incremento en el eje X en pixels // Devuelve el incremento en el eje X en pixels
auto MovingSprite::getIncX() const -> int { auto MovingSprite::getIncX() const -> int {
return (int)x - (int)xPrev; return (int)x_ - (int)x_prev_;
} }
+73 -149
View File
@@ -7,161 +7,85 @@ class Texture;
// Clase MovingSprite. Añade posicion y velocidad en punto flotante // Clase MovingSprite. Añade posicion y velocidad en punto flotante
class MovingSprite : public Sprite { class MovingSprite : public Sprite {
public:
explicit MovingSprite(float x = 0, float y = 0, int w = 0, int h = 0, float velx = 0, float vely = 0, float accelx = 0, float accely = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr); // Constructor
void move(); // Mueve el sprite
void rotate(); // Rota el sprite
virtual void update(); // Actualiza las variables internas del objeto
void clear(); // Reinicia todas las variables
void render() override; // Muestra el sprite por pantalla
// cppcheck-suppress duplInheritedMember
[[nodiscard]] auto getPosX() const -> float; // Obten el valor de la variable
// cppcheck-suppress duplInheritedMember
[[nodiscard]] auto getPosY() const -> float; // Obten el valor de la variable
[[nodiscard]] auto getVelX() const -> float; // Obten el valor de la variable
[[nodiscard]] auto getVelY() const -> float; // Obten el valor de la variable
[[nodiscard]] auto getAccelX() const -> float; // Obten el valor de la variable
[[nodiscard]] auto getAccelY() const -> float; // Obten el valor de la variable
[[nodiscard]] auto getZoomW() const -> float; // Obten el valor de la variable
[[nodiscard]] auto getZoomH() const -> float; // Obten el valor de la variable
[[nodiscard]] auto getAngle() const -> double; // Obten el valor de la variable
[[nodiscard]] auto getRotate() const -> bool; // Obtiene el valor de la variable
[[nodiscard]] auto getRotateSpeed() const -> Uint16; // Obtiene el valor de la variable
void setRect(SDL_Rect rect) override; // Establece la posición y el tamaño del objeto
void setPosX(float value); // Establece el valor de la variable
void setPosY(float value); // Establece el valor de la variable
void setVelX(float value); // Establece el valor de la variable
void setVelY(float value); // Establece el valor de la variable
void setAccelX(float value); // Establece el valor de la variable
void setAccelY(float value); // Establece el valor de la variable
void setZoomW(float value); // Establece el valor de la variable
void setZoomH(float value); // Establece el valor de la variable
void setAngle(double value); // Establece el valor de la variable
void incAngle(double value); // Incrementa el valor de la variable
void decAngle(double value); // Decrementa el valor de la variable
void setRotate(bool value); // Establece el valor de la variable
void setRotateSpeed(int value); // Establece el valor de la variable
void setRotateAmount(double value); // Establece el valor de la variable
void disableRotate(); // Quita el efecto de rotación y deja el sprite en su angulo inicial.
void switchRotate(); // Cambia el sentido de la rotación
void setFlip(SDL_FlipMode flip); // Establece el valor de la variable
void flip(); // Gira el sprite horizontalmente
auto getFlip() -> SDL_FlipMode; // Obtiene el valor de la variable
auto getRect() -> SDL_Rect override; // Devuelve el rectangulo donde está el sprite
void undoMove(); // Deshace el último movimiento
void undoMoveX(); // Deshace el último movimiento en el eje X
void undoMoveY(); // Deshace el último movimiento en el eje Y
void clearVel(); // Pone a cero las velocidades de desplacamiento
[[nodiscard]] auto getIncX() const -> int; // Devuelve el incremento en el eje X en pixels
protected: protected:
// cppcheck-suppress duplInheritedMember // cppcheck-suppress duplInheritedMember
float x; // Posición en el eje X (sub-pixel; Sprite::x es int) float x_; // Posición en el eje X (sub-pixel; Sprite::x_ es int)
// cppcheck-suppress duplInheritedMember // cppcheck-suppress duplInheritedMember
float y; // Posición en el eje Y (sub-pixel; Sprite::y es int) float y_; // Posición en el eje Y (sub-pixel; Sprite::y_ es int)
float xPrev; // Posición anterior en el eje X float x_prev_; // Posición anterior en el eje X
float yPrev; // Posición anterior en el eje Y float y_prev_; // Posición anterior en el eje Y
float vx; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float vx_; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float vy; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse float vy_; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float ax; // Aceleración en el eje X. Variación de la velocidad float ax_; // Aceleración en el eje X. Variación de la velocidad
float ay; // Aceleración en el eje Y. Variación de la velocidad float ay_; // Aceleración en el eje Y. Variación de la velocidad
float zoomW{1}; // Zoom aplicado a la anchura float zoom_w_{1}; // Zoom aplicado a la anchura
float zoomH{1}; // Zoom aplicado a la altura float zoom_h_{1}; // Zoom aplicado a la altura
double angle{0.0}; // Angulo para dibujarlo double angle_{0.0}; // Angulo para dibujarlo
bool rotateEnabled{false}; // Indica si ha de rotar bool rotate_enabled_{false}; // Indica si ha de rotar
int rotateSpeed{0}; // Velocidad de giro int rotate_speed_{0}; // Velocidad de giro
double rotateAmount{0.0}; // Cantidad de grados a girar en cada iteración double rotate_amount_{0.0}; // Cantidad de grados a girar en cada iteración
int counter{0}; // Contador interno int counter_{0}; // Contador interno
SDL_Point *center{nullptr}; // Centro de rotación SDL_Point *center_{nullptr}; // Centro de rotación
SDL_FlipMode currentFlip{SDL_FLIP_NONE}; // Indica como se voltea el sprite SDL_FlipMode current_flip_{SDL_FLIP_NONE}; // Indica como se voltea el sprite
public:
// Constructor
explicit MovingSprite(float x = 0, float y = 0, int w = 0, int h = 0, float velx = 0, float vely = 0, float accelx = 0, float accely = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr);
// Mueve el sprite
void move();
// Rota el sprite
void rotate();
// Actualiza las variables internas del objeto
virtual void update();
// Reinicia todas las variables
void clear();
// Muestra el sprite por pantalla
void render() override;
// Obten el valor de la variable
// cppcheck-suppress duplInheritedMember
[[nodiscard]] auto getPosX() const -> float;
// Obten el valor de la variable
// cppcheck-suppress duplInheritedMember
[[nodiscard]] auto getPosY() const -> float;
// Obten el valor de la variable
[[nodiscard]] auto getVelX() const -> float;
// Obten el valor de la variable
[[nodiscard]] auto getVelY() const -> float;
// Obten el valor de la variable
[[nodiscard]] auto getAccelX() const -> float;
// Obten el valor de la variable
[[nodiscard]] auto getAccelY() const -> float;
// Obten el valor de la variable
[[nodiscard]] auto getZoomW() const -> float;
// Obten el valor de la variable
[[nodiscard]] auto getZoomH() const -> float;
// Obten el valor de la variable
[[nodiscard]] auto getAngle() const -> double;
// Obtiene el valor de la variable
[[nodiscard]] auto getRotate() const -> bool;
// Obtiene el valor de la variable
[[nodiscard]] auto getRotateSpeed() const -> Uint16;
// Establece la posición y el tamaño del objeto
void setRect(SDL_Rect rect) override;
// Establece el valor de la variable
void setPosX(float value);
// Establece el valor de la variable
void setPosY(float value);
// Establece el valor de la variable
void setVelX(float value);
// Establece el valor de la variable
void setVelY(float value);
// Establece el valor de la variable
void setAccelX(float value);
// Establece el valor de la variable
void setAccelY(float value);
// Establece el valor de la variable
void setZoomW(float value);
// Establece el valor de la variable
void setZoomH(float value);
// Establece el valor de la variable
void setAngle(double value);
// Incrementa el valor de la variable
void incAngle(double value);
// Decrementa el valor de la variable
void decAngle(double value);
// Establece el valor de la variable
void setRotate(bool value);
// Establece el valor de la variable
void setRotateSpeed(int value);
// Establece el valor de la variable
void setRotateAmount(double value);
// Quita el efecto de rotación y deja el sprite en su angulo inicial.
void disableRotate();
// Cambia el sentido de la rotación
void switchRotate();
// Establece el valor de la variable
void setFlip(SDL_FlipMode flip);
// Gira el sprite horizontalmente
void flip();
// Obtiene el valor de la variable
auto getFlip() -> SDL_FlipMode;
// Devuelve el rectangulo donde está el sprite
auto getRect() -> SDL_Rect override;
// Deshace el último movimiento
void undoMove();
// Deshace el último movimiento en el eje X
void undoMoveX();
// Deshace el último movimiento en el eje Y
void undoMoveY();
// Pone a cero las velocidades de desplacamiento
void clearVel();
// Devuelve el incremento en el eje X en pixels
[[nodiscard]] auto getIncX() const -> int;
}; };
+106 -106
View File
@@ -79,13 +79,13 @@ auto Screen::get() -> Screen * {
// Constructor // Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
: borderColor{0x00, 0x00, 0x00} { : border_color_{0x00, 0x00, 0x00} {
// Inicializa variables // Inicializa variables
this->window = window; this->window_ = window;
this->renderer = renderer; this->renderer_ = renderer;
gameCanvasWidth = GAMECANVAS_WIDTH; game_canvas_width_ = GAMECANVAS_WIDTH;
gameCanvasHeight = GAMECANVAS_HEIGHT; game_canvas_height_ = GAMECANVAS_HEIGHT;
// Establece el modo de video (fullscreen/ventana + logical presentation) // Establece el modo de video (fullscreen/ventana + logical presentation)
// ANTES de crear la textura — SDL3 GPU necesita la logical presentation // ANTES de crear la textura — SDL3 GPU necesita la logical presentation
@@ -103,11 +103,11 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
// Crea la textura donde se dibujan los graficos del juego. // Crea la textura donde se dibujan los graficos del juego.
// ARGB8888 per simplificar el readback cap al pipeline SDL3 GPU. // ARGB8888 per simplificar el readback cap al pipeline SDL3 GPU.
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight); game_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_, game_canvas_height_);
if (gameCanvas != nullptr) { if (game_canvas_ != nullptr) {
SDL_SetTextureScaleMode(gameCanvas, Options::video.scale_mode); SDL_SetTextureScaleMode(game_canvas_, Options::video.scale_mode);
} }
if (gameCanvas == nullptr) { if (game_canvas_ == nullptr) {
if (Options::settings.console) { if (Options::settings.console) {
std::cout << "gameCanvas could not be created!\nSDL Error: " << SDL_GetError() << '\n'; std::cout << "gameCanvas could not be created!\nSDL Error: " << SDL_GetError() << '\n';
} }
@@ -115,14 +115,14 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
#ifndef NO_SHADERS #ifndef NO_SHADERS
// Buffer de readback del gameCanvas (lo dimensionamos una vez) // Buffer de readback del gameCanvas (lo dimensionamos una vez)
pixel_buffer_.resize(static_cast<size_t>(gameCanvasWidth) * static_cast<size_t>(gameCanvasHeight)); pixel_buffer_.resize(static_cast<size_t>(game_canvas_width_) * static_cast<size_t>(game_canvas_height_));
#endif #endif
// Renderiza una vez la textura vacía al renderer abans d'inicialitzar els // Renderiza una vez la textura vacía al renderer abans d'inicialitzar els
// shaders: jaildoctors_dilemma ho fa així i evita que el driver Vulkan // shaders: jaildoctors_dilemma ho fa així i evita que el driver Vulkan
// crashegi en la creació del pipeline gràfic. `initShaders()` es crida // crashegi en la creació del pipeline gràfic. `initShaders()` es crida
// després des de `Director` amb el swapchain ja estable. // després des de `Director` amb el swapchain ja estable.
SDL_RenderTexture(renderer, gameCanvas, nullptr, nullptr); SDL_RenderTexture(renderer, game_canvas_, nullptr, nullptr);
// Estado inicial de las notificaciones. El Text real se enlaza después vía // Estado inicial de las notificaciones. El Text real se enlaza después vía
// `initNotifications()` quan `Resource` ja estigui inicialitzat. Dividim // `initNotifications()` quan `Resource` ja estigui inicialitzat. Dividim
@@ -130,12 +130,12 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
// de carregar recursos: si el SDL_Renderer ha fet abans moltes // de carregar recursos: si el SDL_Renderer ha fet abans moltes
// allocacions (carrega de textures), el driver Vulkan crasheja quan // allocacions (carrega de textures), el driver Vulkan crasheja quan
// després es reclama la ventana per al dispositiu GPU. // després es reclama la ventana per al dispositiu GPU.
notificationText = nullptr; notification_text_ = nullptr;
notificationMessage = ""; notification_message_ = "";
notificationTextColor = {0xFF, 0xFF, 0xFF}; notification_text_color_ = {0xFF, 0xFF, 0xFF};
notificationOutlineColor = {0x00, 0x00, 0x00}; notification_outline_color_ = {0x00, 0x00, 0x00};
notificationEndTime = 0; notification_end_time_ = 0;
notificationY = 2; notification_y_ = 2;
// Registra callbacks natius d'Emscripten per a fullscreen/orientation // Registra callbacks natius d'Emscripten per a fullscreen/orientation
registerEmscriptenEventCallbacks(); registerEmscriptenEventCallbacks();
@@ -144,7 +144,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
// Enllaça el Text de les notificacions amb el recurs compartit de `Resource`. // Enllaça el Text de les notificacions amb el recurs compartit de `Resource`.
// S'ha de cridar després de `Resource::init(...)`. // S'ha de cridar després de `Resource::init(...)`.
void Screen::initNotifications() { void Screen::initNotifications() {
notificationText = Resource::get()->getText("8bithud"); notification_text_ = Resource::get()->getText("8bithud");
} }
// Destructor // Destructor
@@ -153,24 +153,24 @@ Screen::~Screen() {
#ifndef NO_SHADERS #ifndef NO_SHADERS
shutdownShaders(); shutdownShaders();
#endif #endif
SDL_DestroyTexture(gameCanvas); SDL_DestroyTexture(game_canvas_);
} }
// Limpia la pantalla // Limpia la pantalla
void Screen::clean(Color color) { void Screen::clean(Color color) {
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer); SDL_RenderClear(renderer_);
} }
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
void Screen::start() { void Screen::start() {
SDL_SetRenderTarget(renderer, gameCanvas); SDL_SetRenderTarget(renderer_, game_canvas_);
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void Screen::blit() { void Screen::blit() {
// Dibuja la notificación activa sobre el gameCanvas antes de presentar // Dibuja la notificación activa sobre el gameCanvas antes de presentar
SDL_SetRenderTarget(renderer, gameCanvas); SDL_SetRenderTarget(renderer_, game_canvas_);
renderNotification(); renderNotification();
#ifndef NO_SHADERS #ifndef NO_SHADERS
@@ -180,7 +180,7 @@ void Screen::blit() {
// i restaurem el shader actiu, així CRTPI no aplica les seues scanlines // i restaurem el shader actiu, així CRTPI no aplica les seues scanlines
// quan l'usuari ho ha desactivat. // quan l'usuari ho ha desactivat.
if (shader_backend_ && shader_backend_->isHardwareAccelerated()) { if (shader_backend_ && shader_backend_->isHardwareAccelerated()) {
SDL_Surface *surface = SDL_RenderReadPixels(renderer, nullptr); SDL_Surface *surface = SDL_RenderReadPixels(renderer_, nullptr);
if (surface != nullptr) { if (surface != nullptr) {
if (surface->format == SDL_PIXELFORMAT_ARGB8888) { if (surface->format == SDL_PIXELFORMAT_ARGB8888) {
std::memcpy(pixel_buffer_.data(), surface->pixels, pixel_buffer_.size() * sizeof(Uint32)); std::memcpy(pixel_buffer_.data(), surface->pixels, pixel_buffer_.size() * sizeof(Uint32));
@@ -193,11 +193,11 @@ void Screen::blit() {
} }
SDL_DestroySurface(surface); SDL_DestroySurface(surface);
} }
SDL_SetRenderTarget(renderer, nullptr); SDL_SetRenderTarget(renderer_, nullptr);
if (Options::video.shader.enabled) { if (Options::video.shader.enabled) {
// Ruta normal: shader amb els seus params. // Ruta normal: shader amb els seus params.
shader_backend_->uploadPixels(pixel_buffer_.data(), gameCanvasWidth, gameCanvasHeight); shader_backend_->uploadPixels(pixel_buffer_.data(), game_canvas_width_, game_canvas_height_);
shader_backend_->render(); shader_backend_->render();
} else { } else {
// Shader off: POSTFX amb params zero (passa-per-aquí). CRTPI no // Shader off: POSTFX amb params zero (passa-per-aquí). CRTPI no
@@ -208,7 +208,7 @@ void Screen::blit() {
shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX); shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX);
} }
shader_backend_->setPostFXParams(Rendering::PostFXParams{}); shader_backend_->setPostFXParams(Rendering::PostFXParams{});
shader_backend_->uploadPixels(pixel_buffer_.data(), gameCanvasWidth, gameCanvasHeight); shader_backend_->uploadPixels(pixel_buffer_.data(), game_canvas_width_, game_canvas_height_);
shader_backend_->render(); shader_backend_->render();
if (PREV_SHADER != Rendering::ShaderType::POSTFX) { if (PREV_SHADER != Rendering::ShaderType::POSTFX) {
shader_backend_->setActiveShader(PREV_SHADER); shader_backend_->setActiveShader(PREV_SHADER);
@@ -219,18 +219,18 @@ void Screen::blit() {
#endif #endif
// Vuelve a dejar el renderizador en modo normal // Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(renderer, nullptr); SDL_SetRenderTarget(renderer_, nullptr);
// Borra el contenido previo // Borra el contenido previo
SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, 0xFF); SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
SDL_RenderClear(renderer); SDL_RenderClear(renderer_);
// Copia la textura de juego en el renderizador en la posición adecuada // Copia la textura de juego en el renderizador en la posición adecuada
SDL_FRect fdest = {(float)dest.x, (float)dest.y, (float)dest.w, (float)dest.h}; SDL_FRect fdest = {(float)dest_.x, (float)dest_.y, (float)dest_.w, (float)dest_.h};
SDL_RenderTexture(renderer, gameCanvas, nullptr, &fdest); SDL_RenderTexture(renderer_, game_canvas_, nullptr, &fdest);
// Muestra por pantalla el renderizador // Muestra por pantalla el renderizador
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer_);
} }
// ============================================================================ // ============================================================================
@@ -254,11 +254,11 @@ void Screen::setVideoMode(bool fullscreen) {
// createTiledBackground() crea/destrueix una textura target nova, i això // createTiledBackground() crea/destrueix una textura target nova, i això
// reinicialitza l'estat intern del renderer. Recreem gameCanvas aquí // reinicialitza l'estat intern del renderer. Recreem gameCanvas aquí
// mateix per garantir el mateix efecte en qualsevol escena. // mateix per garantir el mateix efecte en qualsevol escena.
if (gameCanvas != nullptr) { if (game_canvas_ != nullptr) {
SDL_DestroyTexture(gameCanvas); SDL_DestroyTexture(game_canvas_);
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight); game_canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_, game_canvas_height_);
if (gameCanvas != nullptr) { if (game_canvas_ != nullptr) {
SDL_SetTextureScaleMode(gameCanvas, Options::video.scale_mode); SDL_SetTextureScaleMode(game_canvas_, Options::video.scale_mode);
} }
} }
} }
@@ -313,7 +313,7 @@ void Screen::toggleIntegerScale() {
// Establece el V-Sync // Establece el V-Sync
void Screen::setVSync(bool enabled) { void Screen::setVSync(bool enabled) {
Options::video.vsync = enabled; Options::video.vsync = enabled;
SDL_SetRenderVSync(renderer, enabled ? 1 : SDL_RENDERER_VSYNC_DISABLED); SDL_SetRenderVSync(renderer_, enabled ? 1 : SDL_RENDERER_VSYNC_DISABLED);
#ifndef NO_SHADERS #ifndef NO_SHADERS
if (shader_backend_) { if (shader_backend_) {
shader_backend_->setVSync(enabled); shader_backend_->setVSync(enabled);
@@ -328,7 +328,7 @@ void Screen::toggleVSync() {
// Cambia el color del borde // Cambia el color del borde
void Screen::setBorderColor(Color color) { void Screen::setBorderColor(Color color) {
borderColor = color; border_color_ = color;
} }
// ============================================================================ // ============================================================================
@@ -337,7 +337,7 @@ void Screen::setBorderColor(Color color) {
// SDL_SetWindowFullscreen + visibilidad del cursor // SDL_SetWindowFullscreen + visibilidad del cursor
void Screen::applyFullscreen(bool fullscreen) { void Screen::applyFullscreen(bool fullscreen) {
SDL_SetWindowFullscreen(window, fullscreen); SDL_SetWindowFullscreen(window_, fullscreen);
if (fullscreen) { if (fullscreen) {
SDL_HideCursor(); SDL_HideCursor();
Mouse::cursor_visible = false; Mouse::cursor_visible = false;
@@ -350,9 +350,9 @@ void Screen::applyFullscreen(bool fullscreen) {
// Calcula windowWidth/Height/dest para el modo ventana y aplica SDL_SetWindowSize // Calcula windowWidth/Height/dest para el modo ventana y aplica SDL_SetWindowSize
void Screen::applyWindowedLayout() { void Screen::applyWindowedLayout() {
windowWidth = gameCanvasWidth; window_width_ = game_canvas_width_;
windowHeight = gameCanvasHeight; window_height_ = game_canvas_height_;
dest = {.x = 0, .y = 0, .w = gameCanvasWidth, .h = gameCanvasHeight}; dest_ = {.x = 0, .y = 0, .w = game_canvas_width_, .h = game_canvas_height_};
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
windowWidth *= WASM_RENDER_SCALE; windowWidth *= WASM_RENDER_SCALE;
@@ -362,20 +362,20 @@ void Screen::applyWindowedLayout() {
#endif #endif
// Modifica el tamaño de la ventana // Modifica el tamaño de la ventana
SDL_SetWindowSize(window, windowWidth * Options::window.zoom, windowHeight * Options::window.zoom); SDL_SetWindowSize(window_, window_width_ * Options::window.zoom, window_height_ * Options::window.zoom);
// Sense aquesta sincronia, en Windows + Vulkan el swapchain del SDL3 GPU // Sense aquesta sincronia, en Windows + Vulkan el swapchain del SDL3 GPU
// es queda en estat out-of-date després del resize i SDL_AcquireGPU- // es queda en estat out-of-date després del resize i SDL_AcquireGPU-
// SwapchainTexture deixa de tornar una textura vàlida → finestra negra. // SwapchainTexture deixa de tornar una textura vàlida → finestra negra.
// En Linux Mesa el driver ho tolera, però el patró segur (igual que // En Linux Mesa el driver ho tolera, però el patró segur (igual que
// jaildoctors_dilemma) és esperar que el WM completi el resize abans de // jaildoctors_dilemma) és esperar que el WM completi el resize abans de
// reposicionar i continuar amb el render. // reposicionar i continuar amb el render.
SDL_SyncWindow(window); SDL_SyncWindow(window_);
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
} }
// Obtiene el tamaño de la ventana en fullscreen y calcula el rect del juego // Obtiene el tamaño de la ventana en fullscreen y calcula el rect del juego
void Screen::applyFullscreenLayout() { void Screen::applyFullscreenLayout() {
SDL_GetWindowSize(window, &windowWidth, &windowHeight); SDL_GetWindowSize(window_, &window_width_, &window_height_);
computeFullscreenGameRect(); computeFullscreenGameRect();
} }
@@ -384,34 +384,34 @@ void Screen::computeFullscreenGameRect() {
if (Options::video.integer_scale) { if (Options::video.integer_scale) {
// Calcula el tamaño de la escala máxima // Calcula el tamaño de la escala máxima
int scale = 0; int scale = 0;
while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight)) { while (((game_canvas_width_ * (scale + 1)) <= window_width_) && ((game_canvas_height_ * (scale + 1)) <= window_height_)) {
scale++; scale++;
} }
dest.w = gameCanvasWidth * scale; dest_.w = game_canvas_width_ * scale;
dest.h = gameCanvasHeight * scale; dest_.h = game_canvas_height_ * scale;
dest.x = (windowWidth - dest.w) / 2; dest_.x = (window_width_ - dest_.w) / 2;
dest.y = (windowHeight - dest.h) / 2; dest_.y = (window_height_ - dest_.h) / 2;
} else { } else {
// Manté la relació d'aspecte sense escalat enter (letterbox/pillarbox). // Manté la relació d'aspecte sense escalat enter (letterbox/pillarbox).
float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight; float ratio = (float)game_canvas_width_ / (float)game_canvas_height_;
if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight)) { if ((window_width_ - game_canvas_width_) >= (window_height_ - game_canvas_height_)) {
dest.h = windowHeight; dest_.h = window_height_;
dest.w = static_cast<int>(std::lround(windowHeight * ratio)); dest_.w = static_cast<int>(std::lround(window_height_ * ratio));
dest.x = (windowWidth - dest.w) / 2; dest_.x = (window_width_ - dest_.w) / 2;
dest.y = (windowHeight - dest.h) / 2; dest_.y = (window_height_ - dest_.h) / 2;
} else { } else {
dest.w = windowWidth; dest_.w = window_width_;
dest.h = static_cast<int>(std::lround(windowWidth / ratio)); dest_.h = static_cast<int>(std::lround(window_width_ / ratio));
dest.x = (windowWidth - dest.w) / 2; dest_.x = (window_width_ - dest_.w) / 2;
dest.y = (windowHeight - dest.h) / 2; dest_.y = (window_height_ - dest_.h) / 2;
} }
} }
} }
// Aplica la logical presentation y persiste el estado en options // Aplica la logical presentation y persiste el estado en options
void Screen::applyLogicalPresentation(bool fullscreen) { void Screen::applyLogicalPresentation(bool fullscreen) {
SDL_SetRenderLogicalPresentation(renderer, windowWidth, windowHeight, SDL_LOGICAL_PRESENTATION_LETTERBOX); SDL_SetRenderLogicalPresentation(renderer_, window_width_, window_height_, SDL_LOGICAL_PRESENTATION_LETTERBOX);
Options::video.fullscreen = fullscreen; Options::video.fullscreen = fullscreen;
} }
@@ -420,32 +420,32 @@ void Screen::applyLogicalPresentation(bool fullscreen) {
// ============================================================================ // ============================================================================
// Muestra una notificación en la línea superior durante durationMs // Muestra una notificación en la línea superior durante durationMs
void Screen::notify(const std::string &text, Color textColor, Color outlineColor, Uint32 durationMs) { void Screen::notify(const std::string &text, Color text_color, Color outline_color, Uint32 duration_ms) {
notificationMessage = text; notification_message_ = text;
notificationTextColor = textColor; notification_text_color_ = text_color;
notificationOutlineColor = outlineColor; notification_outline_color_ = outline_color;
notificationEndTime = SDL_GetTicks() + durationMs; notification_end_time_ = SDL_GetTicks() + duration_ms;
} }
// Limpia la notificación actual // Limpia la notificación actual
void Screen::clearNotification() { void Screen::clearNotification() {
notificationEndTime = 0; notification_end_time_ = 0;
notificationMessage.clear(); notification_message_.clear();
} }
// Dibuja la notificación activa (si la hay) sobre el gameCanvas // Dibuja la notificación activa (si la hay) sobre el gameCanvas
void Screen::renderNotification() { void Screen::renderNotification() {
if (notificationText == nullptr || SDL_GetTicks() >= notificationEndTime) { if (notification_text_ == nullptr || SDL_GetTicks() >= notification_end_time_) {
return; return;
} }
notificationText->writeDX(TXT_CENTER | TXT_COLOR | TXT_STROKE, notification_text_->writeDX(TXT_CENTER | TXT_COLOR | TXT_STROKE,
gameCanvasWidth / 2, game_canvas_width_ / 2,
notificationY, notification_y_,
notificationMessage, notification_message_,
1, 1,
notificationTextColor, notification_text_color_,
1, 1,
notificationOutlineColor); notification_outline_color_);
} }
// ============================================================================ // ============================================================================
@@ -462,11 +462,11 @@ void Screen::handleCanvasResized() {
#endif #endif
} }
void Screen::syncFullscreenFlagFromBrowser(bool isFullscreen) { void Screen::syncFullscreenFlagFromBrowser(bool is_fullscreen) {
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
Options::video.fullscreen = isFullscreen; Options::video.fullscreen = isFullscreen;
#else #else
(void)isFullscreen; (void)is_fullscreen;
#endif #endif
} }
@@ -511,9 +511,9 @@ void Screen::initShaders() {
Options::video.gpu.acceleration ? Options::video.gpu.preferred_driver : FALLBACK_DRIVER); Options::video.gpu.acceleration ? Options::video.gpu.preferred_driver : FALLBACK_DRIVER);
} }
if (!shader_backend_->isHardwareAccelerated()) { if (!shader_backend_->isHardwareAccelerated()) {
const bool ok = shader_backend_->init(window, gameCanvas, "", ""); const bool OK = shader_backend_->init(window_, game_canvas_, "", "");
if (Options::settings.console) { if (Options::settings.console) {
std::cout << "Screen::initShaders: SDL3GPUShader::init() = " << (ok ? "OK" : "FAILED") << '\n'; std::cout << "Screen::initShaders: SDL3GPUShader::init() = " << (OK ? "OK" : "FAILED") << '\n';
} }
} }
if (shader_backend_->isHardwareAccelerated()) { if (shader_backend_->isHardwareAccelerated()) {
@@ -625,16 +625,16 @@ void Screen::applyCurrentPostFXPreset() {
if (Options::current_postfx_preset < 0 || Options::current_postfx_preset >= static_cast<int>(Options::postfx_presets.size())) { if (Options::current_postfx_preset < 0 || Options::current_postfx_preset >= static_cast<int>(Options::postfx_presets.size())) {
Options::current_postfx_preset = 0; Options::current_postfx_preset = 0;
} }
const auto &PRESET = Options::postfx_presets[Options::current_postfx_preset]; const auto &preset = Options::postfx_presets[Options::current_postfx_preset];
Rendering::PostFXParams p; Rendering::PostFXParams p;
p.vignette = PRESET.vignette; p.vignette = preset.vignette;
p.scanlines = PRESET.scanlines; p.scanlines = preset.scanlines;
p.chroma = PRESET.chroma; p.chroma = preset.chroma;
p.mask = PRESET.mask; p.mask = preset.mask;
p.gamma = PRESET.gamma; p.gamma = preset.gamma;
p.curvature = PRESET.curvature; p.curvature = preset.curvature;
p.bleeding = PRESET.bleeding; p.bleeding = preset.bleeding;
p.flicker = PRESET.flicker; p.flicker = preset.flicker;
shader_backend_->setPostFXParams(p); shader_backend_->setPostFXParams(p);
#endif #endif
} }
@@ -646,22 +646,22 @@ void Screen::applyCurrentCrtPiPreset() {
if (Options::current_crtpi_preset < 0 || Options::current_crtpi_preset >= static_cast<int>(Options::crtpi_presets.size())) { if (Options::current_crtpi_preset < 0 || Options::current_crtpi_preset >= static_cast<int>(Options::crtpi_presets.size())) {
Options::current_crtpi_preset = 0; Options::current_crtpi_preset = 0;
} }
const auto &PRESET = Options::crtpi_presets[Options::current_crtpi_preset]; const auto &preset = Options::crtpi_presets[Options::current_crtpi_preset];
Rendering::CrtPiParams p; Rendering::CrtPiParams p;
p.scanline_weight = PRESET.scanline_weight; p.scanline_weight = preset.scanline_weight;
p.scanline_gap_brightness = PRESET.scanline_gap_brightness; p.scanline_gap_brightness = preset.scanline_gap_brightness;
p.bloom_factor = PRESET.bloom_factor; p.bloom_factor = preset.bloom_factor;
p.input_gamma = PRESET.input_gamma; p.input_gamma = preset.input_gamma;
p.output_gamma = PRESET.output_gamma; p.output_gamma = preset.output_gamma;
p.mask_brightness = PRESET.mask_brightness; p.mask_brightness = preset.mask_brightness;
p.curvature_x = PRESET.curvature_x; p.curvature_x = preset.curvature_x;
p.curvature_y = PRESET.curvature_y; p.curvature_y = preset.curvature_y;
p.mask_type = PRESET.mask_type; p.mask_type = preset.mask_type;
p.enable_scanlines = PRESET.enable_scanlines; p.enable_scanlines = preset.enable_scanlines;
p.enable_multisample = PRESET.enable_multisample; p.enable_multisample = preset.enable_multisample;
p.enable_gamma = PRESET.enable_gamma; p.enable_gamma = preset.enable_gamma;
p.enable_curvature = PRESET.enable_curvature; p.enable_curvature = preset.enable_curvature;
p.enable_sharper = PRESET.enable_sharper; p.enable_sharper = preset.enable_sharper;
shader_backend_->setCrtPiParams(p); shader_backend_->setCrtPiParams(p);
#endif #endif
} }
+17 -17
View File
@@ -46,7 +46,7 @@ class Screen {
void setVideoMode(bool fullscreen); // Establece el modo de video void setVideoMode(bool fullscreen); // Establece el modo de video
void toggleVideoMode(); // Cambia entre pantalla completa y ventana void toggleVideoMode(); // Cambia entre pantalla completa y ventana
void handleCanvasResized(); // En Emscripten, reaplica setVideoMode tras un cambio del navegador (salida de fullscreen con Esc, rotación). No-op fuera de Emscripten void handleCanvasResized(); // En Emscripten, reaplica setVideoMode tras un cambio del navegador (salida de fullscreen con Esc, rotación). No-op fuera de Emscripten
static void syncFullscreenFlagFromBrowser(bool isFullscreen); // Sincroniza el flag interno de fullscreen con el estado real del navegador. Debe llamarse antes de diferir handleCanvasResized. No-op fuera de Emscripten static void syncFullscreenFlagFromBrowser(bool is_fullscreen); // Sincroniza el flag interno de fullscreen con el estado real del navegador. Debe llamarse antes de diferir handleCanvasResized. No-op fuera de Emscripten
void toggleIntegerScale(); // Alterna el escalado entero void toggleIntegerScale(); // Alterna el escalado entero
void setIntegerScale(bool enabled); // Establece el escalado entero void setIntegerScale(bool enabled); // Establece el escalado entero
void toggleVSync(); // Alterna el V-Sync void toggleVSync(); // Alterna el V-Sync
@@ -60,7 +60,7 @@ class Screen {
// Notificaciones // Notificaciones
void initNotifications(); // Enllaça el Text de notificacions amb `Resource`. A cridar després de `Resource::init(...)`. void initNotifications(); // Enllaça el Text de notificacions amb `Resource`. A cridar després de `Resource::init(...)`.
void notify(const std::string &text, Color textColor, Color outlineColor, Uint32 durationMs); // Muestra una notificación en la línea superior del canvas durante durationMs. Sobrescribe cualquier notificación activa (sin apilación). void notify(const std::string &text, Color text_color, Color outline_color, Uint32 duration_ms); // Muestra una notificación en la línea superior del canvas durante durationMs. Sobrescribe cualquier notificación activa (sin apilación).
void clearNotification(); // Limpia la notificación actual void clearNotification(); // Limpia la notificación actual
// GPU / shaders (post-procesado). En builds con NO_SHADERS (Emscripten) son no-op. // GPU / shaders (post-procesado). En builds con NO_SHADERS (Emscripten) son no-op.
@@ -111,25 +111,25 @@ class Screen {
#endif #endif
// Objetos y punteros // Objetos y punteros
SDL_Window *window; // Ventana de la aplicación SDL_Window *window_; // Ventana de la aplicación
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa SDL_Texture *game_canvas_; // Textura para completar la ventana de juego hasta la pantalla completa
// Variables // Variables
int windowWidth; // Ancho de la pantalla o ventana int window_width_; // Ancho de la pantalla o ventana
int windowHeight; // Alto de la pantalla o ventana int window_height_; // Alto de la pantalla o ventana
int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego int game_canvas_width_; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego
int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego int game_canvas_height_; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego
SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana SDL_Rect dest_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
Color borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla
// Notificaciones - una sola activa, sin apilación ni animaciones // Notificaciones - una sola activa, sin apilación ni animaciones
Text *notificationText; // Fuente 8bithud dedicada a las notificaciones Text *notification_text_; // Fuente 8bithud dedicada a las notificaciones
std::string notificationMessage; // Texto a mostrar std::string notification_message_; // Texto a mostrar
Color notificationTextColor; // Color del texto Color notification_text_color_; // Color del texto
Color notificationOutlineColor; // Color del outline Color notification_outline_color_; // Color del outline
Uint32 notificationEndTime; // SDL_GetTicks() hasta el cual se muestra Uint32 notification_end_time_; // SDL_GetTicks() hasta el cual se muestra
int notificationY; // Fila vertical en el canvas virtual int notification_y_; // Fila vertical en el canvas virtual
#ifndef NO_SHADERS #ifndef NO_SHADERS
// GPU / shaders // GPU / shaders
+30 -30
View File
@@ -15,18 +15,18 @@ SmartSprite::SmartSprite(Texture *texture, SDL_Renderer *renderer) {
// Inicializa el objeto // Inicializa el objeto
void SmartSprite::init() { void SmartSprite::init() {
enabled = false; enabled_ = false;
enabledCounter = 0; enabled_counter_ = 0;
onDestination = false; on_destination_ = false;
destX = 0; dest_x_ = 0;
destY = 0; dest_y_ = 0;
counter = 0; counter_ = 0;
finished = false; finished_ = false;
} }
// Actualiza la posición y comprueba si ha llegado a su destino // Actualiza la posición y comprueba si ha llegado a su destino
void SmartSprite::update() { void SmartSprite::update() {
if (enabled) { if (enabled_) {
// Actualiza només la posició; els SmartSprite no usen animació de // Actualiza només la posició; els SmartSprite no usen animació de
// frames i salten deliberadament AnimatedSprite::animate(). // frames i salten deliberadament AnimatedSprite::animate().
// NOLINTNEXTLINE(bugprone-parent-virtual-call) // NOLINTNEXTLINE(bugprone-parent-virtual-call)
@@ -42,7 +42,7 @@ void SmartSprite::update() {
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void SmartSprite::render() { void SmartSprite::render() {
if (enabled) { if (enabled_) {
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
MovingSprite::render(); MovingSprite::render();
} }
@@ -50,32 +50,32 @@ void SmartSprite::render() {
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto SmartSprite::getEnabledCounter() const -> int { auto SmartSprite::getEnabledCounter() const -> int {
return enabledCounter; return enabled_counter_;
} }
// Establece el valor de la variable // Establece el valor de la variable
void SmartSprite::setEnabledCounter(int value) { void SmartSprite::setEnabledCounter(int value) {
enabledCounter = value; enabled_counter_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void SmartSprite::setDestX(int x) { void SmartSprite::setDestX(int x) {
destX = x; dest_x_ = x;
} }
// Establece el valor de la variable // Establece el valor de la variable
void SmartSprite::setDestY(int y) { void SmartSprite::setDestY(int y) {
destY = y; dest_y_ = y;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto SmartSprite::getDestX() const -> int { auto SmartSprite::getDestX() const -> int {
return destX; return dest_x_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto SmartSprite::getDestY() const -> int { auto SmartSprite::getDestY() const -> int {
return destY; return dest_y_;
} }
// Comprueba el movimiento // Comprueba el movimiento
@@ -83,9 +83,9 @@ void SmartSprite::checkMove() {
// Comprueba si se desplaza en el eje X hacia la derecha // Comprueba si se desplaza en el eje X hacia la derecha
if (getAccelX() > 0 || getVelX() > 0) { if (getAccelX() > 0 || getVelX() > 0) {
// Comprueba si ha llegado al destino // Comprueba si ha llegado al destino
if (getPosX() > destX) { if (getPosX() > dest_x_) {
// Lo coloca en posición // Lo coloca en posición
setPosX(destX); setPosX(dest_x_);
// Lo detiene // Lo detiene
setVelX(0.0F); setVelX(0.0F);
@@ -95,9 +95,9 @@ void SmartSprite::checkMove() {
// Comprueba si se desplaza en el eje X hacia la izquierda // Comprueba si se desplaza en el eje X hacia la izquierda
else if (getAccelX() < 0 || getVelX() < 0) { else if (getAccelX() < 0 || getVelX() < 0) {
// Comprueba si ha llegado al destino // Comprueba si ha llegado al destino
if (getPosX() < destX) { if (getPosX() < dest_x_) {
// Lo coloca en posición // Lo coloca en posición
setPosX(destX); setPosX(dest_x_);
// Lo detiene // Lo detiene
setVelX(0.0F); setVelX(0.0F);
@@ -108,9 +108,9 @@ void SmartSprite::checkMove() {
// Comprueba si se desplaza en el eje Y hacia abajo // Comprueba si se desplaza en el eje Y hacia abajo
if (getAccelY() > 0 || getVelY() > 0) { if (getAccelY() > 0 || getVelY() > 0) {
// Comprueba si ha llegado al destino // Comprueba si ha llegado al destino
if (getPosY() > destY) { if (getPosY() > dest_y_) {
// Lo coloca en posición // Lo coloca en posición
setPosY(destY); setPosY(dest_y_);
// Lo detiene // Lo detiene
setVelY(0.0F); setVelY(0.0F);
@@ -120,9 +120,9 @@ void SmartSprite::checkMove() {
// Comprueba si se desplaza en el eje Y hacia arriba // Comprueba si se desplaza en el eje Y hacia arriba
else if (getAccelY() < 0 || getVelY() < 0) { else if (getAccelY() < 0 || getVelY() < 0) {
// Comprueba si ha llegado al destino // Comprueba si ha llegado al destino
if (getPosY() < destY) { if (getPosY() < dest_y_) {
// Lo coloca en posición // Lo coloca en posición
setPosY(destY); setPosY(dest_y_);
// Lo detiene // Lo detiene
setVelY(0.0F); setVelY(0.0F);
@@ -134,23 +134,23 @@ void SmartSprite::checkMove() {
// Comprueba si ha terminado // Comprueba si ha terminado
void SmartSprite::checkFinished() { void SmartSprite::checkFinished() {
// Comprueba si ha llegado a su destino // Comprueba si ha llegado a su destino
onDestination = getPosX() == destX && getPosY() == destY; on_destination_ = getPosX() == dest_x_ && getPosY() == dest_y_;
if (onDestination) { // Si esta en el destino comprueba su contador if (on_destination_) { // Si esta en el destino comprueba su contador
if (enabledCounter == 0) { // Si ha llegado a cero, deshabilita el objeto y lo marca como finalizado if (enabled_counter_ == 0) { // Si ha llegado a cero, deshabilita el objeto y lo marca como finalizado
finished = true; finished_ = true;
} else { // Si no ha llegado a cero, decrementa el contador } else { // Si no ha llegado a cero, decrementa el contador
enabledCounter--; enabled_counter_--;
} }
} }
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto SmartSprite::isOnDestination() const -> bool { auto SmartSprite::isOnDestination() const -> bool {
return onDestination; return on_destination_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto SmartSprite::hasFinished() const -> bool { auto SmartSprite::hasFinished() const -> bool {
return finished; return finished_;
} }
+23 -47
View File
@@ -7,54 +7,30 @@ class Texture;
// Clase SmartSprite // Clase SmartSprite
class SmartSprite : public AnimatedSprite { class SmartSprite : public AnimatedSprite {
public:
SmartSprite(Texture *texture, SDL_Renderer *renderer); // Constructor
void init(); // Inicializa el objeto
void update() override; // Actualiza la posición y comprueba si ha llegado a su destino
void render() override; // Pinta el objeto en pantalla
[[nodiscard]] auto getEnabledCounter() const -> int; // Obtiene el valor de la variable
void setEnabledCounter(int value); // Establece el valor de la variable
void setDestX(int x); // Establece el valor de la variable
void setDestY(int y); // Establece el valor de la variable
[[nodiscard]] auto getDestX() const -> int; // Obtiene el valor de la variable
[[nodiscard]] auto getDestY() const -> int; // Obtiene el valor de la variable
[[nodiscard]] auto isOnDestination() const -> bool; // Obtiene el valor de la variable
[[nodiscard]] auto hasFinished() const -> bool; // Obtiene el valor de la variable
private: private:
// Variables // Variables
bool onDestination; // Indica si está en el destino bool on_destination_; // Indica si está en el destino
int destX; // Posicion de destino en el eje X int dest_x_; // Posicion de destino en el eje X
int destY; // Posicion de destino en el eje Y int dest_y_; // Posicion de destino en el eje Y
int enabledCounter; // Contador para deshabilitarlo int enabled_counter_; // Contador para deshabilitarlo
bool finished; // Indica si ya ha terminado bool finished_; // Indica si ya ha terminado
// Comprueba el movimiento void checkMove(); // Comprueba el movimiento
void checkMove(); void checkFinished(); // Comprueba si ha terminado
// Comprueba si ha terminado
void checkFinished();
public:
// Constructor
SmartSprite(Texture *texture, SDL_Renderer *renderer);
// Inicializa el objeto
void init();
// Actualiza la posición y comprueba si ha llegado a su destino
void update() override;
// Pinta el objeto en pantalla
void render() override;
// Obtiene el valor de la variable
[[nodiscard]] auto getEnabledCounter() const -> int;
// Establece el valor de la variable
void setEnabledCounter(int value);
// Establece el valor de la variable
void setDestX(int x);
// Establece el valor de la variable
void setDestY(int y);
// Obtiene el valor de la variable
[[nodiscard]] auto getDestX() const -> int;
// Obtiene el valor de la variable
[[nodiscard]] auto getDestY() const -> int;
// Obtiene el valor de la variable
[[nodiscard]] auto isOnDestination() const -> bool;
// Obtiene el valor de la variable
[[nodiscard]] auto hasFinished() const -> bool;
}; };
+44 -44
View File
@@ -4,141 +4,141 @@
// Constructor // Constructor
Sprite::Sprite(int x, int y, int w, int h, Texture *texture, SDL_Renderer *renderer) Sprite::Sprite(int x, int y, int w, int h, Texture *texture, SDL_Renderer *renderer)
: x(x), : x_(x),
y(y), y_(y),
w(w), w_(w),
h(h), h_(h),
renderer(renderer), renderer_(renderer),
texture(texture), texture_(texture),
spriteClip{0, 0, w, h}, sprite_clip_{0, 0, w, h},
enabled(true) { enabled_(true) {
} }
Sprite::Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer) Sprite::Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer)
: x(rect.x), : x_(rect.x),
y(rect.y), y_(rect.y),
w(rect.w), w_(rect.w),
h(rect.h), h_(rect.h),
renderer(renderer), renderer_(renderer),
texture(texture), texture_(texture),
spriteClip{0, 0, rect.w, rect.h}, sprite_clip_{0, 0, rect.w, rect.h},
enabled(true) { enabled_(true) {
} }
// Destructor // Destructor
Sprite::~Sprite() { Sprite::~Sprite() {
texture = nullptr; texture_ = nullptr;
renderer = nullptr; renderer_ = nullptr;
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void Sprite::render() { void Sprite::render() {
if (enabled) { if (enabled_) {
texture->render(renderer, x, y, &spriteClip); texture_->render(renderer_, x_, y_, &sprite_clip_);
} }
} }
// Obten el valor de la variable // Obten el valor de la variable
auto Sprite::getPosX() const -> int { auto Sprite::getPosX() const -> int {
return x; return x_;
} }
// Obten el valor de la variable // Obten el valor de la variable
auto Sprite::getPosY() const -> int { auto Sprite::getPosY() const -> int {
return y; return y_;
} }
// Obten el valor de la variable // Obten el valor de la variable
auto Sprite::getWidth() const -> int { auto Sprite::getWidth() const -> int {
return w; return w_;
} }
// Obten el valor de la variable // Obten el valor de la variable
auto Sprite::getHeight() const -> int { auto Sprite::getHeight() const -> int {
return h; return h_;
} }
// Establece la posición del objeto // Establece la posición del objeto
void Sprite::setPos(SDL_Rect rect) { void Sprite::setPos(SDL_Rect rect) {
this->x = rect.x; this->x_ = rect.x;
this->y = rect.y; this->y_ = rect.y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setPosX(int x) { void Sprite::setPosX(int x) {
this->x = x; this->x_ = x;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setPosY(int y) { void Sprite::setPosY(int y) {
this->y = y; this->y_ = y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setWidth(int w) { void Sprite::setWidth(int w) {
this->w = w; this->w_ = w;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setHeight(int h) { void Sprite::setHeight(int h) {
this->h = h; this->h_ = h;
} }
// Obten el valor de la variable // Obten el valor de la variable
auto Sprite::getSpriteClip() -> SDL_Rect { auto Sprite::getSpriteClip() -> SDL_Rect {
return spriteClip; return sprite_clip_;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setSpriteClip(SDL_Rect rect) { void Sprite::setSpriteClip(SDL_Rect rect) {
spriteClip = rect; sprite_clip_ = rect;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setSpriteClip(int x, int y, int w, int h) { void Sprite::setSpriteClip(int x, int y, int w, int h) {
spriteClip = {.x = x, .y = y, .w = w, .h = h}; sprite_clip_ = {.x = x, .y = y, .w = w, .h = h};
} }
// Obten el valor de la variable // Obten el valor de la variable
auto Sprite::getTexture() -> Texture * { auto Sprite::getTexture() -> Texture * {
return texture; return texture_;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setTexture(Texture *texture) { void Sprite::setTexture(Texture *texture) {
this->texture = texture; this->texture_ = texture;
} }
// Obten el valor de la variable // Obten el valor de la variable
auto Sprite::getRenderer() -> SDL_Renderer * { auto Sprite::getRenderer() -> SDL_Renderer * {
return renderer; return renderer_;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setRenderer(SDL_Renderer *renderer) { void Sprite::setRenderer(SDL_Renderer *renderer) {
this->renderer = renderer; this->renderer_ = renderer;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setEnabled(bool value) { void Sprite::setEnabled(bool value) {
enabled = value; enabled_ = value;
} }
// Comprueba si el objeto está habilitado // Comprueba si el objeto está habilitado
auto Sprite::isEnabled() -> bool { auto Sprite::isEnabled() -> bool {
return enabled; return enabled_;
} }
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
auto Sprite::getRect() -> SDL_Rect { auto Sprite::getRect() -> SDL_Rect {
SDL_Rect rect = {x, y, w, h}; SDL_Rect rect = {x_, y_, w_, h_};
return rect; return rect;
} }
// Establece los valores de posición y tamaño del sprite // Establece los valores de posición y tamaño del sprite
void Sprite::setRect(SDL_Rect rect) { void Sprite::setRect(SDL_Rect rect) {
x = rect.x; x_ = rect.x;
y = rect.y; y_ = rect.y;
w = rect.w; w_ = rect.w;
h = rect.h; h_ = rect.h;
} }
+32 -68
View File
@@ -5,86 +5,50 @@ class Texture;
// Clase sprite // Clase sprite
class Sprite { class Sprite {
protected:
int x; // Posición en el eje X donde dibujar el sprite
int y; // Posición en el eje Y donde dibujar el sprite
int w; // Ancho del sprite
int h; // Alto del sprite
SDL_Renderer *renderer; // Puntero al renderizador de la ventana
Texture *texture; // Textura donde estan todos los dibujos del sprite
SDL_Rect spriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla
bool enabled; // Indica si el sprite esta habilitado
public: public:
// Constructor explicit Sprite(int x = 0, int y = 0, int w = 0, int h = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr); // Constructor
explicit Sprite(int x = 0, int y = 0, int w = 0, int h = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr);
Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer); Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer);
// Destructor virtual ~Sprite(); // Destructor
virtual ~Sprite();
// Muestra el sprite por pantalla virtual void render(); // Muestra el sprite por pantalla
virtual void render();
// Obten el valor de la variable [[nodiscard]] auto getPosX() const -> int; // Obten el valor de la variable
[[nodiscard]] auto getPosX() const -> int; [[nodiscard]] auto getPosY() const -> int; // Obten el valor de la variable
[[nodiscard]] auto getWidth() const -> int; // Obten el valor de la variable
[[nodiscard]] auto getHeight() const -> int; // Obten el valor de la variable
// Obten el valor de la variable void setPos(SDL_Rect rect); // Establece la posición del objeto
[[nodiscard]] auto getPosY() const -> int; void setPosX(int x); // Establece el valor de la variable
void setPosY(int y); // Establece el valor de la variable
void setWidth(int w); // Establece el valor de la variable
void setHeight(int h); // Establece el valor de la variable
// Obten el valor de la variable auto getSpriteClip() -> SDL_Rect; // Obten el valor de la variable
[[nodiscard]] auto getWidth() const -> int; void setSpriteClip(SDL_Rect rect); // Establece el valor de la variable
void setSpriteClip(int x, int y, int w, int h); // Establece el valor de la variable
// Obten el valor de la variable auto getTexture() -> Texture *; // Obten el valor de la variable
[[nodiscard]] auto getHeight() const -> int; void setTexture(Texture *texture); // Establece el valor de la variable
// Establece la posición del objeto auto getRenderer() -> SDL_Renderer *; // Obten el valor de la variable
void setPos(SDL_Rect rect); void setRenderer(SDL_Renderer *renderer); // Establece el valor de la variable
// Establece el valor de la variable virtual void setEnabled(bool value); // Establece el valor de la variable
void setPosX(int x); virtual auto isEnabled() -> bool; // Comprueba si el objeto está habilitado
// Establece el valor de la variable virtual auto getRect() -> SDL_Rect; // Devuelve el rectangulo donde está el sprite
void setPosY(int y); virtual void setRect(SDL_Rect rect); // Establece los valores de posición y tamaño del sprite
// Establece el valor de la variable protected:
void setWidth(int w); int x_; // Posición en el eje X donde dibujar el sprite
int y_; // Posición en el eje Y donde dibujar el sprite
int w_; // Ancho del sprite
int h_; // Alto del sprite
// Establece el valor de la variable SDL_Renderer *renderer_; // Puntero al renderizador de la ventana
void setHeight(int h); Texture *texture_; // Textura donde estan todos los dibujos del sprite
SDL_Rect sprite_clip_; // Rectangulo de origen de la textura que se dibujará en pantalla
// Obten el valor de la variable bool enabled_; // Indica si el sprite esta habilitado
auto getSpriteClip() -> SDL_Rect;
// Establece el valor de la variable
void setSpriteClip(SDL_Rect rect);
// Establece el valor de la variable
void setSpriteClip(int x, int y, int w, int h);
// Obten el valor de la variable
auto getTexture() -> Texture *;
// Establece el valor de la variable
void setTexture(Texture *texture);
// Obten el valor de la variable
auto getRenderer() -> SDL_Renderer *;
// Establece el valor de la variable
void setRenderer(SDL_Renderer *renderer);
// Establece el valor de la variable
virtual void setEnabled(bool value);
// Comprueba si el objeto está habilitado
virtual auto isEnabled() -> bool;
// Devuelve el rectangulo donde está el sprite
virtual auto getRect() -> SDL_Rect;
// Establece los valores de posición y tamaño del sprite
virtual void setRect(SDL_Rect rect);
}; };
+86 -87
View File
@@ -1,7 +1,6 @@
#include "core/rendering/text.h" #include "core/rendering/text.h"
#include <fstream> // for char_traits, basic_ostream, basic_ifstream, ope...
#include <iostream> // for cout #include <iostream> // for cout
#include <sstream> #include <sstream>
@@ -15,11 +14,11 @@ static void parseTextFileStream(std::istream &rfile, TextFile &tf) {
std::string buffer; std::string buffer;
std::getline(rfile, buffer); std::getline(rfile, buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
tf.boxWidth = std::stoi(buffer); tf.box_width = std::stoi(buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
tf.boxHeight = std::stoi(buffer); tf.box_height = std::stoi(buffer);
int index = 32; int index = 32;
int line_read = 0; int line_read = 0;
@@ -34,22 +33,22 @@ static void parseTextFileStream(std::istream &rfile, TextFile &tf) {
static void computeTextFileOffsets(TextFile &tf) { static void computeTextFileOffsets(TextFile &tf) {
for (int i = 32; i < 128; ++i) { for (int i = 32; i < 128; ++i) {
tf.offset[i].x = ((i - 32) % 15) * tf.boxWidth; tf.offset[i].x = ((i - 32) % 15) * tf.box_width;
tf.offset[i].y = ((i - 32) / 15) * tf.boxHeight; tf.offset[i].y = ((i - 32) / 15) * tf.box_height;
} }
} }
// Llena una estructuta TextFile desde un fichero (vía ResourceHelper: pack o filesystem) // Llena una estructuta TextFile desde un fichero (vía ResourceHelper: pack o filesystem)
auto LoadTextFile(const std::string &file, bool verbose) -> TextFile { auto loadTextFile(const std::string &file, bool verbose) -> TextFile {
const std::string filename = file.substr(file.find_last_of("\\/") + 1); const std::string FILE_NAME = file.substr(file.find_last_of("\\/") + 1);
auto bytes = ResourceHelper::loadFile(file); auto bytes = ResourceHelper::loadFile(file);
if (bytes.empty()) { if (bytes.empty()) {
if (verbose) { if (verbose) {
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << '\n'; std::cout << "Warning: Unable to open " << FILE_NAME.c_str() << " file" << '\n';
} }
TextFile tf; TextFile tf;
tf.boxWidth = 0; tf.box_width = 0;
tf.boxHeight = 0; tf.box_height = 0;
for (auto &i : tf.offset) { for (auto &i : tf.offset) {
i.x = 0; i.x = 0;
i.y = 0; i.y = 0;
@@ -59,16 +58,16 @@ auto LoadTextFile(const std::string &file, bool verbose) -> TextFile {
return tf; return tf;
} }
if (verbose) { if (verbose) {
std::cout << "Text loaded: " << filename.c_str() << '\n'; std::cout << "Text loaded: " << FILE_NAME.c_str() << '\n';
} }
return LoadTextFileFromMemory(bytes, verbose); return loadTextFileFromMemory(bytes, verbose);
} }
// Llena una estructura TextFile desde bytes en memoria // Llena una estructura TextFile desde bytes en memoria
auto LoadTextFileFromMemory(const std::vector<uint8_t> &bytes, bool verbose) -> TextFile { auto loadTextFileFromMemory(const std::vector<uint8_t> &bytes, bool verbose) -> TextFile {
TextFile tf; TextFile tf;
tf.boxWidth = 0; tf.box_width = 0;
tf.boxHeight = 0; tf.box_height = 0;
for (auto &i : tf.offset) { for (auto &i : tf.offset) {
i.x = 0; i.x = 0;
i.y = 0; i.y = 0;
@@ -87,91 +86,91 @@ auto LoadTextFileFromMemory(const std::vector<uint8_t> &bytes, bool verbose) ->
} }
// Constructor // Constructor
Text::Text(const std::string &bitmapFile, const std::string &textFile, SDL_Renderer *renderer) { Text::Text(const std::string &bitmap_file, const std::string &text_file, SDL_Renderer *renderer) {
// Carga los offsets desde el fichero // Carga los offsets desde el fichero
TextFile tf = LoadTextFile(textFile); TextFile tf = loadTextFile(text_file);
// Inicializa variables desde la estructura // Inicializa variables desde la estructura
boxHeight = tf.boxHeight; box_height_ = tf.box_height;
boxWidth = tf.boxWidth; box_width_ = tf.box_width;
for (int i = 0; i < 128; ++i) { for (int i = 0; i < 128; ++i) {
offset[i].x = tf.offset[i].x; offset_[i].x = tf.offset[i].x;
offset[i].y = tf.offset[i].y; offset_[i].y = tf.offset[i].y;
offset[i].w = tf.offset[i].w; offset_[i].w = tf.offset[i].w;
} }
// Crea los objetos // Crea los objetos
texture = new Texture(renderer, bitmapFile); texture_ = new Texture(renderer, bitmap_file);
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite_ = new Sprite({0, 0, box_width_, box_height_}, texture_, renderer);
// Inicializa variables // Inicializa variables
fixedWidth = false; fixed_width_ = false;
} }
// Constructor // Constructor
Text::Text(const std::string &textFile, Texture *texture, SDL_Renderer *renderer) { Text::Text(const std::string &text_file, Texture *texture, SDL_Renderer *renderer) {
// Carga los offsets desde el fichero // Carga los offsets desde el fichero
TextFile tf = LoadTextFile(textFile); TextFile tf = loadTextFile(text_file);
// Inicializa variables desde la estructura // Inicializa variables desde la estructura
boxHeight = tf.boxHeight; box_height_ = tf.box_height;
boxWidth = tf.boxWidth; box_width_ = tf.box_width;
for (int i = 0; i < 128; ++i) { for (int i = 0; i < 128; ++i) {
offset[i].x = tf.offset[i].x; offset_[i].x = tf.offset[i].x;
offset[i].y = tf.offset[i].y; offset_[i].y = tf.offset[i].y;
offset[i].w = tf.offset[i].w; offset_[i].w = tf.offset[i].w;
} }
// Crea los objetos // Crea los objetos
this->texture = nullptr; this->texture_ = nullptr;
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite_ = new Sprite({0, 0, box_width_, box_height_}, texture, renderer);
// Inicializa variables // Inicializa variables
fixedWidth = false; fixed_width_ = false;
} }
// Constructor // Constructor
Text::Text(TextFile *textFile, Texture *texture, SDL_Renderer *renderer) { Text::Text(TextFile *text_file, Texture *texture, SDL_Renderer *renderer) {
// Inicializa variables desde la estructura // Inicializa variables desde la estructura
boxHeight = textFile->boxHeight; box_height_ = text_file->box_height;
boxWidth = textFile->boxWidth; box_width_ = text_file->box_width;
for (int i = 0; i < 128; ++i) { for (int i = 0; i < 128; ++i) {
offset[i].x = textFile->offset[i].x; offset_[i].x = text_file->offset[i].x;
offset[i].y = textFile->offset[i].y; offset_[i].y = text_file->offset[i].y;
offset[i].w = textFile->offset[i].w; offset_[i].w = text_file->offset[i].w;
} }
// Crea los objetos // Crea los objetos
this->texture = nullptr; this->texture_ = nullptr;
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite_ = new Sprite({0, 0, box_width_, box_height_}, texture, renderer);
// Inicializa variables // Inicializa variables
fixedWidth = false; fixed_width_ = false;
} }
// Constructor desde bytes // Constructor desde bytes
Text::Text(const std::vector<uint8_t> &pngBytes, const std::vector<uint8_t> &txtBytes, SDL_Renderer *renderer) { Text::Text(const std::vector<uint8_t> &png_bytes, const std::vector<uint8_t> &txt_bytes, SDL_Renderer *renderer) {
TextFile tf = LoadTextFileFromMemory(txtBytes); TextFile tf = loadTextFileFromMemory(txt_bytes);
boxHeight = tf.boxHeight; box_height_ = tf.box_height;
boxWidth = tf.boxWidth; box_width_ = tf.box_width;
for (int i = 0; i < 128; ++i) { for (int i = 0; i < 128; ++i) {
offset[i].x = tf.offset[i].x; offset_[i].x = tf.offset[i].x;
offset[i].y = tf.offset[i].y; offset_[i].y = tf.offset[i].y;
offset[i].w = tf.offset[i].w; offset_[i].w = tf.offset[i].w;
} }
// Crea la textura desde bytes (Text es dueño en este overload) // Crea la textura desde bytes (Text es dueño en este overload)
texture = new Texture(renderer, pngBytes); texture_ = new Texture(renderer, png_bytes);
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite_ = new Sprite({0, 0, box_width_, box_height_}, texture_, renderer);
fixedWidth = false; fixed_width_ = false;
} }
// Destructor // Destructor
Text::~Text() { Text::~Text() {
delete sprite; delete sprite_;
delete texture; delete texture_;
} }
// Escribe texto en pantalla // Escribe texto en pantalla
@@ -182,30 +181,30 @@ void Text::write(int x, int y, const std::string &text, int kerning, int lenght)
lenght = text.length(); lenght = text.length();
} }
sprite->setPosY(y); sprite_->setPosY(y);
const int width = sprite->getWidth(); const int WIDTH = sprite_->getWidth();
const int height = sprite->getHeight(); const int HEIGHT = sprite_->getHeight();
for (int i = 0; i < lenght; ++i) { for (int i = 0; i < lenght; ++i) {
const int index = static_cast<unsigned char>(text[i]); const int INDEX = static_cast<unsigned char>(text[i]);
sprite->setSpriteClip(offset[index].x, offset[index].y, width, height); sprite_->setSpriteClip(offset_[INDEX].x, offset_[INDEX].y, WIDTH, HEIGHT);
sprite->setPosX(x + shift); sprite_->setPosX(x + shift);
sprite->render(); sprite_->render();
shift += fixedWidth ? boxWidth : (offset[index].w + kerning); shift += fixed_width_ ? box_width_ : (offset_[INDEX].w + kerning);
} }
} }
// Escribe el texto con colores // Escribe el texto con colores
void Text::writeColored(int x, int y, const std::string &text, Color color, int kerning, int lenght) { void Text::writeColored(int x, int y, const std::string &text, Color color, int kerning, int lenght) {
sprite->getTexture()->setColor(color.r, color.g, color.b); sprite_->getTexture()->setColor(color.r, color.g, color.b);
write(x, y, text, kerning, lenght); write(x, y, text, kerning, lenght);
sprite->getTexture()->setColor(255, 255, 255); sprite_->getTexture()->setColor(255, 255, 255);
} }
// Escribe el texto con sombra // Escribe el texto con sombra
void Text::writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadowDistance, int kerning, int lenght) { void Text::writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance, int kerning, int lenght) {
sprite->getTexture()->setColor(color.r, color.g, color.b); sprite_->getTexture()->setColor(color.r, color.g, color.b);
write(x + shadowDistance, y + shadowDistance, text, kerning, lenght); write(x + shadow_distance, y + shadow_distance, text, kerning, lenght);
sprite->getTexture()->setColor(255, 255, 255); sprite_->getTexture()->setColor(255, 255, 255);
write(x, y, text, kerning, lenght); write(x, y, text, kerning, lenght);
} }
@@ -216,32 +215,32 @@ void Text::writeCentered(int x, int y, const std::string &text, int kerning, int
} }
// Escribe texto con extras // Escribe texto con extras
void Text::writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning, Color textColor, Uint8 shadowDistance, Color shadowColor, int lenght) { void Text::writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning, Color text_color, Uint8 shadow_distance, Color shadow_color, int lenght) {
const bool centered = ((flags & TXT_CENTER) == TXT_CENTER); const bool CENTERED = ((flags & TXT_CENTER) == TXT_CENTER);
const bool shadowed = ((flags & TXT_SHADOW) == TXT_SHADOW); const bool SHADOWED = ((flags & TXT_SHADOW) == TXT_SHADOW);
const bool colored = ((flags & TXT_COLOR) == TXT_COLOR); const bool COLORED = ((flags & TXT_COLOR) == TXT_COLOR);
const bool stroked = ((flags & TXT_STROKE) == TXT_STROKE); const bool STROKED = ((flags & TXT_STROKE) == TXT_STROKE);
if (centered) { if (CENTERED) {
x -= (Text::lenght(text, kerning) / 2); x -= (Text::lenght(text, kerning) / 2);
} }
if (shadowed) { if (SHADOWED) {
writeColored(x + shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght); writeColored(x + shadow_distance, y + shadow_distance, text, shadow_color, kerning, lenght);
} }
if (stroked) { if (STROKED) {
for (int dist = 1; dist <= shadowDistance; ++dist) { for (int dist = 1; dist <= shadow_distance; ++dist) {
for (int dy = -dist; dy <= dist; ++dy) { for (int dy = -dist; dy <= dist; ++dy) {
for (int dx = -dist; dx <= dist; ++dx) { for (int dx = -dist; dx <= dist; ++dx) {
writeColored(x + dx, y + dy, text, shadowColor, kerning, lenght); writeColored(x + dx, y + dy, text, shadow_color, kerning, lenght);
} }
} }
} }
} }
if (colored) { if (COLORED) {
writeColored(x, y, text, textColor, kerning, lenght); writeColored(x, y, text, text_color, kerning, lenght);
} else { } else {
write(x, y, text, kerning, lenght); write(x, y, text, kerning, lenght);
} }
@@ -252,7 +251,7 @@ auto Text::lenght(const std::string &text, int kerning) -> int {
int shift = 0; int shift = 0;
for (int i = 0; i < (int)text.length(); ++i) { for (int i = 0; i < (int)text.length(); ++i) {
shift += (offset[static_cast<unsigned char>(text[i])].w + kerning); shift += (offset_[static_cast<unsigned char>(text[i])].w + kerning);
} }
// Descuenta el kerning del último caracter // Descuenta el kerning del último caracter
@@ -261,15 +260,15 @@ auto Text::lenght(const std::string &text, int kerning) -> int {
// Devuelve el valor de la variable // Devuelve el valor de la variable
auto Text::getCharacterSize() const -> int { auto Text::getCharacterSize() const -> int {
return boxWidth; return box_width_;
} }
// Recarga la textura // Recarga la textura
void Text::reLoadTexture() { void Text::reLoadTexture() {
sprite->getTexture()->reLoad(); sprite_->getTexture()->reLoad();
} }
// Establece si se usa un tamaño fijo de letra // Establece si se usa un tamaño fijo de letra
void Text::setFixedWidth(bool value) { void Text::setFixedWidth(bool value) {
fixedWidth = value; fixed_width_ = value;
} }
+27 -45
View File
@@ -22,70 +22,52 @@ struct Offset {
}; };
struct TextFile { struct TextFile {
int boxWidth; // Anchura de la caja de cada caracter en el png int box_width; // Anchura de la caja de cada caracter en el png
int boxHeight; // Altura de la caja de cada caracter en el png int box_height; // Altura de la caja de cada caracter en el png
Offset offset[128]; // Vector con las posiciones y ancho de cada letra Offset offset[128]; // Vector con las posiciones y ancho de cada letra
}; };
// Llena una estructuta TextFile desde un fichero // Llena una estructuta TextFile desde un fichero
auto LoadTextFile(const std::string &file, bool verbose = false) -> TextFile; auto loadTextFile(const std::string &file, bool verbose = false) -> TextFile;
// Llena una estructura TextFile desde bytes en memoria // Llena una estructura TextFile desde bytes en memoria
auto LoadTextFileFromMemory(const std::vector<uint8_t> &bytes, bool verbose = false) -> TextFile; auto loadTextFileFromMemory(const std::vector<uint8_t> &bytes, bool verbose = false) -> TextFile;
// Clase texto. Pinta texto en pantalla a partir de un bitmap // Clase texto. Pinta texto en pantalla a partir de un bitmap
class Text { class Text {
private:
// Objetos y punteros
Sprite *sprite; // Objeto con los graficos para el texto
Texture *texture; // Textura con los bitmaps del texto
// Variables
int boxWidth; // Anchura de la caja de cada caracter en el png
int boxHeight; // Altura de la caja de cada caracter en el png
bool fixedWidth; // Indica si el texto se ha de escribir con longitud fija en todas las letras
Offset offset[128]; // Vector con las posiciones y ancho de cada letra
public: public:
// Constructor Text(const std::string &bitmap_file, const std::string &text_file, SDL_Renderer *renderer); // Constructor
Text(const std::string &bitmapFile, const std::string &textFile, SDL_Renderer *renderer); Text(const std::string &text_file, Texture *texture, SDL_Renderer *renderer);
Text(const std::string &textFile, Texture *texture, SDL_Renderer *renderer); Text(TextFile *text_file, Texture *texture, SDL_Renderer *renderer);
Text(TextFile *textFile, Texture *texture, SDL_Renderer *renderer); Text(const std::vector<uint8_t> &png_bytes, const std::vector<uint8_t> &txt_bytes, SDL_Renderer *renderer); // Constructor desde bytes en memoria: comparte ownership del texture (no lo libera)
// Constructor desde bytes en memoria: comparte ownership del texture (no lo libera) ~Text(); // Destructor
Text(const std::vector<uint8_t> &pngBytes, const std::vector<uint8_t> &txtBytes, SDL_Renderer *renderer);
// Destructor
~Text();
// No copiable (gestiona memoria dinámica) // No copiable (gestiona memoria dinámica)
Text(const Text &) = delete; Text(const Text &) = delete;
auto operator=(const Text &) -> Text & = delete; auto operator=(const Text &) -> Text & = delete;
// Escribe el texto en pantalla void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla
void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1); // Escribe el texto con colores
void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); // Escribe el texto con sombra
void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x
void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color text_color = Color(255, 255, 255), Uint8 shadow_distance = 1, Color shadow_color = Color(0, 0, 0), int lenght = -1); // Escribe texto con extras
// Escribe el texto con colores auto lenght(const std::string &text, int kerning = 1) -> int; // Obtiene la longitud en pixels de una cadena
void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1);
// Escribe el texto con sombra [[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el valor de la variable
void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1);
// Escribe el texto centrado en un punto x void reLoadTexture(); // Recarga la textura
void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra
// Escribe texto con extras private:
void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color textColor = Color(255, 255, 255), Uint8 shadowDistance = 1, Color shadowColor = Color(0, 0, 0), int lenght = -1); // Objetos y punteros
Sprite *sprite_; // Objeto con los graficos para el texto
Texture *texture_; // Textura con los bitmaps del texto
// Obtiene la longitud en pixels de una cadena // Variables
auto lenght(const std::string &text, int kerning = 1) -> int; int box_width_; // Anchura de la caja de cada caracter en el png
int box_height_; // Altura de la caja de cada caracter en el png
// Devuelve el valor de la variable bool fixed_width_; // Indica si el texto se ha de escribir con longitud fija en todas las letras
[[nodiscard]] auto getCharacterSize() const -> int; Offset offset_[128]; // Vector con las posiciones y ancho de cada letra
// Recarga la textura
void reLoadTexture();
// Establece si se usa un tamaño fijo de letra
void setFixedWidth(bool value);
}; };
+65 -65
View File
@@ -9,19 +9,19 @@
#include "core/resources/resource_helper.h" // for loadFile (pack + filesystem fallback) #include "core/resources/resource_helper.h" // for loadFile (pack + filesystem fallback)
#include "external/stb_image.h" // for stbi_failure_reason, stbi_image_free #include "external/stb_image.h" // for stbi_failure_reason, stbi_image_free
SDL_ScaleMode Texture::currentScaleMode = SDL_SCALEMODE_NEAREST; SDL_ScaleMode Texture::current_scale_mode = SDL_SCALEMODE_NEAREST;
void Texture::setGlobalScaleMode(SDL_ScaleMode mode) { void Texture::setGlobalScaleMode(SDL_ScaleMode mode) {
currentScaleMode = mode; current_scale_mode = mode;
} }
// Constructor // Constructor
Texture::Texture(SDL_Renderer *renderer, const std::string &path, bool verbose) Texture::Texture(SDL_Renderer *renderer, const std::string &path, bool verbose)
: texture(nullptr), : texture_(nullptr),
renderer(renderer), renderer_(renderer),
width(0), width_(0),
height(0), height_(0),
path(path) { path_(path) {
// Carga el fichero en la textura // Carga el fichero en la textura
if (!path.empty()) { if (!path.empty()) {
loadFromFile(path, renderer, verbose); loadFromFile(path, renderer, verbose);
@@ -30,10 +30,10 @@ Texture::Texture(SDL_Renderer *renderer, const std::string &path, bool verbose)
// Constructor desde bytes // Constructor desde bytes
Texture::Texture(SDL_Renderer *renderer, const std::vector<uint8_t> &bytes, bool verbose) Texture::Texture(SDL_Renderer *renderer, const std::vector<uint8_t> &bytes, bool verbose)
: texture(nullptr), : texture_(nullptr),
renderer(renderer), renderer_(renderer),
width(0), width_(0),
height(0) { height_(0) {
if (!bytes.empty()) { if (!bytes.empty()) {
loadFromMemory(bytes.data(), bytes.size(), renderer, verbose); loadFromMemory(bytes.data(), bytes.size(), renderer, verbose);
} }
@@ -47,24 +47,24 @@ Texture::~Texture() {
// Helper: convierte píxeles RGBA decodificados por stbi en SDL_Texture // Helper: convierte píxeles RGBA decodificados por stbi en SDL_Texture
static auto createTextureFromPixels(SDL_Renderer *renderer, unsigned char *data, int w, int h, int *out_w, int *out_h) -> SDL_Texture * { static auto createTextureFromPixels(SDL_Renderer *renderer, unsigned char *data, int w, int h, int *out_w, int *out_h) -> SDL_Texture * {
const int pitch = 4 * w; const int PITCH = 4 * w;
SDL_Surface *loadedSurface = SDL_CreateSurfaceFrom(w, h, SDL_PIXELFORMAT_RGBA32, static_cast<void *>(data), pitch); SDL_Surface *loaded_surface = SDL_CreateSurfaceFrom(w, h, SDL_PIXELFORMAT_RGBA32, static_cast<void *>(data), PITCH);
if (loadedSurface == nullptr) { if (loaded_surface == nullptr) {
return nullptr; return nullptr;
} }
SDL_Texture *newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); SDL_Texture *new_texture = SDL_CreateTextureFromSurface(renderer, loaded_surface);
if (newTexture != nullptr) { if (new_texture != nullptr) {
*out_w = loadedSurface->w; *out_w = loaded_surface->w;
*out_h = loadedSurface->h; *out_h = loaded_surface->h;
SDL_SetTextureScaleMode(newTexture, Texture::currentScaleMode); SDL_SetTextureScaleMode(new_texture, Texture::current_scale_mode);
} }
SDL_DestroySurface(loadedSurface); SDL_DestroySurface(loaded_surface);
return newTexture; return new_texture;
} }
// Carga una imagen desde un fichero (vía ResourceHelper: pack si està inicialitzat, filesystem si no) // Carga una imagen desde un fichero (vía ResourceHelper: pack si està inicialitzat, filesystem si no)
auto Texture::loadFromFile(const std::string &path, SDL_Renderer *renderer, bool verbose) -> bool { auto Texture::loadFromFile(const std::string &path, SDL_Renderer *renderer, bool verbose) -> bool {
const std::string filename = path.substr(path.find_last_of("\\/") + 1); const std::string FILE_NAME = path.substr(path.find_last_of("\\/") + 1);
auto bytes = ResourceHelper::loadFile(path); auto bytes = ResourceHelper::loadFile(path);
if (bytes.empty()) { if (bytes.empty()) {
@@ -81,18 +81,18 @@ auto Texture::loadFromFile(const std::string &path, SDL_Renderer *renderer, bool
SDL_Log("Loading image failed: %s", stbi_failure_reason()); SDL_Log("Loading image failed: %s", stbi_failure_reason());
exit(1); exit(1);
} else if (verbose) { } else if (verbose) {
std::cout << "Image loaded: " << filename.c_str() << '\n'; std::cout << "Image loaded: " << FILE_NAME.c_str() << '\n';
} }
unload(); unload();
SDL_Texture *newTexture = createTextureFromPixels(renderer, data, w, h, &this->width, &this->height); SDL_Texture *new_texture = createTextureFromPixels(renderer, data, w, h, &this->width_, &this->height_);
if (newTexture == nullptr && verbose) { if (new_texture == nullptr && verbose) {
std::cout << "Unable to load image " << path.c_str() << '\n'; std::cout << "Unable to load image " << path.c_str() << '\n';
} }
stbi_image_free(data); stbi_image_free(data);
texture = newTexture; texture_ = new_texture;
return texture != nullptr; return texture_ != nullptr;
} }
// Carga una imagen desde bytes en memoria // Carga una imagen desde bytes en memoria
@@ -107,112 +107,112 @@ auto Texture::loadFromMemory(const uint8_t *data, size_t size, SDL_Renderer *ren
} }
unload(); unload();
SDL_Texture *newTexture = createTextureFromPixels(renderer, pixels, w, h, &this->width, &this->height); SDL_Texture *new_texture = createTextureFromPixels(renderer, pixels, w, h, &this->width_, &this->height_);
if (newTexture == nullptr && verbose) { if (new_texture == nullptr && verbose) {
std::cout << "Unable to create texture from memory" << '\n'; std::cout << "Unable to create texture from memory" << '\n';
} }
stbi_image_free(pixels); stbi_image_free(pixels);
texture = newTexture; texture_ = new_texture;
return texture != nullptr; return texture_ != nullptr;
} }
// Crea una textura en blanco // Crea una textura en blanco
auto Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) -> bool { auto Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) -> bool {
// Crea una textura sin inicializar // Crea una textura sin inicializar
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height); texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
if (texture == nullptr) { if (texture_ == nullptr) {
std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << '\n'; std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << '\n';
} else { } else {
this->width = width; this->width_ = width;
this->height = height; this->height_ = height;
SDL_SetTextureScaleMode(texture, currentScaleMode); SDL_SetTextureScaleMode(texture_, current_scale_mode);
} }
return texture != nullptr; return texture_ != nullptr;
} }
// Libera la memoria de la textura // Libera la memoria de la textura
void Texture::unload() { void Texture::unload() {
// Libera la textura si existe // Libera la textura si existe
if (texture != nullptr) { if (texture_ != nullptr) {
SDL_DestroyTexture(texture); SDL_DestroyTexture(texture_);
texture = nullptr; texture_ = nullptr;
width = 0; width_ = 0;
height = 0; height_ = 0;
} }
} }
// Establece el color para la modulacion // Establece el color para la modulacion
void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue) { void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue) {
SDL_SetTextureColorMod(texture, red, green, blue); SDL_SetTextureColorMod(texture_, red, green, blue);
} }
// Establece el blending // Establece el blending
void Texture::setBlendMode(SDL_BlendMode blending) { void Texture::setBlendMode(SDL_BlendMode blending) {
SDL_SetTextureBlendMode(texture, blending); SDL_SetTextureBlendMode(texture_, blending);
} }
// Establece el alpha para la modulación // Establece el alpha para la modulación
void Texture::setAlpha(Uint8 alpha) { void Texture::setAlpha(Uint8 alpha) {
SDL_SetTextureAlphaMod(texture, alpha); SDL_SetTextureAlphaMod(texture_, alpha);
} }
// Renderiza la textura en un punto específico // Renderiza la textura en un punto específico
void Texture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float zoomW, float zoomH, double angle, SDL_Point *center, SDL_FlipMode flip) { void Texture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float zoom_w, float zoom_h, double angle, SDL_Point *center, SDL_FlipMode flip) {
// Establece el destino de renderizado en la pantalla // Establece el destino de renderizado en la pantalla
SDL_FRect renderQuad = {(float)x, (float)y, (float)width, (float)height}; SDL_FRect render_quad = {(float)x, (float)y, (float)width_, (float)height_};
// Obtiene las dimesiones del clip de renderizado // Obtiene las dimesiones del clip de renderizado
if (clip != nullptr) { if (clip != nullptr) {
renderQuad.w = (float)clip->w; render_quad.w = (float)clip->w;
renderQuad.h = (float)clip->h; render_quad.h = (float)clip->h;
} }
renderQuad.w = renderQuad.w * zoomW; render_quad.w = render_quad.w * zoom_w;
renderQuad.h = renderQuad.h * zoomH; render_quad.h = render_quad.h * zoom_h;
// Convierte el clip a SDL_FRect // Convierte el clip a SDL_FRect
SDL_FRect srcRect; SDL_FRect src_rect;
SDL_FRect *srcRectPtr = nullptr; SDL_FRect *src_rect_ptr = nullptr;
if (clip != nullptr) { if (clip != nullptr) {
srcRect = {.x = (float)clip->x, .y = (float)clip->y, .w = (float)clip->w, .h = (float)clip->h}; src_rect = {.x = (float)clip->x, .y = (float)clip->y, .w = (float)clip->w, .h = (float)clip->h};
srcRectPtr = &srcRect; src_rect_ptr = &src_rect;
} }
// Convierte el centro a SDL_FPoint // Convierte el centro a SDL_FPoint
SDL_FPoint fCenter; SDL_FPoint f_center;
SDL_FPoint *fCenterPtr = nullptr; SDL_FPoint *f_center_ptr = nullptr;
if (center != nullptr) { if (center != nullptr) {
fCenter = {.x = (float)center->x, .y = (float)center->y}; f_center = {.x = (float)center->x, .y = (float)center->y};
fCenterPtr = &fCenter; f_center_ptr = &f_center;
} }
// Renderiza a pantalla // Renderiza a pantalla
SDL_RenderTextureRotated(renderer, texture, srcRectPtr, &renderQuad, angle, fCenterPtr, flip); SDL_RenderTextureRotated(renderer, texture_, src_rect_ptr, &render_quad, angle, f_center_ptr, flip);
} }
// Establece la textura como objetivo de renderizado // Establece la textura como objetivo de renderizado
void Texture::setAsRenderTarget(SDL_Renderer *renderer) { void Texture::setAsRenderTarget(SDL_Renderer *renderer) {
SDL_SetRenderTarget(renderer, texture); SDL_SetRenderTarget(renderer, texture_);
} }
// Obtiene el ancho de la imagen // Obtiene el ancho de la imagen
auto Texture::getWidth() const -> int { auto Texture::getWidth() const -> int {
return width; return width_;
} }
// Obtiene el alto de la imagen // Obtiene el alto de la imagen
auto Texture::getHeight() const -> int { auto Texture::getHeight() const -> int {
return height; return height_;
} }
// Recarga la textura // Recarga la textura
auto Texture::reLoad() -> bool { auto Texture::reLoad() -> bool {
return loadFromFile(path, renderer); return loadFromFile(path_, renderer_);
} }
// Obtiene la textura // Obtiene la textura
auto Texture::getSDLTexture() -> SDL_Texture * { auto Texture::getSDLTexture() -> SDL_Texture * {
return texture; return texture_;
} }
+32 -59
View File
@@ -7,67 +7,40 @@
#include <vector> #include <vector>
class Texture { class Texture {
public:
static SDL_ScaleMode current_scale_mode; // Modo de escalado global para nuevas texturas
static void setGlobalScaleMode(SDL_ScaleMode mode); // Establece el modo de escalado global para nuevas texturas
explicit Texture(SDL_Renderer *renderer, const std::string &path = "", bool verbose = false); // Constructor
Texture(SDL_Renderer *renderer, const std::vector<uint8_t> &bytes, bool verbose = false); // Constructor desde bytes (PNG en memoria)
~Texture(); // Destructor
auto loadFromFile(const std::string &path, SDL_Renderer *renderer, bool verbose = false) -> bool; // Carga una imagen desde un fichero
auto loadFromMemory(const uint8_t *data, size_t size, SDL_Renderer *renderer, bool verbose = false) -> bool; // Carga una imagen desde bytes en memoria
auto createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess /*access*/ = SDL_TEXTUREACCESS_STREAMING) -> bool; // Crea una textura en blanco
void unload(); // Libera la memoria de la textura
void setColor(Uint8 red, Uint8 green, Uint8 blue); // Establece el color para la modulacion
void setBlendMode(SDL_BlendMode blending); // Establece el blending
void setAlpha(Uint8 alpha); // Establece el alpha para la modulación
void render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip = nullptr, float zoom_w = 1, float zoom_h = 1, double angle = 0.0, SDL_Point *center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Renderiza la textura en un punto específico
void setAsRenderTarget(SDL_Renderer *renderer); // Establece la textura como objetivo de renderizado
[[nodiscard]] auto getWidth() const -> int; // Obtiene el ancho de la imagen
[[nodiscard]] auto getHeight() const -> int; // Obtiene el alto de la imagen
auto reLoad() -> bool; // Recarga la textura
auto getSDLTexture() -> SDL_Texture *; // Obtiene la textura
private: private:
// Objetos y punteros // Objetos y punteros
SDL_Texture *texture; // La textura SDL_Texture *texture_; // La textura
SDL_Renderer *renderer; // Renderizador donde dibujar la textura SDL_Renderer *renderer_; // Renderizador donde dibujar la textura
// Variables // Variables
int width; // Ancho de la imagen int width_; // Ancho de la imagen
int height; // Alto de la imagen int height_; // Alto de la imagen
std::string path; // Ruta de la imagen de la textura std::string path_; // Ruta de la imagen de la textura
public:
static SDL_ScaleMode currentScaleMode; // Modo de escalado global para nuevas texturas
// Establece el modo de escalado global para nuevas texturas
static void setGlobalScaleMode(SDL_ScaleMode mode);
// Constructor
explicit Texture(SDL_Renderer *renderer, const std::string &path = "", bool verbose = false);
// Constructor desde bytes (PNG en memoria)
Texture(SDL_Renderer *renderer, const std::vector<uint8_t> &bytes, bool verbose = false);
// Destructor
~Texture();
// Carga una imagen desde un fichero
auto loadFromFile(const std::string &path, SDL_Renderer *renderer, bool verbose = false) -> bool;
// Carga una imagen desde bytes en memoria
auto loadFromMemory(const uint8_t *data, size_t size, SDL_Renderer *renderer, bool verbose = false) -> bool;
// Crea una textura en blanco
auto createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess /*access*/ = SDL_TEXTUREACCESS_STREAMING) -> bool;
// Libera la memoria de la textura
void unload();
// Establece el color para la modulacion
void setColor(Uint8 red, Uint8 green, Uint8 blue);
// Establece el blending
void setBlendMode(SDL_BlendMode blending);
// Establece el alpha para la modulación
void setAlpha(Uint8 alpha);
// Renderiza la textura en un punto específico
void render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip = nullptr, float zoomW = 1, float zoomH = 1, double angle = 0.0, SDL_Point *center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE);
// Establece la textura como objetivo de renderizado
void setAsRenderTarget(SDL_Renderer *renderer);
// Obtiene el ancho de la imagen
[[nodiscard]] auto getWidth() const -> int;
// Obtiene el alto de la imagen
[[nodiscard]] auto getHeight() const -> int;
// Recarga la textura
auto reLoad() -> bool;
// Obtiene la textura
auto getSDLTexture() -> SDL_Texture *;
}; };
+31 -31
View File
@@ -4,32 +4,32 @@
// Constructor // Constructor
Writer::Writer(Text *text) Writer::Writer(Text *text)
: text(text) { : text_(text) {
} }
// Actualiza el objeto // Actualiza el objeto
void Writer::update() { void Writer::update() {
if (enabled) { if (enabled_) {
if (!completed) { // No completado if (!completed_) { // No completado
if (writingCounter > 0) { if (writing_counter_ > 0) {
writingCounter--; writing_counter_--;
} }
else if (writingCounter == 0) { else if (writing_counter_ == 0) {
index++; index_++;
writingCounter = speed; writing_counter_ = speed_;
} }
if (index == lenght) { if (index_ == length_) {
completed = true; completed_ = true;
} }
} }
if (completed) { // Completado if (completed_) { // Completado
if (enabledCounter > 0) { if (enabled_counter_ > 0) {
enabledCounter--; enabled_counter_--;
} else if (enabledCounter == 0) { } else if (enabled_counter_ == 0) {
finished = true; finished_ = true;
} }
} }
} }
@@ -37,64 +37,64 @@ void Writer::update() {
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
void Writer::render() { void Writer::render() {
if (enabled) { if (enabled_) {
text->write(posX, posY, caption, kerning, index); text_->write(pos_x_, pos_y_, caption_, kerning_, index_);
} }
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setPosX(int value) { void Writer::setPosX(int value) {
posX = value; pos_x_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setPosY(int value) { void Writer::setPosY(int value) {
posY = value; pos_y_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setKerning(int value) { void Writer::setKerning(int value) {
kerning = value; kerning_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setCaption(const std::string &text) { void Writer::setCaption(const std::string &text) {
caption = text; caption_ = text;
lenght = text.length(); length_ = text.length();
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setSpeed(int value) { void Writer::setSpeed(int value) {
speed = value; speed_ = value;
writingCounter = value; writing_counter_ = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setEnabled(bool value) { void Writer::setEnabled(bool value) {
enabled = value; enabled_ = value;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto Writer::IsEnabled() const -> bool { auto Writer::isEnabled() const -> bool {
return enabled; return enabled_;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setEnabledCounter(int time) { void Writer::setEnabledCounter(int time) {
enabledCounter = time; enabled_counter_ = time;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto Writer::getEnabledCounter() const -> int { auto Writer::getEnabledCounter() const -> int {
return enabledCounter; return enabled_counter_;
} }
// Centra la cadena de texto a un punto X // Centra la cadena de texto a un punto X
void Writer::center(int x) { void Writer::center(int x) {
setPosX(x - (text->lenght(caption, kerning) / 2)); setPosX(x - (text_->lenght(caption_, kerning_) / 2));
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
auto Writer::hasFinished() const -> bool { auto Writer::hasFinished() const -> bool {
return finished; return finished_;
} }
+33 -56
View File
@@ -5,64 +5,41 @@ class Text;
// Clase Writer. Pinta texto en pantalla letra a letra a partir de una cadena y un bitmap // Clase Writer. Pinta texto en pantalla letra a letra a partir de una cadena y un bitmap
class Writer { class Writer {
public:
explicit Writer(Text *text); // Constructor
void update(); // Actualiza el objeto
void render(); // Dibuja el objeto en pantalla
void setPosX(int value); // Establece el valor de la variable
void setPosY(int value); // Establece el valor de la variable
void setKerning(int value); // Establece el valor de la variable
void setCaption(const std::string &text); // Establece el valor de la variable
void setSpeed(int value); // Establece el valor de la variable
void setEnabled(bool value); // Establece el valor de la variable
[[nodiscard]] auto isEnabled() const -> bool; // Obtiene el valor de la variable
void setEnabledCounter(int time); // Establece el valor de la variable
[[nodiscard]] auto getEnabledCounter() const -> int; // Obtiene el valor de la variable
void center(int x); // Centra la cadena de texto a un punto X
[[nodiscard]] auto hasFinished() const -> bool; // Obtiene el valor de la variable
private: private:
// Objetos y punteros // Objetos y punteros
Text *text; // Objeto encargado de escribir el texto Text *text_; // Objeto encargado de escribir el texto
// Variables // Variables
int posX{0}; // Posicion en el eje X donde empezar a escribir el texto int pos_x_{0}; // Posicion en el eje X donde empezar a escribir el texto
int posY{0}; // Posicion en el eje Y donde empezar a escribir el texto int pos_y_{0}; // Posicion en el eje Y donde empezar a escribir el texto
int kerning{0}; // Kerning del texto, es decir, espaciado entre caracteres int kerning_{0}; // Kerning del texto, es decir, espaciado entre caracteres
std::string caption; // El texto para escribir std::string caption_; // El texto para escribir
int speed{0}; // Velocidad de escritura int speed_{0}; // Velocidad de escritura
int writingCounter{0}; // Temporizador de escritura para cada caracter int writing_counter_{0}; // Temporizador de escritura para cada caracter
int index{0}; // Posición del texto que se está escribiendo int index_{0}; // Posición del texto que se está escribiendo
int lenght{0}; // Longitud de la cadena a escribir int length_{0}; // Longitud de la cadena a escribir
bool completed{false}; // Indica si se ha escrito todo el texto bool completed_{false}; // Indica si se ha escrito todo el texto
bool enabled{false}; // Indica si el objeto está habilitado bool enabled_{false}; // Indica si el objeto está habilitado
int enabledCounter{0}; // Temporizador para deshabilitar el objeto int enabled_counter_{0}; // Temporizador para deshabilitar el objeto
bool finished{false}; // Indica si ya ha terminado bool finished_{false}; // Indica si ya ha terminado
public:
// Constructor
explicit Writer(Text *text);
// Actualiza el objeto
void update();
// Dibuja el objeto en pantalla
void render();
// Establece el valor de la variable
void setPosX(int value);
// Establece el valor de la variable
void setPosY(int value);
// Establece el valor de la variable
void setKerning(int value);
// Establece el valor de la variable
void setCaption(const std::string &text);
// Establece el valor de la variable
void setSpeed(int value);
// Establece el valor de la variable
void setEnabled(bool value);
// Obtiene el valor de la variable
[[nodiscard]] auto IsEnabled() const -> bool;
// Establece el valor de la variable
void setEnabledCounter(int time);
// Obtiene el valor de la variable
[[nodiscard]] auto getEnabledCounter() const -> int;
// Centra la cadena de texto a un punto X
void center(int x);
// Obtiene el valor de la variable
[[nodiscard]] auto hasFinished() const -> bool;
}; };
+35 -61
View File
@@ -26,24 +26,24 @@ auto Asset::get() -> Asset * {
// Constructor // Constructor
Asset::Asset(const std::string &executablePath) Asset::Asset(const std::string &executablePath)
: executablePath(executablePath.substr(0, executablePath.find_last_of("\\/"))) { : executable_path_(executablePath.substr(0, executablePath.find_last_of("\\/"))) {
} }
// Añade un elemento a la lista // Añade un elemento a la lista
void Asset::add(const std::string &file, enum AssetType type, bool required, bool absolute) { void Asset::add(const std::string &file, Type type, bool required, bool absolute) {
Item temp; Item temp;
temp.file = absolute ? file : executablePath + file; temp.file = absolute ? file : executable_path_ + file;
temp.type = type; temp.type = type;
temp.required = required; temp.required = required;
fileList.push_back(temp); file_list_.push_back(temp);
const std::string filename = file.substr(file.find_last_of("\\/") + 1); const std::string filename = file.substr(file.find_last_of("\\/") + 1);
longestName = SDL_max(longestName, filename.size()); longest_name_ = SDL_max(longest_name_, filename.size());
} }
// Devuelve el fichero de un elemento de la lista a partir de una cadena // Devuelve el fichero de un elemento de la lista a partir de una cadena
auto Asset::get(const std::string &text) -> std::string { auto Asset::get(const std::string &text) -> std::string {
for (const auto &f : fileList) { for (const auto &f : file_list_) {
const size_t lastIndex = f.file.find_last_of('/') + 1; const size_t lastIndex = f.file.find_last_of('/') + 1;
const std::string file = f.file.substr(lastIndex); const std::string file = f.file.substr(lastIndex);
@@ -52,7 +52,7 @@ auto Asset::get(const std::string &text) -> std::string {
} }
} }
if (verbose) { if (verbose_) {
std::cout << "Warning: file " << text.c_str() << " not found" << '\n'; std::cout << "Warning: file " << text.c_str() << " not found" << '\n';
} }
return ""; return "";
@@ -62,32 +62,34 @@ auto Asset::get(const std::string &text) -> std::string {
auto Asset::check() -> bool { auto Asset::check() -> bool {
bool success = true; bool success = true;
if (verbose) { if (verbose_) {
std::cout << "\n** Checking files" << '\n'; std::cout << "\n** Checking files" << '\n';
std::cout << "Executable path is: " << executablePath << '\n'; std::cout << "Executable path is: " << executable_path_ << '\n';
std::cout << "Sample filepath: " << fileList.back().file << '\n'; std::cout << "Sample filepath: " << file_list_.back().file << '\n';
} }
// Comprueba la lista de ficheros clasificandolos por tipo // Comprueba la lista de ficheros clasificandolos por tipo
for (int type = 0; type < t_maxAssetType; ++type) { for (int i = 0; i < static_cast<int>(Type::COUNT); ++i) {
const Type TYPE = static_cast<Type>(i);
// Comprueba si hay ficheros de ese tipo // Comprueba si hay ficheros de ese tipo
bool any = false; bool any = false;
for (const auto &f : fileList) { for (const auto &f : file_list_) {
if ((f.required) && (f.type == type)) { if (f.required && f.type == TYPE) {
any = true; any = true;
} }
} }
// Si hay ficheros de ese tipo, comprueba si existen // Si hay ficheros de ese tipo, comprueba si existen
if (any) { if (any) {
if (verbose) { if (verbose_) {
std::cout << "\n>> " << getTypeName(type).c_str() << " FILES" << '\n'; std::cout << "\n>> " << getTypeName(TYPE).c_str() << " FILES" << '\n';
} }
for (const auto &f : fileList) { for (const auto &f : file_list_) {
if ((f.required) && (f.type == type)) { if (f.required && f.type == TYPE) {
success &= checkFile(f.file); success &= checkFile(f.file);
} }
} }
@@ -95,7 +97,7 @@ auto Asset::check() -> bool {
} }
// Resultado // Resultado
if (verbose) { if (verbose_) {
if (success) { if (success) {
std::cout << "\n** All files OK.\n" std::cout << "\n** All files OK.\n"
<< '\n'; << '\n';
@@ -130,10 +132,10 @@ auto Asset::checkFile(const std::string &path) const -> bool {
} }
} }
if (verbose) { if (verbose_) {
std::cout.setf(std::ios::left, std::ios::adjustfield); std::cout.setf(std::ios::left, std::ios::adjustfield);
std::cout << "Checking file: "; std::cout << "Checking file: ";
std::cout.width(longestName + 2); std::cout.width(longest_name_ + 2);
std::cout.fill('.'); std::cout.fill('.');
std::cout << filename + " "; std::cout << filename + " ";
std::cout << " [" + result + "]" << '\n'; std::cout << " [" + result + "]" << '\n';
@@ -143,51 +145,23 @@ auto Asset::checkFile(const std::string &path) const -> bool {
} }
// Devuelve el nombre del tipo de recurso // Devuelve el nombre del tipo de recurso
auto Asset::getTypeName(int type) -> std::string { auto Asset::getTypeName(Type type) -> std::string {
switch (type) { switch (type) {
case t_bitmap: case Type::BITMAP: return "BITMAP";
return "BITMAP"; case Type::MUSIC: return "MUSIC";
break; case Type::SOUND: return "SOUND";
case Type::FONT: return "FONT";
case t_music: case Type::LANG: return "LANG";
return "MUSIC"; case Type::DATA: return "DATA";
break; case Type::ROOM: return "ROOM";
case Type::ENEMY: return "ENEMY";
case t_sound: case Type::ITEM: return "ITEM";
return "SOUND"; case Type::COUNT:
break; default: return "ERROR";
case t_font:
return "FONT";
break;
case t_lang:
return "LANG";
break;
case t_data:
return "DATA";
break;
case t_room:
return "ROOM";
break;
case t_enemy:
return "ENEMY";
break;
case t_item:
return "ITEM";
break;
default:
return "ERROR";
break;
} }
} }
// Establece si ha de mostrar texto por pantalla // Establece si ha de mostrar texto por pantalla
void Asset::setVerbose(bool value) { void Asset::setVerbose(bool value) {
verbose = value; verbose_ = value;
} }
+31 -45
View File
@@ -4,66 +4,52 @@
#include <string> // for string, basic_string #include <string> // for string, basic_string
#include <vector> // for vector #include <vector> // for vector
enum AssetType : std::uint8_t {
t_bitmap,
t_music,
t_sound,
t_font,
t_lang,
t_data,
t_room,
t_enemy,
t_item,
t_maxAssetType
};
// Clase Asset // Clase Asset
class Asset { class Asset {
public: public:
// Tipos de recurso
enum class Type : std::uint8_t {
BITMAP,
MUSIC,
SOUND,
FONT,
LANG,
DATA,
ROOM,
ENEMY,
ITEM,
COUNT // Centinela: número total de tipos
};
// Estructura para definir un item // Estructura para definir un item
struct Item { struct Item {
std::string file; // Ruta del fichero desde la raiz del directorio std::string file; // Ruta del fichero desde la raiz del directorio
enum AssetType type; // Indica el tipo de recurso Type type; // Indica el tipo de recurso
bool required; // Indica si es un fichero que debe de existir bool required; // Indica si es un fichero que debe de existir
}; };
private:
// Variables
int longestName{0}; // Contiene la longitud del nombre de fichero mas largo
std::vector<Item> fileList; // Listado con todas las rutas a los ficheros
std::string executablePath; // Ruta al ejecutable
bool verbose{true}; // Indica si ha de mostrar información por pantalla
// Comprueba que existe un fichero
[[nodiscard]] auto checkFile(const std::string &executablePath) const -> bool;
// Devuelve el nombre del tipo de recurso
static auto getTypeName(int type) -> std::string;
// Constructor privado (usar Asset::init)
explicit Asset(const std::string &path);
// Instancia única
static Asset *instance;
public:
// Singleton API // Singleton API
static void init(const std::string &executablePath); // Crea la instancia static void init(const std::string &executable_path); // Crea la instancia
static void destroy(); // Libera la instancia static void destroy(); // Libera la instancia
static auto get() -> Asset *; // Obtiene el puntero a la instancia static auto get() -> Asset *; // Obtiene el puntero a la instancia
// Añade un elemento a la lista void add(const std::string &file, Type type, bool required = true, bool absolute = false); // Añade un elemento a la lista
void add(const std::string &file, enum AssetType type, bool required = true, bool absolute = false); auto get(const std::string &text) -> std::string; // Devuelve un elemento de la lista a partir de una cadena
[[nodiscard]] auto getAll() const -> const std::vector<Item> & { return file_list_; } // Devuelve toda la lista de items registrados
auto check() -> bool; // Comprueba que existen todos los elementos
void setVerbose(bool value); // Establece si ha de mostrar texto por pantalla
// Devuelve un elemento de la lista a partir de una cadena private:
auto get(const std::string &text) -> std::string; // Variables
int longest_name_{0}; // Contiene la longitud del nombre de fichero mas largo
std::vector<Item> file_list_; // Listado con todas las rutas a los ficheros
std::string executable_path_; // Ruta al ejecutable
bool verbose_{true}; // Indica si ha de mostrar información por pantalla
// Devuelve toda la lista de items registrados static Asset *instance; // Instancia única
[[nodiscard]] auto getAll() const -> const std::vector<Item> & { return fileList; }
// Comprueba que existen todos los elementos explicit Asset(const std::string &path); // Constructor privado (usar Asset::init)
auto check() -> bool;
// Establece si ha de mostrar texto por pantalla [[nodiscard]] auto checkFile(const std::string &executable_path) const -> bool; // Comprueba que existe un fichero
void setVerbose(bool value); static auto getTypeName(Type type) -> std::string; // Devuelve el nombre del tipo de recurso
}; };
+76 -61
View File
@@ -1,7 +1,5 @@
#include "core/resources/resource.h" #include "core/resources/resource.h"
#include <algorithm>
#include <filesystem>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@@ -15,7 +13,7 @@
// Nota: Asset::get() e Input::get() se consultan en preloadAll y al construir // Nota: Asset::get() e Input::get() se consultan en preloadAll y al construir
// los menús; no se guardan punteros en el objeto Resource. // los menús; no se guardan punteros en el objeto Resource.
Resource *Resource::instance_ = nullptr; Resource *Resource::instance = nullptr;
static auto basename(const std::string &path) -> std::string { static auto basename(const std::string &path) -> std::string {
return path.substr(path.find_last_of("\\/") + 1); return path.substr(path.find_last_of("\\/") + 1);
@@ -31,19 +29,19 @@ static auto stem(const std::string &path) -> std::string {
} }
void Resource::init(SDL_Renderer *renderer) { void Resource::init(SDL_Renderer *renderer) {
if (instance_ == nullptr) { if (instance == nullptr) {
instance_ = new Resource(renderer); instance = new Resource(renderer);
instance_->preloadAll(); instance->preloadAll();
} }
} }
void Resource::destroy() { void Resource::destroy() {
delete instance_; delete instance;
instance_ = nullptr; instance = nullptr;
} }
auto Resource::get() -> Resource * { auto Resource::get() -> Resource * {
return instance_; return instance;
} }
Resource::Resource(SDL_Renderer *renderer) Resource::Resource(SDL_Renderer *renderer)
@@ -77,11 +75,17 @@ Resource::~Resource() {
} }
void Resource::preloadAll() { void Resource::preloadAll() {
preloadResources();
preloadFonts();
preloadMenus();
}
// Pass 1: texturas, sonidos, músicas y datos (animaciones / demo / menús)
void Resource::preloadResources() {
const auto &items = Asset::get()->getAll(); const auto &items = Asset::get()->getAll();
// Pass 1: texturas, sonidos, músicas, animaciones (raw lines), demo, lenguajes
for (const auto &it : items) { for (const auto &it : items) {
if (!ResourceHelper::shouldUseResourcePack(it.file) && it.type != t_lang) { if (!ResourceHelper::shouldUseResourcePack(it.file) && it.type != Asset::Type::LANG) {
// Ficheros absolutos (config.txt, score.bin, systemFolder) — no se precargan // Ficheros absolutos (config.txt, score.bin, systemFolder) — no se precargan
continue; continue;
} }
@@ -90,29 +94,42 @@ void Resource::preloadAll() {
continue; continue;
} }
const std::string bname = basename(it.file); const std::string BASE_NAME = basename(it.file);
switch (it.type) { switch (it.type) {
case t_bitmap: { case Asset::Type::BITMAP: {
auto *tex = new Texture(renderer_, bytes); auto *tex = new Texture(renderer_, bytes);
textures_[bname] = tex; textures_[BASE_NAME] = tex;
break; break;
} }
case t_sound: { case Asset::Type::SOUND: {
JA_Sound_t *s = JA_LoadSound(bytes.data(), (uint32_t)bytes.size()); JA_Sound_t *s = JA_LoadSound(bytes.data(), (uint32_t)bytes.size());
if (s != nullptr) { if (s != nullptr) {
sounds_[bname] = s; sounds_[BASE_NAME] = s;
} }
break; break;
} }
case t_music: { case Asset::Type::MUSIC: {
JA_Music_t *m = JA_LoadMusic(bytes.data(), (Uint32)bytes.size()); JA_Music_t *m = JA_LoadMusic(bytes.data(), (Uint32)bytes.size());
if (m != nullptr) { if (m != nullptr) {
musics_[bname] = m; musics_[BASE_NAME] = m;
} }
break; break;
} }
case t_data: { case Asset::Type::DATA:
loadDataAsset(BASE_NAME, bytes);
break;
case Asset::Type::FONT: // Fonts: se emparejan en pass 2
case Asset::Type::LANG: // Lenguaje: lo sigue leyendo la clase Lang via ResourceHelper
default:
break;
}
}
}
// Despacha un asset Asset::Type::DATA en función de la extensión / nombre
void Resource::loadDataAsset(const std::string &bname, const std::vector<uint8_t> &bytes) {
if (bname.size() >= 4 && bname.substr(bname.size() - 4) == ".ani") { if (bname.size() >= 4 && bname.substr(bname.size() - 4) == ".ani") {
std::string content(reinterpret_cast<const char *>(bytes.data()), bytes.size()); std::string content(reinterpret_cast<const char *>(bytes.data()), bytes.size());
std::stringstream ss(content); std::stringstream ss(content);
@@ -126,61 +143,59 @@ void Resource::preloadAll() {
} }
lines.push_back(line); lines.push_back(line);
} }
animationLines_[bname] = std::move(lines); animation_lines_[bname] = std::move(lines);
} else if (bname == "demo.bin") { } else if (bname == "demo.bin") {
demoBytes_ = bytes; demo_bytes_ = bytes;
} else if (bname.size() >= 4 && bname.substr(bname.size() - 4) == ".men") {
// Menús: se construyen en pass 2 porque dependen de textos y sonidos
}
break;
}
case t_font: // Fonts: se emparejan en pass 2
case t_lang: // Lenguaje: lo sigue leyendo la clase Lang via ResourceHelper
default:
break;
}
} }
// Menús (.men): se construyen en pass 2 porque dependen de textos y sonidos
}
// Pass 2: Text (fuentes emparejadas png+txt) y Menus (dependen de Text+sonidos) // Pass 2a: construye Text por cada par basename.png + basename.txt
// Fuentes: construimos un Text por cada par basename.png + basename.txt void Resource::preloadFonts() {
// Acumulamos los bytes encontrados por stem (basename sin ext.) const auto &items = Asset::get()->getAll();
std::unordered_map<std::string, std::vector<uint8_t>> fontPngs;
std::unordered_map<std::string, std::vector<uint8_t>> fontTxts; std::unordered_map<std::string, std::vector<uint8_t>> font_pngs;
std::unordered_map<std::string, std::vector<uint8_t>> font_txts;
for (const auto &it : items) { for (const auto &it : items) {
if (it.type != t_font) { if (it.type != Asset::Type::FONT) {
continue; continue;
} }
auto bytes = ResourceHelper::loadFile(it.file); auto bytes = ResourceHelper::loadFile(it.file);
if (bytes.empty()) { if (bytes.empty()) {
continue; continue;
} }
const std::string s = stem(it.file); const std::string S = stem(it.file);
const std::string bname = basename(it.file); const std::string BASE_NAME = basename(it.file);
if (bname.size() >= 4 && bname.substr(bname.size() - 4) == ".png") { if (BASE_NAME.size() >= 4 && BASE_NAME.substr(BASE_NAME.size() - 4) == ".png") {
fontPngs[s] = std::move(bytes); font_pngs[S] = std::move(bytes);
} else if (bname.size() >= 4 && bname.substr(bname.size() - 4) == ".txt") { } else if (BASE_NAME.size() >= 4 && BASE_NAME.substr(BASE_NAME.size() - 4) == ".txt") {
fontTxts[s] = std::move(bytes); font_txts[S] = std::move(bytes);
} }
} }
for (const auto &[s, png] : fontPngs) { for (const auto &[s, png] : font_pngs) {
auto itTxt = fontTxts.find(s); auto it_txt = font_txts.find(s);
if (itTxt == fontTxts.end()) { if (it_txt == font_txts.end()) {
continue; continue;
} }
Text *t = new Text(png, itTxt->second, renderer_); Text *t = new Text(png, it_txt->second, renderer_);
texts_[s] = t; texts_[s] = t;
} }
}
// Pass 2b: construye los Menu (dependen de Text+sonidos cargados antes)
//
// NOTA: Menu::loadFromBytes aún llama internamente a asset->get() y Text/
// JA_LoadSound por path. Funciona en modo fallback; en pack estricto requiere
// que Menu se adapte a cargar desde ResourceHelper. Migración pendiente.
void Resource::preloadMenus() {
const auto &items = Asset::get()->getAll();
// Menus: usan aún Menu::loadFromBytes que internamente llama a asset->get() y
// Text/JA_LoadSound por path. Funciona en modo fallback; en pack estricto
// requiere que Menu se adapte a cargar desde ResourceHelper. Por ahora
// lo dejamos así y será una migración del paso 7.
for (const auto &it : items) { for (const auto &it : items) {
if (it.type != t_data) { if (it.type != Asset::Type::DATA) {
continue; continue;
} }
const std::string bname = basename(it.file); const std::string BASE_NAME = basename(it.file);
if (bname.size() < 4 || bname.substr(bname.size() - 4) != ".men") { if (BASE_NAME.size() < 4 || BASE_NAME.substr(BASE_NAME.size() - 4) != ".men") {
continue; continue;
} }
auto bytes = ResourceHelper::loadFile(it.file); auto bytes = ResourceHelper::loadFile(it.file);
@@ -188,9 +203,9 @@ void Resource::preloadAll() {
continue; continue;
} }
Menu *m = new Menu(renderer_, ""); Menu *m = new Menu(renderer_, "");
m->loadFromBytes(bytes, bname); m->loadFromBytes(bytes, BASE_NAME);
const std::string s = stem(it.file); const std::string S = stem(it.file);
menus_[s] = m; menus_[S] = m;
} }
} }
@@ -222,11 +237,11 @@ auto Resource::getMusic(const std::string &name) -> JA_Music_t * {
} }
auto Resource::getAnimationLines(const std::string &name) -> std::vector<std::string> & { auto Resource::getAnimationLines(const std::string &name) -> std::vector<std::string> & {
auto it = animationLines_.find(name); auto it = animation_lines_.find(name);
if (it == animationLines_.end()) { if (it == animation_lines_.end()) {
static std::vector<std::string> empty; static std::vector<std::string> empty_;
std::cerr << "Resource::getAnimationLines: missing " << name << '\n'; std::cerr << "Resource::getAnimationLines: missing " << name << '\n';
return empty; return empty_;
} }
return it->second; return it->second;
} }
+10 -4
View File
@@ -27,7 +27,7 @@ class Resource {
auto getAnimationLines(const std::string &name) -> std::vector<std::string> &; auto getAnimationLines(const std::string &name) -> std::vector<std::string> &;
auto getText(const std::string &name) -> Text *; // name sin extensión: "smb2", "nokia2", ... auto getText(const std::string &name) -> Text *; // name sin extensión: "smb2", "nokia2", ...
auto getMenu(const std::string &name) -> Menu *; // name sin extensión: "title", "options", ... auto getMenu(const std::string &name) -> Menu *; // name sin extensión: "title", "options", ...
auto getDemoBytes() const -> const std::vector<uint8_t> & { return demoBytes_; } auto getDemoBytes() const -> const std::vector<uint8_t> & { return demo_bytes_; }
private: private:
explicit Resource(SDL_Renderer *renderer); explicit Resource(SDL_Renderer *renderer);
@@ -35,15 +35,21 @@ class Resource {
void preloadAll(); void preloadAll();
// Helpers de preloadAll
void preloadResources();
void loadDataAsset(const std::string &bname, const std::vector<uint8_t> &bytes);
void preloadFonts();
void preloadMenus();
SDL_Renderer *renderer_; SDL_Renderer *renderer_;
std::unordered_map<std::string, Texture *> textures_; std::unordered_map<std::string, Texture *> textures_;
std::unordered_map<std::string, JA_Sound_t *> sounds_; std::unordered_map<std::string, JA_Sound_t *> sounds_;
std::unordered_map<std::string, JA_Music_t *> musics_; std::unordered_map<std::string, JA_Music_t *> musics_;
std::unordered_map<std::string, std::vector<std::string>> animationLines_; std::unordered_map<std::string, std::vector<std::string>> animation_lines_;
std::unordered_map<std::string, Text *> texts_; std::unordered_map<std::string, Text *> texts_;
std::unordered_map<std::string, Menu *> menus_; std::unordered_map<std::string, Menu *> menus_;
std::vector<uint8_t> demoBytes_; std::vector<uint8_t> demo_bytes_;
static Resource *instance_; static Resource *instance;
}; };
+118 -120
View File
@@ -12,19 +12,17 @@
#include <cstdlib> // for exit, EXIT_FAILURE, srand #include <cstdlib> // for exit, EXIT_FAILURE, srand
#include <filesystem> #include <filesystem>
#include <fstream> // for basic_ostream, operator<<, basi...
#include <iostream> // for cout #include <iostream> // for cout
#include <memory> #include <memory>
#include <string> // for basic_string, operator+, char_t... #include <string> // for basic_string, operator+, char_t...
#include <vector> // for vector
#include "core/audio/audio.hpp" // for Audio::init, Audio::destroy #include "core/audio/audio.hpp" // for Audio::init, Audio::destroy
#include "core/input/input.h" // for Input, InputAction, INPUT_USE_GAME... #include "core/input/input.h" // for Input, InputAction, INPUT_USE_GAME...
#include "core/input/mouse.hpp" // for Mouse::handleEvent, Mouse::upda... #include "core/input/mouse.hpp" // for Mouse::handleEvent, Mouse::upda...
#include "core/locale/lang.h" // for Lang, MAX_LANGUAGES, ba_BA, en_UK #include "core/locale/lang.h" // for Lang, Lang::Code
#include "core/rendering/screen.h" // for Screen #include "core/rendering/screen.h" // for Screen
#include "core/rendering/texture.h" // for Texture #include "core/rendering/texture.h" // for Texture
#include "core/resources/asset.h" // for Asset, AssetType #include "core/resources/asset.h" // for Asset, Asset::Type
#include "core/resources/resource.h" #include "core/resources/resource.h"
#include "core/resources/resource_helper.h" #include "core/resources/resource_helper.h"
#include "game/defaults.hpp" // for SECTION_PROG_LOGO, GAMECANVAS_H... #include "game/defaults.hpp" // for SECTION_PROG_LOGO, GAMECANVAS_H...
@@ -86,18 +84,18 @@ Director::Director(int argc, const char *argv[]) {
// de emscripten ya empaqueta data/ — no hay resources.pack. // de emscripten ya empaqueta data/ — no hay resources.pack.
{ {
#if defined(__EMSCRIPTEN__) #if defined(__EMSCRIPTEN__)
const bool enable_fallback = true; const bool ENABLE_FALLBACK = true;
#elif defined(RELEASE_BUILD) #elif defined(RELEASE_BUILD)
const bool enable_fallback = false; const bool ENABLE_FALLBACK = false;
#else #else
const bool enable_fallback = true; const bool ENABLE_FALLBACK = true;
#endif #endif
#ifdef MACOS_BUNDLE #ifdef MACOS_BUNDLE
const std::string pack_path = executablePath + "../Resources/resources.pack"; const std::string PACK_PATH = executablePath + "../Resources/resources.pack";
#else #else
const std::string pack_path = executablePath + "resources.pack"; const std::string PACK_PATH = executablePath + "resources.pack";
#endif #endif
if (!ResourceHelper::initializeResourceSystem(pack_path, enable_fallback)) { if (!ResourceHelper::initializeResourceSystem(PACK_PATH, ENABLE_FALLBACK)) {
std::cerr << "Fatal: resource system init failed (missing resources.pack?)" << '\n'; std::cerr << "Fatal: resource system init failed (missing resources.pack?)" << '\n';
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@@ -129,11 +127,11 @@ Director::Director(int argc, const char *argv[]) {
Input::init("/gamecontrollerdb.txt"); Input::init("/gamecontrollerdb.txt");
#else #else
{ {
const std::string binDir = std::filesystem::path(executablePath).parent_path().string(); const std::string BIN_DIR = std::filesystem::path(executablePath).parent_path().string();
#ifdef MACOS_BUNDLE #ifdef MACOS_BUNDLE
Input::init(binDir + "/../Resources/gamecontrollerdb.txt"); Input::init(BIN_DIR + "/../Resources/gamecontrollerdb.txt");
#else #else
Input::init(binDir + "/gamecontrollerdb.txt"); Input::init(BIN_DIR + "/gamecontrollerdb.txt");
#endif #endif
} }
#endif #endif
@@ -324,127 +322,127 @@ auto Director::initSDL() -> bool {
// Crea el indice de ficheros // Crea el indice de ficheros
auto Director::setFileList() -> bool { auto Director::setFileList() -> bool {
#ifdef MACOS_BUNDLE #ifdef MACOS_BUNDLE
const std::string prefix = "/../Resources"; const std::string PREFIX = "/../Resources";
#else #else
const std::string prefix; const std::string PREFIX;
#endif #endif
// Ficheros de configuración // Ficheros de configuración
Asset::get()->add(systemFolder + "/score.bin", t_data, false, true); Asset::get()->add(systemFolder + "/score.bin", Asset::Type::DATA, false, true);
Asset::get()->add(prefix + "/data/demo/demo.bin", t_data); Asset::get()->add(PREFIX + "/data/demo/demo.bin", Asset::Type::DATA);
// Musicas // Musicas
Asset::get()->add(prefix + "/data/music/intro.ogg", t_music); Asset::get()->add(PREFIX + "/data/music/intro.ogg", Asset::Type::MUSIC);
Asset::get()->add(prefix + "/data/music/playing.ogg", t_music); Asset::get()->add(PREFIX + "/data/music/playing.ogg", Asset::Type::MUSIC);
Asset::get()->add(prefix + "/data/music/title.ogg", t_music); Asset::get()->add(PREFIX + "/data/music/title.ogg", Asset::Type::MUSIC);
// Sonidos // Sonidos
Asset::get()->add(prefix + "/data/sound/balloon.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/balloon.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/bubble1.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/bubble1.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/bubble2.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/bubble2.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/bubble3.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/bubble3.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/bubble4.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/bubble4.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/bullet.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/bullet.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/coffeeout.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/coffeeout.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/hiscore.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/hiscore.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/itemdrop.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/itemdrop.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/itempickup.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/itempickup.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/menu_move.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/menu_move.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/menu_select.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/menu_select.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/player_collision.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/player_collision.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/stage_change.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/stage_change.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/title.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/title.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/clock.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/clock.wav", Asset::Type::SOUND);
Asset::get()->add(prefix + "/data/sound/powerball.wav", t_sound); Asset::get()->add(PREFIX + "/data/sound/powerball.wav", Asset::Type::SOUND);
// Texturas // Texturas
Asset::get()->add(prefix + "/data/gfx/balloon1.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/balloon1.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon1.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/balloon1.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/balloon2.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/balloon2.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon2.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/balloon2.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/balloon3.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/balloon3.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon3.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/balloon3.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/balloon4.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/balloon4.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon4.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/balloon4.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/bullet.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/bullet.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_buildings.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/game_buildings.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_clouds.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/game_clouds.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_grass.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/game_grass.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_power_meter.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/game_power_meter.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_sky_colors.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/game_sky_colors.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/game_text.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/intro.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/intro.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/logo.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/logo.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/menu_game_over.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/menu_game_over.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/menu_game_over_end.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/menu_game_over_end.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item_points1_disk.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/item_points1_disk.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item_points1_disk.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/item_points1_disk.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/item_points2_gavina.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/item_points2_gavina.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item_points2_gavina.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/item_points2_gavina.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/item_points3_pacmar.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/item_points3_pacmar.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item_points3_pacmar.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/item_points3_pacmar.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/item_clock.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/item_clock.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item_clock.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/item_clock.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/item_coffee.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/item_coffee.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item_coffee.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/item_coffee.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/item_coffee_machine.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/item_coffee_machine.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item_coffee_machine.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/item_coffee_machine.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/title_bg_tile.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/title_bg_tile.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title_coffee.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/title_coffee.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title_crisis.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/title_crisis.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title_dust.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/title_dust.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title_dust.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/title_dust.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/title_gradient.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/title_gradient.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_head.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/player_head.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/player_body.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/player_body.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/player_legs.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/player_legs.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/player_death.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/player_death.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/player_fire.ani", t_data); Asset::get()->add(PREFIX + "/data/gfx/player_fire.ani", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/gfx/player_bal1_head.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_bal1_head.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_bal1_body.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_bal1_body.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_bal1_legs.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_bal1_legs.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_bal1_death.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_bal1_death.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_bal1_fire.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_bal1_fire.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_arounder_head.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_arounder_head.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_arounder_body.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_arounder_body.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_arounder_legs.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_arounder_legs.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_arounder_death.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_arounder_death.png", Asset::Type::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player_arounder_fire.png", t_bitmap); Asset::get()->add(PREFIX + "/data/gfx/player_arounder_fire.png", Asset::Type::BITMAP);
// Fuentes // Fuentes
Asset::get()->add(prefix + "/data/font/8bithud.png", t_font); Asset::get()->add(PREFIX + "/data/font/8bithud.png", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/8bithud.txt", t_font); Asset::get()->add(PREFIX + "/data/font/8bithud.txt", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/nokia.png", t_font); Asset::get()->add(PREFIX + "/data/font/nokia.png", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/nokia_big2.png", t_font); Asset::get()->add(PREFIX + "/data/font/nokia_big2.png", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/nokia.txt", t_font); Asset::get()->add(PREFIX + "/data/font/nokia.txt", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/nokia2.png", t_font); Asset::get()->add(PREFIX + "/data/font/nokia2.png", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/nokia2.txt", t_font); Asset::get()->add(PREFIX + "/data/font/nokia2.txt", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/nokia_big2.txt", t_font); Asset::get()->add(PREFIX + "/data/font/nokia_big2.txt", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/smb2_big.png", t_font); Asset::get()->add(PREFIX + "/data/font/smb2_big.png", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/smb2_big.txt", t_font); Asset::get()->add(PREFIX + "/data/font/smb2_big.txt", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/smb2.png", t_font); Asset::get()->add(PREFIX + "/data/font/smb2.png", Asset::Type::FONT);
Asset::get()->add(prefix + "/data/font/smb2.txt", t_font); Asset::get()->add(PREFIX + "/data/font/smb2.txt", Asset::Type::FONT);
// Textos // Textos
Asset::get()->add(prefix + "/data/lang/es_ES.txt", t_lang); Asset::get()->add(PREFIX + "/data/lang/es_ES.txt", Asset::Type::LANG);
Asset::get()->add(prefix + "/data/lang/en_UK.txt", t_lang); Asset::get()->add(PREFIX + "/data/lang/en_UK.txt", Asset::Type::LANG);
Asset::get()->add(prefix + "/data/lang/ba_BA.txt", t_lang); Asset::get()->add(PREFIX + "/data/lang/ba_BA.txt", Asset::Type::LANG);
// Menus // Menus
Asset::get()->add(prefix + "/data/menu/title.men", t_data); Asset::get()->add(PREFIX + "/data/menu/title.men", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/menu/title_gc.men", t_data); Asset::get()->add(PREFIX + "/data/menu/title_gc.men", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/menu/options.men", t_data); Asset::get()->add(PREFIX + "/data/menu/options.men", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/menu/options_gc.men", t_data); Asset::get()->add(PREFIX + "/data/menu/options_gc.men", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/menu/pause.men", t_data); Asset::get()->add(PREFIX + "/data/menu/pause.men", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/menu/gameover.men", t_data); Asset::get()->add(PREFIX + "/data/menu/gameover.men", Asset::Type::DATA);
Asset::get()->add(prefix + "/data/menu/player_select.men", t_data); Asset::get()->add(PREFIX + "/data/menu/player_select.men", Asset::Type::DATA);
return Asset::get()->check(); return Asset::get()->check();
} }
@@ -524,26 +522,26 @@ void Director::createSystemFolder(const std::string &folder) {
// Gestiona las transiciones entre secciones // Gestiona las transiciones entre secciones
void Director::handleSectionTransition() { void Director::handleSectionTransition() {
// Determina qué sección debería estar activa // Determina qué sección debería estar activa
ActiveSection targetSection = ActiveSection::None; ActiveSection target_section = ActiveSection::None;
switch (section->name) { switch (section->name) {
case SECTION_PROG_LOGO: case SECTION_PROG_LOGO:
targetSection = ActiveSection::Logo; target_section = ActiveSection::Logo;
break; break;
case SECTION_PROG_INTRO: case SECTION_PROG_INTRO:
targetSection = ActiveSection::Intro; target_section = ActiveSection::Intro;
break; break;
case SECTION_PROG_TITLE: case SECTION_PROG_TITLE:
targetSection = ActiveSection::Title; target_section = ActiveSection::Title;
break; break;
case SECTION_PROG_GAME: case SECTION_PROG_GAME:
targetSection = ActiveSection::Game; target_section = ActiveSection::Game;
break; break;
default: default:
break; break;
} }
// Si no ha cambiado, no hay nada que hacer // Si no ha cambiado, no hay nada que hacer
if (targetSection == activeSection) { if (target_section == activeSection) {
return; return;
} }
@@ -554,7 +552,7 @@ void Director::handleSectionTransition() {
game.reset(); game.reset();
// Crea la nueva sección // Crea la nueva sección
activeSection = targetSection; activeSection = target_section;
switch (activeSection) { switch (activeSection) {
case ActiveSection::Logo: case ActiveSection::Logo:
logo = std::make_unique<Logo>(renderer, section); logo = std::make_unique<Logo>(renderer, section);
@@ -566,8 +564,8 @@ void Director::handleSectionTransition() {
title = std::make_unique<Title>(renderer, section); title = std::make_unique<Title>(renderer, section);
break; break;
case ActiveSection::Game: { case ActiveSection::Game: {
const int numPlayers = section->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2; const int NUM_PLAYERS = section->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2;
game = std::make_unique<Game>(numPlayers, 0, renderer, false, section); game = std::make_unique<Game>(NUM_PLAYERS, 0, renderer, false, section);
break; break;
} }
case ActiveSection::None: case ActiveSection::None:
+1 -1
View File
@@ -51,7 +51,7 @@ namespace Defaults::Loading {
namespace Defaults::Settings { namespace Defaults::Settings {
constexpr int DIFFICULTY = DIFFICULTY_NORMAL; constexpr int DIFFICULTY = DIFFICULTY_NORMAL;
constexpr int LANGUAGE = ba_BA; constexpr Lang::Code LANGUAGE = Lang::Code::BA_BA;
} // namespace Defaults::Settings } // namespace Defaults::Settings
// Tamaño de bloque // Tamaño de bloque
+7 -5
View File
@@ -8,7 +8,7 @@
#include <string> #include <string>
#include "core/input/input.h" // for INPUT_USE_KEYBOARD, INPUT_USE_GAMECONTROLLER #include "core/input/input.h" // for INPUT_USE_KEYBOARD, INPUT_USE_GAMECONTROLLER
#include "core/locale/lang.h" // for MAX_LANGUAGES, en_UK #include "core/locale/lang.h" // for Lang::Code, Lang::MAX_LANGUAGES
#include "external/fkyaml_node.hpp" // for fkyaml::node #include "external/fkyaml_node.hpp" // for fkyaml::node
#include "utils/utils.h" // for boolToString #include "utils/utils.h" // for boolToString
@@ -148,10 +148,12 @@ namespace Options {
if (!yaml.contains("settings")) { return; } if (!yaml.contains("settings")) { return; }
const auto &st = yaml["settings"]; const auto &st = yaml["settings"];
parseIntField(st, "difficulty", settings.difficulty); parseIntField(st, "difficulty", settings.difficulty);
parseIntField(st, "language", settings.language); int language_int = static_cast<int>(settings.language);
if (settings.language < 0 || settings.language > MAX_LANGUAGES) { parseIntField(st, "language", language_int);
settings.language = en_UK; if (language_int < 0 || language_int >= Lang::MAX_LANGUAGES) {
language_int = static_cast<int>(Lang::Code::EN_UK);
} }
settings.language = static_cast<Lang::Code>(language_int);
parseIntField(st, "player_selected", settings.player_selected); parseIntField(st, "player_selected", settings.player_selected);
} }
@@ -318,7 +320,7 @@ namespace Options {
file << "# SETTINGS\n"; file << "# SETTINGS\n";
file << "settings:\n"; file << "settings:\n";
file << " difficulty: " << settings.difficulty << "\n"; file << " difficulty: " << settings.difficulty << "\n";
file << " language: " << settings.language << "\n"; file << " language: " << static_cast<int>(settings.language) << "\n";
file << " player_selected: " << settings.player_selected << "\n\n"; file << " player_selected: " << settings.player_selected << "\n\n";
// INPUT // INPUT
+1 -1
View File
@@ -81,7 +81,7 @@ namespace Options {
static constexpr int CURRENT_CONFIG_VERSION = 1; static constexpr int CURRENT_CONFIG_VERSION = 1;
int config_version = CURRENT_CONFIG_VERSION; int config_version = CURRENT_CONFIG_VERSION;
int difficulty = Defaults::Settings::DIFFICULTY; int difficulty = Defaults::Settings::DIFFICULTY;
int language = Defaults::Settings::LANGUAGE; Lang::Code language = Defaults::Settings::LANGUAGE;
bool console = false; bool console = false;
int player_selected = 0; int player_selected = 0;
std::string config_file; std::string config_file;
+1 -1
View File
@@ -41,7 +41,7 @@ Instructions::Instructions(SDL_Renderer *renderer, Section *section) {
// Crea un backbuffer para el renderizador // Crea un backbuffer para el renderizador
backbuffer_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); backbuffer_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (backbuffer_ != nullptr) { if (backbuffer_ != nullptr) {
SDL_SetTextureScaleMode(backbuffer_, Texture::currentScaleMode); SDL_SetTextureScaleMode(backbuffer_, Texture::current_scale_mode);
} else { } else {
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << '\n'; std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << '\n';
} }
+6 -9
View File
@@ -9,7 +9,7 @@
#include "core/audio/audio.hpp" // for Audio #include "core/audio/audio.hpp" // for Audio
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle #include "core/input/global_inputs.hpp" // for GlobalInputs::handle
#include "core/input/input.h" // for Input, INPUT_USE_GAMECONTROLLER, INPUT_... #include "core/input/input.h" // for Input, INPUT_USE_GAMECONTROLLER, INPUT_...
#include "core/locale/lang.h" // for Lang, ba_BA, en_UK, es_ES #include "core/locale/lang.h" // for Lang, Lang::Code
#include "core/rendering/animatedsprite.h" // for AnimatedSprite #include "core/rendering/animatedsprite.h" // for AnimatedSprite
#include "core/rendering/fade.h" // for Fade #include "core/rendering/fade.h" // for Fade
#include "core/rendering/screen.h" // for Screen #include "core/rendering/screen.h" // for Screen
@@ -450,10 +450,7 @@ void Title::handleOptionsMenuSelection() {
break; break;
case 5: // Language case 5: // Language
Options::settings.language++; Options::settings.language = Lang::nextLanguage(Options::settings.language);
if (Options::settings.language == 3) {
Options::settings.language = 0;
}
updateMenuLabels(); updateMenuLabels();
break; break;
@@ -729,15 +726,15 @@ void Title::updateMenuLabels() const {
i++; i++;
// LANGUAGE // LANGUAGE
switch (Options::settings.language) { switch (Options::settings.language) {
case es_ES: case Lang::Code::ES_ES:
menu_.options->setItemCaption(i, Lang::get()->getText(8) + ": " + Lang::get()->getText(24)); // SPANISH menu_.options->setItemCaption(i, Lang::get()->getText(8) + ": " + Lang::get()->getText(24)); // SPANISH
break; break;
case ba_BA: case Lang::Code::BA_BA:
menu_.options->setItemCaption(i, Lang::get()->getText(8) + ": " + Lang::get()->getText(25)); // VALENCIAN menu_.options->setItemCaption(i, Lang::get()->getText(8) + ": " + Lang::get()->getText(25)); // VALENCIAN
break; break;
case en_UK: case Lang::Code::EN_UK:
default: default:
// ENGLISH (i fallback per a llengües no reconegudes) // ENGLISH (i fallback per a llengües no reconegudes)
menu_.options->setItemCaption(i, Lang::get()->getText(8) + ": " + Lang::get()->getText(26)); menu_.options->setItemCaption(i, Lang::get()->getText(8) + ": " + Lang::get()->getText(26));
@@ -1010,7 +1007,7 @@ void Title::createTiledBackground() {
// Crea la textura para el mosaico de fondo // Crea la textura para el mosaico de fondo
background_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH * 2, GAMECANVAS_HEIGHT * 2); background_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH * 2, GAMECANVAS_HEIGHT * 2);
if (background_ != nullptr) { if (background_ != nullptr) {
SDL_SetTextureScaleMode(background_, Texture::currentScaleMode); SDL_SetTextureScaleMode(background_, Texture::current_scale_mode);
} }
if (background_ == nullptr) { if (background_ == nullptr) {
if (Options::settings.console) { if (Options::settings.console) {