Compare commits
2 Commits
49145905e3
...
8d2c24deb9
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d2c24deb9 | |||
| 100b7265d5 |
@@ -4,13 +4,18 @@
|
|||||||
"[CREDITS] MUSIC_COMPOSED_BY": "MUSICA COMPOSADA PER",
|
"[CREDITS] MUSIC_COMPOSED_BY": "MUSICA COMPOSADA PER",
|
||||||
"[CREDITS] SOUND_EFFECTS": "EFECTES DE SO",
|
"[CREDITS] SOUND_EFFECTS": "EFECTES DE SO",
|
||||||
|
|
||||||
|
"[DEFINE_BUTTONS] TITLE": "define buttons title",
|
||||||
"[DEFINE_BUTTONS] FIRE_LEFT": "Disparar cap a l'esquerra",
|
"[DEFINE_BUTTONS] FIRE_LEFT": "Disparar cap a l'esquerra",
|
||||||
"[DEFINE_BUTTONS] FIRE_UP": "Disparar cap amunt",
|
"[DEFINE_BUTTONS] FIRE_UP": "Disparar cap amunt amunt amunt amunt",
|
||||||
"[DEFINE_BUTTONS] FIRE_RIGHT": "Disparar cap a la dreta",
|
"[DEFINE_BUTTONS] FIRE_RIGHT": "Disparar cap a la dreta",
|
||||||
"[DEFINE_BUTTONS] START": "Start",
|
"[DEFINE_BUTTONS] START": "Start",
|
||||||
"[DEFINE_BUTTONS] SERVICE_MENU": "Menu de servei",
|
"[DEFINE_BUTTONS] SERVICE_MENU": "Menu de servei",
|
||||||
"[DEFINE_BUTTONS] PLAYER": "Jugador",
|
"[DEFINE_BUTTONS] PLAYER": "Jugador",
|
||||||
"[DEFINE_BUTTONS] KEYBOARD": "Teclat",
|
"[DEFINE_BUTTONS] KEYBOARD": "Teclat",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURATION_COMPLETE" : "Configuracio completada",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURING" : "Configurant",
|
||||||
|
"[DEFINE_BUTTONS] PRESS_BUTTON_FOR" : "Prem un boto per a",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURED" : "configurat",
|
||||||
|
|
||||||
"[GAME_TEXT] 1": "Felicitats!!",
|
"[GAME_TEXT] 1": "Felicitats!!",
|
||||||
"[GAME_TEXT] 2": " fases mes!",
|
"[GAME_TEXT] 2": " fases mes!",
|
||||||
|
|||||||
@@ -11,6 +11,10 @@
|
|||||||
"[DEFINE_BUTTONS] SERVICE_MENU" : "Service menu",
|
"[DEFINE_BUTTONS] SERVICE_MENU" : "Service menu",
|
||||||
"[DEFINE_BUTTONS] PLAYER" : "Player",
|
"[DEFINE_BUTTONS] PLAYER" : "Player",
|
||||||
"[DEFINE_BUTTONS] KEYBOARD" : "Keyboard",
|
"[DEFINE_BUTTONS] KEYBOARD" : "Keyboard",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURATION_COMPLETE": "Configuration complete",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURING" : "Configuring",
|
||||||
|
"[DEFINE_BUTTONS] PRESS_BUTTON_FOR" : "Press button for",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURED" : "Configured",
|
||||||
|
|
||||||
"[GAME_TEXT] 1": "Congratulations!!",
|
"[GAME_TEXT] 1": "Congratulations!!",
|
||||||
"[GAME_TEXT] 2": " stages left!",
|
"[GAME_TEXT] 2": " stages left!",
|
||||||
|
|||||||
@@ -11,6 +11,10 @@
|
|||||||
"[DEFINE_BUTTONS] SERVICE_MENU" : "Menu de servicio",
|
"[DEFINE_BUTTONS] SERVICE_MENU" : "Menu de servicio",
|
||||||
"[DEFINE_BUTTONS] PLAYER" : "Jugador",
|
"[DEFINE_BUTTONS] PLAYER" : "Jugador",
|
||||||
"[DEFINE_BUTTONS] KEYBOARD" : "Teclado",
|
"[DEFINE_BUTTONS] KEYBOARD" : "Teclado",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURATION_COMPLETE": "Configuracion completada",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURING" : "Configurando",
|
||||||
|
"[DEFINE_BUTTONS] PRESS_BUTTON_FOR" : "Pulsa un boton para",
|
||||||
|
"[DEFINE_BUTTONS] CONFIGURED" : "Configurado",
|
||||||
|
|
||||||
"[GAME_TEXT] 1": "Felicidades!!",
|
"[GAME_TEXT] 1": "Felicidades!!",
|
||||||
"[GAME_TEXT] 2": " fases mas!",
|
"[GAME_TEXT] 2": " fases mas!",
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
DefineButtons::DefineButtons()
|
DefineButtons::DefineButtons()
|
||||||
: input_(Input::get()) {
|
: input_(Input::get()) {
|
||||||
|
|
||||||
clearButtons();
|
clearButtons();
|
||||||
|
|
||||||
auto gamepads = input_->getGamepads();
|
auto gamepads = input_->getGamepads();
|
||||||
@@ -24,18 +23,26 @@ DefineButtons::DefineButtons()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crear la ventana de mensaje
|
// Crear la ventana de mensaje
|
||||||
|
WindowMessage::Config config;
|
||||||
|
config.bg_color = Color{20, 30, 50, 224}; // Fondo azul oscuro semi-transparente
|
||||||
|
config.border_color = Color{100, 150, 200, 255}; // Borde azul claro
|
||||||
|
config.title_color = Color{100, 150, 200, 255}; // Titulo azul claro
|
||||||
|
config.text_color = Color{220, 220, 220, 255}; // Texto gris claro
|
||||||
|
config.padding = 15.0f;
|
||||||
|
config.line_spacing = 5.0f;
|
||||||
|
config.title_separator_spacing = 15;
|
||||||
|
config.min_width = 250.0f;
|
||||||
|
config.text_safety_margin = 15.0f;
|
||||||
|
config.min_width = 100;
|
||||||
|
config.min_height = 32;
|
||||||
|
|
||||||
auto text_renderer = Resource::get()->getText("04b_25_flat");
|
auto text_renderer = Resource::get()->getText("04b_25_flat");
|
||||||
window_message_ = std::make_unique<WindowMessage>(
|
window_message_ = std::make_unique<WindowMessage>(
|
||||||
text_renderer,
|
text_renderer,
|
||||||
Lang::getText("[DEFINE_BUTTONS] TITLE"),
|
Lang::getText("[DEFINE_BUTTONS] TITLE"),
|
||||||
Color{20, 30, 50, 200}, // Fondo azul oscuro semi-transparente
|
config
|
||||||
Color{100, 150, 200, 255}, // Borde azul claro
|
|
||||||
Color{255, 255, 255, 255}, // Título blanco
|
|
||||||
Color{220, 220, 220, 255} // Texto gris claro
|
|
||||||
);
|
);
|
||||||
|
window_message_->setPosition(param.game.game_area.center_x, param.game.game_area.center_y, WindowMessage::PositionMode::CENTERED);
|
||||||
window_message_->setPadding(20.0f);
|
|
||||||
window_message_->setLineSpacing(8.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefineButtons::render() {
|
void DefineButtons::render() {
|
||||||
@@ -76,7 +83,6 @@ auto DefineButtons::enable(Options::Gamepad *options_gamepad) -> bool {
|
|||||||
|
|
||||||
if (window_message_) {
|
if (window_message_) {
|
||||||
window_message_->autoSize();
|
window_message_->autoSize();
|
||||||
window_message_->centerOnScreen();
|
|
||||||
window_message_->show();
|
window_message_->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,10 +179,10 @@ void DefineButtons::updateWindowMessage() {
|
|||||||
|
|
||||||
if (index_button_ < buttons_.size()) {
|
if (index_button_ < buttons_.size()) {
|
||||||
// Mostrar progreso
|
// Mostrar progreso
|
||||||
std::string progress = "(" + std::to_string(index_button_ + 1) + "/" +
|
/*std::string progress = "(" + std::to_string(index_button_ + 1) + "/" +
|
||||||
std::to_string(buttons_.size()) + ")";
|
std::to_string(buttons_.size()) + ")";
|
||||||
window_message_->addText(progress);
|
window_message_->addText(progress);
|
||||||
window_message_->addText("");
|
window_message_->addText("");*/
|
||||||
|
|
||||||
// Instrucción actual
|
// Instrucción actual
|
||||||
std::string instruction = Lang::getText("[DEFINE_BUTTONS] PRESS_BUTTON_FOR") + ":";
|
std::string instruction = Lang::getText("[DEFINE_BUTTONS] PRESS_BUTTON_FOR") + ":";
|
||||||
@@ -184,7 +190,7 @@ void DefineButtons::updateWindowMessage() {
|
|||||||
window_message_->addText(buttons_.at(index_button_).label);
|
window_message_->addText(buttons_.at(index_button_).label);
|
||||||
|
|
||||||
// Botones ya configurados
|
// Botones ya configurados
|
||||||
if (index_button_ > 0) {
|
/*if (index_button_ > 0) {
|
||||||
window_message_->addText("");
|
window_message_->addText("");
|
||||||
window_message_->addText(Lang::getText("[DEFINE_BUTTONS] CONFIGURED") + ":");
|
window_message_->addText(Lang::getText("[DEFINE_BUTTONS] CONFIGURED") + ":");
|
||||||
|
|
||||||
@@ -192,6 +198,6 @@ void DefineButtons::updateWindowMessage() {
|
|||||||
std::string configured = "✓ " + buttons_[i].label;
|
std::string configured = "✓ " + buttons_[i].label;
|
||||||
window_message_->addText(configured);
|
window_message_->addText(configured);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ auto Resource::getTexture(const std::string &name) -> std::shared_ptr<Texture> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el fichero de texto a partir de un nombre. Lanza excepción si no existe.
|
// Obtiene el fichero de texto a partir de un nombre. Lanza excepción si no existe.
|
||||||
auto Resource::getTextFile(const std::string &name) -> std::shared_ptr<TextFile> {
|
auto Resource::getTextFile(const std::string &name) -> std::shared_ptr<Text::File> {
|
||||||
auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t) { return t.name == name; });
|
auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t) { return t.name == name; });
|
||||||
|
|
||||||
if (it != text_files_.end()) {
|
if (it != text_files_.end()) {
|
||||||
@@ -225,7 +225,7 @@ void Resource::loadTextFiles() {
|
|||||||
for (const auto &l : list) {
|
for (const auto &l : list) {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
updateLoadingProgress(name);
|
updateLoadingProgress(name);
|
||||||
text_files_.emplace_back(name, loadTextFile(l));
|
text_files_.emplace_back(name, Text::loadFile(l));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Resource {
|
|||||||
auto getSound(const std::string &name) -> JA_Sound_t *; // Obtiene el sonido por nombre
|
auto getSound(const std::string &name) -> JA_Sound_t *; // Obtiene el sonido por nombre
|
||||||
auto getMusic(const std::string &name) -> JA_Music_t *; // Obtiene la música por nombre
|
auto getMusic(const std::string &name) -> JA_Music_t *; // Obtiene la música por nombre
|
||||||
auto getTexture(const std::string &name) -> std::shared_ptr<Texture>; // Obtiene la textura por nombre
|
auto getTexture(const std::string &name) -> std::shared_ptr<Texture>; // Obtiene la textura por nombre
|
||||||
auto getTextFile(const std::string &name) -> std::shared_ptr<TextFile>; // Obtiene el fichero de texto por nombre
|
auto getTextFile(const std::string &name) -> std::shared_ptr<Text::File>; // Obtiene el fichero de texto por nombre
|
||||||
auto getText(const std::string &name) -> std::shared_ptr<Text>; // Obtiene el objeto de texto por nombre
|
auto getText(const std::string &name) -> std::shared_ptr<Text>; // Obtiene el objeto de texto por nombre
|
||||||
auto getAnimation(const std::string &name) -> AnimationsFileBuffer &; // Obtiene la animación por nombre
|
auto getAnimation(const std::string &name) -> AnimationsFileBuffer &; // Obtiene la animación por nombre
|
||||||
auto getDemoData(int index) -> DemoData &; // Obtiene los datos de demo por índice
|
auto getDemoData(int index) -> DemoData &; // Obtiene los datos de demo por índice
|
||||||
@@ -65,9 +65,9 @@ class Resource {
|
|||||||
|
|
||||||
struct ResourceTextFile {
|
struct ResourceTextFile {
|
||||||
std::string name; // Nombre del fichero
|
std::string name; // Nombre del fichero
|
||||||
std::shared_ptr<TextFile> text_file; // Objeto con los descriptores de la fuente de texto
|
std::shared_ptr<Text::File> text_file; // Objeto con los descriptores de la fuente de texto
|
||||||
|
|
||||||
ResourceTextFile(std::string name, std::shared_ptr<TextFile> text_file)
|
ResourceTextFile(std::string name, std::shared_ptr<Text::File> text_file)
|
||||||
: name(std::move(name)), text_file(std::move(text_file)) {}
|
: name(std::move(name)), text_file(std::move(text_file)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include "resource.h" // Para Resource
|
#include "resource.h" // Para Resource
|
||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "text.h" // Para Text, TEXT_CENTER, TEXT_COLOR
|
#include "text.h" // Para Text, Text::CENTER, Text::COLOR
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
|
||||||
// .at(SINGLETON) Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
// .at(SINGLETON) Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
||||||
@@ -198,50 +198,50 @@ void Scoreboard::renderPanelContent(size_t panel_index) {
|
|||||||
|
|
||||||
void Scoreboard::renderScoreMode(size_t panel_index) {
|
void Scoreboard::renderScoreMode(size_t panel_index) {
|
||||||
// SCORE
|
// SCORE
|
||||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::COLOR | Text::CENTER, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
text_scoreboard_->writeDX(Text::COLOR | Text::CENTER, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||||
|
|
||||||
// MULT
|
// MULT
|
||||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 3"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::COLOR | Text::CENTER, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 3"), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_4_.x, slot4_4_.y, "x" + std::to_string(mult_.at(panel_index)).substr(0, 3), 1, text_color2_);
|
text_scoreboard_->writeDX(Text::COLOR | Text::CENTER, slot4_4_.x, slot4_4_.y, "x" + std::to_string(mult_.at(panel_index)).substr(0, 3), 1, text_color2_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scoreboard::renderDemoMode() {
|
void Scoreboard::renderDemoMode() {
|
||||||
// DEMO MODE
|
// DEMO MODE
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 6"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 6"), 1, text_color1_);
|
||||||
|
|
||||||
// PRESS START TO PLAY
|
// PRESS START TO PLAY
|
||||||
if (time_counter_ % 10 < 8) {
|
if (time_counter_ % 10 < 8) {
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 8"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 8"), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 9"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 9"), 1, text_color1_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scoreboard::renderWaitingMode() {
|
void Scoreboard::renderWaitingMode() {
|
||||||
// GAME OVER
|
// GAME OVER
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
||||||
|
|
||||||
// PRESS START TO PLAY
|
// PRESS START TO PLAY
|
||||||
if (time_counter_ % 10 < 8) {
|
if (time_counter_ % 10 < 8) {
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 8"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 8"), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 9"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 9"), 1, text_color1_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scoreboard::renderGameOverMode() {
|
void Scoreboard::renderGameOverMode() {
|
||||||
// GAME OVER
|
// GAME OVER
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
||||||
|
|
||||||
// PLEASE WAIT
|
// PLEASE WAIT
|
||||||
if (time_counter_ % 10 < 8) {
|
if (time_counter_ % 10 < 8) {
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 12"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 12"), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 13"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 13"), 1, text_color1_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scoreboard::renderStageInfoMode() {
|
void Scoreboard::renderStageInfoMode() {
|
||||||
// STAGE
|
// STAGE
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, Lang::getText("[SCOREBOARD] 5") + std::to_string(stage_), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y, Lang::getText("[SCOREBOARD] 5") + std::to_string(stage_), 1, text_color1_);
|
||||||
|
|
||||||
// POWERMETER
|
// POWERMETER
|
||||||
power_meter_sprite_->setSpriteClip(0, 0, 40, 7);
|
power_meter_sprite_->setSpriteClip(0, 0, 40, 7);
|
||||||
@@ -250,28 +250,28 @@ void Scoreboard::renderStageInfoMode() {
|
|||||||
power_meter_sprite_->render();
|
power_meter_sprite_->render();
|
||||||
|
|
||||||
// HI-SCORE
|
// HI-SCORE
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 4"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 4"), 1, text_color1_);
|
||||||
const std::string NAME = hi_score_name_.empty() ? "" : hi_score_name_ + " - ";
|
const std::string NAME = hi_score_name_.empty() ? "" : hi_score_name_ + " - ";
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, NAME + updateScoreText(hi_score_), 1, text_color2_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y, NAME + updateScoreText(hi_score_), 1, text_color2_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scoreboard::renderContinueMode(size_t panel_index) {
|
void Scoreboard::renderContinueMode(size_t panel_index) {
|
||||||
// SCORE
|
// SCORE
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||||
|
|
||||||
// CONTINUE
|
// CONTINUE
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 10"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 10"), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, std::to_string(continue_counter_.at(panel_index)), 1, text_color2_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y, std::to_string(continue_counter_.at(panel_index)), 1, text_color2_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scoreboard::renderEnterNameMode(size_t panel_index) {
|
void Scoreboard::renderEnterNameMode(size_t panel_index) {
|
||||||
// SCORE
|
// SCORE
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||||
|
|
||||||
// ENTER NAME
|
// ENTER NAME
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
||||||
|
|
||||||
renderNameInputField(panel_index);
|
renderNameInputField(panel_index);
|
||||||
}
|
}
|
||||||
@@ -302,14 +302,14 @@ void Scoreboard::renderNameInputField(size_t panel_index) {
|
|||||||
|
|
||||||
void Scoreboard::renderShowNameMode(size_t panel_index) {
|
void Scoreboard::renderShowNameMode(size_t panel_index) {
|
||||||
// SCORE
|
// SCORE
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||||
|
|
||||||
// NAME
|
// NAME
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
||||||
|
|
||||||
/* TEXTO CENTRADO */
|
/* TEXTO CENTRADO */
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, record_name_.at(panel_index), 1, getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y, record_name_.at(panel_index), 1, getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||||
|
|
||||||
/* TEXTO A LA IZQUIERDA */
|
/* TEXTO A LA IZQUIERDA */
|
||||||
// text_scoreboard_->writeColored(enter_name_pos_.x, enter_name_pos_.y, record_name_.at(panelIndex), getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
// text_scoreboard_->writeColored(enter_name_pos_.x, enter_name_pos_.y, record_name_.at(panelIndex), getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||||
@@ -317,12 +317,12 @@ void Scoreboard::renderShowNameMode(size_t panel_index) {
|
|||||||
|
|
||||||
void Scoreboard::renderGameCompletedMode(size_t panel_index) {
|
void Scoreboard::renderGameCompletedMode(size_t panel_index) {
|
||||||
// GAME OVER
|
// GAME OVER
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
||||||
|
|
||||||
// SCORE
|
// SCORE
|
||||||
if (time_counter_ % 10 < 8) {
|
if (time_counter_ % 10 < 8) {
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 14"), 1, text_color1_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 14"), 1, text_color1_);
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
text_scoreboard_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y - 2, updateScoreText(score_.at(panel_index)), 1, text_color2_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +382,7 @@ void Scoreboard::recalculateAnchors() {
|
|||||||
slot4_4_ = {COL, ROW4};
|
slot4_4_ = {COL, ROW4};
|
||||||
|
|
||||||
// Primer cuadrado para poner el nombre de record
|
// Primer cuadrado para poner el nombre de record
|
||||||
const int ENTER_NAME_LENGHT = text_scoreboard_->lenght(std::string(NAME_SIZE, 'A'));
|
const int ENTER_NAME_LENGHT = text_scoreboard_->length(std::string(NAME_SIZE, 'A'));
|
||||||
enter_name_pos_.x = COL - (ENTER_NAME_LENGHT / 2);
|
enter_name_pos_.x = COL - (ENTER_NAME_LENGHT / 2);
|
||||||
enter_name_pos_.y = ROW4;
|
enter_name_pos_.y = ROW4;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "mouse.h" // Para updateCursorVisibility
|
#include "mouse.h" // Para updateCursorVisibility
|
||||||
#include "options.h" // Para VideoOptions, video, WindowOptions, window
|
#include "options.h" // Para VideoOptions, video, WindowOptions, window
|
||||||
#include "param.h" // Para Param, param, ParamGame, ParamDebug
|
#include "param.h" // Para Param, param, ParamGame, ParamDebug
|
||||||
#include "text.h" // Para Text, TEXT_COLOR, TEXT_STROKE
|
#include "text.h" // Para Text, Text::COLOR, Text::STROKE
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
#include "ui/notifier.h" // Para Notifier
|
#include "ui/notifier.h" // Para Notifier
|
||||||
#include "ui/service_menu.h" // Para ServiceMenu
|
#include "ui/service_menu.h" // Para ServiceMenu
|
||||||
@@ -81,7 +81,7 @@ void Screen::start() { SDL_SetRenderTarget(renderer_, game_canvas_); }
|
|||||||
void Screen::render() {
|
void Screen::render() {
|
||||||
fps_.increment();
|
fps_.increment();
|
||||||
renderOverlays(); // Renderiza todos los overlays y efectos
|
renderOverlays(); // Renderiza todos los overlays y efectos
|
||||||
renderScreen(); // Renderiza el contenido del game_canvas_
|
renderPresent(); // Renderiza el contenido del game_canvas_
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vuelca el contenido del renderizador en pantalla exceptuando ciertas partes
|
// Vuelca el contenido del renderizador en pantalla exceptuando ciertas partes
|
||||||
@@ -90,11 +90,11 @@ void Screen::coreRender() {
|
|||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
renderInfo();
|
renderInfo();
|
||||||
#endif
|
#endif
|
||||||
renderScreen(); // Renderiza el contenido del game_canvas_
|
renderPresent(); // Renderiza el contenido del game_canvas_
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderiza el contenido del game_canvas_
|
// Renderiza el contenido del game_canvas_
|
||||||
void Screen::renderScreen() {
|
void Screen::renderPresent() {
|
||||||
SDL_SetRenderTarget(renderer_, nullptr);
|
SDL_SetRenderTarget(renderer_, nullptr);
|
||||||
clean();
|
clean();
|
||||||
|
|
||||||
@@ -212,11 +212,11 @@ void Screen::renderShake() {
|
|||||||
void Screen::renderInfo() {
|
void Screen::renderInfo() {
|
||||||
if (debug_info_.show) {
|
if (debug_info_.show) {
|
||||||
// Resolution
|
// Resolution
|
||||||
debug_info_.text->writeDX(TEXT_COLOR | TEXT_STROKE, param.game.width - debug_info_.text->lenght(Options::video.info) - 2, 1, Options::video.info, 1, param.debug.color, 1, param.debug.color.DARKEN(150));
|
debug_info_.text->writeDX(Text::COLOR | Text::STROKE, param.game.width - debug_info_.text->length(Options::video.info) - 2, 1, Options::video.info, 1, param.debug.color, 1, param.debug.color.DARKEN(150));
|
||||||
|
|
||||||
// FPS
|
// FPS
|
||||||
const std::string FPS_TEXT = std::to_string(fps_.last_value) + " FPS";
|
const std::string FPS_TEXT = std::to_string(fps_.last_value) + " FPS";
|
||||||
debug_info_.text->writeDX(TEXT_COLOR | TEXT_STROKE, param.game.width - debug_info_.text->lenght(FPS_TEXT) - 2, 1 + debug_info_.text->getCharacterSize(), FPS_TEXT, 1, param.debug.color, 1, param.debug.color.DARKEN(150));
|
debug_info_.text->writeDX(Text::COLOR | Text::STROKE, param.game.width - debug_info_.text->length(FPS_TEXT) - 2, 1 + debug_info_.text->getCharacterSize(), FPS_TEXT, 1, param.debug.color, 1, param.debug.color.DARKEN(150));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ class Screen {
|
|||||||
void renderFlash(); // Dibuja el efecto de flash en la pantalla
|
void renderFlash(); // Dibuja el efecto de flash en la pantalla
|
||||||
void renderShake(); // Aplica el efecto de agitar la pantalla
|
void renderShake(); // Aplica el efecto de agitar la pantalla
|
||||||
void renderInfo(); // Muestra información por pantalla
|
void renderInfo(); // Muestra información por pantalla
|
||||||
void renderScreen(); // Selecciona y ejecuta el método de renderizado adecuado
|
void renderPresent(); // Selecciona y ejecuta el método de renderizado adecuado
|
||||||
void loadShaders(); // Carga el contenido del archivo GLSL
|
void loadShaders(); // Carga el contenido del archivo GLSL
|
||||||
void adjustWindowSize(); // Calcula el tamaño de la ventana
|
void adjustWindowSize(); // Calcula el tamaño de la ventana
|
||||||
static void getDisplayInfo(); // Obtiene información sobre la pantalla
|
static void getDisplayInfo(); // Obtiene información sobre la pantalla
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "section.hpp" // Para Name, name
|
#include "section.hpp" // Para Name, name
|
||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "text.h" // Para Text, TEXT_CENTER, TEXT_SHADOW
|
#include "text.h" // Para Text, Text::CENTER, Text::SHADOW
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
#include "tiled_bg.h" // Para TiledBG, TiledBGMode
|
#include "tiled_bg.h" // Para TiledBG, TiledBGMode
|
||||||
#include "ui/service_menu.h" // Para ServiceMenu
|
#include "ui/service_menu.h" // Para ServiceMenu
|
||||||
@@ -171,37 +171,37 @@ void Credits::fillTextTexture() {
|
|||||||
|
|
||||||
// PROGRAMMED_AND_DESIGNED_BY
|
// PROGRAMMED_AND_DESIGNED_BY
|
||||||
int y = 0;
|
int y = 0;
|
||||||
text_grad->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(0), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text_grad->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(0), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
y += SPACE_POST_TITLE;
|
y += SPACE_POST_TITLE;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(4), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(4), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
// PIXELART_DRAWN_BY
|
// PIXELART_DRAWN_BY
|
||||||
y += SPACE_PRE_TITLE;
|
y += SPACE_PRE_TITLE;
|
||||||
text_grad->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(1), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text_grad->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(1), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
y += SPACE_POST_TITLE;
|
y += SPACE_POST_TITLE;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(4), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(4), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
// MUSIC_COMPOSED_BY
|
// MUSIC_COMPOSED_BY
|
||||||
y += SPACE_PRE_TITLE;
|
y += SPACE_PRE_TITLE;
|
||||||
text_grad->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(2), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text_grad->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(2), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
y += SPACE_POST_TITLE;
|
y += SPACE_POST_TITLE;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(5), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(5), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
y += SPACE_POST_TITLE;
|
y += SPACE_POST_TITLE;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(6), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(6), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
// SOUND_EFFECTS
|
// SOUND_EFFECTS
|
||||||
y += SPACE_PRE_TITLE;
|
y += SPACE_PRE_TITLE;
|
||||||
text_grad->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(3), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text_grad->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(3), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
y += SPACE_POST_TITLE;
|
y += SPACE_POST_TITLE;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(7), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(7), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
y += SPACE_POST_TITLE;
|
y += SPACE_POST_TITLE;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(8), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(8), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
y += SPACE_POST_TITLE;
|
y += SPACE_POST_TITLE;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(9), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(9), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
y += SPACE_POST_TITLE;
|
y += SPACE_POST_TITLE;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXTS.at(10), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, TEXTS.at(10), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
// Mini logo
|
// Mini logo
|
||||||
y += SPACE_PRE_TITLE;
|
y += SPACE_PRE_TITLE;
|
||||||
@@ -217,7 +217,7 @@ void Credits::fillTextTexture() {
|
|||||||
|
|
||||||
// Texto con el copyright
|
// Texto con el copyright
|
||||||
y += mini_logo_sprite->getHeight() + 3;
|
y += mini_logo_sprite->getHeight() + 3;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, std::string(TEXT_COPYRIGHT), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(Text::CENTER | Text::SHADOW, param.game.game_area.center_x, y, std::string(TEXT_COPYRIGHT), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
// Resetea el renderizador
|
// Resetea el renderizador
|
||||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "section.hpp" // Para Name, name, Options, options
|
#include "section.hpp" // Para Name, name, Options, options
|
||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "text.h" // Para Text, TEXT_SHADOW, TEXT_COLOR
|
#include "text.h" // Para Text, Text::SHADOW, Text::COLOR
|
||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@@ -186,13 +186,13 @@ void HiScoreTable::createSprites() {
|
|||||||
const int FIRST_LINE = (param.game.height - SIZE) / 2;
|
const int FIRST_LINE = (param.game.height - SIZE) / 2;
|
||||||
|
|
||||||
// Crea el sprite para el texto de cabecera
|
// Crea el sprite para el texto de cabecera
|
||||||
header_ = std::make_unique<Sprite>(header_text->writeDXToTexture(TEXT_COLOR, Lang::getText("[HIGHSCORE_TABLE] CAPTION"), -2, background_fade_color_.INVERSE().LIGHTEN(25)));
|
header_ = std::make_unique<Sprite>(header_text->writeDXToTexture(Text::COLOR, Lang::getText("[HIGHSCORE_TABLE] CAPTION"), -2, background_fade_color_.INVERSE().LIGHTEN(25)));
|
||||||
header_->setPosition(param.game.game_area.center_x - (header_->getWidth() / 2), FIRST_LINE);
|
header_->setPosition(param.game.game_area.center_x - (header_->getWidth() / 2), FIRST_LINE);
|
||||||
|
|
||||||
// Crea los sprites para las entradas en la tabla de puntuaciones
|
// Crea los sprites para las entradas en la tabla de puntuaciones
|
||||||
const int ANIMATION = rand() % 4;
|
const int ANIMATION = rand() % 4;
|
||||||
const std::string SAMPLE_LINE(ENTRY_LENGHT + 3, ' ');
|
const std::string SAMPLE_LINE(ENTRY_LENGHT + 3, ' ');
|
||||||
auto sample_entry = std::make_unique<Sprite>(entry_text->writeDXToTexture(TEXT_SHADOW, SAMPLE_LINE, 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR));
|
auto sample_entry = std::make_unique<Sprite>(entry_text->writeDXToTexture(Text::SHADOW, SAMPLE_LINE, 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR));
|
||||||
const auto ENTRY_WIDTH = sample_entry->getWidth();
|
const auto ENTRY_WIDTH = sample_entry->getWidth();
|
||||||
for (int i = 0; i < MAX_NAMES; ++i) {
|
for (int i = 0; i < MAX_NAMES; ++i) {
|
||||||
const auto TABLE_POSITION = format(i + 1) + ". ";
|
const auto TABLE_POSITION = format(i + 1) + ". ";
|
||||||
@@ -205,7 +205,7 @@ void HiScoreTable::createSprites() {
|
|||||||
}
|
}
|
||||||
const auto LINE = TABLE_POSITION + Options::settings.hi_score_table.at(i).name + dots + SCORE + ONE_CC;
|
const auto LINE = TABLE_POSITION + Options::settings.hi_score_table.at(i).name + dots + SCORE + ONE_CC;
|
||||||
|
|
||||||
entry_names_.emplace_back(std::make_shared<PathSprite>(entry_text->writeDXToTexture(TEXT_SHADOW, LINE, 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR)));
|
entry_names_.emplace_back(std::make_shared<PathSprite>(entry_text->writeDXToTexture(Text::SHADOW, LINE, 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR)));
|
||||||
const int DEFAULT_POS_X = (backbuffer_width - ENTRY_WIDTH) / 2;
|
const int DEFAULT_POS_X = (backbuffer_width - ENTRY_WIDTH) / 2;
|
||||||
const int POS_X = (i < 9) ? DEFAULT_POS_X : DEFAULT_POS_X - entry_text->getCharacterSize();
|
const int POS_X = (i < 9) ? DEFAULT_POS_X : DEFAULT_POS_X - entry_text->getCharacterSize();
|
||||||
const int POS_Y = (i * SPACE_BETWEEN_LINES) + FIRST_LINE + SPACE_BETWEEN_HEADER;
|
const int POS_Y = (i * SPACE_BETWEEN_LINES) + FIRST_LINE + SPACE_BETWEEN_HEADER;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "section.hpp" // Para Name, name, Options, options
|
#include "section.hpp" // Para Name, name, Options, options
|
||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "text.h" // Para Text, TEXT_CENTER, TEXT_COLOR, TEXT_SHADOW
|
#include "text.h" // Para Text, Text::CENTER, Text::COLOR, Text::SHADOW
|
||||||
#include "tiled_bg.h" // Para TiledBG, TiledBGMode
|
#include "tiled_bg.h" // Para TiledBG, TiledBGMode
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@@ -145,26 +145,26 @@ void Instructions::fillTexture() {
|
|||||||
Lang::getText("[INSTRUCTIONS] 10"),
|
Lang::getText("[INSTRUCTIONS] 10"),
|
||||||
Lang::getText("[INSTRUCTIONS] 11")};
|
Lang::getText("[INSTRUCTIONS] 11")};
|
||||||
for (const auto &desc : ITEM_DESCRIPTIONS) {
|
for (const auto &desc : ITEM_DESCRIPTIONS) {
|
||||||
const int L = text_->lenght(desc);
|
const int L = text_->length(desc);
|
||||||
lenght = L > lenght ? L : lenght;
|
lenght = L > lenght ? L : lenght;
|
||||||
}
|
}
|
||||||
const int ANCHOR_ITEM = (param.game.width - (lenght + X_OFFSET)) / 2;
|
const int ANCHOR_ITEM = (param.game.width - (lenght + X_OFFSET)) / 2;
|
||||||
|
|
||||||
auto caption_style = TextStyle(ORANGE_TEXT_COLOR, SHADOW_TEXT_COLOR);
|
auto caption_style = Text::Style(Text::CENTER | Text::COLOR | Text::SHADOW, ORANGE_TEXT_COLOR, SHADOW_TEXT_COLOR);
|
||||||
auto text_style = TextStyle(NO_TEXT_COLOR, SHADOW_TEXT_COLOR);
|
auto text_style = Text::Style(Text::CENTER | Text::COLOR | Text::SHADOW, NO_TEXT_COLOR, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
// Escribe el texto de las instrucciones
|
// Escribe el texto de las instrucciones
|
||||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, FIRST_LINE, Lang::getText("[INSTRUCTIONS] 01"), caption_style);
|
text_->writeStyle(param.game.game_area.center_x, FIRST_LINE, Lang::getText("[INSTRUCTIONS] 01"), caption_style);
|
||||||
|
|
||||||
const int ANCHOR1 = FIRST_LINE + SPACE_POST_HEADER;
|
const int ANCHOR1 = FIRST_LINE + SPACE_POST_HEADER;
|
||||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, ANCHOR1 + SPACE_BETWEEN_LINES * 0, Lang::getText("[INSTRUCTIONS] 02"), text_style);
|
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_BETWEEN_LINES * 0, Lang::getText("[INSTRUCTIONS] 02"), text_style);
|
||||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, ANCHOR1 + SPACE_BETWEEN_LINES * 1, Lang::getText("[INSTRUCTIONS] 03"), text_style);
|
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_BETWEEN_LINES * 1, Lang::getText("[INSTRUCTIONS] 03"), text_style);
|
||||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, ANCHOR1 + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 2, Lang::getText("[INSTRUCTIONS] 04"), text_style);
|
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 2, Lang::getText("[INSTRUCTIONS] 04"), text_style);
|
||||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, ANCHOR1 + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 3, Lang::getText("[INSTRUCTIONS] 05"), text_style);
|
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 3, Lang::getText("[INSTRUCTIONS] 05"), text_style);
|
||||||
|
|
||||||
// Escribe el texto de los objetos y sus puntos
|
// Escribe el texto de los objetos y sus puntos
|
||||||
const int ANCHOR2 = ANCHOR1 + SPACE_PRE_HEADER + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 3;
|
const int ANCHOR2 = ANCHOR1 + SPACE_PRE_HEADER + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 3;
|
||||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, ANCHOR2, Lang::getText("[INSTRUCTIONS] 06"), caption_style);
|
text_->writeStyle(param.game.game_area.center_x, ANCHOR2, Lang::getText("[INSTRUCTIONS] 06"), caption_style);
|
||||||
|
|
||||||
const int ANCHOR3 = ANCHOR2 + SPACE_POST_HEADER;
|
const int ANCHOR3 = ANCHOR2 + SPACE_POST_HEADER;
|
||||||
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + SPACE_BETWEEN_ITEM_LINES * 0, Lang::getText("[INSTRUCTIONS] 07"), SHADOW_TEXT_COLOR);
|
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + SPACE_BETWEEN_ITEM_LINES * 0, Lang::getText("[INSTRUCTIONS] 07"), SHADOW_TEXT_COLOR);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "section.hpp" // Para Name, name, Options, options, AttractMode, attract_mode
|
#include "section.hpp" // Para Name, name, Options, options, AttractMode, attract_mode
|
||||||
#include "sprite.h" // Para Sprite
|
#include "sprite.h" // Para Sprite
|
||||||
#include "text.h" // Para TEXT_CENTER, TEXT_SHADOW, Text
|
#include "text.h" // Para Text::CENTER, Text::SHADOW, Text
|
||||||
#include "tiled_bg.h" // Para TiledBG, TiledBGMode
|
#include "tiled_bg.h" // Para TiledBG, TiledBGMode
|
||||||
#include "ui/notifier.h" // Para Notifier
|
#include "ui/notifier.h" // Para Notifier
|
||||||
#include "ui/service_menu.h" // Para ServiceMenu
|
#include "ui/service_menu.h" // Para ServiceMenu
|
||||||
@@ -405,7 +405,7 @@ void Title::updateStartPrompt() {
|
|||||||
|
|
||||||
void Title::renderStartPrompt() {
|
void Title::renderStartPrompt() {
|
||||||
if (should_render_start_prompt_) {
|
if (should_render_start_prompt_) {
|
||||||
text_->writeDX(TEXT_CENTER | TEXT_SHADOW,
|
text_->writeDX(Text::CENTER | Text::SHADOW,
|
||||||
param.game.game_area.center_x,
|
param.game.game_area.center_x,
|
||||||
param.title.press_start_position,
|
param.title.press_start_position,
|
||||||
Lang::getText("[TITLE] PRESS_BUTTON_TO_PLAY"),
|
Lang::getText("[TITLE] PRESS_BUTTON_TO_PLAY"),
|
||||||
@@ -422,7 +422,7 @@ void Title::renderCopyright() {
|
|||||||
mini_logo_sprite_->render();
|
mini_logo_sprite_->render();
|
||||||
|
|
||||||
// Texto con el copyright
|
// Texto con el copyright
|
||||||
text_->writeDX(TEXT_CENTER | TEXT_SHADOW,
|
text_->writeDX(Text::CENTER | Text::SHADOW,
|
||||||
param.game.game_area.center_x,
|
param.game.game_area.center_x,
|
||||||
anchor_.copyright_text,
|
anchor_.copyright_text,
|
||||||
std::string(TEXT_COPYRIGHT),
|
std::string(TEXT_COPYRIGHT),
|
||||||
|
|||||||
394
source/text.cpp
394
source/text.cpp
@@ -13,9 +13,208 @@
|
|||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
Text::Text(std::shared_ptr<Texture> texture, const std::string &text_file) {
|
||||||
|
// Carga los offsets desde el fichero
|
||||||
|
auto tf = loadFile(text_file);
|
||||||
|
|
||||||
|
// Inicializa variables desde la estructura
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crea los objetos
|
||||||
|
sprite_ = std::make_unique<Sprite>(texture, (SDL_FRect){0, 0, static_cast<float>(box_width_), static_cast<float>(box_height_)});
|
||||||
|
|
||||||
|
// Inicializa variables
|
||||||
|
fixed_width_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
Text::Text(std::shared_ptr<Texture> texture, std::shared_ptr<Text::File> text_file) {
|
||||||
|
// Inicializa variables desde la estructura
|
||||||
|
box_height_ = text_file->box_height;
|
||||||
|
box_width_ = text_file->box_width;
|
||||||
|
for (int i = 0; i < 128; ++i) {
|
||||||
|
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
|
||||||
|
sprite_ = std::make_unique<Sprite>(texture, (SDL_FRect){0, 0, static_cast<float>(box_width_), static_cast<float>(box_height_)});
|
||||||
|
|
||||||
|
// Inicializa variables
|
||||||
|
fixed_width_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribe texto en pantalla
|
||||||
|
void Text::write(int x, int y, const std::string &text, int kerning, int length) {
|
||||||
|
int shift = 0;
|
||||||
|
const std::string_view visible_text = (length == -1) ? std::string_view(text) : std::string_view(text).substr(0, length);
|
||||||
|
|
||||||
|
sprite_->setY(y);
|
||||||
|
for (const auto ch : visible_text) {
|
||||||
|
const auto index = static_cast<unsigned char>(ch);
|
||||||
|
|
||||||
|
if (index < offset_.size()) {
|
||||||
|
sprite_->setSpriteClip(offset_[index].x, offset_[index].y, box_width_, box_height_);
|
||||||
|
sprite_->setX(x + shift);
|
||||||
|
sprite_->render();
|
||||||
|
shift += offset_[index].w + kerning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribe el texto al doble de tamaño
|
||||||
|
void Text::write2X(int x, int y, const std::string &text, int kerning, int length) {
|
||||||
|
int shift = 0;
|
||||||
|
const std::string_view visible_text = (length == -1) ? std::string_view(text) : std::string_view(text).substr(0, length);
|
||||||
|
|
||||||
|
for (const auto ch : visible_text) {
|
||||||
|
const auto index = static_cast<unsigned char>(ch);
|
||||||
|
|
||||||
|
if (index < offset_.size()) {
|
||||||
|
SDL_FRect rect = {
|
||||||
|
static_cast<float>(offset_[index].x),
|
||||||
|
static_cast<float>(offset_[index].y),
|
||||||
|
static_cast<float>(box_width_),
|
||||||
|
static_cast<float>(box_height_)};
|
||||||
|
|
||||||
|
sprite_->getTexture()->render(x + shift, y, &rect, 2.0F, 2.0F);
|
||||||
|
shift += (offset_[index].w + kerning) * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribe el texto en una textura
|
||||||
|
auto Text::writeToTexture(const std::string &text, int zoom, int kerning, int length) -> std::shared_ptr<Texture> {
|
||||||
|
auto *renderer = Screen::get()->getRenderer();
|
||||||
|
auto texture = std::make_shared<Texture>(renderer);
|
||||||
|
auto width = Text::length(text, kerning) * zoom;
|
||||||
|
auto height = box_height_ * zoom;
|
||||||
|
auto *temp = SDL_GetRenderTarget(renderer);
|
||||||
|
|
||||||
|
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||||
|
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||||
|
texture->setAsRenderTarget(renderer);
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
zoom == 1 ? write(0, 0, text, kerning) : write2X(0, 0, text, kerning);
|
||||||
|
SDL_SetRenderTarget(renderer, temp);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribe el texto con extras en una textura
|
||||||
|
auto Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, Color text_color, Uint8 shadow_distance, Color shadow_color, int length) -> std::shared_ptr<Texture> {
|
||||||
|
auto *renderer = Screen::get()->getRenderer();
|
||||||
|
auto texture = std::make_shared<Texture>(renderer);
|
||||||
|
auto width = Text::length(text, kerning) + shadow_distance;
|
||||||
|
auto height = box_height_ + shadow_distance;
|
||||||
|
auto *temp = SDL_GetRenderTarget(renderer);
|
||||||
|
|
||||||
|
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||||
|
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||||
|
texture->setAsRenderTarget(renderer);
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
writeDX(flags, 0, 0, text, kerning, text_color, shadow_distance, shadow_color, length);
|
||||||
|
SDL_SetRenderTarget(renderer, temp);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribe el texto con colores
|
||||||
|
void Text::writeColored(int x, int y, const std::string &text, Color color, int kerning, int length) {
|
||||||
|
sprite_->getTexture()->setColor(color.r, color.g, color.b);
|
||||||
|
write(x, y, text, kerning, length);
|
||||||
|
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 shadow_distance, int kerning, int length) {
|
||||||
|
writeDX(Text::SHADOW, x, y, text, kerning, color, shadow_distance, color, length);
|
||||||
|
write(x, y, text, kerning, length); // Dibuja el texto principal encima
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribe el texto centrado en un punto x
|
||||||
|
void Text::writeCentered(int x, int y, const std::string &text, int kerning, int length) {
|
||||||
|
x -= (Text::length(text, kerning) / 2);
|
||||||
|
write(x, y, text, kerning, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribe texto con extras
|
||||||
|
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 length) {
|
||||||
|
const auto CENTERED = ((flags & Text::CENTER) == Text::CENTER);
|
||||||
|
const auto SHADOWED = ((flags & Text::SHADOW) == Text::SHADOW);
|
||||||
|
const auto COLORED = ((flags & Text::COLOR) == Text::COLOR);
|
||||||
|
const auto STROKED = ((flags & Text::STROKE) == Text::STROKE);
|
||||||
|
|
||||||
|
if (CENTERED) {
|
||||||
|
x -= (Text::length(text, kerning) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SHADOWED) {
|
||||||
|
writeColored(x + shadow_distance, y + shadow_distance, text, shadow_color, kerning, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
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, shadow_color, kerning, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COLORED) {
|
||||||
|
writeColored(x, y, text, text_color, kerning, length);
|
||||||
|
} else {
|
||||||
|
write(x, y, text, kerning, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escribe texto a partir de un TextStyle
|
||||||
|
void Text::writeStyle(int x, int y, const std::string &text, const Style &style, int length) {
|
||||||
|
writeDX(style.flags, x, y, text, style.kerning, style.text_color, style.shadow_distance, style.shadow_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtiene la longitud en pixels de una cadena
|
||||||
|
auto Text::length(const std::string &text, int kerning) const -> int {
|
||||||
|
int shift = 0;
|
||||||
|
for (const auto &ch : text) {
|
||||||
|
// Convertimos a unsigned char para obtener el valor ASCII correcto (0-255)
|
||||||
|
const auto index = static_cast<unsigned char>(ch);
|
||||||
|
|
||||||
|
// Verificamos si el carácter está dentro de los límites del array
|
||||||
|
if (index < offset_.size()) {
|
||||||
|
shift += (offset_[index].w + kerning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Descuenta el kerning del último caracter si el texto no está vacío
|
||||||
|
return text.empty() ? 0 : shift - kerning;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Devuelve el valor de la variable
|
||||||
|
auto Text::getCharacterSize() const -> int {
|
||||||
|
return box_width_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece si se usa un tamaño fijo de letra
|
||||||
|
void Text::setFixedWidth(bool value) {
|
||||||
|
fixed_width_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
// Llena una estructuta TextFile desde un fichero
|
// Llena una estructuta TextFile desde un fichero
|
||||||
auto loadTextFile(const std::string &file_path) -> std::shared_ptr<TextFile> {
|
auto Text::loadFile(const std::string &file_path) -> std::shared_ptr<Text::File> {
|
||||||
auto tf = std::make_shared<TextFile>();
|
auto tf = std::make_shared<Text::File>();
|
||||||
|
|
||||||
// Inicializa a cero el vector con las coordenadas
|
// Inicializa a cero el vector con las coordenadas
|
||||||
for (auto &i : tf->offset) {
|
for (auto &i : tf->offset) {
|
||||||
@@ -74,194 +273,3 @@ auto loadTextFile(const std::string &file_path) -> std::shared_ptr<TextFile> {
|
|||||||
|
|
||||||
return tf;
|
return tf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
|
||||||
Text::Text(std::shared_ptr<Texture> texture, const std::string &text_file) {
|
|
||||||
// Carga los offsets desde el fichero
|
|
||||||
auto tf = loadTextFile(text_file);
|
|
||||||
|
|
||||||
// Inicializa variables desde la estructura
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crea los objetos
|
|
||||||
sprite_ = std::make_unique<Sprite>(texture, (SDL_FRect){0, 0, static_cast<float>(box_width_), static_cast<float>(box_height_)});
|
|
||||||
|
|
||||||
// Inicializa variables
|
|
||||||
fixed_width_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
Text::Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file) {
|
|
||||||
// Inicializa variables desde la estructura
|
|
||||||
box_height_ = text_file->box_height;
|
|
||||||
box_width_ = text_file->box_width;
|
|
||||||
for (int i = 0; i < 128; ++i) {
|
|
||||||
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
|
|
||||||
sprite_ = std::make_unique<Sprite>(texture, (SDL_FRect){0, 0, static_cast<float>(box_width_), static_cast<float>(box_height_)});
|
|
||||||
|
|
||||||
// Inicializa variables
|
|
||||||
fixed_width_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escribe texto en pantalla
|
|
||||||
void Text::write(int x, int y, const std::string &text, int kerning, int lenght) {
|
|
||||||
int shift = 0;
|
|
||||||
|
|
||||||
if (lenght == -1) {
|
|
||||||
lenght = text.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite_->setY(y);
|
|
||||||
for (int i = 0; i < lenght; ++i) {
|
|
||||||
auto index = static_cast<int>(text[i]);
|
|
||||||
sprite_->setSpriteClip(offset_[index].x, offset_[index].y, box_width_, box_height_);
|
|
||||||
sprite_->setX(x + shift);
|
|
||||||
sprite_->render();
|
|
||||||
shift += offset_[static_cast<int>(text[i])].w + kerning;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escribe texto en pantalla
|
|
||||||
void Text::write2X(int x, int y, const std::string &text, int kerning) {
|
|
||||||
int shift = 0;
|
|
||||||
for (size_t i = 0; i < text.length(); ++i) {
|
|
||||||
auto index = static_cast<size_t>(text[i]);
|
|
||||||
SDL_FRect rect = {static_cast<float>(offset_[index].x), static_cast<float>(offset_[index].y), static_cast<float>(box_width_), static_cast<float>(box_height_)};
|
|
||||||
sprite_->getTexture()->render(x + shift, y, &rect, 2.0F, 2.0F);
|
|
||||||
shift += (offset_[index].w + kerning) * 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escribe el texto en una textura
|
|
||||||
auto Text::writeToTexture(const std::string &text, int zoom, int kerning) -> std::shared_ptr<Texture> {
|
|
||||||
auto *renderer = Screen::get()->getRenderer();
|
|
||||||
auto texture = std::make_shared<Texture>(renderer);
|
|
||||||
auto width = lenght(text, kerning) * zoom;
|
|
||||||
auto height = box_height_ * zoom;
|
|
||||||
auto *temp = SDL_GetRenderTarget(renderer);
|
|
||||||
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
|
||||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
|
||||||
texture->setAsRenderTarget(renderer);
|
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
|
||||||
SDL_RenderClear(renderer);
|
|
||||||
zoom == 1 ? write(0, 0, text, kerning) : write2X(0, 0, text, kerning);
|
|
||||||
SDL_SetRenderTarget(renderer, temp);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escribe el texto con extras en una textura
|
|
||||||
auto Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, Color text_color, Uint8 shadow_distance, Color shadow_color, int lenght) -> std::shared_ptr<Texture> {
|
|
||||||
auto *renderer = Screen::get()->getRenderer();
|
|
||||||
auto texture = std::make_shared<Texture>(renderer);
|
|
||||||
auto width = Text::lenght(text, kerning) + shadow_distance;
|
|
||||||
auto height = box_height_ + shadow_distance;
|
|
||||||
auto *temp = SDL_GetRenderTarget(renderer);
|
|
||||||
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
|
||||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
|
||||||
texture->setAsRenderTarget(renderer);
|
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
|
||||||
SDL_RenderClear(renderer);
|
|
||||||
writeDX(flags, 0, 0, text, kerning, text_color, shadow_distance, shadow_color, lenght);
|
|
||||||
SDL_SetRenderTarget(renderer, temp);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
write(x, y, text, kerning, lenght);
|
|
||||||
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 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escribe el texto centrado en un punto x
|
|
||||||
void Text::writeCentered(int x, int y, const std::string &text, int kerning, int lenght) {
|
|
||||||
x -= (Text::lenght(text, kerning) / 2);
|
|
||||||
write(x, y, text, kerning, lenght);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escribe texto con extras
|
|
||||||
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 auto CENTERED = ((flags & TEXT_CENTER) == TEXT_CENTER);
|
|
||||||
const auto SHADOWED = ((flags & TEXT_SHADOW) == TEXT_SHADOW);
|
|
||||||
const auto COLORED = ((flags & TEXT_COLOR) == TEXT_COLOR);
|
|
||||||
const auto STROKED = ((flags & TEXT_STROKE) == TEXT_STROKE);
|
|
||||||
|
|
||||||
if (CENTERED) {
|
|
||||||
x -= (Text::lenght(text, kerning) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SHADOWED) {
|
|
||||||
writeColored(x + shadow_distance, y + shadow_distance, text, shadow_color, kerning, lenght);
|
|
||||||
}
|
|
||||||
|
|
||||||
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, shadow_color, kerning, lenght);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (COLORED) {
|
|
||||||
writeColored(x, y, text, text_color, kerning, lenght);
|
|
||||||
} else {
|
|
||||||
write(x, y, text, kerning, lenght);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escribe texto a partir de un TextStyle
|
|
||||||
void Text::writeDX(Uint8 flags, int x, int y, const std::string &text, const TextStyle &style, int length) {
|
|
||||||
writeDX(flags, x, y, text, style.kerning, style.text_color, style.shadow_distance, style.shadow_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtiene la longitud en pixels de una cadena
|
|
||||||
auto Text::lenght(const std::string &text, int kerning) const -> int {
|
|
||||||
int shift = 0;
|
|
||||||
for (size_t i = 0; i < text.length(); ++i) {
|
|
||||||
shift += (offset_[static_cast<int>(text[i])].w + kerning);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Descuenta el kerning del último caracter
|
|
||||||
return shift - kerning;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Devuelve el valor de la variable
|
|
||||||
auto Text::getCharacterSize() const -> int {
|
|
||||||
return box_width_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece si se usa un tamaño fijo de letra
|
|
||||||
void Text::setFixedWidth(bool value) {
|
|
||||||
fixed_width_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece una paleta
|
|
||||||
void Text::setPalette(int number) {
|
|
||||||
auto *temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
|
||||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
|
||||||
sprite_->getTexture()->setPalette(number);
|
|
||||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
|
||||||
}
|
|
||||||
@@ -11,57 +11,57 @@
|
|||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
|
// --- Clase Text: pinta texto en pantalla a partir de un bitmap ---
|
||||||
|
class Text {
|
||||||
|
public:
|
||||||
// --- Constantes para flags de texto ---
|
// --- Constantes para flags de texto ---
|
||||||
constexpr int TEXT_COLOR = 1;
|
static constexpr int COLOR = 1;
|
||||||
constexpr int TEXT_SHADOW = 2;
|
static constexpr int SHADOW = 2;
|
||||||
constexpr int TEXT_CENTER = 4;
|
static constexpr int CENTER = 4;
|
||||||
constexpr int TEXT_STROKE = 8;
|
static constexpr int STROKE = 8;
|
||||||
|
|
||||||
// --- Estructuras auxiliares ---
|
// --- Estructuras ---
|
||||||
struct TextOffset {
|
struct Offset {
|
||||||
int x, y, w;
|
int x, y, w;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextFile {
|
struct File {
|
||||||
int box_width; // Anchura 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
|
int box_height; // Altura de la caja de cada caracter en el png
|
||||||
std::array<TextOffset, 128> offset = {}; // Vector con las posiciones y ancho de cada letra
|
std::array<Offset, 128> offset = {}; // Vector con las posiciones y ancho de cada letra
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextStyle {
|
struct Style {
|
||||||
|
Uint8 flags;
|
||||||
Color text_color;
|
Color text_color;
|
||||||
Color shadow_color;
|
Color shadow_color;
|
||||||
Uint8 shadow_distance;
|
Uint8 shadow_distance;
|
||||||
int kerning;
|
int kerning;
|
||||||
|
|
||||||
// Constructor con argumentos por defecto
|
// Constructor con argumentos por defecto
|
||||||
TextStyle(Color text = Color(),
|
Style(Uint8 flags = 0,
|
||||||
|
Color text = Color(),
|
||||||
Color shadow = Color(),
|
Color shadow = Color(),
|
||||||
Uint8 distance = 1,
|
Uint8 distance = 1,
|
||||||
int kern = 1)
|
int kern = 1)
|
||||||
: text_color(text),
|
: flags(flags),
|
||||||
|
text_color(text),
|
||||||
shadow_color(shadow),
|
shadow_color(shadow),
|
||||||
shadow_distance(distance),
|
shadow_distance(distance),
|
||||||
kerning(kern) {}
|
kerning(kern) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Llena una estructura TextFile desde un fichero
|
|
||||||
auto loadTextFile(const std::string &file_path) -> std::shared_ptr<TextFile>;
|
|
||||||
|
|
||||||
// --- Clase Text: pinta texto en pantalla a partir de un bitmap ---
|
|
||||||
class Text {
|
|
||||||
public:
|
|
||||||
// --- Constructores y destructor ---
|
// --- Constructores y destructor ---
|
||||||
Text(std::shared_ptr<Texture> texture, const std::string &text_file);
|
Text(std::shared_ptr<Texture> texture, const std::string &text_file);
|
||||||
Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file);
|
Text(std::shared_ptr<Texture> texture, std::shared_ptr<Text::File> text_file);
|
||||||
~Text() = default;
|
~Text() = default;
|
||||||
|
|
||||||
// --- Métodos de escritura en pantalla ---
|
// --- Métodos de escritura en pantalla ---
|
||||||
void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla
|
void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla
|
||||||
void write2X(int x, int y, const std::string &text, int kerning = 1); // Escribe el texto al doble de tamaño
|
void write2X(int x, int y, const std::string &text, int kerning = 1, int length = -1); // Escribe el texto al doble de tamaño
|
||||||
|
|
||||||
// --- Escritura en textura ---
|
// --- Escritura en textura ---
|
||||||
auto writeToTexture(const std::string &text, int zoom = 1, int kerning = 1) -> std::shared_ptr<Texture>; // Escribe el texto en una textura
|
auto writeToTexture(const std::string &text, int zoom = 1, int kerning = 1, int lenght = -1) -> std::shared_ptr<Texture>; // Escribe el texto en una textura
|
||||||
auto writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1) -> std::shared_ptr<Texture>; // Escribe el texto con extras en una textura
|
auto writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1) -> std::shared_ptr<Texture>; // Escribe el texto con extras en una textura
|
||||||
|
|
||||||
// --- Métodos de escritura avanzada ---
|
// --- Métodos de escritura avanzada ---
|
||||||
@@ -69,15 +69,17 @@ class Text {
|
|||||||
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 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 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(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe texto con extras
|
void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe texto con extras
|
||||||
void writeDX(Uint8 flags, int x, int y, const std::string &text, const TextStyle &style, int length = -1); // Escribe texto a partir de un TextStyle
|
void writeStyle(int x, int y, const std::string &text, const Style &style, int length = -1); // Escribe texto a partir de un TextStyle
|
||||||
|
|
||||||
// --- Utilidades ---
|
// --- Utilidades ---
|
||||||
[[nodiscard]] auto lenght(const std::string &text, int kerning = 1) const -> int; // Obtiene la longitud en pixels de una cadena
|
[[nodiscard]] auto length(const std::string &text, int kerning = 1) const -> int; // Obtiene la longitud en pixels de una cadena
|
||||||
[[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el tamaño de caracter actual
|
[[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el tamaño de caracter actual
|
||||||
|
|
||||||
// --- Configuración ---
|
// --- Configuración ---
|
||||||
void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra
|
void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra
|
||||||
void setPalette(int number); // Establece una paleta
|
|
||||||
|
// Llena una estructura Text::File desde un fichero
|
||||||
|
static auto loadFile(const std::string &file_path) -> std::shared_ptr<Text::File>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Objetos y punteros ---
|
// --- Objetos y punteros ---
|
||||||
@@ -87,6 +89,5 @@ class Text {
|
|||||||
int box_width_ = 0; // Anchura de la caja de cada caracter en el png
|
int box_width_ = 0; // Anchura de la caja de cada caracter en el png
|
||||||
int box_height_ = 0; // Altura de la caja de cada caracter en el png
|
int box_height_ = 0; // Altura de la caja de cada caracter en el png
|
||||||
bool fixed_width_ = false; // Indica si el texto se ha de escribir con longitud fija en todas las letras
|
bool fixed_width_ = false; // Indica si el texto se ha de escribir con longitud fija en todas las letras
|
||||||
std::array<TextOffset, 128> offset_ = {};
|
std::array<Offset, 128> offset_ = {}; // Vector con las posiciones y ancho de cada letra
|
||||||
; // Vector con las posiciones y ancho de cada letra
|
|
||||||
};
|
};
|
||||||
@@ -19,7 +19,7 @@ auto ActionListOption::getValueAsString() const -> std::string {
|
|||||||
auto ActionListOption::getMaxValueWidth(Text* text) const -> int {
|
auto ActionListOption::getMaxValueWidth(Text* text) const -> int {
|
||||||
int max_width = 0;
|
int max_width = 0;
|
||||||
for (const auto& option : options_) {
|
for (const auto& option : options_) {
|
||||||
int width = text->lenght(option, -2);
|
int width = text->length(option, -2);
|
||||||
if (width > max_width) {
|
if (width > max_width) {
|
||||||
max_width = width;
|
max_width = width;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ class BoolOption : public MenuOption {
|
|||||||
}
|
}
|
||||||
auto getMaxValueWidth(Text *text_renderer) const -> int override {
|
auto getMaxValueWidth(Text *text_renderer) const -> int override {
|
||||||
return std::max(
|
return std::max(
|
||||||
text_renderer->lenght(Lang::getText("[SERVICE_MENU] ON"), -2),
|
text_renderer->length(Lang::getText("[SERVICE_MENU] ON"), -2),
|
||||||
text_renderer->lenght(Lang::getText("[SERVICE_MENU] OFF"), -2));
|
text_renderer->length(Lang::getText("[SERVICE_MENU] OFF"), -2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -87,7 +87,7 @@ class IntOption : public MenuOption {
|
|||||||
|
|
||||||
// Iterar por todos los valores posibles en el rango
|
// Iterar por todos los valores posibles en el rango
|
||||||
for (int value = min_value_; value <= max_value_; value += step_value_) {
|
for (int value = min_value_; value <= max_value_; value += step_value_) {
|
||||||
int width = text_renderer->lenght(std::to_string(value), -2);
|
int width = text_renderer->length(std::to_string(value), -2);
|
||||||
max_width = std::max(max_width, width);
|
max_width = std::max(max_width, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ class ListOption : public MenuOption {
|
|||||||
auto getMaxValueWidth(Text *text_renderer) const -> int override {
|
auto getMaxValueWidth(Text *text_renderer) const -> int override {
|
||||||
int max_w = 0;
|
int max_w = 0;
|
||||||
for (const auto &val : value_list_) {
|
for (const auto &val : value_list_) {
|
||||||
max_w = std::max(max_w, text_renderer->lenght(val, -2));
|
max_w = std::max(max_w, text_renderer->length(val, -2));
|
||||||
}
|
}
|
||||||
return max_w;
|
return max_w;
|
||||||
}
|
}
|
||||||
@@ -182,12 +182,8 @@ class ActionListOption : public MenuOption {
|
|||||||
using ValueSetter = std::function<void(const std::string &)>;
|
using ValueSetter = std::function<void(const std::string &)>;
|
||||||
using ActionExecutor = std::function<void()>;
|
using ActionExecutor = std::function<void()>;
|
||||||
|
|
||||||
ActionListOption(const std::string& caption, ServiceMenu::SettingsGroup group,
|
ActionListOption(const std::string &caption, ServiceMenu::SettingsGroup group, std::vector<std::string> options, ValueGetter getter, ValueSetter setter, ActionExecutor action_executor, bool hidden = false)
|
||||||
std::vector<std::string> options, ValueGetter getter, ValueSetter setter,
|
: MenuOption(caption, group, hidden), options_(std::move(options)), value_getter_(std::move(getter)), value_setter_(std::move(setter)), action_executor_(std::move(action_executor)), current_index_(0) {
|
||||||
ActionExecutor action_executor, bool hidden = false)
|
|
||||||
: MenuOption(caption, group, hidden), options_(std::move(options)),
|
|
||||||
value_getter_(std::move(getter)), value_setter_(std::move(setter)),
|
|
||||||
action_executor_(std::move(action_executor)), current_index_(0) {
|
|
||||||
updateCurrentIndex();
|
updateCurrentIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "menu_option.h" // Para MenuOption
|
#include "menu_option.h" // Para MenuOption
|
||||||
#include "param.h" // Para Param, param, ParamServiceMenu, ParamGame
|
#include "param.h" // Para Param, param, ParamServiceMenu, ParamGame
|
||||||
#include "screen.h" // Para Screen
|
#include "screen.h" // Para Screen
|
||||||
#include "text.h" // Para Text, TEXT_CENTER, TEXT_COLOR
|
#include "text.h" // Para Text, Text::CENTER, Text::COLOR
|
||||||
#include "utils.h" // Para Zone, truncateWithEllipsis
|
#include "utils.h" // Para Zone, truncateWithEllipsis
|
||||||
|
|
||||||
MenuRenderer::MenuRenderer(const ServiceMenu *menu_state, std::shared_ptr<Text> element_text, std::shared_ptr<Text> title_text)
|
MenuRenderer::MenuRenderer(const ServiceMenu *menu_state, std::shared_ptr<Text> element_text, std::shared_ptr<Text> title_text)
|
||||||
@@ -35,7 +35,7 @@ void MenuRenderer::render(const ServiceMenu *menu_state) {
|
|||||||
|
|
||||||
// Dibuja el título
|
// Dibuja el título
|
||||||
float y = rect_.y + title_padding_;
|
float y = rect_.y + title_padding_;
|
||||||
title_text_->writeDX(TEXT_COLOR | TEXT_CENTER, param.game.game_area.center_x, y, menu_state->getTitle(), -4, param.service_menu.title_color);
|
title_text_->writeDX(Text::COLOR | Text::CENTER, param.game.game_area.center_x, y, menu_state->getTitle(), -4, param.service_menu.title_color);
|
||||||
|
|
||||||
// Dibuja la línea separadora
|
// Dibuja la línea separadora
|
||||||
y = rect_.y + upper_height_;
|
y = rect_.y + upper_height_;
|
||||||
@@ -54,18 +54,18 @@ void MenuRenderer::render(const ServiceMenu *menu_state) {
|
|||||||
if (menu_state->getCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) {
|
if (menu_state->getCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) {
|
||||||
// Para opciones alineadas a la izquierda, truncamos el valor si es necesario
|
// Para opciones alineadas a la izquierda, truncamos el valor si es necesario
|
||||||
const int available_width = rect_.w - (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2) -
|
const int available_width = rect_.w - (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2) -
|
||||||
element_text_->lenght(option_pairs.at(i).first, -2) -
|
element_text_->length(option_pairs.at(i).first, -2) -
|
||||||
ServiceMenu::MIN_GAP_OPTION_VALUE;
|
ServiceMenu::MIN_GAP_OPTION_VALUE;
|
||||||
|
|
||||||
std::string truncated_value = getTruncatedValue(option_pairs.at(i).second, available_width);
|
std::string truncated_value = getTruncatedValue(option_pairs.at(i).second, available_width);
|
||||||
|
|
||||||
// Si la opción tiene Behavior::BOTH, añadir indicador visual
|
// Si la opción tiene Behavior::BOTH, añadir indicador visual
|
||||||
if (i < display_options.size() && display_options[i]->getBehavior() == MenuOption::Behavior::BOTH) {
|
if (i < display_options.size() && display_options[i]->getBehavior() == MenuOption::Behavior::BOTH) {
|
||||||
truncated_value = "► " + truncated_value + " ◄";
|
truncated_value = "-" + truncated_value + "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
element_text_->writeColored(rect_.x + ServiceMenu::OPTIONS_HORIZONTAL_PADDING, y, option_pairs.at(i).first, current_color, -2);
|
element_text_->writeColored(rect_.x + ServiceMenu::OPTIONS_HORIZONTAL_PADDING, y, option_pairs.at(i).first, current_color, -2);
|
||||||
const int X = rect_.x + rect_.w - ServiceMenu::OPTIONS_HORIZONTAL_PADDING - element_text_->lenght(truncated_value, -2);
|
const int X = rect_.x + rect_.w - ServiceMenu::OPTIONS_HORIZONTAL_PADDING - element_text_->length(truncated_value, -2);
|
||||||
element_text_->writeColored(X, y, truncated_value, current_color, -2);
|
element_text_->writeColored(X, y, truncated_value, current_color, -2);
|
||||||
} else {
|
} else {
|
||||||
// Para opciones centradas, también truncamos si es necesario
|
// Para opciones centradas, también truncamos si es necesario
|
||||||
@@ -74,10 +74,10 @@ void MenuRenderer::render(const ServiceMenu *menu_state) {
|
|||||||
|
|
||||||
// Si la opción tiene Behavior::BOTH, añadir indicador visual
|
// Si la opción tiene Behavior::BOTH, añadir indicador visual
|
||||||
if (i < display_options.size() && display_options[i]->getBehavior() == MenuOption::Behavior::BOTH) {
|
if (i < display_options.size() && display_options[i]->getBehavior() == MenuOption::Behavior::BOTH) {
|
||||||
truncated_caption = "► " + truncated_caption + " ◄";
|
truncated_caption = "-" + truncated_caption + "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
element_text_->writeDX(TEXT_CENTER | TEXT_COLOR, rect_.x + rect_.w / 2, y, truncated_caption, -2, current_color);
|
element_text_->writeDX(Text::CENTER | Text::COLOR, rect_.x + rect_.w / 2, y, truncated_caption, -2, current_color);
|
||||||
}
|
}
|
||||||
y += options_height_ + options_padding_;
|
y += options_height_ + options_padding_;
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ void MenuRenderer::precalculateMenuWidths(const std::vector<std::unique_ptr<Menu
|
|||||||
if (option->getGroup() != sg) {
|
if (option->getGroup() != sg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
max_option_width = std::max(max_option_width, element_text_->lenght(option->getCaption(), -2));
|
max_option_width = std::max(max_option_width, element_text_->length(option->getCaption(), -2));
|
||||||
if (menu_state->getCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) {
|
if (menu_state->getCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) {
|
||||||
// Para calcular el ancho máximo, necesitamos considerar la truncación
|
// Para calcular el ancho máximo, necesitamos considerar la truncación
|
||||||
int max_available_value_width = static_cast<int>(max_menu_width_) - max_option_width -
|
int max_available_value_width = static_cast<int>(max_menu_width_) - max_option_width -
|
||||||
@@ -240,14 +240,14 @@ auto MenuRenderer::setRect(SDL_FRect rect) -> SDL_FRect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto MenuRenderer::getTruncatedValueWidth(const std::string &value, int available_width) const -> int {
|
auto MenuRenderer::getTruncatedValueWidth(const std::string &value, int available_width) const -> int {
|
||||||
int value_width = element_text_->lenght(value, -2);
|
int value_width = element_text_->length(value, -2);
|
||||||
if (value_width <= available_width) {
|
if (value_width <= available_width) {
|
||||||
return value_width;
|
return value_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculamos cuántos caracteres podemos mostrar más los puntos suspensivos
|
// Calculamos cuántos caracteres podemos mostrar más los puntos suspensivos
|
||||||
// Estimamos el ancho de los puntos suspensivos como 3 caracteres promedio
|
// Estimamos el ancho de los puntos suspensivos como 3 caracteres promedio
|
||||||
int ellipsis_width = element_text_->lenght("...", -2);
|
int ellipsis_width = element_text_->length("...", -2);
|
||||||
int available_for_text = available_width - ellipsis_width;
|
int available_for_text = available_width - ellipsis_width;
|
||||||
|
|
||||||
if (available_for_text <= 0) {
|
if (available_for_text <= 0) {
|
||||||
@@ -260,17 +260,17 @@ auto MenuRenderer::getTruncatedValueWidth(const std::string &value, int availabl
|
|||||||
|
|
||||||
// Verificamos el ancho real del texto truncado
|
// Verificamos el ancho real del texto truncado
|
||||||
std::string truncated = truncateWithEllipsis(value, max_chars);
|
std::string truncated = truncateWithEllipsis(value, max_chars);
|
||||||
return element_text_->lenght(truncated, -2);
|
return element_text_->length(truncated, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto MenuRenderer::getTruncatedValue(const std::string &value, int available_width) const -> std::string {
|
auto MenuRenderer::getTruncatedValue(const std::string &value, int available_width) const -> std::string {
|
||||||
int value_width = element_text_->lenght(value, -2);
|
int value_width = element_text_->length(value, -2);
|
||||||
if (value_width <= available_width) {
|
if (value_width <= available_width) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculamos cuántos caracteres podemos mostrar
|
// Calculamos cuántos caracteres podemos mostrar
|
||||||
int ellipsis_width = element_text_->lenght("...", -2);
|
int ellipsis_width = element_text_->length("...", -2);
|
||||||
int available_for_text = available_width - ellipsis_width;
|
int available_for_text = available_width - ellipsis_width;
|
||||||
|
|
||||||
if (available_for_text <= 0) {
|
if (available_for_text <= 0) {
|
||||||
@@ -283,7 +283,7 @@ auto MenuRenderer::getTruncatedValue(const std::string &value, int available_wid
|
|||||||
|
|
||||||
// Ajustamos iterativamente hasta que el texto quepa
|
// Ajustamos iterativamente hasta que el texto quepa
|
||||||
std::string truncated = truncateWithEllipsis(value, max_chars);
|
std::string truncated = truncateWithEllipsis(value, max_chars);
|
||||||
while (element_text_->lenght(truncated, -2) > available_width && max_chars > 1) {
|
while (element_text_->length(truncated, -2) > available_width && max_chars > 1) {
|
||||||
max_chars--;
|
max_chars--;
|
||||||
truncated = truncateWithEllipsis(value, max_chars);
|
truncated = truncateWithEllipsis(value, max_chars);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string&
|
|||||||
const float PADDING_IN_H = text_->getCharacterSize();
|
const float PADDING_IN_H = text_->getCharacterSize();
|
||||||
const float PADDING_IN_V = text_->getCharacterSize() / 2;
|
const float PADDING_IN_V = text_->getCharacterSize() / 2;
|
||||||
const int ICON_SPACE = icon >= 0 ? ICON_SIZE + PADDING_IN_H : 0;
|
const int ICON_SPACE = icon >= 0 ? ICON_SIZE + PADDING_IN_H : 0;
|
||||||
const float WIDTH = text_->lenght(longest) + (PADDING_IN_H * 2) + ICON_SPACE;
|
const float WIDTH = text_->length(longest) + (PADDING_IN_H * 2) + ICON_SPACE;
|
||||||
const float HEIGHT = (text_->getCharacterSize() * texts.size()) + (PADDING_IN_V * 2);
|
const float HEIGHT = (text_->getCharacterSize() * texts.size()) + (PADDING_IN_V * 2);
|
||||||
const auto SHAPE = NotificationShape::SQUARED;
|
const auto SHAPE = NotificationShape::SQUARED;
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ void ServiceMenu::selectOption() {
|
|||||||
current_settings_group_ = folder->getTargetGroup();
|
current_settings_group_ = folder->getTargetGroup();
|
||||||
selected_ = 0;
|
selected_ = 0;
|
||||||
updateMenu();
|
updateMenu();
|
||||||
} else if (selected_option->getBehavior() == MenuOption::Behavior::SELECT) {
|
} else if (selected_option->getBehavior() == MenuOption::Behavior::SELECT or selected_option->getBehavior() == MenuOption::Behavior::BOTH) {
|
||||||
selected_option->executeAction();
|
selected_option->executeAction();
|
||||||
}
|
}
|
||||||
playSelectSound();
|
playSelectSound();
|
||||||
@@ -554,7 +554,7 @@ void ServiceMenu::handleEvent(const SDL_Event &event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Procesar eventos normales del ServiceMenu
|
// Procesar eventos normales del ServiceMenu
|
||||||
switch (event.type) {
|
/*switch (event.type) {
|
||||||
case SDL_EVENT_KEY_DOWN:
|
case SDL_EVENT_KEY_DOWN:
|
||||||
switch (event.key.key) {
|
switch (event.key.key) {
|
||||||
case SDLK_ESCAPE:
|
case SDLK_ESCAPE:
|
||||||
@@ -611,5 +611,5 @@ void ServiceMenu::handleEvent(const SDL_Event &event) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <cmath> // Para pow
|
#include <cmath> // Para pow
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "text.h" // Para TEXT_CENTER, TEXT_COLOR, Text
|
#include "text.h" // Para Text::CENTER, Text::COLOR, Text
|
||||||
|
|
||||||
// Constructor: inicializa el renderizador, el texto y el color del mensaje
|
// Constructor: inicializa el renderizador, el texto y el color del mensaje
|
||||||
UIMessage::UIMessage(std::shared_ptr<Text> text_renderer, std::string message_text, const Color &color)
|
UIMessage::UIMessage(std::shared_ptr<Text> text_renderer, std::string message_text, const Color &color)
|
||||||
@@ -70,7 +70,7 @@ void UIMessage::updateAnimation() {
|
|||||||
void UIMessage::render() {
|
void UIMessage::render() {
|
||||||
if (visible_) {
|
if (visible_) {
|
||||||
text_renderer_->writeDX(
|
text_renderer_->writeDX(
|
||||||
TEXT_COLOR | TEXT_CENTER,
|
Text::COLOR | Text::CENTER,
|
||||||
base_x_,
|
base_x_,
|
||||||
base_y_ + y_offset_,
|
base_y_ + y_offset_,
|
||||||
text_,
|
text_,
|
||||||
|
|||||||
@@ -10,16 +10,12 @@
|
|||||||
WindowMessage::WindowMessage(
|
WindowMessage::WindowMessage(
|
||||||
std::shared_ptr<Text> text_renderer,
|
std::shared_ptr<Text> text_renderer,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const Color& bg_color,
|
const Config& config)
|
||||||
const Color& border_color,
|
: text_renderer_(std::move(text_renderer)),
|
||||||
const Color& title_color,
|
config_(config),
|
||||||
const Color& text_color
|
|
||||||
) : text_renderer_(std::move(text_renderer)),
|
|
||||||
title_(title),
|
title_(title),
|
||||||
bg_color_(bg_color),
|
title_style_(Text::CENTER | Text::COLOR, config_.title_color, config_.title_color, 0, -2),
|
||||||
border_color_(border_color),
|
text_style_(Text::CENTER | Text::COLOR, config_.text_color, config_.text_color, 0, -2) {
|
||||||
title_color_(title_color),
|
|
||||||
text_color_(text_color) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::render() {
|
void WindowMessage::render() {
|
||||||
@@ -30,49 +26,59 @@ void WindowMessage::render() {
|
|||||||
SDL_Renderer* renderer = Screen::get()->getRenderer();
|
SDL_Renderer* renderer = Screen::get()->getRenderer();
|
||||||
|
|
||||||
// Dibujar fondo con transparencia
|
// Dibujar fondo con transparencia
|
||||||
SDL_SetRenderDrawColor(renderer, bg_color_.r, bg_color_.g, bg_color_.b, bg_color_.a);
|
SDL_SetRenderDrawColor(renderer, config_.bg_color.r, config_.bg_color.g,
|
||||||
|
config_.bg_color.b, config_.bg_color.a);
|
||||||
SDL_RenderFillRect(renderer, &rect_);
|
SDL_RenderFillRect(renderer, &rect_);
|
||||||
|
|
||||||
// Dibujar borde
|
// Dibujar borde
|
||||||
SDL_SetRenderDrawColor(renderer, border_color_.r, border_color_.g, border_color_.b, border_color_.a);
|
SDL_SetRenderDrawColor(renderer, config_.border_color.r, config_.border_color.g,
|
||||||
|
config_.border_color.b, config_.border_color.a);
|
||||||
SDL_RenderRect(renderer, &rect_);
|
SDL_RenderRect(renderer, &rect_);
|
||||||
|
|
||||||
float current_y = rect_.y + padding_;
|
float current_y = rect_.y + config_.padding;
|
||||||
|
|
||||||
// Dibujar título si existe
|
// Dibujar título si existe
|
||||||
if (!title_.empty()) {
|
if (!title_.empty()) {
|
||||||
text_renderer_->writeCentered(
|
text_renderer_->writeStyle(
|
||||||
rect_.x + rect_.w / 2.0f,
|
rect_.x + rect_.w / 2.0f,
|
||||||
current_y,
|
current_y,
|
||||||
title_
|
title_,
|
||||||
//title_color_
|
title_style_);
|
||||||
);
|
current_y += text_renderer_->getCharacterSize() + config_.title_separator_spacing;
|
||||||
current_y += text_renderer_->getCharacterSize() + line_spacing_ * 2;
|
|
||||||
|
|
||||||
// Línea separadora debajo del título
|
// Línea separadora debajo del título
|
||||||
SDL_SetRenderDrawColor(renderer, border_color_.r, border_color_.g, border_color_.b, border_color_.a);
|
SDL_SetRenderDrawColor(renderer, config_.border_color.r, config_.border_color.g,
|
||||||
|
config_.border_color.b, config_.border_color.a);
|
||||||
SDL_RenderLine(renderer,
|
SDL_RenderLine(renderer,
|
||||||
rect_.x + padding_, current_y - line_spacing_,
|
rect_.x + config_.padding,
|
||||||
rect_.x + rect_.w - padding_, current_y - line_spacing_);
|
current_y - config_.title_separator_spacing / 2.0f,
|
||||||
|
rect_.x + rect_.w - config_.padding,
|
||||||
|
current_y - config_.title_separator_spacing / 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dibujar textos
|
// Dibujar textos
|
||||||
for (const auto& text : texts_) {
|
for (const auto& text : texts_) {
|
||||||
text_renderer_->writeCentered(
|
text_renderer_->writeStyle(
|
||||||
rect_.x + rect_.w / 2.0f,
|
rect_.x + rect_.w / 2.0f,
|
||||||
current_y,
|
current_y,
|
||||||
text
|
text,
|
||||||
//text_color_
|
text_style_);
|
||||||
);
|
current_y += text_renderer_->getCharacterSize() + config_.line_spacing;
|
||||||
current_y += text_renderer_->getCharacterSize() + line_spacing_;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::update() {
|
void WindowMessage::update() {
|
||||||
// Por ahora no hay animaciones, pero se puede extender
|
// Actualizar animación de redimensionado
|
||||||
|
if (resize_animation_.active) {
|
||||||
|
// Aquí necesitarías el delta_time del game loop
|
||||||
|
// Por ahora usamos un valor fijo, pero idealmente se pasaría como parámetro
|
||||||
|
float delta_time = 1.0f / 60.0f; // Asumiendo 60 FPS
|
||||||
|
updateAnimation(delta_time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::show() {
|
void WindowMessage::show() {
|
||||||
|
ensureTextFits();
|
||||||
visible_ = true;
|
visible_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,58 +88,120 @@ void WindowMessage::hide() {
|
|||||||
|
|
||||||
void WindowMessage::setTitle(const std::string& title) {
|
void WindowMessage::setTitle(const std::string& title) {
|
||||||
title_ = title;
|
title_ = title;
|
||||||
|
triggerAutoResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::setText(const std::string& text) {
|
void WindowMessage::setText(const std::string& text) {
|
||||||
texts_.clear();
|
texts_.clear();
|
||||||
texts_.push_back(text);
|
texts_.push_back(text);
|
||||||
|
triggerAutoResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::setTexts(const std::vector<std::string>& texts) {
|
void WindowMessage::setTexts(const std::vector<std::string>& texts) {
|
||||||
texts_ = texts;
|
texts_ = texts;
|
||||||
|
triggerAutoResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::addText(const std::string& text) {
|
void WindowMessage::addText(const std::string& text) {
|
||||||
texts_.push_back(text);
|
texts_.push_back(text);
|
||||||
|
triggerAutoResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::clearTexts() {
|
void WindowMessage::clearTexts() {
|
||||||
texts_.clear();
|
texts_.clear();
|
||||||
|
triggerAutoResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::setPosition(float x, float y) {
|
void WindowMessage::setPosition(float x, float y, PositionMode mode) {
|
||||||
rect_.x = x;
|
anchor_x_ = x;
|
||||||
rect_.y = y;
|
anchor_y_ = y;
|
||||||
|
position_mode_ = mode;
|
||||||
|
updatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::setSize(float width, float height) {
|
void WindowMessage::setSize(float width, float height) {
|
||||||
rect_.w = width;
|
rect_.w = width;
|
||||||
rect_.h = height;
|
rect_.h = height;
|
||||||
|
updatePosition(); // Reposicionar después de cambiar el tamaño
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::centerOnScreen() {
|
void WindowMessage::centerOnScreen() {
|
||||||
rect_.x = (param.game.width - rect_.w) / 2.0f;
|
setPosition(getScreenWidth() / 2.0f, getScreenHeight() / 2.0f, PositionMode::CENTERED);
|
||||||
rect_.y = (param.game.height - rect_.h) / 2.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::autoSize() {
|
void WindowMessage::autoSize() {
|
||||||
|
if (resize_animation_.active) {
|
||||||
|
resize_animation_.stop(); // Detener animación anterior
|
||||||
|
}
|
||||||
|
|
||||||
|
float old_width = rect_.w;
|
||||||
|
float old_height = rect_.h;
|
||||||
|
|
||||||
calculateAutoSize();
|
calculateAutoSize();
|
||||||
|
|
||||||
|
// Solo animar si hay cambio en el tamaño y la ventana está visible
|
||||||
|
if (visible_ && (old_width != rect_.w || old_height != rect_.h)) {
|
||||||
|
resize_animation_.start(old_width, old_height, rect_.w, rect_.h);
|
||||||
|
// Restaurar el tamaño anterior para que la animación funcione
|
||||||
|
rect_.w = old_width;
|
||||||
|
rect_.h = old_height;
|
||||||
|
} else {
|
||||||
|
updatePosition(); // Reposicionar después de ajustar el tamaño
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowMessage::updateStyles() {
|
||||||
|
title_style_ = Text::Style(Text::CENTER | Text::COLOR, config_.title_color,
|
||||||
|
config_.title_color, 0, -2);
|
||||||
|
text_style_ = Text::Style(Text::CENTER | Text::COLOR, config_.text_color,
|
||||||
|
config_.text_color, 0, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowMessage::updatePosition() {
|
||||||
|
switch (position_mode_) {
|
||||||
|
case PositionMode::CENTERED:
|
||||||
|
rect_.x = anchor_x_ - rect_.w / 2.0f;
|
||||||
|
rect_.y = anchor_y_ - rect_.h / 2.0f;
|
||||||
|
break;
|
||||||
|
case PositionMode::FIXED:
|
||||||
|
rect_.x = anchor_x_;
|
||||||
|
rect_.y = anchor_y_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asegurar que la ventana esté dentro de los límites de la pantalla
|
||||||
|
rect_.x = std::max(0.0f, std::min(rect_.x, getScreenWidth() - rect_.w));
|
||||||
|
rect_.y = std::max(0.0f, std::min(rect_.y, getScreenHeight() - rect_.h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowMessage::ensureTextFits() {
|
||||||
|
float required_width = calculateContentWidth() + (config_.padding * 2) + config_.text_safety_margin;
|
||||||
|
float required_height = calculateContentHeight() + (config_.padding * 2) + config_.text_safety_margin;
|
||||||
|
|
||||||
|
// Verificar si el tamaño actual es suficiente
|
||||||
|
if (rect_.w < required_width || rect_.h < required_height) {
|
||||||
|
autoSize(); // Recalcular tamaño automáticamente
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowMessage::calculateAutoSize() {
|
void WindowMessage::calculateAutoSize() {
|
||||||
float content_width = calculateContentWidth();
|
float content_width = calculateContentWidth();
|
||||||
float content_height = calculateContentHeight();
|
float content_height = calculateContentHeight();
|
||||||
|
|
||||||
rect_.w = content_width + (padding_ * 2);
|
// Calcular dimensiones con padding y margen de seguridad
|
||||||
rect_.h = content_height + (padding_ * 2);
|
rect_.w = content_width + (config_.padding * 2) + config_.text_safety_margin;
|
||||||
|
rect_.h = content_height + (config_.padding * 2);
|
||||||
|
|
||||||
// Aplicar límites mínimos y máximos
|
// Aplicar límites mínimos
|
||||||
rect_.w = std::max(rect_.w, 200.0f);
|
rect_.w = std::max(rect_.w, config_.min_width);
|
||||||
rect_.h = std::max(rect_.h, 100.0f);
|
rect_.h = std::max(rect_.h, config_.min_height);
|
||||||
|
|
||||||
// No exceder el 80% de la pantalla
|
// Aplicar límites máximos basados en el tamaño de pantalla
|
||||||
rect_.w = std::min(rect_.w, param.game.width * 0.8f);
|
float max_width = getScreenWidth() * config_.max_width_ratio;
|
||||||
rect_.h = std::min(rect_.h, param.game.height * 0.8f);
|
float max_height = getScreenHeight() * config_.max_height_ratio;
|
||||||
|
|
||||||
|
rect_.w = std::min(rect_.w, max_width);
|
||||||
|
rect_.h = std::min(rect_.h, max_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto WindowMessage::calculateContentHeight() const -> float {
|
auto WindowMessage::calculateContentHeight() const -> float {
|
||||||
@@ -141,32 +209,79 @@ auto WindowMessage::calculateContentHeight() const -> float {
|
|||||||
|
|
||||||
// Altura del título
|
// Altura del título
|
||||||
if (!title_.empty()) {
|
if (!title_.empty()) {
|
||||||
height += text_renderer_->getCharacterSize() + line_spacing_ * 2; // Espacio extra para separador
|
height += text_renderer_->getCharacterSize() + config_.title_separator_spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Altura de los textos
|
// Altura de los textos
|
||||||
if (!texts_.empty()) {
|
if (!texts_.empty()) {
|
||||||
height += (texts_.size() * text_renderer_->getCharacterSize());
|
height += (texts_.size() * text_renderer_->getCharacterSize());
|
||||||
height += ((texts_.size() - 1) * line_spacing_); // Espaciado entre líneas
|
if (texts_.size() > 1) {
|
||||||
|
height += ((texts_.size() - 1) * config_.line_spacing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto WindowMessage::calculateContentWidth() const -> float {
|
auto WindowMessage::calculateContentWidth() const -> float {
|
||||||
float max_width = 200.0f; // Ancho mínimo
|
float max_width = config_.min_width - (config_.padding * 2); // Ancho mínimo sin padding
|
||||||
|
|
||||||
// Ancho del título
|
// Ancho del título
|
||||||
if (!title_.empty()) {
|
if (!title_.empty()) {
|
||||||
float title_width = text_renderer_->lenght(title_, -2);
|
float title_width = text_renderer_->length(title_, -2);
|
||||||
max_width = std::max(max_width, title_width);
|
max_width = std::max(max_width, title_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ancho de los textos
|
// Ancho de los textos
|
||||||
for (const auto& text : texts_) {
|
for (const auto& text : texts_) {
|
||||||
float text_width = text_renderer_->lenght(text, -2);
|
float text_width = text_renderer_->length(text, -2);
|
||||||
max_width = std::max(max_width, text_width);
|
max_width = std::max(max_width, text_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
return max_width;
|
return max_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto WindowMessage::getScreenWidth() const -> float {
|
||||||
|
return static_cast<float>(param.game.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WindowMessage::getScreenHeight() const -> float {
|
||||||
|
return static_cast<float>(param.game.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowMessage::triggerAutoResize() {
|
||||||
|
if (auto_resize_enabled_) {
|
||||||
|
autoSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowMessage::updateAnimation(float delta_time) {
|
||||||
|
if (!resize_animation_.active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resize_animation_.elapsed += delta_time;
|
||||||
|
|
||||||
|
if (resize_animation_.isFinished()) {
|
||||||
|
// Animación terminada
|
||||||
|
rect_.w = resize_animation_.target_width;
|
||||||
|
rect_.h = resize_animation_.target_height;
|
||||||
|
resize_animation_.stop();
|
||||||
|
updatePosition();
|
||||||
|
} else {
|
||||||
|
// Interpolar el tamaño
|
||||||
|
float progress = easeOut(resize_animation_.getProgress());
|
||||||
|
|
||||||
|
rect_.w = resize_animation_.start_width +
|
||||||
|
(resize_animation_.target_width - resize_animation_.start_width) * progress;
|
||||||
|
rect_.h = resize_animation_.start_height +
|
||||||
|
(resize_animation_.target_height - resize_animation_.start_height) * progress;
|
||||||
|
|
||||||
|
updatePosition(); // Mantener la posición centrada durante la animación
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WindowMessage::easeOut(float t) const -> float {
|
||||||
|
// Función de suavizado ease-out cuadrática
|
||||||
|
return 1.0f - (1.0f - t) * (1.0f - t);
|
||||||
|
}
|
||||||
@@ -7,18 +7,57 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
#include "text.h"
|
||||||
class Text;
|
|
||||||
|
|
||||||
class WindowMessage {
|
class WindowMessage {
|
||||||
public:
|
public:
|
||||||
|
enum class PositionMode {
|
||||||
|
CENTERED, // La ventana se centra en el punto especificado
|
||||||
|
FIXED // La esquina superior izquierda coincide con el punto
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
// Colores
|
||||||
|
Color bg_color;
|
||||||
|
Color border_color;
|
||||||
|
Color title_color;
|
||||||
|
Color text_color;
|
||||||
|
|
||||||
|
// Espaciado y dimensiones
|
||||||
|
float padding;
|
||||||
|
float line_spacing;
|
||||||
|
float title_separator_spacing; // Espacio extra para separador del título
|
||||||
|
|
||||||
|
// Límites de tamaño
|
||||||
|
float min_width;
|
||||||
|
float min_height;
|
||||||
|
float max_width_ratio; // % máximo de ancho de pantalla
|
||||||
|
float max_height_ratio; // % máximo de alto de pantalla
|
||||||
|
|
||||||
|
// Margen de seguridad para texto
|
||||||
|
float text_safety_margin; // Margen extra para evitar texto cortado
|
||||||
|
|
||||||
|
// Constructor con valores por defecto
|
||||||
|
Config()
|
||||||
|
: bg_color{40, 40, 60, 220}
|
||||||
|
, border_color{100, 100, 120, 255}
|
||||||
|
, title_color{255, 255, 255, 255}
|
||||||
|
, text_color{200, 200, 200, 255}
|
||||||
|
, padding{15.0f}
|
||||||
|
, line_spacing{5.0f}
|
||||||
|
, title_separator_spacing{10.0f}
|
||||||
|
, min_width{200.0f}
|
||||||
|
, min_height{100.0f}
|
||||||
|
, max_width_ratio{0.8f}
|
||||||
|
, max_height_ratio{0.8f}
|
||||||
|
, text_safety_margin{20.0f}
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
WindowMessage(
|
WindowMessage(
|
||||||
std::shared_ptr<Text> text_renderer,
|
std::shared_ptr<Text> text_renderer,
|
||||||
const std::string& title = "",
|
const std::string& title = "",
|
||||||
const Color& bg_color = Color{40, 40, 60, 220},
|
const Config& config = Config{}
|
||||||
const Color& border_color = Color{100, 100, 120, 255},
|
|
||||||
const Color& title_color = Color{255, 255, 255, 255},
|
|
||||||
const Color& text_color = Color{200, 200, 200, 255}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Métodos principales
|
// Métodos principales
|
||||||
@@ -37,30 +76,42 @@ class WindowMessage {
|
|||||||
void addText(const std::string& text);
|
void addText(const std::string& text);
|
||||||
void clearTexts();
|
void clearTexts();
|
||||||
|
|
||||||
|
// Control de redimensionado automático
|
||||||
|
void enableAutoResize(bool enabled) { auto_resize_enabled_ = enabled; }
|
||||||
|
[[nodiscard]] auto isAutoResizeEnabled() const -> bool { return auto_resize_enabled_; }
|
||||||
|
|
||||||
// Configuración de posición y tamaño
|
// Configuración de posición y tamaño
|
||||||
void setPosition(float x, float y);
|
void setPosition(float x, float y, PositionMode mode = PositionMode::CENTERED);
|
||||||
void setSize(float width, float height);
|
void setSize(float width, float height);
|
||||||
void centerOnScreen();
|
void centerOnScreen();
|
||||||
void autoSize(); // Ajusta automáticamente al contenido
|
void autoSize(); // Ajusta automáticamente al contenido y reposiciona si es necesario
|
||||||
|
|
||||||
// Configuración de colores
|
// Configuración de colores
|
||||||
void setBackgroundColor(const Color& color) { bg_color_ = color; }
|
void setBackgroundColor(const Color& color) { config_.bg_color = color; }
|
||||||
void setBorderColor(const Color& color) { border_color_ = color; }
|
void setBorderColor(const Color& color) { config_.border_color = color; }
|
||||||
void setTitleColor(const Color& color) { title_color_ = color; }
|
void setTitleColor(const Color& color) { config_.title_color = color; updateStyles(); }
|
||||||
void setTextColor(const Color& color) { text_color_ = color; }
|
void setTextColor(const Color& color) { config_.text_color = color; updateStyles(); }
|
||||||
|
|
||||||
// Configuración de espaciado
|
// Configuración de espaciado
|
||||||
void setPadding(float padding) { padding_ = padding; }
|
void setPadding(float padding) { config_.padding = padding; }
|
||||||
void setLineSpacing(float spacing) { line_spacing_ = spacing; }
|
void setLineSpacing(float spacing) { config_.line_spacing = spacing; }
|
||||||
|
|
||||||
|
// Configuración avanzada
|
||||||
|
void setConfig(const Config& config) { config_ = config; updateStyles(); }
|
||||||
|
[[nodiscard]] auto getConfig() const -> const Config& { return config_; }
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
[[nodiscard]] auto getRect() const -> const SDL_FRect& { return rect_; }
|
[[nodiscard]] auto getRect() const -> const SDL_FRect& { return rect_; }
|
||||||
|
[[nodiscard]] auto getPositionMode() const -> PositionMode { return position_mode_; }
|
||||||
|
[[nodiscard]] auto getAnchorPoint() const -> std::pair<float, float> { return {anchor_x_, anchor_y_}; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Text> text_renderer_;
|
std::shared_ptr<Text> text_renderer_;
|
||||||
|
Config config_;
|
||||||
|
|
||||||
// Estado de visibilidad
|
// Estado de visibilidad y redimensionado
|
||||||
bool visible_ = false;
|
bool visible_ = false;
|
||||||
|
bool auto_resize_enabled_ = true; // Por defecto habilitado
|
||||||
|
|
||||||
// Contenido
|
// Contenido
|
||||||
std::string title_;
|
std::string title_;
|
||||||
@@ -68,17 +119,58 @@ class WindowMessage {
|
|||||||
|
|
||||||
// Posición y tamaño
|
// Posición y tamaño
|
||||||
SDL_FRect rect_{0, 0, 300, 200};
|
SDL_FRect rect_{0, 0, 300, 200};
|
||||||
float padding_ = 15.0f;
|
PositionMode position_mode_ = PositionMode::CENTERED;
|
||||||
float line_spacing_ = 5.0f;
|
float anchor_x_ = 0.0f;
|
||||||
|
float anchor_y_ = 0.0f;
|
||||||
|
|
||||||
// Colores
|
// Animación de redimensionado
|
||||||
Color bg_color_;
|
struct ResizeAnimation {
|
||||||
Color border_color_;
|
bool active = false;
|
||||||
Color title_color_;
|
float start_width, start_height;
|
||||||
Color text_color_;
|
float target_width, target_height;
|
||||||
|
float duration = 0.3f; // segundos
|
||||||
|
float elapsed = 0.0f;
|
||||||
|
|
||||||
|
void start(float from_w, float from_h, float to_w, float to_h) {
|
||||||
|
start_width = from_w;
|
||||||
|
start_height = from_h;
|
||||||
|
target_width = to_w;
|
||||||
|
target_height = to_h;
|
||||||
|
elapsed = 0.0f;
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
active = false;
|
||||||
|
elapsed = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto isFinished() const -> bool {
|
||||||
|
return elapsed >= duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto getProgress() const -> float {
|
||||||
|
return std::min(elapsed / duration, 1.0f);
|
||||||
|
}
|
||||||
|
} resize_animation_;
|
||||||
|
|
||||||
|
// Estilos
|
||||||
|
Text::Style title_style_;
|
||||||
|
Text::Style text_style_;
|
||||||
|
|
||||||
// Métodos privados
|
// Métodos privados
|
||||||
void calculateAutoSize();
|
void calculateAutoSize();
|
||||||
|
void updatePosition(); // Actualiza la posición según el modo y punto de anclaje
|
||||||
|
void updateStyles(); // Actualiza los estilos de texto cuando cambian los colores
|
||||||
|
void ensureTextFits(); // Verifica y ajusta para que todo el texto sea visible
|
||||||
|
void triggerAutoResize(); // Inicia redimensionado automático si está habilitado
|
||||||
|
void updateAnimation(float delta_time); // Actualiza la animación de redimensionado
|
||||||
|
|
||||||
|
// Función de suavizado (ease-out)
|
||||||
|
[[nodiscard]] auto easeOut(float t) const -> float;
|
||||||
|
|
||||||
[[nodiscard]] auto calculateContentHeight() const -> float;
|
[[nodiscard]] auto calculateContentHeight() const -> float;
|
||||||
[[nodiscard]] auto calculateContentWidth() const -> float;
|
[[nodiscard]] auto calculateContentWidth() const -> float;
|
||||||
|
[[nodiscard]] auto getScreenWidth() const -> float;
|
||||||
|
[[nodiscard]] auto getScreenHeight() const -> float;
|
||||||
};
|
};
|
||||||
@@ -78,7 +78,7 @@ void Writer::setFinishedCounter(int time) {
|
|||||||
|
|
||||||
// Centra la cadena de texto a un punto X
|
// Centra la cadena de texto a un punto X
|
||||||
void Writer::center(int x) {
|
void Writer::center(int x) {
|
||||||
setPosX(x - (text_->lenght(caption_, kerning_) / 2));
|
setPosX(x - (text_->length(caption_, kerning_) / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el valor de la variable
|
// Obtiene el valor de la variable
|
||||||
|
|||||||
Reference in New Issue
Block a user