treball en curs: correccions de tidy
This commit is contained in:
@@ -30,19 +30,19 @@ Lang::Lang() = default;
|
||||
Lang::~Lang() = default;
|
||||
|
||||
// Inicializa los textos del juego en el idioma seleccionado
|
||||
auto Lang::setLang(Uint8 lang) -> bool {
|
||||
auto Lang::setLang(Code lang) -> bool {
|
||||
std::string file;
|
||||
|
||||
switch (lang) {
|
||||
case es_ES:
|
||||
case Code::ES_ES:
|
||||
file = Asset::get()->get("es_ES.txt");
|
||||
break;
|
||||
|
||||
case en_UK:
|
||||
case Code::EN_UK:
|
||||
file = Asset::get()->get("en_UK.txt");
|
||||
break;
|
||||
|
||||
case ba_BA:
|
||||
case Code::BA_BA:
|
||||
file = Asset::get()->get("ba_BA.txt");
|
||||
break;
|
||||
|
||||
@@ -51,7 +51,7 @@ auto Lang::setLang(Uint8 lang) -> bool {
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto &mTextString : mTextStrings) {
|
||||
for (auto &mTextString : text_strings_) {
|
||||
mTextString = "";
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ auto Lang::setLang(Uint8 lang) -> bool {
|
||||
if (index >= MAX_TEXT_STRINGS) {
|
||||
break;
|
||||
}
|
||||
mTextStrings[index] = line;
|
||||
text_strings_[index] = line;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
@@ -90,5 +90,11 @@ auto Lang::setLang(Uint8 lang) -> bool {
|
||||
|
||||
// Obtiene la cadena de texto del indice
|
||||
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);
|
||||
}
|
||||
+40
-41
@@ -1,41 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#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
|
||||
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:
|
||||
// Singleton API
|
||||
static void init(); // Crea la instancia
|
||||
static void destroy(); // Libera la instancia
|
||||
static auto get() -> Lang *; // Obtiene el puntero a la instancia
|
||||
|
||||
// Destructor
|
||||
~Lang();
|
||||
|
||||
// Inicializa los textos del juego en el idioma seleccionado
|
||||
auto setLang(Uint8 lang) -> bool;
|
||||
|
||||
// Obtiene la cadena de texto del indice
|
||||
auto getText(int index) -> std::string;
|
||||
};
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <string> // for string, basic_string
|
||||
|
||||
// Clase Lang
|
||||
class Lang {
|
||||
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
|
||||
static void init(); // Crea la instancia
|
||||
static void destroy(); // Libera la instancia
|
||||
static auto get() -> Lang *; // Obtiene el puntero a la instancia
|
||||
|
||||
~Lang(); // Destructor
|
||||
|
||||
auto setLang(Code lang) -> bool; // Inicializa los textos del juego en el idioma seleccionado
|
||||
auto getText(int index) -> std::string; // Obtiene la cadena de texto del indice
|
||||
|
||||
static auto nextLanguage(Code c) -> Code; // Devuelve el siguiente idioma del ciclo
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ static auto parseAnimationStream(std::istream &file, Texture *texture, const std
|
||||
buffer.speed = 0;
|
||||
buffer.loop = -1;
|
||||
buffer.counter = 0;
|
||||
buffer.currentFrame = 0;
|
||||
buffer.current_frame = 0;
|
||||
buffer.completed = false;
|
||||
|
||||
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)
|
||||
auto loadAnimationFromFile(Texture *texture, const std::string &filePath, bool verbose) -> AnimatedSpriteData {
|
||||
const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1);
|
||||
auto bytes = ResourceHelper::loadFile(filePath);
|
||||
auto loadAnimationFromFile(Texture *texture, const std::string &file_path, bool verbose) -> AnimatedSpriteData {
|
||||
const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1);
|
||||
auto bytes = ResourceHelper::loadFile(file_path);
|
||||
if (bytes.empty()) {
|
||||
if (verbose) {
|
||||
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
|
||||
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()) {
|
||||
AnimatedSpriteData as;
|
||||
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::stringstream ss(content);
|
||||
return parseAnimationStream(ss, texture, nameForLogs, verbose);
|
||||
return parseAnimationStream(ss, texture, name_for_logs, verbose);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, const std::string &file, std::vector<std::string> *buffer)
|
||||
: currentAnimation(0) {
|
||||
: current_animation_(0) {
|
||||
// Copia los punteros
|
||||
setTexture(texture);
|
||||
setRenderer(renderer);
|
||||
@@ -136,7 +136,7 @@ AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, const s
|
||||
AnimatedSpriteData as = loadAnimationFromFile(texture, file);
|
||||
|
||||
// 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) {
|
||||
@@ -145,29 +145,29 @@ AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, const s
|
||||
}
|
||||
|
||||
// Constructor
|
||||
AnimatedSprite::AnimatedSprite(SDL_Renderer *renderer, AnimatedSpriteData *animation)
|
||||
: currentAnimation(0) {
|
||||
AnimatedSprite::AnimatedSprite(SDL_Renderer *renderer, AnimatedSpriteData *data)
|
||||
: current_animation_(0) {
|
||||
// Copia los punteros
|
||||
setTexture(animation->texture);
|
||||
setTexture(data->texture);
|
||||
setRenderer(renderer);
|
||||
|
||||
// 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
|
||||
AnimatedSprite::~AnimatedSprite() {
|
||||
for (auto &a : animation) {
|
||||
for (auto &a : animation_) {
|
||||
a.frames.clear();
|
||||
}
|
||||
animation.clear();
|
||||
animation_.clear();
|
||||
}
|
||||
|
||||
// Obtiene el indice de la animación a partir del nombre
|
||||
auto AnimatedSprite::getIndex(const std::string &name) -> int {
|
||||
int index = -1;
|
||||
|
||||
for (const auto &a : animation) {
|
||||
for (const auto &a : animation_) {
|
||||
index++;
|
||||
if (a.name == name) {
|
||||
return index;
|
||||
@@ -181,102 +181,102 @@ auto AnimatedSprite::getIndex(const std::string &name) -> int {
|
||||
|
||||
// Calcula el frame correspondiente a la animación
|
||||
void AnimatedSprite::animate() {
|
||||
if (!enabled || animation[currentAnimation].speed == 0) {
|
||||
if (!enabled_ || animation_[current_animation_].speed == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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
|
||||
// en función de la variable loop y coloca el nuevo frame
|
||||
if (animation[currentAnimation].currentFrame >= (int)animation[currentAnimation].frames.size()) {
|
||||
if (animation[currentAnimation].loop == -1) { // Si no hay loop, deja el último frame
|
||||
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size();
|
||||
animation[currentAnimation].completed = true;
|
||||
if (animation_[current_animation_].current_frame >= (int)animation_[current_animation_].frames.size()) {
|
||||
if (animation_[current_animation_].loop == -1) { // Si no hay loop, deja el último frame
|
||||
animation_[current_animation_].current_frame = animation_[current_animation_].frames.size();
|
||||
animation_[current_animation_].completed = true;
|
||||
} else { // Si hay loop, vuelve al frame indicado
|
||||
animation[currentAnimation].counter = 0;
|
||||
animation[currentAnimation].currentFrame = animation[currentAnimation].loop;
|
||||
animation_[current_animation_].counter = 0;
|
||||
animation_[current_animation_].current_frame = animation_[current_animation_].loop;
|
||||
}
|
||||
}
|
||||
// En caso contrario
|
||||
else {
|
||||
// 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
|
||||
animation[currentAnimation].counter++;
|
||||
animation_[current_animation_].counter++;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtiene el numero de frames de la animación actual
|
||||
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
|
||||
void AnimatedSprite::setCurrentFrame(int num) {
|
||||
// Descarta valores fuera de rango
|
||||
if (num >= (int)animation[currentAnimation].frames.size()) {
|
||||
if (num >= (int)animation_[current_animation_].frames.size()) {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
// Cambia el valor de la variable
|
||||
animation[currentAnimation].currentFrame = num;
|
||||
animation[currentAnimation].counter = 0;
|
||||
animation_[current_animation_].current_frame = num;
|
||||
animation_[current_animation_].counter = 0;
|
||||
|
||||
// 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
|
||||
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
|
||||
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
|
||||
void AnimatedSprite::setAnimationSpeed(int index, int speed) {
|
||||
animation[index].counter = speed;
|
||||
animation_[index].counter = speed;
|
||||
}
|
||||
|
||||
// Establece si la animación se reproduce en bucle
|
||||
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
|
||||
void AnimatedSprite::setAnimationLoop(int index, int loop) {
|
||||
animation[index].loop = loop;
|
||||
animation_[index].loop = loop;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
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
|
||||
void AnimatedSprite::setAnimationCompleted(int index, bool value) {
|
||||
animation[index].completed = value;
|
||||
animation_[index].completed = value;
|
||||
}
|
||||
|
||||
// Comprueba si ha terminado la animación
|
||||
auto AnimatedSprite::animationIsCompleted() -> bool {
|
||||
return animation[currentAnimation].completed;
|
||||
return animation_[current_animation_].completed;
|
||||
}
|
||||
|
||||
// Devuelve el rectangulo de una animación y frame concreto
|
||||
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
|
||||
auto AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF) -> SDL_Rect {
|
||||
return animation[indexA].frames[indexF];
|
||||
auto AnimatedSprite::getAnimationClip(int index_a, Uint8 index_f) -> SDL_Rect {
|
||||
return animation_[index_a].frames[index_f];
|
||||
}
|
||||
|
||||
// Carga la animación desde un vector
|
||||
@@ -297,13 +297,13 @@ auto AnimatedSprite::loadFromVector(std::vector<std::string> *source) -> bool {
|
||||
// Lee desde el vector
|
||||
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]") {
|
||||
Animation buffer;
|
||||
buffer.speed = 0;
|
||||
buffer.loop = -1;
|
||||
buffer.counter = 0;
|
||||
buffer.currentFrame = 0;
|
||||
buffer.current_frame = 0;
|
||||
buffer.completed = false;
|
||||
|
||||
do {
|
||||
@@ -350,7 +350,7 @@ auto AnimatedSprite::loadFromVector(std::vector<std::string> *source) -> bool {
|
||||
} while (line != "[/animation]");
|
||||
|
||||
// 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
|
||||
@@ -379,12 +379,12 @@ auto AnimatedSprite::loadFromVector(std::vector<std::string> *source) -> bool {
|
||||
|
||||
// Normaliza valores
|
||||
if (framesPerRow == 0 && frameWidth > 0) {
|
||||
framesPerRow = texture->getWidth() / frameWidth;
|
||||
framesPerRow = texture_->getWidth() / frameWidth;
|
||||
}
|
||||
|
||||
if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0) {
|
||||
const int w = texture->getWidth() / frameWidth;
|
||||
const int h = texture->getHeight() / frameHeight;
|
||||
const int w = texture_->getWidth() / frameWidth;
|
||||
const int h = texture_->getHeight() / frameHeight;
|
||||
maxTiles = w * h;
|
||||
}
|
||||
}
|
||||
@@ -403,22 +403,22 @@ auto AnimatedSprite::loadFromVector(std::vector<std::string> *source) -> bool {
|
||||
// Establece la animacion actual
|
||||
void AnimatedSprite::setCurrentAnimation(const std::string &name) {
|
||||
const int newAnimation = getIndex(name);
|
||||
if (currentAnimation != newAnimation) {
|
||||
currentAnimation = newAnimation;
|
||||
animation[currentAnimation].currentFrame = 0;
|
||||
animation[currentAnimation].counter = 0;
|
||||
animation[currentAnimation].completed = false;
|
||||
if (current_animation_ != newAnimation) {
|
||||
current_animation_ = newAnimation;
|
||||
animation_[current_animation_].current_frame = 0;
|
||||
animation_[current_animation_].counter = 0;
|
||||
animation_[current_animation_].completed = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Establece la animacion actual
|
||||
void AnimatedSprite::setCurrentAnimation(int index) {
|
||||
const int newAnimation = index;
|
||||
if (currentAnimation != newAnimation) {
|
||||
currentAnimation = newAnimation;
|
||||
animation[currentAnimation].currentFrame = 0;
|
||||
animation[currentAnimation].counter = 0;
|
||||
animation[currentAnimation].completed = false;
|
||||
if (current_animation_ != newAnimation) {
|
||||
current_animation_ = newAnimation;
|
||||
animation_[current_animation_].current_frame = 0;
|
||||
animation_[current_animation_].counter = 0;
|
||||
animation_[current_animation_].completed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,19 +430,19 @@ void AnimatedSprite::update() {
|
||||
|
||||
// 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) {
|
||||
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
|
||||
void AnimatedSprite::setAnimationCounter(int value) {
|
||||
for (auto &a : animation) {
|
||||
for (auto &a : animation_) {
|
||||
a.counter = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Reinicia la animación
|
||||
void AnimatedSprite::resetAnimation() {
|
||||
animation[currentAnimation].currentFrame = 0;
|
||||
animation[currentAnimation].counter = 0;
|
||||
animation[currentAnimation].completed = false;
|
||||
animation_[current_animation_].current_frame = 0;
|
||||
animation_[current_animation_].counter = 0;
|
||||
animation_[current_animation_].completed = false;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ struct Animation {
|
||||
int speed; // Velocidad de la animación
|
||||
int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
|
||||
bool completed; // Indica si ha finalizado la animación
|
||||
int currentFrame; // Frame actual
|
||||
int current_frame; // Frame actual
|
||||
int counter; // Contador para las animaciones
|
||||
};
|
||||
|
||||
@@ -25,75 +25,52 @@ struct AnimatedSpriteData {
|
||||
};
|
||||
|
||||
// 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
|
||||
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 {
|
||||
private:
|
||||
// Variables
|
||||
std::vector<Animation> animation; // Vector con las diferentes animaciones
|
||||
int currentAnimation; // Animacion activa
|
||||
|
||||
public:
|
||||
// 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 *animation);
|
||||
explicit AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, const std::string &file = "", std::vector<std::string> *buffer = nullptr); // Constructor
|
||||
AnimatedSprite(SDL_Renderer *renderer, AnimatedSpriteData *data);
|
||||
|
||||
// Destructor
|
||||
~AnimatedSprite() override;
|
||||
~AnimatedSprite() override; // Destructor
|
||||
|
||||
// Calcula el frame correspondiente a la animación actual
|
||||
void animate();
|
||||
void animate(); // Calcula el frame correspondiente a la animación actual
|
||||
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
|
||||
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(const std::string &name, int speed); // Establece la velocidad de una animación
|
||||
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);
|
||||
void setAnimationLoop(const std::string &name, int loop); // Establece el frame al que vuelve la animación al finalizar
|
||||
void setAnimationLoop(int index, int loop);
|
||||
|
||||
// Establece el valor de la variable
|
||||
void setAnimationCompleted(const std::string &name, bool value);
|
||||
void setAnimationCompleted(const std::string &name, bool value); // Establece el valor de la variable
|
||||
void setAnimationCompleted(int index, bool value);
|
||||
|
||||
// Comprueba si ha terminado la animación
|
||||
auto animationIsCompleted() -> bool;
|
||||
auto animationIsCompleted() -> bool; // Comprueba si ha terminado la animación
|
||||
|
||||
// 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 indexA = 0, Uint8 indexF = 0) -> SDL_Rect;
|
||||
auto getAnimationClip(const std::string &name = "default", Uint8 index = 0) -> SDL_Rect; // Devuelve el rectangulo de una animación y frame concreto
|
||||
auto getAnimationClip(int index_a = 0, Uint8 index_f = 0) -> SDL_Rect;
|
||||
|
||||
// Obtiene el indice de la animación a partir del nombre
|
||||
auto getIndex(const std::string &name) -> int;
|
||||
auto getIndex(const std::string &name) -> int; // Obtiene el indice de la animación a partir del nombre
|
||||
auto loadFromVector(std::vector<std::string> *source) -> bool; // Carga la animación desde un vector
|
||||
|
||||
// Carga la animación desde un vector
|
||||
auto loadFromVector(std::vector<std::string> *source) -> bool;
|
||||
|
||||
// Establece la animacion actual
|
||||
void setCurrentAnimation(const std::string &name = "default");
|
||||
void setCurrentAnimation(const std::string &name = "default"); // Establece la animacion actual
|
||||
void setCurrentAnimation(int index = 0);
|
||||
|
||||
// Actualiza las variables del objeto
|
||||
void update() override;
|
||||
void update() override; // Actualiza las variables del objeto
|
||||
|
||||
// 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 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 setAnimationCounter(int value); // OLD - Establece el contador para todas las animaciones
|
||||
|
||||
// OLD - Establece el contador para todas las animaciones
|
||||
void setAnimationCounter(int value);
|
||||
void resetAnimation(); // Reinicia la animación
|
||||
|
||||
// Reinicia la animación
|
||||
void resetAnimation();
|
||||
private:
|
||||
// Variables
|
||||
std::vector<Animation> animation_; // Vector con las diferentes animaciones
|
||||
int current_animation_; // Animacion activa
|
||||
};
|
||||
|
||||
@@ -9,70 +9,70 @@
|
||||
|
||||
// Constructor
|
||||
Fade::Fade(SDL_Renderer *renderer)
|
||||
: mRenderer(renderer) {
|
||||
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
|
||||
if (mBackbuffer != nullptr) {
|
||||
SDL_SetTextureScaleMode(mBackbuffer, SDL_SCALEMODE_NEAREST);
|
||||
: renderer_(renderer) {
|
||||
backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
|
||||
if (backbuffer_ != nullptr) {
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Fade::~Fade() {
|
||||
SDL_DestroyTexture(mBackbuffer);
|
||||
mBackbuffer = nullptr;
|
||||
SDL_DestroyTexture(backbuffer_);
|
||||
backbuffer_ = nullptr;
|
||||
}
|
||||
|
||||
// Inicializa las variables
|
||||
void Fade::init(Uint8 r, Uint8 g, Uint8 b) {
|
||||
mFadeType = FADE_CENTER;
|
||||
mEnabled = false;
|
||||
mFinished = false;
|
||||
mCounter = 0;
|
||||
mR = r;
|
||||
mG = g;
|
||||
mB = b;
|
||||
mROriginal = r;
|
||||
mGOriginal = g;
|
||||
mBOriginal = b;
|
||||
mLastSquareTicks = 0;
|
||||
mSquaresDrawn = 0;
|
||||
mFullscreenDone = false;
|
||||
fade_type_ = FADE_CENTER;
|
||||
enabled_ = false;
|
||||
finished_ = false;
|
||||
counter_ = 0;
|
||||
r_ = r;
|
||||
g_ = g;
|
||||
b_ = b;
|
||||
r_original_ = r;
|
||||
g_original_ = g;
|
||||
b_original_ = b;
|
||||
last_square_ticks_ = 0;
|
||||
squares_drawn_ = 0;
|
||||
fullscreen_done_ = false;
|
||||
}
|
||||
|
||||
// Pinta una transición en pantalla
|
||||
void Fade::render() {
|
||||
if (mEnabled && !mFinished) {
|
||||
switch (mFadeType) {
|
||||
if (enabled_ && !finished_) {
|
||||
switch (fade_type_) {
|
||||
case FADE_FULLSCREEN: {
|
||||
if (!mFullscreenDone) {
|
||||
if (!fullscreen_done_) {
|
||||
SDL_FRect fRect1 = {0, 0, (float)GAMECANVAS_WIDTH, (float)GAMECANVAS_HEIGHT};
|
||||
|
||||
int alpha = mCounter * 4;
|
||||
int alpha = counter_ * 4;
|
||||
if (alpha >= 255) {
|
||||
mFullscreenDone = true;
|
||||
fullscreen_done_ = true;
|
||||
|
||||
// Deja todos los buffers del mismo color
|
||||
SDL_SetRenderTarget(mRenderer, mBackbuffer);
|
||||
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
|
||||
SDL_RenderClear(mRenderer);
|
||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, 255);
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
SDL_SetRenderTarget(mRenderer, nullptr);
|
||||
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
|
||||
SDL_RenderClear(mRenderer);
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, 255);
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
mFinished = true;
|
||||
finished_ = true;
|
||||
} else {
|
||||
// Dibujamos sobre el renderizador
|
||||
SDL_SetRenderTarget(mRenderer, nullptr);
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
|
||||
// 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_RenderFillRect(mRenderer, &fRect1);
|
||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, alpha);
|
||||
SDL_RenderFillRect(renderer_, &fRect1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -82,26 +82,26 @@ void Fade::render() {
|
||||
SDL_FRect fR1 = {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);
|
||||
fR2.y = (float)(GAMECANVAS_HEIGHT - (i * 4));
|
||||
|
||||
SDL_RenderFillRect(mRenderer, &fR1);
|
||||
SDL_RenderFillRect(mRenderer, &fR2);
|
||||
SDL_RenderFillRect(renderer_, &fR1);
|
||||
SDL_RenderFillRect(renderer_, &fR2);
|
||||
}
|
||||
|
||||
if ((mCounter * 4) > GAMECANVAS_HEIGHT) {
|
||||
mFinished = true;
|
||||
if ((counter_ * 4) > GAMECANVAS_HEIGHT) {
|
||||
finished_ = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FADE_RANDOM_SQUARE: {
|
||||
Uint32 now = SDL_GetTicks();
|
||||
if (mSquaresDrawn < 50 && now - mLastSquareTicks >= 100) {
|
||||
mLastSquareTicks = now;
|
||||
if (squares_drawn_ < 50 && now - last_square_ticks_ >= 100) {
|
||||
last_square_ticks_ = now;
|
||||
|
||||
SDL_FRect fRs = {0, 0, 32, 32};
|
||||
|
||||
@@ -109,26 +109,26 @@ void Fade::render() {
|
||||
Uint8 r = 255 * (rand() % 2);
|
||||
Uint8 g = 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
|
||||
SDL_SetRenderTarget(mRenderer, mBackbuffer);
|
||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||
|
||||
fRs.x = (float)(rand() % (GAMECANVAS_WIDTH - 32));
|
||||
fRs.y = (float)(rand() % (GAMECANVAS_HEIGHT - 32));
|
||||
SDL_RenderFillRect(mRenderer, &fRs);
|
||||
SDL_RenderFillRect(renderer_, &fRs);
|
||||
|
||||
// Volvemos a usar el renderizador de forma normal
|
||||
SDL_SetRenderTarget(mRenderer, nullptr);
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
|
||||
mSquaresDrawn++;
|
||||
squares_drawn_++;
|
||||
}
|
||||
|
||||
// Copiamos el backbuffer al renderizador
|
||||
SDL_RenderTexture(mRenderer, mBackbuffer, nullptr, nullptr);
|
||||
SDL_RenderTexture(renderer_, backbuffer_, nullptr, nullptr);
|
||||
|
||||
if (mSquaresDrawn >= 50) {
|
||||
mFinished = true;
|
||||
if (squares_drawn_ >= 50) {
|
||||
finished_ = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -138,43 +138,43 @@ void Fade::render() {
|
||||
}
|
||||
}
|
||||
|
||||
if (mFinished) {
|
||||
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
|
||||
SDL_RenderClear(mRenderer);
|
||||
if (finished_) {
|
||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, 255);
|
||||
SDL_RenderClear(renderer_);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza las variables internas
|
||||
void Fade::update() {
|
||||
if (mEnabled) {
|
||||
mCounter++;
|
||||
if (enabled_) {
|
||||
counter_++;
|
||||
}
|
||||
}
|
||||
|
||||
// Activa el fade
|
||||
void Fade::activateFade() {
|
||||
mEnabled = true;
|
||||
mFinished = false;
|
||||
mCounter = 0;
|
||||
mSquaresDrawn = 0;
|
||||
mLastSquareTicks = 0;
|
||||
mFullscreenDone = false;
|
||||
mR = mROriginal;
|
||||
mG = mGOriginal;
|
||||
mB = mBOriginal;
|
||||
enabled_ = true;
|
||||
finished_ = false;
|
||||
counter_ = 0;
|
||||
squares_drawn_ = 0;
|
||||
last_square_ticks_ = 0;
|
||||
fullscreen_done_ = false;
|
||||
r_ = r_original_;
|
||||
g_ = g_original_;
|
||||
b_ = b_original_;
|
||||
}
|
||||
|
||||
// Comprueba si está activo
|
||||
auto Fade::isEnabled() const -> bool {
|
||||
return mEnabled;
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
// Comprueba si ha terminado la transicion
|
||||
auto Fade::hasEnded() const -> bool {
|
||||
return mFinished;
|
||||
return finished_;
|
||||
}
|
||||
|
||||
// Establece el tipo de fade
|
||||
void Fade::setFadeType(Uint8 fadeType) {
|
||||
mFadeType = fadeType;
|
||||
void Fade::setFadeType(Uint8 fade_type) {
|
||||
fade_type_ = fade_type;
|
||||
}
|
||||
@@ -9,46 +9,32 @@ constexpr int FADE_RANDOM_SQUARE = 2;
|
||||
|
||||
// Clase 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:
|
||||
// Constructor
|
||||
explicit Fade(SDL_Renderer *renderer);
|
||||
explicit Fade(SDL_Renderer *renderer); // Constructor
|
||||
~Fade(); // Destructor
|
||||
|
||||
// Destructor
|
||||
~Fade();
|
||||
void init(Uint8 r, Uint8 g, Uint8 b); // Inicializa las variables
|
||||
void render(); // Pinta una transición en pantalla
|
||||
void update(); // Actualiza las variables internas
|
||||
void activateFade(); // Activa el fade
|
||||
|
||||
// Inicializa las variables
|
||||
void init(Uint8 r, Uint8 g, Uint8 b);
|
||||
[[nodiscard]] auto hasEnded() const -> bool; // Comprueba si ha terminado la transicion
|
||||
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activo
|
||||
|
||||
// Pinta una transición en pantalla
|
||||
void render();
|
||||
void setFadeType(Uint8 fade_type); // Establece el tipo de fade
|
||||
|
||||
// Actualiza las variables internas
|
||||
void update();
|
||||
|
||||
// Activa el fade
|
||||
void activateFade();
|
||||
|
||||
// Comprueba si ha terminado la transicion
|
||||
[[nodiscard]] auto hasEnded() const -> bool;
|
||||
|
||||
// Comprueba si está activo
|
||||
[[nodiscard]] auto isEnabled() const -> bool;
|
||||
|
||||
// Establece el tipo de fade
|
||||
void setFadeType(Uint8 fadeType);
|
||||
};
|
||||
private:
|
||||
SDL_Renderer *renderer_ = nullptr; // El renderizador de la ventana
|
||||
SDL_Texture *backbuffer_ = nullptr; // Textura para usar como backbuffer
|
||||
Uint8 fade_type_ = FADE_FULLSCREEN; // Tipo de fade a realizar
|
||||
Uint16 counter_ = 0; // Contador interno
|
||||
bool enabled_ = false; // Indica si el fade está activo
|
||||
bool finished_ = false; // Indica si ha terminado la transición
|
||||
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
|
||||
Uint32 last_square_ticks_ = 0; // Ticks del último cuadrado dibujado (FADE_RANDOM_SQUARE)
|
||||
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
|
||||
SDL_Rect rect1_{}; // Rectangulo usado para crear los efectos de transición
|
||||
SDL_Rect rect2_{}; // Rectangulo usado para crear los efectos de transición
|
||||
};
|
||||
|
||||
@@ -5,187 +5,187 @@
|
||||
// Constructor
|
||||
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),
|
||||
x(x),
|
||||
y(y),
|
||||
xPrev(x),
|
||||
yPrev(y),
|
||||
vx(velx),
|
||||
vy(vely),
|
||||
ax(accelx),
|
||||
ay(accely) {
|
||||
x_(x),
|
||||
y_(y),
|
||||
x_prev_(x),
|
||||
y_prev_(y),
|
||||
vx_(velx),
|
||||
vy_(vely),
|
||||
ax_(accelx),
|
||||
ay_(accely) {
|
||||
}
|
||||
|
||||
// Reinicia todas las variables
|
||||
void MovingSprite::clear() {
|
||||
x = 0.0F; // Posición en el eje X
|
||||
y = 0.0F; // Posición en el eje Y
|
||||
x_ = 0.0F;
|
||||
y_ = 0.0F;
|
||||
|
||||
vx = 0.0F; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
|
||||
vy = 0.0F; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
|
||||
vx_ = 0.0F;
|
||||
vy_ = 0.0F;
|
||||
|
||||
ax = 0.0F; // Aceleración en el eje X. Variación de la velocidad
|
||||
ay = 0.0F; // Aceleración en el eje Y. Variación de la velocidad
|
||||
ax_ = 0.0F;
|
||||
ay_ = 0.0F;
|
||||
|
||||
zoomW = 1.0F; // Zoom aplicado a la anchura
|
||||
zoomH = 1.0F; // Zoom aplicado a la altura
|
||||
zoom_w_ = 1.0F;
|
||||
zoom_h_ = 1.0F;
|
||||
|
||||
angle = 0.0; // Angulo para dibujarlo
|
||||
rotateEnabled = false; // Indica si ha de rotar
|
||||
center = nullptr; // Centro de rotación
|
||||
rotateSpeed = 0; // Velocidad de giro
|
||||
rotateAmount = 0.0; // Cantidad de grados a girar en cada iteración
|
||||
counter = 0; // Contador interno
|
||||
angle_ = 0.0;
|
||||
rotate_enabled_ = false;
|
||||
center_ = nullptr;
|
||||
rotate_speed_ = 0;
|
||||
rotate_amount_ = 0.0;
|
||||
counter_ = 0;
|
||||
|
||||
currentFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
|
||||
current_flip_ = SDL_FLIP_NONE;
|
||||
}
|
||||
|
||||
// Mueve el sprite
|
||||
void MovingSprite::move() {
|
||||
if (enabled) {
|
||||
xPrev = x;
|
||||
yPrev = y;
|
||||
if (enabled_) {
|
||||
x_prev_ = x_;
|
||||
y_prev_ = y_;
|
||||
|
||||
x += vx;
|
||||
y += vy;
|
||||
x_ += vx_;
|
||||
y_ += vy_;
|
||||
|
||||
vx += ax;
|
||||
vy += ay;
|
||||
vx_ += ax_;
|
||||
vy_ += ay_;
|
||||
}
|
||||
}
|
||||
|
||||
// Muestra el sprite por pantalla
|
||||
void MovingSprite::render() {
|
||||
if (enabled) {
|
||||
texture->render(renderer, (int)x, (int)y, &spriteClip, zoomW, zoomH, angle, center, currentFlip);
|
||||
if (enabled_) {
|
||||
texture_->render(renderer_, (int)x_, (int)y_, &sprite_clip_, zoom_w_, zoom_h_, angle_, center_, current_flip_);
|
||||
}
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
// cppcheck-suppress duplInheritedMember
|
||||
auto MovingSprite::getPosX() const -> float {
|
||||
return x;
|
||||
return x_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
// cppcheck-suppress duplInheritedMember
|
||||
auto MovingSprite::getPosY() const -> float {
|
||||
return y;
|
||||
return y_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getVelX() const -> float {
|
||||
return vx;
|
||||
return vx_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getVelY() const -> float {
|
||||
return vy;
|
||||
return vy_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getAccelX() const -> float {
|
||||
return ax;
|
||||
return ax_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getAccelY() const -> float {
|
||||
return ay;
|
||||
return ay_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getZoomW() const -> float {
|
||||
return zoomW;
|
||||
return zoom_w_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getZoomH() const -> float {
|
||||
return zoomH;
|
||||
return zoom_h_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getAngle() const -> double {
|
||||
return angle;
|
||||
return angle_;
|
||||
}
|
||||
|
||||
// Establece la posición y el tamaño del objeto
|
||||
void MovingSprite::setRect(SDL_Rect rect) {
|
||||
x = (float)rect.x;
|
||||
y = (float)rect.y;
|
||||
w = rect.w;
|
||||
h = rect.h;
|
||||
x_ = (float)rect.x;
|
||||
y_ = (float)rect.y;
|
||||
w_ = rect.w;
|
||||
h_ = rect.h;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setPosX(float value) {
|
||||
x = value;
|
||||
x_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setPosY(float value) {
|
||||
y = value;
|
||||
y_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setVelX(float value) {
|
||||
vx = value;
|
||||
vx_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setVelY(float value) {
|
||||
vy = value;
|
||||
vy_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setAccelX(float value) {
|
||||
ax = value;
|
||||
ax_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setAccelY(float value) {
|
||||
ay = value;
|
||||
ay_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setZoomW(float value) {
|
||||
zoomW = value;
|
||||
zoom_w_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setZoomH(float value) {
|
||||
zoomH = value;
|
||||
zoom_h_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setAngle(double value) {
|
||||
angle = value;
|
||||
angle_ = value;
|
||||
}
|
||||
|
||||
// Incrementa el valor de la variable
|
||||
void MovingSprite::incAngle(double value) {
|
||||
angle += value;
|
||||
angle_ += value;
|
||||
}
|
||||
|
||||
// Decrementa el valor de la variable
|
||||
void MovingSprite::decAngle(double value) {
|
||||
angle -= value;
|
||||
angle_ -= value;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getRotate() const -> bool {
|
||||
return rotateEnabled;
|
||||
return rotate_enabled_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto MovingSprite::getRotateSpeed() const -> Uint16 {
|
||||
return rotateSpeed;
|
||||
return rotate_speed_;
|
||||
}
|
||||
|
||||
// Establece la rotacion
|
||||
void MovingSprite::rotate() {
|
||||
if (enabled) {
|
||||
if (rotateEnabled) {
|
||||
if (counter % rotateSpeed == 0) {
|
||||
incAngle(rotateAmount);
|
||||
if (enabled_) {
|
||||
if (rotate_enabled_) {
|
||||
if (counter_ % rotate_speed_ == 0) {
|
||||
incAngle(rotate_amount_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,27 +193,27 @@ void MovingSprite::rotate() {
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setRotate(bool value) {
|
||||
rotateEnabled = value;
|
||||
rotate_enabled_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setRotateSpeed(int value) {
|
||||
if (value < 1) {
|
||||
rotateSpeed = 1;
|
||||
rotate_speed_ = 1;
|
||||
} else {
|
||||
rotateSpeed = value;
|
||||
rotate_speed_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setRotateAmount(double value) {
|
||||
rotateAmount = value;
|
||||
rotate_amount_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::disableRotate() {
|
||||
rotateEnabled = false;
|
||||
angle = (double)0;
|
||||
rotate_enabled_ = false;
|
||||
angle_ = (double)0;
|
||||
}
|
||||
|
||||
// Actualiza las variables internas del objeto
|
||||
@@ -221,59 +221,59 @@ void MovingSprite::update() {
|
||||
move();
|
||||
rotate();
|
||||
|
||||
if (enabled) {
|
||||
++counter %= 60000;
|
||||
if (enabled_) {
|
||||
++counter_ %= 60000;
|
||||
}
|
||||
}
|
||||
|
||||
// Cambia el sentido de la rotación
|
||||
void MovingSprite::switchRotate() {
|
||||
rotateAmount *= -1;
|
||||
rotate_amount_ *= -1;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void MovingSprite::setFlip(SDL_FlipMode flip) {
|
||||
currentFlip = flip;
|
||||
current_flip_ = flip;
|
||||
}
|
||||
|
||||
// Gira el sprite horizontalmente
|
||||
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
|
||||
auto MovingSprite::getFlip() -> SDL_FlipMode {
|
||||
return currentFlip;
|
||||
return current_flip_;
|
||||
}
|
||||
|
||||
// Devuelve el rectangulo donde está el sprite
|
||||
auto MovingSprite::getRect() -> SDL_Rect {
|
||||
const SDL_Rect rect = {(int)x, (int)y, w, h};
|
||||
return rect;
|
||||
const SDL_Rect RECT = {(int)x_, (int)y_, w_, h_};
|
||||
return RECT;
|
||||
}
|
||||
|
||||
// Deshace el último movimiento
|
||||
void MovingSprite::undoMove() {
|
||||
x = xPrev;
|
||||
y = yPrev;
|
||||
x_ = x_prev_;
|
||||
y_ = y_prev_;
|
||||
}
|
||||
|
||||
// Deshace el último movimiento en el eje X
|
||||
void MovingSprite::undoMoveX() {
|
||||
x = xPrev;
|
||||
x_ = x_prev_;
|
||||
}
|
||||
|
||||
// Deshace el último movimiento en el eje Y
|
||||
void MovingSprite::undoMoveY() {
|
||||
y = yPrev;
|
||||
y_ = y_prev_;
|
||||
}
|
||||
|
||||
// Pone a cero las velocidades de desplacamiento
|
||||
void MovingSprite::clearVel() {
|
||||
vx = vy = 0.0F;
|
||||
vx_ = vy_ = 0.0F;
|
||||
}
|
||||
|
||||
// Devuelve el incremento en el eje X en pixels
|
||||
auto MovingSprite::getIncX() const -> int {
|
||||
return (int)x - (int)xPrev;
|
||||
}
|
||||
return (int)x_ - (int)x_prev_;
|
||||
}
|
||||
|
||||
@@ -7,161 +7,85 @@ class Texture;
|
||||
|
||||
// Clase MovingSprite. Añade posicion y velocidad en punto flotante
|
||||
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:
|
||||
// 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
|
||||
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 yPrev; // Posición anterior en el eje Y
|
||||
float x_prev_; // Posición anterior en el eje X
|
||||
float y_prev_; // Posición anterior en el eje Y
|
||||
|
||||
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 vx_; // Velocidad en el eje X. 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 ay; // Aceleración en el eje Y. 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 zoomW{1}; // Zoom aplicado a la anchura
|
||||
float zoomH{1}; // Zoom aplicado a la altura
|
||||
float zoom_w_{1}; // Zoom aplicado a la anchura
|
||||
float zoom_h_{1}; // Zoom aplicado a la altura
|
||||
|
||||
double angle{0.0}; // Angulo para dibujarlo
|
||||
bool rotateEnabled{false}; // Indica si ha de rotar
|
||||
int rotateSpeed{0}; // Velocidad de giro
|
||||
double rotateAmount{0.0}; // Cantidad de grados a girar en cada iteración
|
||||
int counter{0}; // Contador interno
|
||||
SDL_Point *center{nullptr}; // Centro de rotación
|
||||
SDL_FlipMode currentFlip{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;
|
||||
double angle_{0.0}; // Angulo para dibujarlo
|
||||
bool rotate_enabled_{false}; // Indica si ha de rotar
|
||||
int rotate_speed_{0}; // Velocidad de giro
|
||||
double rotate_amount_{0.0}; // Cantidad de grados a girar en cada iteración
|
||||
int counter_{0}; // Contador interno
|
||||
SDL_Point *center_{nullptr}; // Centro de rotación
|
||||
SDL_FlipMode current_flip_{SDL_FLIP_NONE}; // Indica como se voltea el sprite
|
||||
};
|
||||
|
||||
+106
-106
@@ -79,13 +79,13 @@ auto Screen::get() -> Screen * {
|
||||
|
||||
// Constructor
|
||||
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
|
||||
: borderColor{0x00, 0x00, 0x00} {
|
||||
: border_color_{0x00, 0x00, 0x00} {
|
||||
// Inicializa variables
|
||||
this->window = window;
|
||||
this->renderer = renderer;
|
||||
this->window_ = window;
|
||||
this->renderer_ = renderer;
|
||||
|
||||
gameCanvasWidth = GAMECANVAS_WIDTH;
|
||||
gameCanvasHeight = GAMECANVAS_HEIGHT;
|
||||
game_canvas_width_ = GAMECANVAS_WIDTH;
|
||||
game_canvas_height_ = GAMECANVAS_HEIGHT;
|
||||
|
||||
// Establece el modo de video (fullscreen/ventana + 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.
|
||||
// ARGB8888 per simplificar el readback cap al pipeline SDL3 GPU.
|
||||
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight);
|
||||
if (gameCanvas != nullptr) {
|
||||
SDL_SetTextureScaleMode(gameCanvas, Options::video.scale_mode);
|
||||
game_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_, game_canvas_height_);
|
||||
if (game_canvas_ != nullptr) {
|
||||
SDL_SetTextureScaleMode(game_canvas_, Options::video.scale_mode);
|
||||
}
|
||||
if (gameCanvas == nullptr) {
|
||||
if (game_canvas_ == nullptr) {
|
||||
if (Options::settings.console) {
|
||||
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
|
||||
// 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
|
||||
|
||||
// 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
|
||||
// crashegi en la creació del pipeline gràfic. `initShaders()` es crida
|
||||
// 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
|
||||
// `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
|
||||
// allocacions (carrega de textures), el driver Vulkan crasheja quan
|
||||
// després es reclama la ventana per al dispositiu GPU.
|
||||
notificationText = nullptr;
|
||||
notificationMessage = "";
|
||||
notificationTextColor = {0xFF, 0xFF, 0xFF};
|
||||
notificationOutlineColor = {0x00, 0x00, 0x00};
|
||||
notificationEndTime = 0;
|
||||
notificationY = 2;
|
||||
notification_text_ = nullptr;
|
||||
notification_message_ = "";
|
||||
notification_text_color_ = {0xFF, 0xFF, 0xFF};
|
||||
notification_outline_color_ = {0x00, 0x00, 0x00};
|
||||
notification_end_time_ = 0;
|
||||
notification_y_ = 2;
|
||||
|
||||
// Registra callbacks natius d'Emscripten per a fullscreen/orientation
|
||||
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`.
|
||||
// S'ha de cridar després de `Resource::init(...)`.
|
||||
void Screen::initNotifications() {
|
||||
notificationText = Resource::get()->getText("8bithud");
|
||||
notification_text_ = Resource::get()->getText("8bithud");
|
||||
}
|
||||
|
||||
// Destructor
|
||||
@@ -153,24 +153,24 @@ Screen::~Screen() {
|
||||
#ifndef NO_SHADERS
|
||||
shutdownShaders();
|
||||
#endif
|
||||
SDL_DestroyTexture(gameCanvas);
|
||||
SDL_DestroyTexture(game_canvas_);
|
||||
}
|
||||
|
||||
// Limpia la pantalla
|
||||
void Screen::clean(Color color) {
|
||||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
}
|
||||
|
||||
// Prepara para empezar a dibujar en la textura de juego
|
||||
void Screen::start() {
|
||||
SDL_SetRenderTarget(renderer, gameCanvas);
|
||||
SDL_SetRenderTarget(renderer_, game_canvas_);
|
||||
}
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
void Screen::blit() {
|
||||
// Dibuja la notificación activa sobre el gameCanvas antes de presentar
|
||||
SDL_SetRenderTarget(renderer, gameCanvas);
|
||||
SDL_SetRenderTarget(renderer_, game_canvas_);
|
||||
renderNotification();
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
@@ -180,7 +180,7 @@ void Screen::blit() {
|
||||
// i restaurem el shader actiu, així CRTPI no aplica les seues scanlines
|
||||
// quan l'usuari ho ha desactivat.
|
||||
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->format == SDL_PIXELFORMAT_ARGB8888) {
|
||||
std::memcpy(pixel_buffer_.data(), surface->pixels, pixel_buffer_.size() * sizeof(Uint32));
|
||||
@@ -193,11 +193,11 @@ void Screen::blit() {
|
||||
}
|
||||
SDL_DestroySurface(surface);
|
||||
}
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
|
||||
if (Options::video.shader.enabled) {
|
||||
// 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();
|
||||
} else {
|
||||
// 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_->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();
|
||||
if (PREV_SHADER != Rendering::ShaderType::POSTFX) {
|
||||
shader_backend_->setActiveShader(PREV_SHADER);
|
||||
@@ -219,18 +219,18 @@ void Screen::blit() {
|
||||
#endif
|
||||
|
||||
// Vuelve a dejar el renderizador en modo normal
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
|
||||
// Borra el contenido previo
|
||||
SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, 0xFF);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
// 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_RenderTexture(renderer, gameCanvas, nullptr, &fdest);
|
||||
SDL_FRect fdest = {(float)dest_.x, (float)dest_.y, (float)dest_.w, (float)dest_.h};
|
||||
SDL_RenderTexture(renderer_, game_canvas_, nullptr, &fdest);
|
||||
|
||||
// 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ò
|
||||
// reinicialitza l'estat intern del renderer. Recreem gameCanvas aquí
|
||||
// mateix per garantir el mateix efecte en qualsevol escena.
|
||||
if (gameCanvas != nullptr) {
|
||||
SDL_DestroyTexture(gameCanvas);
|
||||
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight);
|
||||
if (gameCanvas != nullptr) {
|
||||
SDL_SetTextureScaleMode(gameCanvas, Options::video.scale_mode);
|
||||
if (game_canvas_ != nullptr) {
|
||||
SDL_DestroyTexture(game_canvas_);
|
||||
game_canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_, game_canvas_height_);
|
||||
if (game_canvas_ != nullptr) {
|
||||
SDL_SetTextureScaleMode(game_canvas_, Options::video.scale_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ void Screen::toggleIntegerScale() {
|
||||
// Establece el V-Sync
|
||||
void Screen::setVSync(bool 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
|
||||
if (shader_backend_) {
|
||||
shader_backend_->setVSync(enabled);
|
||||
@@ -328,7 +328,7 @@ void Screen::toggleVSync() {
|
||||
|
||||
// Cambia el color del borde
|
||||
void Screen::setBorderColor(Color color) {
|
||||
borderColor = color;
|
||||
border_color_ = color;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -337,7 +337,7 @@ void Screen::setBorderColor(Color color) {
|
||||
|
||||
// SDL_SetWindowFullscreen + visibilidad del cursor
|
||||
void Screen::applyFullscreen(bool fullscreen) {
|
||||
SDL_SetWindowFullscreen(window, fullscreen);
|
||||
SDL_SetWindowFullscreen(window_, fullscreen);
|
||||
if (fullscreen) {
|
||||
SDL_HideCursor();
|
||||
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
|
||||
void Screen::applyWindowedLayout() {
|
||||
windowWidth = gameCanvasWidth;
|
||||
windowHeight = gameCanvasHeight;
|
||||
dest = {.x = 0, .y = 0, .w = gameCanvasWidth, .h = gameCanvasHeight};
|
||||
window_width_ = game_canvas_width_;
|
||||
window_height_ = game_canvas_height_;
|
||||
dest_ = {.x = 0, .y = 0, .w = game_canvas_width_, .h = game_canvas_height_};
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
windowWidth *= WASM_RENDER_SCALE;
|
||||
@@ -362,20 +362,20 @@ void Screen::applyWindowedLayout() {
|
||||
#endif
|
||||
|
||||
// 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
|
||||
// es queda en estat out-of-date després del resize i SDL_AcquireGPU-
|
||||
// SwapchainTexture deixa de tornar una textura vàlida → finestra negra.
|
||||
// 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
|
||||
// reposicionar i continuar amb el render.
|
||||
SDL_SyncWindow(window);
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_SyncWindow(window_);
|
||||
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
}
|
||||
|
||||
// Obtiene el tamaño de la ventana en fullscreen y calcula el rect del juego
|
||||
void Screen::applyFullscreenLayout() {
|
||||
SDL_GetWindowSize(window, &windowWidth, &windowHeight);
|
||||
SDL_GetWindowSize(window_, &window_width_, &window_height_);
|
||||
computeFullscreenGameRect();
|
||||
}
|
||||
|
||||
@@ -384,34 +384,34 @@ void Screen::computeFullscreenGameRect() {
|
||||
if (Options::video.integer_scale) {
|
||||
// Calcula el tamaño de la escala máxima
|
||||
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++;
|
||||
}
|
||||
|
||||
dest.w = gameCanvasWidth * scale;
|
||||
dest.h = gameCanvasHeight * scale;
|
||||
dest.x = (windowWidth - dest.w) / 2;
|
||||
dest.y = (windowHeight - dest.h) / 2;
|
||||
dest_.w = game_canvas_width_ * scale;
|
||||
dest_.h = game_canvas_height_ * scale;
|
||||
dest_.x = (window_width_ - dest_.w) / 2;
|
||||
dest_.y = (window_height_ - dest_.h) / 2;
|
||||
} else {
|
||||
// Manté la relació d'aspecte sense escalat enter (letterbox/pillarbox).
|
||||
float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight;
|
||||
if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight)) {
|
||||
dest.h = windowHeight;
|
||||
dest.w = static_cast<int>(std::lround(windowHeight * ratio));
|
||||
dest.x = (windowWidth - dest.w) / 2;
|
||||
dest.y = (windowHeight - dest.h) / 2;
|
||||
float ratio = (float)game_canvas_width_ / (float)game_canvas_height_;
|
||||
if ((window_width_ - game_canvas_width_) >= (window_height_ - game_canvas_height_)) {
|
||||
dest_.h = window_height_;
|
||||
dest_.w = static_cast<int>(std::lround(window_height_ * ratio));
|
||||
dest_.x = (window_width_ - dest_.w) / 2;
|
||||
dest_.y = (window_height_ - dest_.h) / 2;
|
||||
} else {
|
||||
dest.w = windowWidth;
|
||||
dest.h = static_cast<int>(std::lround(windowWidth / ratio));
|
||||
dest.x = (windowWidth - dest.w) / 2;
|
||||
dest.y = (windowHeight - dest.h) / 2;
|
||||
dest_.w = window_width_;
|
||||
dest_.h = static_cast<int>(std::lround(window_width_ / ratio));
|
||||
dest_.x = (window_width_ - dest_.w) / 2;
|
||||
dest_.y = (window_height_ - dest_.h) / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Aplica la logical presentation y persiste el estado en options
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -420,32 +420,32 @@ void Screen::applyLogicalPresentation(bool fullscreen) {
|
||||
// ============================================================================
|
||||
|
||||
// Muestra una notificación en la línea superior durante durationMs
|
||||
void Screen::notify(const std::string &text, Color textColor, Color outlineColor, Uint32 durationMs) {
|
||||
notificationMessage = text;
|
||||
notificationTextColor = textColor;
|
||||
notificationOutlineColor = outlineColor;
|
||||
notificationEndTime = SDL_GetTicks() + durationMs;
|
||||
void Screen::notify(const std::string &text, Color text_color, Color outline_color, Uint32 duration_ms) {
|
||||
notification_message_ = text;
|
||||
notification_text_color_ = text_color;
|
||||
notification_outline_color_ = outline_color;
|
||||
notification_end_time_ = SDL_GetTicks() + duration_ms;
|
||||
}
|
||||
|
||||
// Limpia la notificación actual
|
||||
void Screen::clearNotification() {
|
||||
notificationEndTime = 0;
|
||||
notificationMessage.clear();
|
||||
notification_end_time_ = 0;
|
||||
notification_message_.clear();
|
||||
}
|
||||
|
||||
// Dibuja la notificación activa (si la hay) sobre el gameCanvas
|
||||
void Screen::renderNotification() {
|
||||
if (notificationText == nullptr || SDL_GetTicks() >= notificationEndTime) {
|
||||
if (notification_text_ == nullptr || SDL_GetTicks() >= notification_end_time_) {
|
||||
return;
|
||||
}
|
||||
notificationText->writeDX(TXT_CENTER | TXT_COLOR | TXT_STROKE,
|
||||
gameCanvasWidth / 2,
|
||||
notificationY,
|
||||
notificationMessage,
|
||||
notification_text_->writeDX(TXT_CENTER | TXT_COLOR | TXT_STROKE,
|
||||
game_canvas_width_ / 2,
|
||||
notification_y_,
|
||||
notification_message_,
|
||||
1,
|
||||
notificationTextColor,
|
||||
notification_text_color_,
|
||||
1,
|
||||
notificationOutlineColor);
|
||||
notification_outline_color_);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -462,11 +462,11 @@ void Screen::handleCanvasResized() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void Screen::syncFullscreenFlagFromBrowser(bool isFullscreen) {
|
||||
void Screen::syncFullscreenFlagFromBrowser(bool is_fullscreen) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Options::video.fullscreen = isFullscreen;
|
||||
#else
|
||||
(void)isFullscreen;
|
||||
(void)is_fullscreen;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -511,9 +511,9 @@ void Screen::initShaders() {
|
||||
Options::video.gpu.acceleration ? Options::video.gpu.preferred_driver : FALLBACK_DRIVER);
|
||||
}
|
||||
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) {
|
||||
std::cout << "Screen::initShaders: SDL3GPUShader::init() = " << (ok ? "OK" : "FAILED") << '\n';
|
||||
std::cout << "Screen::initShaders: SDL3GPUShader::init() = " << (OK ? "OK" : "FAILED") << '\n';
|
||||
}
|
||||
}
|
||||
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())) {
|
||||
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;
|
||||
p.vignette = PRESET.vignette;
|
||||
p.scanlines = PRESET.scanlines;
|
||||
p.chroma = PRESET.chroma;
|
||||
p.mask = PRESET.mask;
|
||||
p.gamma = PRESET.gamma;
|
||||
p.curvature = PRESET.curvature;
|
||||
p.bleeding = PRESET.bleeding;
|
||||
p.flicker = PRESET.flicker;
|
||||
p.vignette = preset.vignette;
|
||||
p.scanlines = preset.scanlines;
|
||||
p.chroma = preset.chroma;
|
||||
p.mask = preset.mask;
|
||||
p.gamma = preset.gamma;
|
||||
p.curvature = preset.curvature;
|
||||
p.bleeding = preset.bleeding;
|
||||
p.flicker = preset.flicker;
|
||||
shader_backend_->setPostFXParams(p);
|
||||
#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())) {
|
||||
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;
|
||||
p.scanline_weight = PRESET.scanline_weight;
|
||||
p.scanline_gap_brightness = PRESET.scanline_gap_brightness;
|
||||
p.bloom_factor = PRESET.bloom_factor;
|
||||
p.input_gamma = PRESET.input_gamma;
|
||||
p.output_gamma = PRESET.output_gamma;
|
||||
p.mask_brightness = PRESET.mask_brightness;
|
||||
p.curvature_x = PRESET.curvature_x;
|
||||
p.curvature_y = PRESET.curvature_y;
|
||||
p.mask_type = PRESET.mask_type;
|
||||
p.enable_scanlines = PRESET.enable_scanlines;
|
||||
p.enable_multisample = PRESET.enable_multisample;
|
||||
p.enable_gamma = PRESET.enable_gamma;
|
||||
p.enable_curvature = PRESET.enable_curvature;
|
||||
p.enable_sharper = PRESET.enable_sharper;
|
||||
p.scanline_weight = preset.scanline_weight;
|
||||
p.scanline_gap_brightness = preset.scanline_gap_brightness;
|
||||
p.bloom_factor = preset.bloom_factor;
|
||||
p.input_gamma = preset.input_gamma;
|
||||
p.output_gamma = preset.output_gamma;
|
||||
p.mask_brightness = preset.mask_brightness;
|
||||
p.curvature_x = preset.curvature_x;
|
||||
p.curvature_y = preset.curvature_y;
|
||||
p.mask_type = preset.mask_type;
|
||||
p.enable_scanlines = preset.enable_scanlines;
|
||||
p.enable_multisample = preset.enable_multisample;
|
||||
p.enable_gamma = preset.enable_gamma;
|
||||
p.enable_curvature = preset.enable_curvature;
|
||||
p.enable_sharper = preset.enable_sharper;
|
||||
shader_backend_->setCrtPiParams(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class Screen {
|
||||
void setVideoMode(bool fullscreen); // Establece el modo de video
|
||||
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
|
||||
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 setIntegerScale(bool enabled); // Establece el escalado entero
|
||||
void toggleVSync(); // Alterna el V-Sync
|
||||
@@ -60,7 +60,7 @@ class Screen {
|
||||
|
||||
// Notificaciones
|
||||
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
|
||||
|
||||
// GPU / shaders (post-procesado). En builds con NO_SHADERS (Emscripten) son no-op.
|
||||
@@ -111,25 +111,25 @@ class Screen {
|
||||
#endif
|
||||
|
||||
// Objetos y punteros
|
||||
SDL_Window *window; // Ventana de la aplicación
|
||||
SDL_Renderer *renderer; // El renderizador de la ventana
|
||||
SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
|
||||
SDL_Window *window_; // Ventana de la aplicación
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
SDL_Texture *game_canvas_; // Textura para completar la ventana de juego hasta la pantalla completa
|
||||
|
||||
// Variables
|
||||
int windowWidth; // Ancho de la pantalla o ventana
|
||||
int windowHeight; // 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 gameCanvasHeight; // 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
|
||||
Color borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
|
||||
int window_width_; // Ancho de la pantalla o ventana
|
||||
int window_height_; // Alto de la pantalla o ventana
|
||||
int game_canvas_width_; // Resolución interna del juego. Es el ancho 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
|
||||
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
|
||||
Text *notificationText; // Fuente 8bithud dedicada a las notificaciones
|
||||
std::string notificationMessage; // Texto a mostrar
|
||||
Color notificationTextColor; // Color del texto
|
||||
Color notificationOutlineColor; // Color del outline
|
||||
Uint32 notificationEndTime; // SDL_GetTicks() hasta el cual se muestra
|
||||
int notificationY; // Fila vertical en el canvas virtual
|
||||
Text *notification_text_; // Fuente 8bithud dedicada a las notificaciones
|
||||
std::string notification_message_; // Texto a mostrar
|
||||
Color notification_text_color_; // Color del texto
|
||||
Color notification_outline_color_; // Color del outline
|
||||
Uint32 notification_end_time_; // SDL_GetTicks() hasta el cual se muestra
|
||||
int notification_y_; // Fila vertical en el canvas virtual
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
// GPU / shaders
|
||||
|
||||
@@ -15,18 +15,18 @@ SmartSprite::SmartSprite(Texture *texture, SDL_Renderer *renderer) {
|
||||
|
||||
// Inicializa el objeto
|
||||
void SmartSprite::init() {
|
||||
enabled = false;
|
||||
enabledCounter = 0;
|
||||
onDestination = false;
|
||||
destX = 0;
|
||||
destY = 0;
|
||||
counter = 0;
|
||||
finished = false;
|
||||
enabled_ = false;
|
||||
enabled_counter_ = 0;
|
||||
on_destination_ = false;
|
||||
dest_x_ = 0;
|
||||
dest_y_ = 0;
|
||||
counter_ = 0;
|
||||
finished_ = false;
|
||||
}
|
||||
|
||||
// Actualiza la posición y comprueba si ha llegado a su destino
|
||||
void SmartSprite::update() {
|
||||
if (enabled) {
|
||||
if (enabled_) {
|
||||
// Actualiza només la posició; els SmartSprite no usen animació de
|
||||
// frames i salten deliberadament AnimatedSprite::animate().
|
||||
// NOLINTNEXTLINE(bugprone-parent-virtual-call)
|
||||
@@ -42,7 +42,7 @@ void SmartSprite::update() {
|
||||
|
||||
// Pinta el objeto en pantalla
|
||||
void SmartSprite::render() {
|
||||
if (enabled) {
|
||||
if (enabled_) {
|
||||
// Muestra el sprite por pantalla
|
||||
MovingSprite::render();
|
||||
}
|
||||
@@ -50,32 +50,32 @@ void SmartSprite::render() {
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto SmartSprite::getEnabledCounter() const -> int {
|
||||
return enabledCounter;
|
||||
return enabled_counter_;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void SmartSprite::setEnabledCounter(int value) {
|
||||
enabledCounter = value;
|
||||
enabled_counter_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void SmartSprite::setDestX(int x) {
|
||||
destX = x;
|
||||
dest_x_ = x;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void SmartSprite::setDestY(int y) {
|
||||
destY = y;
|
||||
dest_y_ = y;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto SmartSprite::getDestX() const -> int {
|
||||
return destX;
|
||||
return dest_x_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto SmartSprite::getDestY() const -> int {
|
||||
return destY;
|
||||
return dest_y_;
|
||||
}
|
||||
|
||||
// Comprueba el movimiento
|
||||
@@ -83,9 +83,9 @@ void SmartSprite::checkMove() {
|
||||
// Comprueba si se desplaza en el eje X hacia la derecha
|
||||
if (getAccelX() > 0 || getVelX() > 0) {
|
||||
// Comprueba si ha llegado al destino
|
||||
if (getPosX() > destX) {
|
||||
if (getPosX() > dest_x_) {
|
||||
// Lo coloca en posición
|
||||
setPosX(destX);
|
||||
setPosX(dest_x_);
|
||||
|
||||
// Lo detiene
|
||||
setVelX(0.0F);
|
||||
@@ -95,9 +95,9 @@ void SmartSprite::checkMove() {
|
||||
// Comprueba si se desplaza en el eje X hacia la izquierda
|
||||
else if (getAccelX() < 0 || getVelX() < 0) {
|
||||
// Comprueba si ha llegado al destino
|
||||
if (getPosX() < destX) {
|
||||
if (getPosX() < dest_x_) {
|
||||
// Lo coloca en posición
|
||||
setPosX(destX);
|
||||
setPosX(dest_x_);
|
||||
|
||||
// Lo detiene
|
||||
setVelX(0.0F);
|
||||
@@ -108,9 +108,9 @@ void SmartSprite::checkMove() {
|
||||
// Comprueba si se desplaza en el eje Y hacia abajo
|
||||
if (getAccelY() > 0 || getVelY() > 0) {
|
||||
// Comprueba si ha llegado al destino
|
||||
if (getPosY() > destY) {
|
||||
if (getPosY() > dest_y_) {
|
||||
// Lo coloca en posición
|
||||
setPosY(destY);
|
||||
setPosY(dest_y_);
|
||||
|
||||
// Lo detiene
|
||||
setVelY(0.0F);
|
||||
@@ -120,9 +120,9 @@ void SmartSprite::checkMove() {
|
||||
// Comprueba si se desplaza en el eje Y hacia arriba
|
||||
else if (getAccelY() < 0 || getVelY() < 0) {
|
||||
// Comprueba si ha llegado al destino
|
||||
if (getPosY() < destY) {
|
||||
if (getPosY() < dest_y_) {
|
||||
// Lo coloca en posición
|
||||
setPosY(destY);
|
||||
setPosY(dest_y_);
|
||||
|
||||
// Lo detiene
|
||||
setVelY(0.0F);
|
||||
@@ -134,23 +134,23 @@ void SmartSprite::checkMove() {
|
||||
// Comprueba si ha terminado
|
||||
void SmartSprite::checkFinished() {
|
||||
// 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 (enabledCounter == 0) { // Si ha llegado a cero, deshabilita el objeto y lo marca como finalizado
|
||||
finished = true;
|
||||
if (on_destination_) { // Si esta en el destino comprueba su contador
|
||||
if (enabled_counter_ == 0) { // Si ha llegado a cero, deshabilita el objeto y lo marca como finalizado
|
||||
finished_ = true;
|
||||
} else { // Si no ha llegado a cero, decrementa el contador
|
||||
enabledCounter--;
|
||||
enabled_counter_--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto SmartSprite::isOnDestination() const -> bool {
|
||||
return onDestination;
|
||||
return on_destination_;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto SmartSprite::hasFinished() const -> bool {
|
||||
return finished;
|
||||
return finished_;
|
||||
}
|
||||
@@ -7,54 +7,30 @@ class Texture;
|
||||
|
||||
// Clase SmartSprite
|
||||
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:
|
||||
// Variables
|
||||
bool onDestination; // Indica si está en el destino
|
||||
int destX; // Posicion de destino en el eje X
|
||||
int destY; // Posicion de destino en el eje Y
|
||||
int enabledCounter; // Contador para deshabilitarlo
|
||||
bool finished; // Indica si ya ha terminado
|
||||
bool on_destination_; // Indica si está en el destino
|
||||
int dest_x_; // Posicion de destino en el eje X
|
||||
int dest_y_; // Posicion de destino en el eje Y
|
||||
int enabled_counter_; // Contador para deshabilitarlo
|
||||
bool finished_; // Indica si ya ha terminado
|
||||
|
||||
// Comprueba el movimiento
|
||||
void checkMove();
|
||||
|
||||
// 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;
|
||||
void checkMove(); // Comprueba el movimiento
|
||||
void checkFinished(); // Comprueba si ha terminado
|
||||
};
|
||||
|
||||
@@ -4,141 +4,141 @@
|
||||
|
||||
// Constructor
|
||||
Sprite::Sprite(int x, int y, int w, int h, Texture *texture, SDL_Renderer *renderer)
|
||||
: x(x),
|
||||
y(y),
|
||||
w(w),
|
||||
h(h),
|
||||
renderer(renderer),
|
||||
texture(texture),
|
||||
spriteClip{0, 0, w, h},
|
||||
enabled(true) {
|
||||
: x_(x),
|
||||
y_(y),
|
||||
w_(w),
|
||||
h_(h),
|
||||
renderer_(renderer),
|
||||
texture_(texture),
|
||||
sprite_clip_{0, 0, w, h},
|
||||
enabled_(true) {
|
||||
}
|
||||
|
||||
Sprite::Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer)
|
||||
: x(rect.x),
|
||||
y(rect.y),
|
||||
w(rect.w),
|
||||
h(rect.h),
|
||||
renderer(renderer),
|
||||
texture(texture),
|
||||
spriteClip{0, 0, rect.w, rect.h},
|
||||
enabled(true) {
|
||||
: x_(rect.x),
|
||||
y_(rect.y),
|
||||
w_(rect.w),
|
||||
h_(rect.h),
|
||||
renderer_(renderer),
|
||||
texture_(texture),
|
||||
sprite_clip_{0, 0, rect.w, rect.h},
|
||||
enabled_(true) {
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Sprite::~Sprite() {
|
||||
texture = nullptr;
|
||||
renderer = nullptr;
|
||||
texture_ = nullptr;
|
||||
renderer_ = nullptr;
|
||||
}
|
||||
|
||||
// Muestra el sprite por pantalla
|
||||
void Sprite::render() {
|
||||
if (enabled) {
|
||||
texture->render(renderer, x, y, &spriteClip);
|
||||
if (enabled_) {
|
||||
texture_->render(renderer_, x_, y_, &sprite_clip_);
|
||||
}
|
||||
}
|
||||
|
||||
// Obten el valor de la variable
|
||||
auto Sprite::getPosX() const -> int {
|
||||
return x;
|
||||
return x_;
|
||||
}
|
||||
|
||||
// Obten el valor de la variable
|
||||
auto Sprite::getPosY() const -> int {
|
||||
return y;
|
||||
return y_;
|
||||
}
|
||||
|
||||
// Obten el valor de la variable
|
||||
auto Sprite::getWidth() const -> int {
|
||||
return w;
|
||||
return w_;
|
||||
}
|
||||
|
||||
// Obten el valor de la variable
|
||||
auto Sprite::getHeight() const -> int {
|
||||
return h;
|
||||
return h_;
|
||||
}
|
||||
|
||||
// Establece la posición del objeto
|
||||
void Sprite::setPos(SDL_Rect rect) {
|
||||
this->x = rect.x;
|
||||
this->y = rect.y;
|
||||
this->x_ = rect.x;
|
||||
this->y_ = rect.y;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Sprite::setPosX(int x) {
|
||||
this->x = x;
|
||||
this->x_ = x;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Sprite::setPosY(int y) {
|
||||
this->y = y;
|
||||
this->y_ = y;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Sprite::setWidth(int w) {
|
||||
this->w = w;
|
||||
this->w_ = w;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Sprite::setHeight(int h) {
|
||||
this->h = h;
|
||||
this->h_ = h;
|
||||
}
|
||||
|
||||
// Obten el valor de la variable
|
||||
auto Sprite::getSpriteClip() -> SDL_Rect {
|
||||
return spriteClip;
|
||||
return sprite_clip_;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Sprite::setSpriteClip(SDL_Rect rect) {
|
||||
spriteClip = rect;
|
||||
sprite_clip_ = rect;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
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
|
||||
auto Sprite::getTexture() -> Texture * {
|
||||
return texture;
|
||||
return texture_;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Sprite::setTexture(Texture *texture) {
|
||||
this->texture = texture;
|
||||
this->texture_ = texture;
|
||||
}
|
||||
|
||||
// Obten el valor de la variable
|
||||
auto Sprite::getRenderer() -> SDL_Renderer * {
|
||||
return renderer;
|
||||
return renderer_;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Sprite::setRenderer(SDL_Renderer *renderer) {
|
||||
this->renderer = renderer;
|
||||
this->renderer_ = renderer;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Sprite::setEnabled(bool value) {
|
||||
enabled = value;
|
||||
enabled_ = value;
|
||||
}
|
||||
|
||||
// Comprueba si el objeto está habilitado
|
||||
auto Sprite::isEnabled() -> bool {
|
||||
return enabled;
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
// Devuelve el rectangulo donde está el sprite
|
||||
auto Sprite::getRect() -> SDL_Rect {
|
||||
SDL_Rect rect = {x, y, w, h};
|
||||
SDL_Rect rect = {x_, y_, w_, h_};
|
||||
return rect;
|
||||
}
|
||||
|
||||
// Establece los valores de posición y tamaño del sprite
|
||||
void Sprite::setRect(SDL_Rect rect) {
|
||||
x = rect.x;
|
||||
y = rect.y;
|
||||
w = rect.w;
|
||||
h = rect.h;
|
||||
x_ = rect.x;
|
||||
y_ = rect.y;
|
||||
w_ = rect.w;
|
||||
h_ = rect.h;
|
||||
}
|
||||
@@ -5,86 +5,50 @@ class Texture;
|
||||
|
||||
// Clase 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:
|
||||
// Constructor
|
||||
explicit Sprite(int x = 0, int y = 0, int w = 0, int h = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr);
|
||||
explicit Sprite(int x = 0, int y = 0, int w = 0, int h = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr); // Constructor
|
||||
Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer);
|
||||
|
||||
// Destructor
|
||||
virtual ~Sprite();
|
||||
virtual ~Sprite(); // Destructor
|
||||
|
||||
// Muestra el sprite por pantalla
|
||||
virtual void render();
|
||||
virtual void render(); // Muestra el sprite por pantalla
|
||||
|
||||
// Obten el valor de la variable
|
||||
[[nodiscard]] auto getPosX() const -> int;
|
||||
[[nodiscard]] auto getPosX() const -> int; // Obten el valor de la variable
|
||||
[[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
|
||||
[[nodiscard]] auto getPosY() const -> int;
|
||||
void setPos(SDL_Rect rect); // Establece la posición del objeto
|
||||
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
|
||||
[[nodiscard]] auto getWidth() const -> int;
|
||||
auto getSpriteClip() -> SDL_Rect; // Obten 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); // Establece el valor de la variable
|
||||
|
||||
// Obten el valor de la variable
|
||||
[[nodiscard]] auto getHeight() const -> int;
|
||||
auto getTexture() -> Texture *; // Obten el valor de la variable
|
||||
void setTexture(Texture *texture); // Establece el valor de la variable
|
||||
|
||||
// Establece la posición del objeto
|
||||
void setPos(SDL_Rect rect);
|
||||
auto getRenderer() -> SDL_Renderer *; // Obten el valor de la variable
|
||||
void setRenderer(SDL_Renderer *renderer); // Establece el valor de la variable
|
||||
|
||||
// Establece el valor de la variable
|
||||
void setPosX(int x);
|
||||
virtual void setEnabled(bool value); // Establece el valor de la variable
|
||||
virtual auto isEnabled() -> bool; // Comprueba si el objeto está habilitado
|
||||
|
||||
// Establece el valor de la variable
|
||||
void setPosY(int y);
|
||||
virtual auto getRect() -> SDL_Rect; // Devuelve el rectangulo donde está el sprite
|
||||
virtual void setRect(SDL_Rect rect); // Establece los valores de posición y tamaño del sprite
|
||||
|
||||
// Establece el valor de la variable
|
||||
void setWidth(int w);
|
||||
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
|
||||
|
||||
// Establece el valor de la variable
|
||||
void setHeight(int h);
|
||||
SDL_Renderer *renderer_; // Puntero al renderizador de la ventana
|
||||
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
|
||||
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);
|
||||
};
|
||||
bool enabled_; // Indica si el sprite esta habilitado
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
#include "core/rendering/text.h"
|
||||
|
||||
#include <fstream> // for char_traits, basic_ostream, basic_ifstream, ope...
|
||||
#include <iostream> // for cout
|
||||
#include <sstream>
|
||||
|
||||
@@ -15,11 +14,11 @@ static void parseTextFileStream(std::istream &rfile, TextFile &tf) {
|
||||
std::string 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);
|
||||
tf.boxHeight = std::stoi(buffer);
|
||||
tf.box_height = std::stoi(buffer);
|
||||
|
||||
int index = 32;
|
||||
int line_read = 0;
|
||||
@@ -34,22 +33,22 @@ static void parseTextFileStream(std::istream &rfile, TextFile &tf) {
|
||||
|
||||
static void computeTextFileOffsets(TextFile &tf) {
|
||||
for (int i = 32; i < 128; ++i) {
|
||||
tf.offset[i].x = ((i - 32) % 15) * tf.boxWidth;
|
||||
tf.offset[i].y = ((i - 32) / 15) * tf.boxHeight;
|
||||
tf.offset[i].x = ((i - 32) % 15) * tf.box_width;
|
||||
tf.offset[i].y = ((i - 32) / 15) * tf.box_height;
|
||||
}
|
||||
}
|
||||
|
||||
// Llena una estructuta TextFile desde un fichero (vía ResourceHelper: pack o filesystem)
|
||||
auto LoadTextFile(const std::string &file, bool verbose) -> TextFile {
|
||||
const std::string filename = file.substr(file.find_last_of("\\/") + 1);
|
||||
auto loadTextFile(const std::string &file, bool verbose) -> TextFile {
|
||||
const std::string FILE_NAME = file.substr(file.find_last_of("\\/") + 1);
|
||||
auto bytes = ResourceHelper::loadFile(file);
|
||||
if (bytes.empty()) {
|
||||
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;
|
||||
tf.boxWidth = 0;
|
||||
tf.boxHeight = 0;
|
||||
tf.box_width = 0;
|
||||
tf.box_height = 0;
|
||||
for (auto &i : tf.offset) {
|
||||
i.x = 0;
|
||||
i.y = 0;
|
||||
@@ -59,16 +58,16 @@ auto LoadTextFile(const std::string &file, bool verbose) -> TextFile {
|
||||
return tf;
|
||||
}
|
||||
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
|
||||
auto LoadTextFileFromMemory(const std::vector<uint8_t> &bytes, bool verbose) -> TextFile {
|
||||
auto loadTextFileFromMemory(const std::vector<uint8_t> &bytes, bool verbose) -> TextFile {
|
||||
TextFile tf;
|
||||
tf.boxWidth = 0;
|
||||
tf.boxHeight = 0;
|
||||
tf.box_width = 0;
|
||||
tf.box_height = 0;
|
||||
for (auto &i : tf.offset) {
|
||||
i.x = 0;
|
||||
i.y = 0;
|
||||
@@ -87,91 +86,91 @@ auto LoadTextFileFromMemory(const std::vector<uint8_t> &bytes, bool verbose) ->
|
||||
}
|
||||
|
||||
// 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
|
||||
TextFile tf = LoadTextFile(textFile);
|
||||
TextFile tf = loadTextFile(text_file);
|
||||
|
||||
// Inicializa variables desde la estructura
|
||||
boxHeight = tf.boxHeight;
|
||||
boxWidth = tf.boxWidth;
|
||||
box_height_ = tf.box_height;
|
||||
box_width_ = tf.box_width;
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
offset[i].x = tf.offset[i].x;
|
||||
offset[i].y = tf.offset[i].y;
|
||||
offset[i].w = tf.offset[i].w;
|
||||
offset_[i].x = tf.offset[i].x;
|
||||
offset_[i].y = tf.offset[i].y;
|
||||
offset_[i].w = tf.offset[i].w;
|
||||
}
|
||||
|
||||
// Crea los objetos
|
||||
texture = new Texture(renderer, bitmapFile);
|
||||
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
|
||||
texture_ = new Texture(renderer, bitmap_file);
|
||||
sprite_ = new Sprite({0, 0, box_width_, box_height_}, texture_, renderer);
|
||||
|
||||
// Inicializa variables
|
||||
fixedWidth = false;
|
||||
fixed_width_ = false;
|
||||
}
|
||||
|
||||
// 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
|
||||
TextFile tf = LoadTextFile(textFile);
|
||||
TextFile tf = loadTextFile(text_file);
|
||||
|
||||
// Inicializa variables desde la estructura
|
||||
boxHeight = tf.boxHeight;
|
||||
boxWidth = tf.boxWidth;
|
||||
box_height_ = tf.box_height;
|
||||
box_width_ = tf.box_width;
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
offset[i].x = tf.offset[i].x;
|
||||
offset[i].y = tf.offset[i].y;
|
||||
offset[i].w = tf.offset[i].w;
|
||||
offset_[i].x = tf.offset[i].x;
|
||||
offset_[i].y = tf.offset[i].y;
|
||||
offset_[i].w = tf.offset[i].w;
|
||||
}
|
||||
|
||||
// Crea los objetos
|
||||
this->texture = nullptr;
|
||||
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
|
||||
this->texture_ = nullptr;
|
||||
sprite_ = new Sprite({0, 0, box_width_, box_height_}, texture, renderer);
|
||||
|
||||
// Inicializa variables
|
||||
fixedWidth = false;
|
||||
fixed_width_ = false;
|
||||
}
|
||||
|
||||
// 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
|
||||
boxHeight = textFile->boxHeight;
|
||||
boxWidth = textFile->boxWidth;
|
||||
box_height_ = text_file->box_height;
|
||||
box_width_ = text_file->box_width;
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
offset[i].x = textFile->offset[i].x;
|
||||
offset[i].y = textFile->offset[i].y;
|
||||
offset[i].w = textFile->offset[i].w;
|
||||
offset_[i].x = text_file->offset[i].x;
|
||||
offset_[i].y = text_file->offset[i].y;
|
||||
offset_[i].w = text_file->offset[i].w;
|
||||
}
|
||||
|
||||
// Crea los objetos
|
||||
this->texture = nullptr;
|
||||
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
|
||||
this->texture_ = nullptr;
|
||||
sprite_ = new Sprite({0, 0, box_width_, box_height_}, texture, renderer);
|
||||
|
||||
// Inicializa variables
|
||||
fixedWidth = false;
|
||||
fixed_width_ = false;
|
||||
}
|
||||
|
||||
// Constructor desde bytes
|
||||
Text::Text(const std::vector<uint8_t> &pngBytes, const std::vector<uint8_t> &txtBytes, SDL_Renderer *renderer) {
|
||||
TextFile tf = LoadTextFileFromMemory(txtBytes);
|
||||
boxHeight = tf.boxHeight;
|
||||
boxWidth = tf.boxWidth;
|
||||
Text::Text(const std::vector<uint8_t> &png_bytes, const std::vector<uint8_t> &txt_bytes, SDL_Renderer *renderer) {
|
||||
TextFile tf = loadTextFileFromMemory(txt_bytes);
|
||||
box_height_ = tf.box_height;
|
||||
box_width_ = tf.box_width;
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
offset[i].x = tf.offset[i].x;
|
||||
offset[i].y = tf.offset[i].y;
|
||||
offset[i].w = tf.offset[i].w;
|
||||
offset_[i].x = tf.offset[i].x;
|
||||
offset_[i].y = tf.offset[i].y;
|
||||
offset_[i].w = tf.offset[i].w;
|
||||
}
|
||||
|
||||
// Crea la textura desde bytes (Text es dueño en este overload)
|
||||
texture = new Texture(renderer, pngBytes);
|
||||
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
|
||||
texture_ = new Texture(renderer, png_bytes);
|
||||
sprite_ = new Sprite({0, 0, box_width_, box_height_}, texture_, renderer);
|
||||
|
||||
fixedWidth = false;
|
||||
fixed_width_ = false;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Text::~Text() {
|
||||
delete sprite;
|
||||
delete sprite_;
|
||||
|
||||
delete texture;
|
||||
delete texture_;
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
sprite->setPosY(y);
|
||||
const int width = sprite->getWidth();
|
||||
const int height = sprite->getHeight();
|
||||
sprite_->setPosY(y);
|
||||
const int WIDTH = sprite_->getWidth();
|
||||
const int HEIGHT = sprite_->getHeight();
|
||||
for (int i = 0; i < lenght; ++i) {
|
||||
const int index = static_cast<unsigned char>(text[i]);
|
||||
sprite->setSpriteClip(offset[index].x, offset[index].y, width, height);
|
||||
sprite->setPosX(x + shift);
|
||||
sprite->render();
|
||||
shift += fixedWidth ? boxWidth : (offset[index].w + kerning);
|
||||
const int INDEX = static_cast<unsigned char>(text[i]);
|
||||
sprite_->setSpriteClip(offset_[INDEX].x, offset_[INDEX].y, WIDTH, HEIGHT);
|
||||
sprite_->setPosX(x + shift);
|
||||
sprite_->render();
|
||||
shift += fixed_width_ ? box_width_ : (offset_[INDEX].w + kerning);
|
||||
}
|
||||
}
|
||||
|
||||
// Escribe el texto con colores
|
||||
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);
|
||||
sprite->getTexture()->setColor(255, 255, 255);
|
||||
sprite_->getTexture()->setColor(255, 255, 255);
|
||||
}
|
||||
|
||||
// Escribe el texto con sombra
|
||||
void Text::writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadowDistance, int kerning, int lenght) {
|
||||
sprite->getTexture()->setColor(color.r, color.g, color.b);
|
||||
write(x + shadowDistance, y + shadowDistance, text, kerning, lenght);
|
||||
sprite->getTexture()->setColor(255, 255, 255);
|
||||
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);
|
||||
write(x + shadow_distance, y + shadow_distance, text, kerning, lenght);
|
||||
sprite_->getTexture()->setColor(255, 255, 255);
|
||||
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
|
||||
void Text::writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning, Color textColor, Uint8 shadowDistance, Color shadowColor, int lenght) {
|
||||
const bool centered = ((flags & TXT_CENTER) == TXT_CENTER);
|
||||
const bool shadowed = ((flags & TXT_SHADOW) == TXT_SHADOW);
|
||||
const bool colored = ((flags & TXT_COLOR) == TXT_COLOR);
|
||||
const bool stroked = ((flags & TXT_STROKE) == TXT_STROKE);
|
||||
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 SHADOWED = ((flags & TXT_SHADOW) == TXT_SHADOW);
|
||||
const bool COLORED = ((flags & TXT_COLOR) == TXT_COLOR);
|
||||
const bool STROKED = ((flags & TXT_STROKE) == TXT_STROKE);
|
||||
|
||||
if (centered) {
|
||||
if (CENTERED) {
|
||||
x -= (Text::lenght(text, kerning) / 2);
|
||||
}
|
||||
|
||||
if (shadowed) {
|
||||
writeColored(x + shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght);
|
||||
if (SHADOWED) {
|
||||
writeColored(x + shadow_distance, y + shadow_distance, text, shadow_color, kerning, lenght);
|
||||
}
|
||||
|
||||
if (stroked) {
|
||||
for (int dist = 1; dist <= shadowDistance; ++dist) {
|
||||
if (STROKED) {
|
||||
for (int dist = 1; dist <= shadow_distance; ++dist) {
|
||||
for (int dy = -dist; dy <= dist; ++dy) {
|
||||
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) {
|
||||
writeColored(x, y, text, textColor, kerning, lenght);
|
||||
if (COLORED) {
|
||||
writeColored(x, y, text, text_color, kerning, lenght);
|
||||
} else {
|
||||
write(x, y, text, kerning, lenght);
|
||||
}
|
||||
@@ -252,7 +251,7 @@ auto Text::lenght(const std::string &text, int kerning) -> int {
|
||||
int shift = 0;
|
||||
|
||||
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
|
||||
@@ -261,15 +260,15 @@ auto Text::lenght(const std::string &text, int kerning) -> int {
|
||||
|
||||
// Devuelve el valor de la variable
|
||||
auto Text::getCharacterSize() const -> int {
|
||||
return boxWidth;
|
||||
return box_width_;
|
||||
}
|
||||
|
||||
// Recarga la textura
|
||||
void Text::reLoadTexture() {
|
||||
sprite->getTexture()->reLoad();
|
||||
sprite_->getTexture()->reLoad();
|
||||
}
|
||||
|
||||
// Establece si se usa un tamaño fijo de letra
|
||||
void Text::setFixedWidth(bool value) {
|
||||
fixedWidth = value;
|
||||
fixed_width_ = value;
|
||||
}
|
||||
@@ -22,70 +22,52 @@ struct Offset {
|
||||
};
|
||||
|
||||
struct TextFile {
|
||||
int boxWidth; // Anchura de la caja de cada caracter en el png
|
||||
int boxHeight; // Altura de la caja de cada caracter en el png
|
||||
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
|
||||
Offset offset[128]; // Vector con las posiciones y ancho de cada letra
|
||||
};
|
||||
|
||||
// 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
|
||||
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
|
||||
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:
|
||||
// Constructor
|
||||
Text(const std::string &bitmapFile, const std::string &textFile, SDL_Renderer *renderer);
|
||||
Text(const std::string &textFile, Texture *texture, SDL_Renderer *renderer);
|
||||
Text(TextFile *textFile, Texture *texture, SDL_Renderer *renderer);
|
||||
Text(const std::string &bitmap_file, const std::string &text_file, SDL_Renderer *renderer); // Constructor
|
||||
Text(const std::string &text_file, Texture *texture, SDL_Renderer *renderer);
|
||||
Text(TextFile *text_file, 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(const std::vector<uint8_t> &pngBytes, const std::vector<uint8_t> &txtBytes, SDL_Renderer *renderer);
|
||||
|
||||
// Destructor
|
||||
~Text();
|
||||
~Text(); // Destructor
|
||||
|
||||
// No copiable (gestiona memoria dinámica)
|
||||
Text(const 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);
|
||||
void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla
|
||||
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
|
||||
void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1);
|
||||
auto lenght(const std::string &text, int kerning = 1) -> int; // Obtiene la longitud en pixels de una cadena
|
||||
|
||||
// Escribe el texto con sombra
|
||||
void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1);
|
||||
[[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el valor de la variable
|
||||
|
||||
// Escribe el texto centrado en un punto x
|
||||
void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1);
|
||||
void reLoadTexture(); // Recarga la textura
|
||||
void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra
|
||||
|
||||
// Escribe texto con extras
|
||||
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);
|
||||
private:
|
||||
// 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
|
||||
auto lenght(const std::string &text, int kerning = 1) -> int;
|
||||
|
||||
// Devuelve el valor de la variable
|
||||
[[nodiscard]] auto getCharacterSize() const -> int;
|
||||
|
||||
// Recarga la textura
|
||||
void reLoadTexture();
|
||||
|
||||
// Establece si se usa un tamaño fijo de letra
|
||||
void setFixedWidth(bool value);
|
||||
// Variables
|
||||
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
|
||||
bool fixed_width_; // 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
|
||||
};
|
||||
|
||||
@@ -9,19 +9,19 @@
|
||||
#include "core/resources/resource_helper.h" // for loadFile (pack + filesystem fallback)
|
||||
#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) {
|
||||
currentScaleMode = mode;
|
||||
current_scale_mode = mode;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Texture::Texture(SDL_Renderer *renderer, const std::string &path, bool verbose)
|
||||
: texture(nullptr),
|
||||
renderer(renderer),
|
||||
width(0),
|
||||
height(0),
|
||||
path(path) {
|
||||
: texture_(nullptr),
|
||||
renderer_(renderer),
|
||||
width_(0),
|
||||
height_(0),
|
||||
path_(path) {
|
||||
// Carga el fichero en la textura
|
||||
if (!path.empty()) {
|
||||
loadFromFile(path, renderer, verbose);
|
||||
@@ -30,10 +30,10 @@ Texture::Texture(SDL_Renderer *renderer, const std::string &path, bool verbose)
|
||||
|
||||
// Constructor desde bytes
|
||||
Texture::Texture(SDL_Renderer *renderer, const std::vector<uint8_t> &bytes, bool verbose)
|
||||
: texture(nullptr),
|
||||
renderer(renderer),
|
||||
width(0),
|
||||
height(0) {
|
||||
: texture_(nullptr),
|
||||
renderer_(renderer),
|
||||
width_(0),
|
||||
height_(0) {
|
||||
if (!bytes.empty()) {
|
||||
loadFromMemory(bytes.data(), bytes.size(), renderer, verbose);
|
||||
}
|
||||
@@ -47,24 +47,24 @@ Texture::~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 * {
|
||||
const int pitch = 4 * w;
|
||||
SDL_Surface *loadedSurface = SDL_CreateSurfaceFrom(w, h, SDL_PIXELFORMAT_RGBA32, static_cast<void *>(data), pitch);
|
||||
if (loadedSurface == nullptr) {
|
||||
const int PITCH = 4 * w;
|
||||
SDL_Surface *loaded_surface = SDL_CreateSurfaceFrom(w, h, SDL_PIXELFORMAT_RGBA32, static_cast<void *>(data), PITCH);
|
||||
if (loaded_surface == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
SDL_Texture *newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
|
||||
if (newTexture != nullptr) {
|
||||
*out_w = loadedSurface->w;
|
||||
*out_h = loadedSurface->h;
|
||||
SDL_SetTextureScaleMode(newTexture, Texture::currentScaleMode);
|
||||
SDL_Texture *new_texture = SDL_CreateTextureFromSurface(renderer, loaded_surface);
|
||||
if (new_texture != nullptr) {
|
||||
*out_w = loaded_surface->w;
|
||||
*out_h = loaded_surface->h;
|
||||
SDL_SetTextureScaleMode(new_texture, Texture::current_scale_mode);
|
||||
}
|
||||
SDL_DestroySurface(loadedSurface);
|
||||
return newTexture;
|
||||
SDL_DestroySurface(loaded_surface);
|
||||
return new_texture;
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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);
|
||||
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());
|
||||
exit(1);
|
||||
} else if (verbose) {
|
||||
std::cout << "Image loaded: " << filename.c_str() << '\n';
|
||||
std::cout << "Image loaded: " << FILE_NAME.c_str() << '\n';
|
||||
}
|
||||
|
||||
unload();
|
||||
SDL_Texture *newTexture = createTextureFromPixels(renderer, data, w, h, &this->width, &this->height);
|
||||
if (newTexture == nullptr && verbose) {
|
||||
SDL_Texture *new_texture = createTextureFromPixels(renderer, data, w, h, &this->width_, &this->height_);
|
||||
if (new_texture == nullptr && verbose) {
|
||||
std::cout << "Unable to load image " << path.c_str() << '\n';
|
||||
}
|
||||
|
||||
stbi_image_free(data);
|
||||
texture = newTexture;
|
||||
return texture != nullptr;
|
||||
texture_ = new_texture;
|
||||
return texture_ != nullptr;
|
||||
}
|
||||
|
||||
// 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();
|
||||
SDL_Texture *newTexture = createTextureFromPixels(renderer, pixels, w, h, &this->width, &this->height);
|
||||
if (newTexture == nullptr && verbose) {
|
||||
SDL_Texture *new_texture = createTextureFromPixels(renderer, pixels, w, h, &this->width_, &this->height_);
|
||||
if (new_texture == nullptr && verbose) {
|
||||
std::cout << "Unable to create texture from memory" << '\n';
|
||||
}
|
||||
|
||||
stbi_image_free(pixels);
|
||||
texture = newTexture;
|
||||
return texture != nullptr;
|
||||
texture_ = new_texture;
|
||||
return texture_ != nullptr;
|
||||
}
|
||||
|
||||
// Crea una textura en blanco
|
||||
auto Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) -> bool {
|
||||
// Crea una textura sin inicializar
|
||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
|
||||
if (texture == nullptr) {
|
||||
texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
|
||||
if (texture_ == nullptr) {
|
||||
std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << '\n';
|
||||
} else {
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
SDL_SetTextureScaleMode(texture, currentScaleMode);
|
||||
this->width_ = width;
|
||||
this->height_ = height;
|
||||
SDL_SetTextureScaleMode(texture_, current_scale_mode);
|
||||
}
|
||||
|
||||
return texture != nullptr;
|
||||
return texture_ != nullptr;
|
||||
}
|
||||
|
||||
// Libera la memoria de la textura
|
||||
void Texture::unload() {
|
||||
// Libera la textura si existe
|
||||
if (texture != nullptr) {
|
||||
SDL_DestroyTexture(texture);
|
||||
texture = nullptr;
|
||||
width = 0;
|
||||
height = 0;
|
||||
if (texture_ != nullptr) {
|
||||
SDL_DestroyTexture(texture_);
|
||||
texture_ = nullptr;
|
||||
width_ = 0;
|
||||
height_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Establece el color para la modulacion
|
||||
void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue) {
|
||||
SDL_SetTextureColorMod(texture, red, green, blue);
|
||||
SDL_SetTextureColorMod(texture_, red, green, blue);
|
||||
}
|
||||
|
||||
// Establece el blending
|
||||
void Texture::setBlendMode(SDL_BlendMode blending) {
|
||||
SDL_SetTextureBlendMode(texture, blending);
|
||||
SDL_SetTextureBlendMode(texture_, blending);
|
||||
}
|
||||
|
||||
// Establece el alpha para la modulación
|
||||
void Texture::setAlpha(Uint8 alpha) {
|
||||
SDL_SetTextureAlphaMod(texture, alpha);
|
||||
SDL_SetTextureAlphaMod(texture_, alpha);
|
||||
}
|
||||
|
||||
// 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
|
||||
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
|
||||
if (clip != nullptr) {
|
||||
renderQuad.w = (float)clip->w;
|
||||
renderQuad.h = (float)clip->h;
|
||||
render_quad.w = (float)clip->w;
|
||||
render_quad.h = (float)clip->h;
|
||||
}
|
||||
|
||||
renderQuad.w = renderQuad.w * zoomW;
|
||||
renderQuad.h = renderQuad.h * zoomH;
|
||||
render_quad.w = render_quad.w * zoom_w;
|
||||
render_quad.h = render_quad.h * zoom_h;
|
||||
|
||||
// Convierte el clip a SDL_FRect
|
||||
SDL_FRect srcRect;
|
||||
SDL_FRect *srcRectPtr = nullptr;
|
||||
SDL_FRect src_rect;
|
||||
SDL_FRect *src_rect_ptr = nullptr;
|
||||
if (clip != nullptr) {
|
||||
srcRect = {.x = (float)clip->x, .y = (float)clip->y, .w = (float)clip->w, .h = (float)clip->h};
|
||||
srcRectPtr = &srcRect;
|
||||
src_rect = {.x = (float)clip->x, .y = (float)clip->y, .w = (float)clip->w, .h = (float)clip->h};
|
||||
src_rect_ptr = &src_rect;
|
||||
}
|
||||
|
||||
// Convierte el centro a SDL_FPoint
|
||||
SDL_FPoint fCenter;
|
||||
SDL_FPoint *fCenterPtr = nullptr;
|
||||
SDL_FPoint f_center;
|
||||
SDL_FPoint *f_center_ptr = nullptr;
|
||||
if (center != nullptr) {
|
||||
fCenter = {.x = (float)center->x, .y = (float)center->y};
|
||||
fCenterPtr = &fCenter;
|
||||
f_center = {.x = (float)center->x, .y = (float)center->y};
|
||||
f_center_ptr = &f_center;
|
||||
}
|
||||
|
||||
// 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
|
||||
void Texture::setAsRenderTarget(SDL_Renderer *renderer) {
|
||||
SDL_SetRenderTarget(renderer, texture);
|
||||
SDL_SetRenderTarget(renderer, texture_);
|
||||
}
|
||||
|
||||
// Obtiene el ancho de la imagen
|
||||
auto Texture::getWidth() const -> int {
|
||||
return width;
|
||||
return width_;
|
||||
}
|
||||
|
||||
// Obtiene el alto de la imagen
|
||||
auto Texture::getHeight() const -> int {
|
||||
return height;
|
||||
return height_;
|
||||
}
|
||||
|
||||
// Recarga la textura
|
||||
auto Texture::reLoad() -> bool {
|
||||
return loadFromFile(path, renderer);
|
||||
return loadFromFile(path_, renderer_);
|
||||
}
|
||||
|
||||
// Obtiene la textura
|
||||
auto Texture::getSDLTexture() -> SDL_Texture * {
|
||||
return texture;
|
||||
return texture_;
|
||||
}
|
||||
@@ -7,67 +7,40 @@
|
||||
#include <vector>
|
||||
|
||||
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:
|
||||
// Objetos y punteros
|
||||
SDL_Texture *texture; // La textura
|
||||
SDL_Renderer *renderer; // Renderizador donde dibujar la textura
|
||||
SDL_Texture *texture_; // La textura
|
||||
SDL_Renderer *renderer_; // Renderizador donde dibujar la textura
|
||||
|
||||
// Variables
|
||||
int width; // Ancho de la imagen
|
||||
int height; // Alto de la imagen
|
||||
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 *;
|
||||
int width_; // Ancho de la imagen
|
||||
int height_; // Alto de la imagen
|
||||
std::string path_; // Ruta de la imagen de la textura
|
||||
};
|
||||
|
||||
@@ -4,32 +4,32 @@
|
||||
|
||||
// Constructor
|
||||
Writer::Writer(Text *text)
|
||||
: text(text) {
|
||||
: text_(text) {
|
||||
}
|
||||
|
||||
// Actualiza el objeto
|
||||
void Writer::update() {
|
||||
if (enabled) {
|
||||
if (!completed) { // No completado
|
||||
if (writingCounter > 0) {
|
||||
writingCounter--;
|
||||
if (enabled_) {
|
||||
if (!completed_) { // No completado
|
||||
if (writing_counter_ > 0) {
|
||||
writing_counter_--;
|
||||
}
|
||||
|
||||
else if (writingCounter == 0) {
|
||||
index++;
|
||||
writingCounter = speed;
|
||||
else if (writing_counter_ == 0) {
|
||||
index_++;
|
||||
writing_counter_ = speed_;
|
||||
}
|
||||
|
||||
if (index == lenght) {
|
||||
completed = true;
|
||||
if (index_ == length_) {
|
||||
completed_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (completed) { // Completado
|
||||
if (enabledCounter > 0) {
|
||||
enabledCounter--;
|
||||
} else if (enabledCounter == 0) {
|
||||
finished = true;
|
||||
if (completed_) { // Completado
|
||||
if (enabled_counter_ > 0) {
|
||||
enabled_counter_--;
|
||||
} else if (enabled_counter_ == 0) {
|
||||
finished_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,64 +37,64 @@ void Writer::update() {
|
||||
|
||||
// Dibuja el objeto en pantalla
|
||||
void Writer::render() {
|
||||
if (enabled) {
|
||||
text->write(posX, posY, caption, kerning, index);
|
||||
if (enabled_) {
|
||||
text_->write(pos_x_, pos_y_, caption_, kerning_, index_);
|
||||
}
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Writer::setPosX(int value) {
|
||||
posX = value;
|
||||
pos_x_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Writer::setPosY(int value) {
|
||||
posY = value;
|
||||
pos_y_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Writer::setKerning(int value) {
|
||||
kerning = value;
|
||||
kerning_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Writer::setCaption(const std::string &text) {
|
||||
caption = text;
|
||||
lenght = text.length();
|
||||
caption_ = text;
|
||||
length_ = text.length();
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Writer::setSpeed(int value) {
|
||||
speed = value;
|
||||
writingCounter = value;
|
||||
speed_ = value;
|
||||
writing_counter_ = value;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Writer::setEnabled(bool value) {
|
||||
enabled = value;
|
||||
enabled_ = value;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto Writer::IsEnabled() const -> bool {
|
||||
return enabled;
|
||||
auto Writer::isEnabled() const -> bool {
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Writer::setEnabledCounter(int time) {
|
||||
enabledCounter = time;
|
||||
enabled_counter_ = time;
|
||||
}
|
||||
|
||||
// Obtiene el valor de la variable
|
||||
auto Writer::getEnabledCounter() const -> int {
|
||||
return enabledCounter;
|
||||
return enabled_counter_;
|
||||
}
|
||||
|
||||
// Centra la cadena de texto a un punto 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
|
||||
auto Writer::hasFinished() const -> bool {
|
||||
return finished;
|
||||
return finished_;
|
||||
}
|
||||
@@ -5,64 +5,41 @@ class Text;
|
||||
|
||||
// Clase Writer. Pinta texto en pantalla letra a letra a partir de una cadena y un bitmap
|
||||
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:
|
||||
// Objetos y punteros
|
||||
Text *text; // Objeto encargado de escribir el texto
|
||||
Text *text_; // Objeto encargado de escribir el texto
|
||||
|
||||
// Variables
|
||||
int posX{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 kerning{0}; // Kerning del texto, es decir, espaciado entre caracteres
|
||||
std::string caption; // El texto para escribir
|
||||
int speed{0}; // Velocidad de escritura
|
||||
int writingCounter{0}; // Temporizador de escritura para cada caracter
|
||||
int index{0}; // Posición del texto que se está escribiendo
|
||||
int lenght{0}; // Longitud de la cadena a escribir
|
||||
bool completed{false}; // Indica si se ha escrito todo el texto
|
||||
bool enabled{false}; // Indica si el objeto está habilitado
|
||||
int enabledCounter{0}; // Temporizador para deshabilitar el objeto
|
||||
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;
|
||||
int pos_x_{0}; // Posicion en el eje X 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
|
||||
std::string caption_; // El texto para escribir
|
||||
int speed_{0}; // Velocidad de escritura
|
||||
int writing_counter_{0}; // Temporizador de escritura para cada caracter
|
||||
int index_{0}; // Posición del texto que se está escribiendo
|
||||
int length_{0}; // Longitud de la cadena a escribir
|
||||
bool completed_{false}; // Indica si se ha escrito todo el texto
|
||||
bool enabled_{false}; // Indica si el objeto está habilitado
|
||||
int enabled_counter_{0}; // Temporizador para deshabilitar el objeto
|
||||
bool finished_{false}; // Indica si ya ha terminado
|
||||
};
|
||||
|
||||
@@ -26,24 +26,24 @@ auto Asset::get() -> Asset * {
|
||||
|
||||
// Constructor
|
||||
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
|
||||
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;
|
||||
temp.file = absolute ? file : executablePath + file;
|
||||
temp.file = absolute ? file : executable_path_ + file;
|
||||
temp.type = type;
|
||||
temp.required = required;
|
||||
fileList.push_back(temp);
|
||||
file_list_.push_back(temp);
|
||||
|
||||
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
|
||||
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 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';
|
||||
}
|
||||
return "";
|
||||
@@ -62,32 +62,34 @@ auto Asset::get(const std::string &text) -> std::string {
|
||||
auto Asset::check() -> bool {
|
||||
bool success = true;
|
||||
|
||||
if (verbose) {
|
||||
if (verbose_) {
|
||||
std::cout << "\n** Checking files" << '\n';
|
||||
|
||||
std::cout << "Executable path is: " << executablePath << '\n';
|
||||
std::cout << "Sample filepath: " << fileList.back().file << '\n';
|
||||
std::cout << "Executable path is: " << executable_path_ << '\n';
|
||||
std::cout << "Sample filepath: " << file_list_.back().file << '\n';
|
||||
}
|
||||
|
||||
// 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
|
||||
bool any = false;
|
||||
|
||||
for (const auto &f : fileList) {
|
||||
if ((f.required) && (f.type == type)) {
|
||||
for (const auto &f : file_list_) {
|
||||
if (f.required && f.type == TYPE) {
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Si hay ficheros de ese tipo, comprueba si existen
|
||||
if (any) {
|
||||
if (verbose) {
|
||||
std::cout << "\n>> " << getTypeName(type).c_str() << " FILES" << '\n';
|
||||
if (verbose_) {
|
||||
std::cout << "\n>> " << getTypeName(TYPE).c_str() << " FILES" << '\n';
|
||||
}
|
||||
|
||||
for (const auto &f : fileList) {
|
||||
if ((f.required) && (f.type == type)) {
|
||||
for (const auto &f : file_list_) {
|
||||
if (f.required && f.type == TYPE) {
|
||||
success &= checkFile(f.file);
|
||||
}
|
||||
}
|
||||
@@ -95,7 +97,7 @@ auto Asset::check() -> bool {
|
||||
}
|
||||
|
||||
// Resultado
|
||||
if (verbose) {
|
||||
if (verbose_) {
|
||||
if (success) {
|
||||
std::cout << "\n** All files OK.\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 << "Checking file: ";
|
||||
std::cout.width(longestName + 2);
|
||||
std::cout.width(longest_name_ + 2);
|
||||
std::cout.fill('.');
|
||||
std::cout << filename + " ";
|
||||
std::cout << " [" + result + "]" << '\n';
|
||||
@@ -143,51 +145,23 @@ auto Asset::checkFile(const std::string &path) const -> bool {
|
||||
}
|
||||
|
||||
// Devuelve el nombre del tipo de recurso
|
||||
auto Asset::getTypeName(int type) -> std::string {
|
||||
auto Asset::getTypeName(Type type) -> std::string {
|
||||
switch (type) {
|
||||
case t_bitmap:
|
||||
return "BITMAP";
|
||||
break;
|
||||
|
||||
case t_music:
|
||||
return "MUSIC";
|
||||
break;
|
||||
|
||||
case t_sound:
|
||||
return "SOUND";
|
||||
break;
|
||||
|
||||
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;
|
||||
case Type::BITMAP: return "BITMAP";
|
||||
case Type::MUSIC: return "MUSIC";
|
||||
case Type::SOUND: return "SOUND";
|
||||
case Type::FONT: return "FONT";
|
||||
case Type::LANG: return "LANG";
|
||||
case Type::DATA: return "DATA";
|
||||
case Type::ROOM: return "ROOM";
|
||||
case Type::ENEMY: return "ENEMY";
|
||||
case Type::ITEM: return "ITEM";
|
||||
case Type::COUNT:
|
||||
default: return "ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
// Establece si ha de mostrar texto por pantalla
|
||||
void Asset::setVerbose(bool value) {
|
||||
verbose = value;
|
||||
verbose_ = value;
|
||||
}
|
||||
@@ -4,66 +4,52 @@
|
||||
#include <string> // for string, basic_string
|
||||
#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
|
||||
class Asset {
|
||||
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
|
||||
struct Item {
|
||||
std::string file; // Ruta del fichero desde la raiz del directorio
|
||||
enum AssetType type; // Indica el tipo de recurso
|
||||
bool required; // Indica si es un fichero que debe de existir
|
||||
std::string file; // Ruta del fichero desde la raiz del directorio
|
||||
Type type; // Indica el tipo de recurso
|
||||
bool required; // Indica si es un fichero que debe de existir
|
||||
};
|
||||
|
||||
// Singleton API
|
||||
static void init(const std::string &executable_path); // Crea la instancia
|
||||
static void destroy(); // Libera la instancia
|
||||
static auto get() -> Asset *; // Obtiene el puntero a la instancia
|
||||
|
||||
void add(const std::string &file, Type type, bool required = true, bool absolute = false); // Añade un elemento a la lista
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
// Comprueba que existe un fichero
|
||||
[[nodiscard]] auto checkFile(const std::string &executablePath) const -> bool;
|
||||
static Asset *instance; // Instancia única
|
||||
|
||||
// Devuelve el nombre del tipo de recurso
|
||||
static auto getTypeName(int type) -> std::string;
|
||||
explicit Asset(const std::string &path); // Constructor privado (usar Asset::init)
|
||||
|
||||
// Constructor privado (usar Asset::init)
|
||||
explicit Asset(const std::string &path);
|
||||
|
||||
// Instancia única
|
||||
static Asset *instance;
|
||||
|
||||
public:
|
||||
// Singleton API
|
||||
static void init(const std::string &executablePath); // Crea la instancia
|
||||
static void destroy(); // Libera 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, enum AssetType type, bool required = true, bool absolute = false);
|
||||
|
||||
// Devuelve un elemento de la lista a partir de una cadena
|
||||
auto get(const std::string &text) -> std::string;
|
||||
|
||||
// Devuelve toda la lista de items registrados
|
||||
[[nodiscard]] auto getAll() const -> const std::vector<Item> & { return fileList; }
|
||||
|
||||
// Comprueba que existen todos los elementos
|
||||
auto check() -> bool;
|
||||
|
||||
// Establece si ha de mostrar texto por pantalla
|
||||
void setVerbose(bool value);
|
||||
[[nodiscard]] auto checkFile(const std::string &executable_path) const -> bool; // Comprueba que existe un fichero
|
||||
static auto getTypeName(Type type) -> std::string; // Devuelve el nombre del tipo de recurso
|
||||
};
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "core/resources/resource.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
@@ -15,7 +13,7 @@
|
||||
// Nota: Asset::get() e Input::get() se consultan en preloadAll y al construir
|
||||
// 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 {
|
||||
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) {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new Resource(renderer);
|
||||
instance_->preloadAll();
|
||||
if (instance == nullptr) {
|
||||
instance = new Resource(renderer);
|
||||
instance->preloadAll();
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::destroy() {
|
||||
delete instance_;
|
||||
instance_ = nullptr;
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
auto Resource::get() -> Resource * {
|
||||
return instance_;
|
||||
return instance;
|
||||
}
|
||||
|
||||
Resource::Resource(SDL_Renderer *renderer)
|
||||
@@ -77,11 +75,17 @@ Resource::~Resource() {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
// Pass 1: texturas, sonidos, músicas, animaciones (raw lines), demo, lenguajes
|
||||
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
|
||||
continue;
|
||||
}
|
||||
@@ -90,97 +94,108 @@ void Resource::preloadAll() {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string bname = basename(it.file);
|
||||
const std::string BASE_NAME = basename(it.file);
|
||||
|
||||
switch (it.type) {
|
||||
case t_bitmap: {
|
||||
case Asset::Type::BITMAP: {
|
||||
auto *tex = new Texture(renderer_, bytes);
|
||||
textures_[bname] = tex;
|
||||
textures_[BASE_NAME] = tex;
|
||||
break;
|
||||
}
|
||||
case t_sound: {
|
||||
case Asset::Type::SOUND: {
|
||||
JA_Sound_t *s = JA_LoadSound(bytes.data(), (uint32_t)bytes.size());
|
||||
if (s != nullptr) {
|
||||
sounds_[bname] = s;
|
||||
sounds_[BASE_NAME] = s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case t_music: {
|
||||
case Asset::Type::MUSIC: {
|
||||
JA_Music_t *m = JA_LoadMusic(bytes.data(), (Uint32)bytes.size());
|
||||
if (m != nullptr) {
|
||||
musics_[bname] = m;
|
||||
musics_[BASE_NAME] = m;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case t_data: {
|
||||
if (bname.size() >= 4 && bname.substr(bname.size() - 4) == ".ani") {
|
||||
std::string content(reinterpret_cast<const char *>(bytes.data()), bytes.size());
|
||||
std::stringstream ss(content);
|
||||
std::vector<std::string> lines;
|
||||
std::string line;
|
||||
while (std::getline(ss, line)) {
|
||||
// Normalitza CRLF perquè loadFromVector compari línies amb literals
|
||||
// ("[animation]", "[/animation]") sense \r residual.
|
||||
if (!line.empty() && line.back() == '\r') {
|
||||
line.pop_back();
|
||||
}
|
||||
lines.push_back(line);
|
||||
}
|
||||
animationLines_[bname] = std::move(lines);
|
||||
} else if (bname == "demo.bin") {
|
||||
demoBytes_ = 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
|
||||
}
|
||||
case Asset::Type::DATA:
|
||||
loadDataAsset(BASE_NAME, bytes);
|
||||
break;
|
||||
}
|
||||
case t_font: // Fonts: se emparejan en pass 2
|
||||
case t_lang: // Lenguaje: lo sigue leyendo la clase Lang via ResourceHelper
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pass 2: Text (fuentes emparejadas png+txt) y Menus (dependen de Text+sonidos)
|
||||
// Fuentes: construimos un Text por cada par basename.png + basename.txt
|
||||
// Acumulamos los bytes encontrados por stem (basename sin ext.)
|
||||
std::unordered_map<std::string, std::vector<uint8_t>> fontPngs;
|
||||
std::unordered_map<std::string, std::vector<uint8_t>> fontTxts;
|
||||
// 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") {
|
||||
std::string content(reinterpret_cast<const char *>(bytes.data()), bytes.size());
|
||||
std::stringstream ss(content);
|
||||
std::vector<std::string> lines;
|
||||
std::string line;
|
||||
while (std::getline(ss, line)) {
|
||||
// Normalitza CRLF perquè loadFromVector compari línies amb literals
|
||||
// ("[animation]", "[/animation]") sense \r residual.
|
||||
if (!line.empty() && line.back() == '\r') {
|
||||
line.pop_back();
|
||||
}
|
||||
lines.push_back(line);
|
||||
}
|
||||
animation_lines_[bname] = std::move(lines);
|
||||
} else if (bname == "demo.bin") {
|
||||
demo_bytes_ = bytes;
|
||||
}
|
||||
// Menús (.men): se construyen en pass 2 porque dependen de textos y sonidos
|
||||
}
|
||||
|
||||
// Pass 2a: construye Text por cada par basename.png + basename.txt
|
||||
void Resource::preloadFonts() {
|
||||
const auto &items = Asset::get()->getAll();
|
||||
|
||||
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) {
|
||||
if (it.type != t_font) {
|
||||
if (it.type != Asset::Type::FONT) {
|
||||
continue;
|
||||
}
|
||||
auto bytes = ResourceHelper::loadFile(it.file);
|
||||
if (bytes.empty()) {
|
||||
continue;
|
||||
}
|
||||
const std::string s = stem(it.file);
|
||||
const std::string bname = basename(it.file);
|
||||
if (bname.size() >= 4 && bname.substr(bname.size() - 4) == ".png") {
|
||||
fontPngs[s] = std::move(bytes);
|
||||
} else if (bname.size() >= 4 && bname.substr(bname.size() - 4) == ".txt") {
|
||||
fontTxts[s] = std::move(bytes);
|
||||
const std::string S = stem(it.file);
|
||||
const std::string BASE_NAME = basename(it.file);
|
||||
if (BASE_NAME.size() >= 4 && BASE_NAME.substr(BASE_NAME.size() - 4) == ".png") {
|
||||
font_pngs[S] = std::move(bytes);
|
||||
} else if (BASE_NAME.size() >= 4 && BASE_NAME.substr(BASE_NAME.size() - 4) == ".txt") {
|
||||
font_txts[S] = std::move(bytes);
|
||||
}
|
||||
}
|
||||
for (const auto &[s, png] : fontPngs) {
|
||||
auto itTxt = fontTxts.find(s);
|
||||
if (itTxt == fontTxts.end()) {
|
||||
for (const auto &[s, png] : font_pngs) {
|
||||
auto it_txt = font_txts.find(s);
|
||||
if (it_txt == font_txts.end()) {
|
||||
continue;
|
||||
}
|
||||
Text *t = new Text(png, itTxt->second, renderer_);
|
||||
Text *t = new Text(png, it_txt->second, renderer_);
|
||||
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) {
|
||||
if (it.type != t_data) {
|
||||
if (it.type != Asset::Type::DATA) {
|
||||
continue;
|
||||
}
|
||||
const std::string bname = basename(it.file);
|
||||
if (bname.size() < 4 || bname.substr(bname.size() - 4) != ".men") {
|
||||
const std::string BASE_NAME = basename(it.file);
|
||||
if (BASE_NAME.size() < 4 || BASE_NAME.substr(BASE_NAME.size() - 4) != ".men") {
|
||||
continue;
|
||||
}
|
||||
auto bytes = ResourceHelper::loadFile(it.file);
|
||||
@@ -188,9 +203,9 @@ void Resource::preloadAll() {
|
||||
continue;
|
||||
}
|
||||
Menu *m = new Menu(renderer_, "");
|
||||
m->loadFromBytes(bytes, bname);
|
||||
const std::string s = stem(it.file);
|
||||
menus_[s] = m;
|
||||
m->loadFromBytes(bytes, BASE_NAME);
|
||||
const std::string S = stem(it.file);
|
||||
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 it = animationLines_.find(name);
|
||||
if (it == animationLines_.end()) {
|
||||
static std::vector<std::string> empty;
|
||||
auto it = animation_lines_.find(name);
|
||||
if (it == animation_lines_.end()) {
|
||||
static std::vector<std::string> empty_;
|
||||
std::cerr << "Resource::getAnimationLines: missing " << name << '\n';
|
||||
return empty;
|
||||
return empty_;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class Resource {
|
||||
auto getAnimationLines(const std::string &name) -> std::vector<std::string> &;
|
||||
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 getDemoBytes() const -> const std::vector<uint8_t> & { return demoBytes_; }
|
||||
auto getDemoBytes() const -> const std::vector<uint8_t> & { return demo_bytes_; }
|
||||
|
||||
private:
|
||||
explicit Resource(SDL_Renderer *renderer);
|
||||
@@ -35,15 +35,21 @@ class Resource {
|
||||
|
||||
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_;
|
||||
|
||||
std::unordered_map<std::string, Texture *> textures_;
|
||||
std::unordered_map<std::string, JA_Sound_t *> sounds_;
|
||||
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, Menu *> menus_;
|
||||
std::vector<uint8_t> demoBytes_;
|
||||
std::vector<uint8_t> demo_bytes_;
|
||||
|
||||
static Resource *instance_;
|
||||
static Resource *instance;
|
||||
};
|
||||
|
||||
+118
-120
@@ -12,19 +12,17 @@
|
||||
|
||||
#include <cstdlib> // for exit, EXIT_FAILURE, srand
|
||||
#include <filesystem>
|
||||
#include <fstream> // for basic_ostream, operator<<, basi...
|
||||
#include <iostream> // for cout
|
||||
#include <memory>
|
||||
#include <string> // for basic_string, operator+, char_t...
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "core/audio/audio.hpp" // for Audio::init, Audio::destroy
|
||||
#include "core/input/input.h" // for Input, InputAction, INPUT_USE_GAME...
|
||||
#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/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_helper.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.
|
||||
{
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
const bool enable_fallback = true;
|
||||
const bool ENABLE_FALLBACK = true;
|
||||
#elif defined(RELEASE_BUILD)
|
||||
const bool enable_fallback = false;
|
||||
const bool ENABLE_FALLBACK = false;
|
||||
#else
|
||||
const bool enable_fallback = true;
|
||||
const bool ENABLE_FALLBACK = true;
|
||||
#endif
|
||||
#ifdef MACOS_BUNDLE
|
||||
const std::string pack_path = executablePath + "../Resources/resources.pack";
|
||||
const std::string PACK_PATH = executablePath + "../Resources/resources.pack";
|
||||
#else
|
||||
const std::string pack_path = executablePath + "resources.pack";
|
||||
const std::string PACK_PATH = executablePath + "resources.pack";
|
||||
#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';
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -129,11 +127,11 @@ Director::Director(int argc, const char *argv[]) {
|
||||
Input::init("/gamecontrollerdb.txt");
|
||||
#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
|
||||
Input::init(binDir + "/../Resources/gamecontrollerdb.txt");
|
||||
Input::init(BIN_DIR + "/../Resources/gamecontrollerdb.txt");
|
||||
#else
|
||||
Input::init(binDir + "/gamecontrollerdb.txt");
|
||||
Input::init(BIN_DIR + "/gamecontrollerdb.txt");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -324,127 +322,127 @@ auto Director::initSDL() -> bool {
|
||||
// Crea el indice de ficheros
|
||||
auto Director::setFileList() -> bool {
|
||||
#ifdef MACOS_BUNDLE
|
||||
const std::string prefix = "/../Resources";
|
||||
const std::string PREFIX = "/../Resources";
|
||||
#else
|
||||
const std::string prefix;
|
||||
const std::string PREFIX;
|
||||
#endif
|
||||
|
||||
// Ficheros de configuración
|
||||
Asset::get()->add(systemFolder + "/score.bin", t_data, false, true);
|
||||
Asset::get()->add(prefix + "/data/demo/demo.bin", t_data);
|
||||
Asset::get()->add(systemFolder + "/score.bin", Asset::Type::DATA, false, true);
|
||||
Asset::get()->add(PREFIX + "/data/demo/demo.bin", Asset::Type::DATA);
|
||||
|
||||
// Musicas
|
||||
Asset::get()->add(prefix + "/data/music/intro.ogg", t_music);
|
||||
Asset::get()->add(prefix + "/data/music/playing.ogg", t_music);
|
||||
Asset::get()->add(prefix + "/data/music/title.ogg", t_music);
|
||||
Asset::get()->add(PREFIX + "/data/music/intro.ogg", Asset::Type::MUSIC);
|
||||
Asset::get()->add(PREFIX + "/data/music/playing.ogg", Asset::Type::MUSIC);
|
||||
Asset::get()->add(PREFIX + "/data/music/title.ogg", Asset::Type::MUSIC);
|
||||
|
||||
// Sonidos
|
||||
Asset::get()->add(prefix + "/data/sound/balloon.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/bubble1.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/bubble2.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/bubble3.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/bubble4.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/bullet.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/coffeeout.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/hiscore.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/itemdrop.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/itempickup.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/menu_move.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/menu_select.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/player_collision.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/stage_change.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/title.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/clock.wav", t_sound);
|
||||
Asset::get()->add(prefix + "/data/sound/powerball.wav", t_sound);
|
||||
Asset::get()->add(PREFIX + "/data/sound/balloon.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/bubble1.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/bubble2.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/bubble3.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/bubble4.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/bullet.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/coffeeout.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/hiscore.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/itemdrop.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/itempickup.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/menu_move.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/menu_select.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/player_collision.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/stage_change.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/title.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/clock.wav", Asset::Type::SOUND);
|
||||
Asset::get()->add(PREFIX + "/data/sound/powerball.wav", Asset::Type::SOUND);
|
||||
|
||||
// Texturas
|
||||
Asset::get()->add(prefix + "/data/gfx/balloon1.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/balloon1.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/balloon2.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/balloon2.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/balloon3.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/balloon3.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/balloon4.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/balloon4.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/bullet.png", t_bitmap);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/balloon1.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/balloon1.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/balloon2.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/balloon2.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/balloon3.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/balloon3.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/balloon4.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/balloon4.ani", Asset::Type::DATA);
|
||||
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_clouds.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/game_grass.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/game_power_meter.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/game_sky_colors.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/game_text.png", t_bitmap);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/game_buildings.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/game_clouds.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/game_grass.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/game_power_meter.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/game_sky_colors.png", Asset::Type::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/logo.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/menu_game_over.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/menu_game_over_end.png", t_bitmap);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/intro.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/logo.png", Asset::Type::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", Asset::Type::BITMAP);
|
||||
|
||||
Asset::get()->add(prefix + "/data/gfx/item_points1_disk.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_points1_disk.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_points2_gavina.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_points2_gavina.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_points3_pacmar.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_points3_pacmar.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_clock.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_clock.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_coffee.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_coffee.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_coffee_machine.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/item_coffee_machine.ani", t_data);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_points1_disk.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_points1_disk.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_points2_gavina.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_points2_gavina.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_points3_pacmar.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_points3_pacmar.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_clock.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_clock.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_coffee.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_coffee.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/item_coffee_machine.png", Asset::Type::BITMAP);
|
||||
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_coffee.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/title_crisis.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/title_dust.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/title_dust.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/title_gradient.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", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/title_crisis.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/title_dust.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/title_dust.ani", Asset::Type::DATA);
|
||||
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_body.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_legs.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_death.ani", t_data);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_fire.ani", t_data);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_head.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_body.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_legs.ani", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_death.ani", Asset::Type::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_body.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_bal1_legs.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_bal1_death.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_bal1_fire.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", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_bal1_legs.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_bal1_death.png", Asset::Type::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_body.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_arounder_legs.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_arounder_death.png", t_bitmap);
|
||||
Asset::get()->add(prefix + "/data/gfx/player_arounder_fire.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", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_arounder_legs.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_arounder_death.png", Asset::Type::BITMAP);
|
||||
Asset::get()->add(PREFIX + "/data/gfx/player_arounder_fire.png", Asset::Type::BITMAP);
|
||||
|
||||
// Fuentes
|
||||
Asset::get()->add(prefix + "/data/font/8bithud.png", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/8bithud.txt", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/nokia.png", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/nokia_big2.png", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/nokia.txt", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/nokia2.png", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/nokia2.txt", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/nokia_big2.txt", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/smb2_big.png", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/smb2_big.txt", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/smb2.png", t_font);
|
||||
Asset::get()->add(prefix + "/data/font/smb2.txt", t_font);
|
||||
Asset::get()->add(PREFIX + "/data/font/8bithud.png", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/8bithud.txt", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/nokia.png", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/nokia_big2.png", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/nokia.txt", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/nokia2.png", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/nokia2.txt", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/nokia_big2.txt", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/smb2_big.png", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/smb2_big.txt", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/smb2.png", Asset::Type::FONT);
|
||||
Asset::get()->add(PREFIX + "/data/font/smb2.txt", Asset::Type::FONT);
|
||||
|
||||
// Textos
|
||||
Asset::get()->add(prefix + "/data/lang/es_ES.txt", t_lang);
|
||||
Asset::get()->add(prefix + "/data/lang/en_UK.txt", t_lang);
|
||||
Asset::get()->add(prefix + "/data/lang/ba_BA.txt", t_lang);
|
||||
Asset::get()->add(PREFIX + "/data/lang/es_ES.txt", Asset::Type::LANG);
|
||||
Asset::get()->add(PREFIX + "/data/lang/en_UK.txt", Asset::Type::LANG);
|
||||
Asset::get()->add(PREFIX + "/data/lang/ba_BA.txt", Asset::Type::LANG);
|
||||
|
||||
// Menus
|
||||
Asset::get()->add(prefix + "/data/menu/title.men", t_data);
|
||||
Asset::get()->add(prefix + "/data/menu/title_gc.men", t_data);
|
||||
Asset::get()->add(prefix + "/data/menu/options.men", t_data);
|
||||
Asset::get()->add(prefix + "/data/menu/options_gc.men", t_data);
|
||||
Asset::get()->add(prefix + "/data/menu/pause.men", t_data);
|
||||
Asset::get()->add(prefix + "/data/menu/gameover.men", t_data);
|
||||
Asset::get()->add(prefix + "/data/menu/player_select.men", t_data);
|
||||
Asset::get()->add(PREFIX + "/data/menu/title.men", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/menu/title_gc.men", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/menu/options.men", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/menu/options_gc.men", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/menu/pause.men", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/menu/gameover.men", Asset::Type::DATA);
|
||||
Asset::get()->add(PREFIX + "/data/menu/player_select.men", Asset::Type::DATA);
|
||||
|
||||
return Asset::get()->check();
|
||||
}
|
||||
@@ -524,26 +522,26 @@ void Director::createSystemFolder(const std::string &folder) {
|
||||
// Gestiona las transiciones entre secciones
|
||||
void Director::handleSectionTransition() {
|
||||
// Determina qué sección debería estar activa
|
||||
ActiveSection targetSection = ActiveSection::None;
|
||||
ActiveSection target_section = ActiveSection::None;
|
||||
switch (section->name) {
|
||||
case SECTION_PROG_LOGO:
|
||||
targetSection = ActiveSection::Logo;
|
||||
target_section = ActiveSection::Logo;
|
||||
break;
|
||||
case SECTION_PROG_INTRO:
|
||||
targetSection = ActiveSection::Intro;
|
||||
target_section = ActiveSection::Intro;
|
||||
break;
|
||||
case SECTION_PROG_TITLE:
|
||||
targetSection = ActiveSection::Title;
|
||||
target_section = ActiveSection::Title;
|
||||
break;
|
||||
case SECTION_PROG_GAME:
|
||||
targetSection = ActiveSection::Game;
|
||||
target_section = ActiveSection::Game;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Si no ha cambiado, no hay nada que hacer
|
||||
if (targetSection == activeSection) {
|
||||
if (target_section == activeSection) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -554,7 +552,7 @@ void Director::handleSectionTransition() {
|
||||
game.reset();
|
||||
|
||||
// Crea la nueva sección
|
||||
activeSection = targetSection;
|
||||
activeSection = target_section;
|
||||
switch (activeSection) {
|
||||
case ActiveSection::Logo:
|
||||
logo = std::make_unique<Logo>(renderer, section);
|
||||
@@ -566,8 +564,8 @@ void Director::handleSectionTransition() {
|
||||
title = std::make_unique<Title>(renderer, section);
|
||||
break;
|
||||
case ActiveSection::Game: {
|
||||
const int numPlayers = section->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2;
|
||||
game = std::make_unique<Game>(numPlayers, 0, renderer, false, section);
|
||||
const int NUM_PLAYERS = section->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2;
|
||||
game = std::make_unique<Game>(NUM_PLAYERS, 0, renderer, false, section);
|
||||
break;
|
||||
}
|
||||
case ActiveSection::None:
|
||||
|
||||
Reference in New Issue
Block a user