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

@@ -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();
}