Tocant coses d'Screen, pero no acaba de funcionar be res

This commit is contained in:
2025-03-11 14:16:02 +01:00
parent be857cc8c8
commit 059a9c863a
7 changed files with 187 additions and 184 deletions

View File

@@ -305,12 +305,12 @@ bool Director::initSDL()
SDL_GetCurrentDisplayMode(0, &DM);
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla
options.video.window.max_size = std::min(DM.w / param.game.width, DM.h / param.game.height);
options.video.window.size = std::min(options.video.window.size, options.video.window.max_size);
options.video.window.max_zoom = std::min(DM.w / param.game.width, DM.h / param.game.height);
options.video.window.zoom = std::min(options.video.window.zoom, options.video.window.max_zoom);
// Muestra información sobre el tamaño de la pantalla y de la ventana de juego
std::cout << "\nCurrent display mode: " << DM.w << "x" << DM.h << " @ " << DM.refresh_rate << "Hz" << std::endl;
std::cout << "Window resolution : " << param.game.width << "x" << param.game.height << " x" << options.video.window.size << std::endl;
std::cout << "Window resolution : " << param.game.width << "x" << param.game.height << " x" << options.video.window.zoom << std::endl;
// Establece el filtro de la textura
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(static_cast<int>(options.video.filter)).c_str()))
@@ -324,7 +324,7 @@ bool Director::initSDL()
}
// Crea la ventana
window_ = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, param.game.width * options.video.window.size, param.game.height * options.video.window.size, SDL_WINDOW_HIDDEN);
window_ = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, param.game.width * options.video.window.zoom, param.game.height * options.video.window.zoom, SDL_WINDOW_HIDDEN);
if (!window_)
{
std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
@@ -354,6 +354,7 @@ bool Director::initSDL()
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderSetLogicalSize(renderer_, param.game.width, param.game.height);
SDL_RenderSetIntegerScale(renderer_, static_cast<SDL_bool>(options.video.integer_scale));
SDL_SetWindowFullscreen(window_, static_cast<Uint32>(options.video.mode));
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
}
}

View File

@@ -172,18 +172,20 @@ namespace globalInputs
// Comprueba el teclado para decrementar el tamaño de la ventana
if (Input::get()->checkInput(InputType::WINDOW_DEC_SIZE, INPUT_DO_NOT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
{
Screen::get()->decWindowSize();
const std::string size = std::to_string(options.video.window.size);
Notifier::get()->show({"Window size x" + size});
if (Screen::get()->decWindowZoom())
{
Notifier::get()->show({"Window zoom x" + std::to_string(options.video.window.zoom)});
}
return;
}
// Comprueba el teclado para incrementar el tamaño de la ventana
if (Input::get()->checkInput(InputType::WINDOW_INC_SIZE, INPUT_DO_NOT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
{
Screen::get()->incWindowSize();
const std::string size = std::to_string(options.video.window.size);
Notifier::get()->show({"Window size x" + size});
if (Screen::get()->incWindowZoom())
{
Notifier::get()->show({"Window zoom x" + std::to_string(options.video.window.zoom)});
}
return;
}
#endif

View File

@@ -25,7 +25,7 @@ void initOptions()
options.video.window.size = 3;
#else
options.video.mode = ScreenVideoMode::WINDOW;
options.video.window.size = 2;
options.video.window.zoom = 2;
#endif
options.video.filter = ScreenFilter::NEAREST;
options.video.v_sync = true;
@@ -105,7 +105,7 @@ bool loadOptionsFile(std::string file_path)
options.video.mode = ScreenVideoMode::WINDOW;
}
options.video.window.size = std::clamp(options.video.window.size, 1, 4);
options.video.window.zoom = std::clamp(options.video.window.zoom, 1, 4);
if (options.game.language != lang::Code::en_UK &&
options.game.language != lang::Code::ba_BA &&
@@ -137,7 +137,7 @@ bool saveOptionsFile(std::string file_path)
file << "\n";
file << "video.mode=" << static_cast<int>(options.video.mode) << "\n";
file << "video.window.size=" << options.video.window.size << "\n";
file << "video.window.size=" << options.video.window.zoom << "\n";
file << "video.filter=" << static_cast<int>(options.video.filter) << "\n";
file << "video.v_sync=" << boolToString(options.video.v_sync) << "\n";
file << "video.integer_scale=" << boolToString(options.video.integer_scale) << "\n";
@@ -204,10 +204,10 @@ bool setOptions(const std::string &var, const std::string &value)
}
else if (var == "video.window.size")
{
options.video.window.size = std::stoi(value);
if ((options.video.window.size < 1) || (options.video.window.size > 4))
options.video.window.zoom = std::stoi(value);
if ((options.video.window.zoom < 1) || (options.video.window.zoom > 4))
{
options.video.window.size = 3;
options.video.window.zoom = 3;
}
}
else if (var == "video.filter")

View File

@@ -6,7 +6,7 @@
#include "input.h" // Para InputType, InputDeviceToUse
#include "manage_hiscore_table.h" // Para HiScoreEntry
enum class ScreenFilter : int; // lines 10-10
enum class ScreenVideoMode : int; // lines 11-11
enum class ScreenVideoMode : Uint32; // lines 11-11
namespace lang
{
enum class Code : int;
@@ -23,8 +23,8 @@ enum class GameDifficulty
// Estructura para las opciones de la ventana
struct OptionsWindow
{
int size = 1; // Contiene el valor por el que se multiplica el tamaño de la ventana
int max_size = 1; // Tamaño máximo para que el tamaño de la ventana no sea mayor que el tamaño de la pantalla
int zoom = 1; // Contiene el valor por el que se multiplica el tamaño de la ventana
int max_zoom = 1; // Tamaño máximo para que el tamaño de la ventana no sea mayor que el tamaño de la pantalla
};
// Estructura con opciones para el video
@@ -64,18 +64,18 @@ struct OptionsAudio
// Estructura para las opciones del juego
struct OptionsGame
{
GameDifficulty difficulty; // Dificultad del juego
lang::Code language; // Idioma usado en el juego
bool autofire; // Indicador de autofire
std::vector<HiScoreEntry> hi_score_table; // Tabla de mejores puntuaciones
std::vector<int> last_hi_score_entry = { -1, -1 }; // Inicialización directa con dos elementos en -1
GameDifficulty difficulty; // Dificultad del juego
lang::Code language; // Idioma usado en el juego
bool autofire; // Indicador de autofire
std::vector<HiScoreEntry> hi_score_table; // Tabla de mejores puntuaciones
std::vector<int> last_hi_score_entry = {-1, -1}; // Inicialización directa con dos elementos en -1
// Método para reiniciar las últimas entradas de puntuación
void clear_last_hi_score_entries()
{
last_hi_score_entry[0] = -1;
last_hi_score_entry[1] = -1;
}
// Método para reiniciar las últimas entradas de puntuación
void clear_last_hi_score_entries()
{
last_hi_score_entry[0] = -1;
last_hi_score_entry[1] = -1;
}
};
// Estructura para los controles del juego

View File

@@ -11,6 +11,7 @@
#include "resource.h"
#include "jail_audio.h"
#include "stage.h"
#include <array>
// Constructor
Player::Player(int id, float x, int y, bool demo, SDL_Rect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations)

View File

@@ -21,22 +21,13 @@
Screen *Screen::screen_ = nullptr;
// [SINGLETON] Crearemos el objeto con esta función estática
void Screen::init(SDL_Window *window, SDL_Renderer *renderer)
{
Screen::screen_ = new Screen(window, renderer);
}
void Screen::init(SDL_Window *window, SDL_Renderer *renderer) { Screen::screen_ = new Screen(window, renderer); }
// [SINGLETON] Destruiremos el objeto con esta función estática
void Screen::destroy()
{
delete Screen::screen_;
}
void Screen::destroy() { delete Screen::screen_; }
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
Screen *Screen::get()
{
return Screen::screen_;
}
Screen *Screen::get() { return Screen::screen_; }
// Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
@@ -51,18 +42,15 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
SDL_GetCurrentDisplayMode(0, &DM);
info_resolution_ = std::to_string(DM.w) + " X " + std::to_string(DM.h) + " AT " + std::to_string(DM.refresh_rate) + " HZ";
// Establece el modo de video
setVideoMode(options.video.mode);
// Inicializa los shaders
initShaders();
// Muestra la ventana
SDL_ShowWindow(window_);
show();
}
// Destructor
Screen::~Screen()
{
SDL_DestroyTexture(game_canvas_);
}
Screen::~Screen() { SDL_DestroyTexture(game_canvas_); }
// Limpia la pantalla
void Screen::clean(Color color)
@@ -72,24 +60,13 @@ void Screen::clean(Color color)
}
// Prepara para empezar a dibujar en la textura de juego
void Screen::start()
{
SDL_SetRenderTarget(renderer_, game_canvas_);
}
void Screen::start() { SDL_SetRenderTarget(renderer_, game_canvas_); }
// Vuelca el contenido del renderizador en pantalla
void Screen::render()
{
// Actualiza el contador de FPS
++fps_counter_;
// Dibuja efectos y elementos sobre el game_canvas_
renderFlash();
renderAttenuate();
renderShake();
OnScreenHelp::get()->render();
renderInfo();
Notifier::get()->render();
// Renderiza todos los overlays y efectos
renderOverlays();
// Renderiza el contenido del game_canvas_
renderScreen();
@@ -98,65 +75,31 @@ void Screen::render()
// Renderiza el contenido del game_canvas_
void Screen::renderScreen()
{
// Restablece el objetivo de renderizado al buffer de pantalla predeterminado
SDL_SetRenderTarget(renderer_, nullptr);
clean();
if (options.video.shaders)
{
// Aplica shaders y renderiza el contenido
shader::render();
}
else
{
// Actualiza la pantalla con el contenido del buffer de renderizado
SDL_RenderCopy(renderer_, game_canvas_, nullptr, nullptr);
SDL_RenderPresent(renderer_);
}
}
// Establece el modo de video
void Screen::setVideoMode(ScreenVideoMode videoMode)
void Screen::setVideoMode(ScreenVideoMode video_mode)
{
switch (options.video.mode)
// Actualiza las opciones
options.video.mode = video_mode;
// Configura el modo de pantalla
Uint32 flags = SDL_GetWindowFlags(window_);
if (flags != static_cast<Uint32>(options.video.mode))
{
case ScreenVideoMode::WINDOW:
{
// Cambia a modo de ventana
SDL_SetWindowFullscreen(window_, 0);
// Modifica el tamaño de la ventana
SDL_Point pos = getNewPosition();
SDL_SetWindowSize(window_, param.game.width * options.video.window.size, param.game.height * options.video.window.size);
SDL_SetWindowPosition(window_, pos.x, pos.y);
break;
}
// Si está activo el modo de pantalla completa añade el borde
case ScreenVideoMode::FULLSCREEN:
{
// Aplica el modo de video
SDL_SetWindowFullscreen(window_, SDL_WINDOW_FULLSCREEN_DESKTOP);
// Oculta el puntero
SDL_ShowCursor(SDL_DISABLE);
break;
}
default:
break;
}
// Reinicia los shaders
if (options.video.shaders)
{
const std::string glsl_file = param.game.game_area.rect.h == 256 ? "crtpi_256.glsl" : "crtpi_240.glsl";
std::ifstream f(Asset::get()->get(glsl_file).c_str());
std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
shader::init(window_, game_canvas_, source.c_str());
SDL_SetWindowFullscreen(window_, static_cast<Uint32>(options.video.mode));
}
}
@@ -164,43 +107,56 @@ void Screen::setVideoMode(ScreenVideoMode videoMode)
void Screen::toggleVideoMode()
{
options.video.mode = options.video.mode == ScreenVideoMode::WINDOW ? ScreenVideoMode::FULLSCREEN : ScreenVideoMode::WINDOW;
setVideoMode(options.video.mode);
setVideoMode();
}
// Cambia el tamaño de la ventana
void Screen::setWindowSize(int size)
void Screen::setWindowZoom(int zoom)
{
options.video.window.size = size;
setVideoMode(ScreenVideoMode::WINDOW);
options.video.window.zoom = zoom;
adjustWindowSize();
}
// Reduce el tamaño de la ventana
void Screen::decWindowSize()
bool Screen::decWindowZoom()
{
--options.video.window.size;
options.video.window.size = std::max(options.video.window.size, 1);
setVideoMode(ScreenVideoMode::WINDOW);
if (options.video.mode == ScreenVideoMode::WINDOW)
{
const int PREVIOUS_ZOOM = options.video.window.zoom;
--options.video.window.zoom;
options.video.window.zoom = std::max(options.video.window.zoom, 1);
if (options.video.window.zoom != PREVIOUS_ZOOM)
{
adjustWindowSize();
return true;
}
}
return false;
}
// Aumenta el tamaño de la ventana
void Screen::incWindowSize()
bool Screen::incWindowZoom()
{
++options.video.window.size;
options.video.window.size = std::min(options.video.window.size, options.video.window.max_size);
setVideoMode(ScreenVideoMode::WINDOW);
}
if (options.video.mode == ScreenVideoMode::WINDOW)
{
const int PREVIOUS_ZOOM = options.video.window.zoom;
++options.video.window.zoom;
options.video.window.zoom = std::min(options.video.window.zoom, options.video.window.max_zoom);
// Cambia el color del borde
void Screen::setBorderColor(Color color)
{
border_color_ = color;
if (options.video.window.zoom != PREVIOUS_ZOOM)
{
adjustWindowSize();
return true;
}
}
return false;
}
// Cambia el tipo de mezcla
void Screen::setBlendMode(SDL_BlendMode blendMode)
{
SDL_SetRenderDrawBlendMode(renderer_, blendMode);
}
void Screen::setBlendMode(SDL_BlendMode blendMode) { SDL_SetRenderDrawBlendMode(renderer_, blendMode); }
// Actualiza la lógica de la clase
void Screen::update()
@@ -260,10 +216,7 @@ void Screen::updateShakeEffect()
}
// Pone la pantalla de color
void Screen::flash(Color color, int lenght, int delay)
{
flash_effect_ = FlashEffect(true, lenght, delay, color);
}
void Screen::flash(Color color, int lenght, int delay) { flash_effect_ = FlashEffect(true, lenght, delay, color); }
// Actualiza y dibuja el efecto de flash en la pantalla
void Screen::renderFlash()
@@ -276,10 +229,7 @@ void Screen::renderFlash()
}
// Actualiza el efecto de flash
void Screen::updateFlash()
{
flash_effect_.update();
}
void Screen::updateFlash() { flash_effect_.update(); }
// Atenua la pantalla
void Screen::renderAttenuate()
@@ -322,22 +272,14 @@ void Screen::renderShake()
void Screen::toggleShaders()
{
options.video.shaders = !options.video.shaders;
setVideoMode(options.video.mode);
const std::string value = options.video.shaders ? "on" : "off";
Notifier::get()->show({"Shaders " + value});
Notifier::get()->show({"Shaders " + std::string(options.video.shaders ? "on" : "off")});
}
// Activa / desactiva la información de debug
void Screen::toggleDebugInfo()
{
show_info_ = !show_info_;
}
void Screen::toggleDebugInfo() { show_debug_info_ = !show_debug_info_; }
// Atenua la pantalla
void Screen::attenuate(bool value)
{
attenuate_effect_ = value;
}
void Screen::attenuate(bool value) { attenuate_effect_ = value; }
// Calcula los frames por segundo
void Screen::updateFPS()
@@ -353,7 +295,7 @@ void Screen::updateFPS()
// Muestra información por pantalla
void Screen::renderInfo()
{
if (show_info_)
if (show_debug_info_)
{
// FPS
const std::string fpstext = std::to_string(fps_) + " FPS";
@@ -370,38 +312,77 @@ void Screen::renderInfo()
}
}
// Calcula la nueva posición de la ventana a partir de la antigua al cambiarla de tamaño
SDL_Point Screen::getNewPosition()
// Reinicia los shaders
void Screen::initShaders()
{
// Obtiene la posición actual de la ventana
SDL_Point current_position;
SDL_GetWindowPosition(window_, &current_position.x, &current_position.y);
if (options.video.shaders)
{
const std::string GLSL_FILE = param.game.game_area.rect.h == 256 ? "crtpi_256.glsl" : "crtpi_240.glsl";
std::ifstream f(Asset::get()->get(GLSL_FILE).c_str());
std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
// Obtiene las dimensiones actuales de la ventana
int current_width, current_height;
SDL_GetWindowSize(window_, &current_width, &current_height);
shader::init(window_, game_canvas_, source.c_str());
}
}
// Obtiene las dimesiones que tendrá la ventana
const int new_width = param.game.width * options.video.window.size;
const int new_height = param.game.height * options.video.window.size;
// Calcula el tamaño de la ventana
void Screen::adjustWindowSize()
{
options.video.window.max_zoom = getMaxZoom();
// Obtiene el centro de la ventana actual
SDL_Point center;
center.x = current_position.x + current_width / 2;
center.y = current_position.y + current_height / 2;
// Establece el nuevo tamaño
if (options.video.mode == ScreenVideoMode::WINDOW)
{
const int WIDTH = param.game.width * options.video.window.zoom;
const int HEIGHT = param.game.height * options.video.window.zoom;
// Calcula la nueva posición a partir del centro y las nuevas diemsiones
SDL_Point new_pos;
new_pos.x = center.x - new_width / 2;
new_pos.y = center.y - new_height / 2;
int old_width, old_height;
SDL_GetWindowSize(window_, &old_width, &old_height);
// Obtiene las dimensiones del escritorio
int old_pos_x, old_pos_y;
SDL_GetWindowPosition(window_, &old_pos_x, &old_pos_y);
const int NEW_POS_X = old_pos_x + (old_width - WIDTH) / 2;
const int NEW_POS_Y = old_pos_y + (old_height - HEIGHT) / 2;
SDL_Rect viewport = {0, 0, WIDTH, HEIGHT};
SDL_RenderSetViewport(renderer_, &viewport);
SDL_SetWindowPosition(window_, std::max(NEW_POS_X, WINDOWS_DECORATIONS_), std::max(NEW_POS_Y, 0));
SDL_SetWindowSize(window_, WIDTH, HEIGHT);
}
}
// Ajusta el tamaño lógico del renderizador
void Screen::adjustRenderLogicalSize() { SDL_RenderSetLogicalSize(renderer_, param.game.width, param.game.height); }
// Obtiene el tamaño máximo de zoom posible para la ventana
int Screen::getMaxZoom()
{
// Obtiene información sobre la pantalla
SDL_DisplayMode DM;
SDL_GetCurrentDisplayMode(0, &DM);
// Evita que la ventana quede fuera del escritorio
new_pos.x = std::clamp(new_pos.x, 30, DM.w - new_width);
new_pos.y = std::clamp(new_pos.y, 30, DM.h - new_height);
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla
const int MAX_ZOOM = std::min(DM.w / param.game.width, (DM.h - WINDOWS_DECORATIONS_) / param.game.height);
return new_pos;
// Normaliza los valores de zoom
options.video.window.zoom = std::min(options.video.window.zoom, MAX_ZOOM);
return MAX_ZOOM;
}
// Renderiza todos los overlays y efectos
void Screen::renderOverlays()
{
// Actualiza el contador de FPS
++fps_counter_;
// Dibuja efectos y elementos sobre el game_canvas_
renderShake();
renderFlash();
renderAttenuate();
OnScreenHelp::get()->render();
renderInfo();
Notifier::get()->render();
}

View File

@@ -8,6 +8,7 @@
#include <string> // Para string
#include "param.h" // Para Param, ParamGame, param
#include "utils.h" // Para Color
#include "options.h"
enum class ScreenFilter : int
{
@@ -15,15 +16,18 @@ enum class ScreenFilter : int
LINEAL = 1,
};
enum class ScreenVideoMode : int
enum class ScreenVideoMode : Uint32
{
WINDOW = 0,
FULLSCREEN = 1,
FULLSCREEN = SDL_WINDOW_FULLSCREEN_DESKTOP,
};
class Screen
{
private:
// Constantes
static constexpr int WINDOWS_DECORATIONS_ = 35;
// [SINGLETON] Objeto privado
static Screen *screen_;
@@ -35,7 +39,6 @@ private:
// Variables
SDL_Rect src_rect_; // Coordenadas de donde va a pillar la textura del juego para dibujarla
SDL_Rect dst_rect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
Color border_color_ = Color(); // Color del borde añadido a la textura de juego para rellenar la pantalla
bool attenuate_effect_ = false; // Indica si la pantalla ha de estar atenuada
Uint32 fps_ticks_ = 0; // Ticks para contar los frames por segundo
int fps_counter_ = 0; // Contador de frames por segundo
@@ -44,7 +47,7 @@ private:
#ifdef DEBUG
bool show_info_ = false; // Indica si ha de mostrar/ocultar la información de la pantalla
#else
bool show_info_ = false; // Indica si ha de mostrar/ocultar la información de la pantalla
bool show_debug_info_ = false; // Indica si ha de mostrar/ocultar la información de la pantalla
#endif
struct FlashEffect
@@ -107,12 +110,24 @@ private:
// Muestra información por pantalla
void renderInfo();
// Calcula la nueva posición de la ventana a partir de la antigua al cambiarla de tamaño
SDL_Point getNewPosition();
// Selecciona y ejecuta el método de renderizado adecuado basado en la configuración de shaders
void renderScreen();
// Reinicia los shaders
void initShaders();
// Calcula el tamaño de la ventana
void adjustWindowSize();
// Ajusta el tamaño lógico del renderizador
void adjustRenderLogicalSize();
// Obtiene el tamaño máximo de zoom posible para la ventana
int getMaxZoom();
// Renderiza todos los overlays y efectos
void renderOverlays();
// Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer);
@@ -142,22 +157,19 @@ public:
void render();
// Establece el modo de video
void setVideoMode(ScreenVideoMode video_mode);
void setVideoMode(ScreenVideoMode video_mode = options.video.mode);
// Cambia entre pantalla completa y ventana
void toggleVideoMode();
// Cambia el tamaño de la ventana
void setWindowSize(int size);
void setWindowZoom(int size);
// Reduce el tamaño de la ventana
void decWindowSize();
bool decWindowZoom();
// Aumenta el tamaño de la ventana
void incWindowSize();
// Cambia el color del borde
void setBorderColor(Color color);
bool incWindowZoom();
// Cambia el tipo de mezcla
void setBlendMode(SDL_BlendMode blend_mode);
@@ -179,4 +191,10 @@ public:
// Getters
SDL_Renderer *getRenderer() { return renderer_; }
// Muestra la ventana
void show() { SDL_ShowWindow(window_); }
// Oculta la ventana
void hide() { SDL_HideWindow(window_); }
};