Arreglos de disseny en Credits

El shaders ja respeten els SDL_RenderSetLogicalSize en pantalla completa, pero no el SDL_RenderSetIntegerScale
This commit is contained in:
2025-03-16 08:50:35 +01:00
parent b5dbb694f3
commit dc7b3bf7e0
8 changed files with 154 additions and 58 deletions

View File

@@ -9,14 +9,14 @@
#include <stdexcept> // Para runtime_error
#include <string> // Para basic_string, string
#include <vector> // Para vector
#include <array> // Para vector
#include <array> // Para vector
#include "balloon_manager.h" // Para BalloonManager
#include "fade.h" // Para Fade, FadeType, FadeMode
#include "global_inputs.h" // Para check, update
#include "input.h" // Para Input
#include "jail_audio.h" // Para JA_GetMusicState, JA_SetMusicVolume
#include "lang.h" // Para getText
#include "global_events.h" // Para handleEvent
#include "global_events.h" // Para handleEvent
#include "param.h" // Para Param, ParamGame, param
#include "player.h" // Para Player, PlayerState
#include "resource.h" // Para Resource
@@ -57,6 +57,9 @@ Credits::Credits()
fade_out_->setType(FadeType::FULLSCREEN);
fade_out_->setPostDuration(400);
updateRedRect();
tiled_bg_->setColor(Color(255, 96, 96));
initPlayers();
SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND);
fillTextTexture();
@@ -94,6 +97,7 @@ void Credits::update()
for (int i = 0; i < REPEAT; ++i)
{
tiled_bg_->update();
cycleColors();
balloon_manager_->update();
updateTextureDstRects();
throwBalloons();
@@ -104,7 +108,7 @@ void Credits::update()
updateAllFades();
++counter_;
}
Screen::get()->update();
globalInputs::update();
@@ -128,23 +132,25 @@ void Credits::render()
// Comprueba el manejador de eventos
void Credits::checkEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
globalEvents::check(event);
}
SDL_Event event;
while (SDL_PollEvent(&event))
{
globalEvents::check(event);
}
}
// Comprueba las entradas
void Credits::checkInput()
{
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
if (Input::get()->checkAnyButtonPressed())
if (Input::get()->checkAnyButtonPressed(INPUT_ALLOW_REPEAT))
{
if (mini_logo_on_position_)
{
// Si el mini_logo ha llegado a su posición final, al pulsar cualquier tecla se activa el fundido
fading_ = true;
want_to_pass_ = true;
}
else
{
@@ -152,6 +158,10 @@ void Credits::checkInput()
want_to_pass_ = true;
}
}
else
{
want_to_pass_ = false;
}
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
globalInputs::check();
@@ -268,12 +278,16 @@ void Credits::fillCanvas()
SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &mini_logo_rect_src_, &mini_logo_rect_dst_);
// Dibuja los rectangulos negros
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 255);
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0xFF);
SDL_RenderFillRect(Screen::get()->getRenderer(), &top_black_rect_);
SDL_RenderFillRect(Screen::get()->getRenderer(), &bottom_black_rect_);
SDL_RenderFillRect(Screen::get()->getRenderer(), &left_black_rect_);
SDL_RenderFillRect(Screen::get()->getRenderer(), &right_black_rect_);
// Dibuja el rectangulo rojo
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0xFF, 0, 0, 0xFF);
SDL_RenderDrawRect(Screen::get()->getRenderer(), &red_rect);
// Si el mini_logo está en su destino, lo dibuja encima de lo anterior
if (mini_logo_on_position_)
{
@@ -419,13 +433,14 @@ void Credits::updateBlackRects()
// Si los rectangulos superior e inferior han llegado al centro
if (left_black_rect_.w != param.game.game_area.center_x && right_black_rect_.x != param.game.game_area.center_x)
{
constexpr int SPEED = 2;
// Si los rectangulos izquierdo y derecho no han llegado al centro
// Incrementa la anchura del rectangulo situado a la izquierda
left_black_rect_.w = std::min(left_black_rect_.w + 4, param.game.game_area.center_x);
left_black_rect_.w = std::min(left_black_rect_.w + SPEED, param.game.game_area.center_x);
// Incrementa la anchura y modifica la posición del rectangulo situado a la derecha
right_black_rect_.w += 4;
right_black_rect_.x = std::max(right_black_rect_.x - 4, param.game.game_area.center_x);
right_black_rect_.w += SPEED;
right_black_rect_.x = std::max(right_black_rect_.x - SPEED, param.game.game_area.center_x);
--current_step;
setVolume(static_cast<int>(initial_volume_ * current_step / steps_));
@@ -447,12 +462,22 @@ void Credits::updateBlackRects()
}
}
// Actualiza el rectangulo rojo
void Credits::updateRedRect()
{
red_rect.x = left_black_rect_.x + left_black_rect_.w;
red_rect.y = top_black_rect_.y + top_black_rect_.h - 1;
red_rect.w = right_black_rect_.x - red_rect.x;
red_rect.h = bottom_black_rect_.y - red_rect.y + 1;
}
// Actualiza el estado de fade
void Credits::updateAllFades()
{
if (fading_)
{
updateBlackRects();
updateRedRect();
}
fade_in_->update();
@@ -483,4 +508,42 @@ void Credits::resetVolume()
{
options.audio.music.volume = initial_volume_;
JA_SetMusicVolume(to_JA_volume(options.audio.music.volume));
}
}
// Cambia el color del fondo
void Credits::cycleColors()
{
constexpr int UPPER_LIMIT = 255; // Límite superior
constexpr int LOWER_LIMIT = 80; // Límite inferior
static float r = static_cast<float>(UPPER_LIMIT);
static float g = static_cast<float>(LOWER_LIMIT);
static float b = static_cast<float>(LOWER_LIMIT);
static float stepR = -0.5f; // Paso flotante para transiciones suaves
static float stepG = 0.3f;
static float stepB = 0.7f;
// Ajustar valores de R
r += stepR;
if (r >= UPPER_LIMIT || r <= LOWER_LIMIT)
{
stepR = -stepR; // Cambia de dirección al alcanzar los límites
}
// Ajustar valores de G
g += stepG;
if (g >= UPPER_LIMIT || g <= LOWER_LIMIT)
{
stepG = -stepG; // Cambia de dirección al alcanzar los límites
}
// Ajustar valores de B
b += stepB;
if (b >= UPPER_LIMIT || b <= LOWER_LIMIT)
{
stepB = -stepB; // Cambia de dirección al alcanzar los límites
}
// Aplicar el color, redondeando a enteros antes de usar
tiled_bg_->setColor(Color(static_cast<int>(r), static_cast<int>(g), static_cast<int>(b)));
}

View File

@@ -54,6 +54,7 @@ private:
SDL_Rect bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_}; // Rectangulo negro inferior
SDL_Rect left_black_rect_ = {play_area_.x, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la izquierda
SDL_Rect right_black_rect_ = {play_area_.x + play_area_.w, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la derecha
SDL_Rect red_rect = play_area_; // Rectangulo rojo para delimitar la ventana
// Actualiza las variables
void update();
@@ -85,6 +86,9 @@ private:
// Actualiza los rectangulos negros
void updateBlackRects();
// Actualiza el rectangulo rojo
void updateRedRect();
// Actualiza el estado de fade
void updateAllFades();
@@ -94,6 +98,9 @@ private:
// Reestablece el nivel de volumen
void resetVolume();
// Cambia el color del fondo
void cycleColors();
public:
// Constructor
Credits();

View File

@@ -55,7 +55,7 @@ Director::Director(int argc, const char *argv[])
section::name = section::Name::GAME;
section::options = section::Options::GAME_PLAY_1P;
#elif DEBUG
section::name = section::Name::LOGO;
section::name = section::Name::CREDITS;
#else // NORMAL GAME
section::name = section::Name::LOGO;
section::options = section::Options::NONE;

View File

@@ -346,8 +346,8 @@ void Game::updateGameStateGameOver()
{
// La partida ha terminado con la derrota de los jugadores
section::name = section::Name::HI_SCORE_TABLE;
section::options = section::Options::HI_SCORE_AFTER_GAME_OVER;
}
section::options = section::Options::HI_SCORE_AFTER_PLAYING;
if (options.audio.enabled)
{
JA_StopChannel(-1);

View File

@@ -176,7 +176,7 @@ void HiScoreTable::updateFade()
if (fade_->hasEnded() && fade_mode_ == FadeMode::OUT)
{
section::name = (section::options == section::Options::HI_SCORE_AFTER_GAME_OVER)
section::name = (section::options == section::Options::HI_SCORE_AFTER_PLAYING)
? section::Name::TITLE
: section::Name::INSTRUCTIONS;
section::options = section::Options::NONE;

View File

@@ -313,7 +313,7 @@ void Intro::initSprites()
const int X_DEST = param.game.game_area.center_x - SPRITE_WIDTH / 2;
const int Y_DEST = param.game.game_area.first_quarter_y - (SPRITE_HEIGHT / 4);
// Inicializa los sprites de la intro
// Inicializa los sprites con las imagenes
constexpr int TOTAL_SPRITES = 6;
for (int i = 0; i < TOTAL_SPRITES; ++i)
{
@@ -339,7 +339,7 @@ void Intro::initSprites()
const int S_X_DEST = X_DEST - BORDER / 2;
const int S_Y_DEST = Y_DEST - BORDER / 2;
// Crea las texturas para las sombras
// Crea las texturas para las imágenes traseras
std::vector<std::shared_ptr<Texture>> shadow_textures;
for (int i = 0; i < TOTAL_SPRITES; ++i)

View File

@@ -10,12 +10,12 @@
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
#include <OpenGL/gl3.h>
#else
#else // NOT ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
#include <OpenGL/gl.h>
#endif //! ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
#else
#endif // ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
#else // NOT __APPLE__
#include <SDL2/SDL_opengl.h>
#endif
#endif // __APPLE__
namespace shader
{
@@ -73,10 +73,13 @@ namespace shader
{
// Create ID for shader
GLuint result = glCreateShader(shaderType);
// Add define depending on shader type
const char *sources[2] = {shaderType == GL_VERTEX_SHADER ? "#define VERTEX\n" : "#define FRAGMENT\n", source};
// Define shader text
glShaderSource(result, 2, sources, NULL);
glShaderSource(result, 2, sources, nullptr);
// Compile shader
glCompileShader(result);
@@ -97,8 +100,6 @@ namespace shader
}
glDeleteShader(result);
result = 0;
// } else {
// std::cout << "Shader compilado correctamente. Id = " << result << std::endl;
}
return result;
}
@@ -127,6 +128,7 @@ namespace shader
if (logLen > 0)
{
char *log = (char *)malloc(logLen * sizeof(char));
// Show any errors as appropriate
glGetProgramInfoLog(programId, logLen, &logLen, log);
std::cout << "Prog Info Log: " << std::endl
@@ -152,11 +154,10 @@ namespace shader
shader::backBuffer = backBuffer;
SDL_GetWindowSize(win, &win_size.x, &win_size.y);
int access;
SDL_QueryTexture(backBuffer, NULL, &access, &tex_size.x, &tex_size.y);
SDL_QueryTexture(backBuffer, nullptr, &access, &tex_size.x, &tex_size.y);
if (access != SDL_TEXTUREACCESS_TARGET)
{
std::cout << "ERROR FATAL: La textura per al render ha de tindre SDL_TEXTUREACCESS_TARGET definit." << std::endl;
exit(1);
throw std::runtime_error("ERROR FATAL: La textura debe tener SDL_TEXTUREACCESS_TARGET definido.");
}
SDL_RendererInfo rendererInfo;
@@ -164,7 +165,6 @@ namespace shader
if (!strncmp(rendererInfo.name, "opengl", 6))
{
// std::cout << "Es OpenGL!" << std::endl;
#ifndef __APPLE__
if (!initGLExtensions())
{
@@ -175,7 +175,6 @@ namespace shader
#endif
// Compilar el shader y dejarlo listo para usar.
programId = compileProgram(vertexShader, fragmentShader);
// std::cout << "programId = " << programId << std::endl;
}
else
{
@@ -190,48 +189,75 @@ namespace shader
void render()
{
GLint oldProgramId;
// Guarrada para obtener el textureid (en driverdata->texture)
// Detach the texture
// Establece el color de fondo
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_SetRenderTarget(renderer, NULL);
SDL_SetRenderTarget(renderer, nullptr);
SDL_RenderClear(renderer);
if (usingOpenGL)
{
SDL_GL_BindTexture(backBuffer, NULL, NULL);
SDL_GL_BindTexture(backBuffer, nullptr, nullptr);
if (programId != 0)
{
glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgramId);
glUseProgram(programId);
}
GLfloat minx, miny, maxx, maxy;
GLfloat minu, maxu, minv, maxv;
// Recupera el tamaño lógico configurado con SDL_RenderSetLogicalSize
int logicalW, logicalH;
SDL_RenderGetLogicalSize(renderer, &logicalW, &logicalH);
if (logicalW == 0 || logicalH == 0)
{
logicalW = win_size.x;
logicalH = win_size.y;
}
// Coordenadas de la ventana donde pintar.
minx = 0.0f;
miny = 0.0f;
maxx = tex_size.x;
maxy = tex_size.y;
// Calcula el viewport para preservar la relación de aspecto (letterboxing)
float windowAspect = static_cast<float>(win_size.x) / win_size.y;
float logicalAspect = static_cast<float>(logicalW) / logicalH;
int viewportX = 0, viewportY = 0, viewportW = win_size.x, viewportH = win_size.y;
minu = 0.0f;
maxu = 1.0f;
minv = 0.0f;
maxv = 1.0f;
if (windowAspect > logicalAspect)
{
// La ventana es más ancha que el espacio lógico:
viewportW = static_cast<int>(logicalAspect * win_size.y);
viewportX = (win_size.x - viewportW) / 2;
}
else
{
// La ventana es más alta que el espacio lógico:
viewportH = static_cast<int>(win_size.x / logicalAspect);
viewportY = (win_size.y - viewportH) / 2;
}
glViewport(viewportX, viewportY, viewportW, viewportH);
glViewport(0, 0, win_size.x, win_size.y);
// Configura la proyección ortográfica usando el espacio lógico
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Se usa glOrtho para definir el espacio lógico:
// el 0 está en la esquina superior izquierda y logicalH en la inferior.
glOrtho(0, static_cast<GLdouble>(logicalW), static_cast<GLdouble>(logicalH), 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Dibuja el quad usando las nuevas coordenadas de textura:
// Se corrigen la inversión vertical y la espejada horizontal.
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(minu, minv);
glVertex2f(minx, miny);
glTexCoord2f(maxu, minv);
glVertex2f(maxx, miny);
glTexCoord2f(minu, maxv);
glVertex2f(minx, maxy);
glTexCoord2f(maxu, maxv);
glVertex2f(maxx, maxy);
// Vértice superior izquierdo: posición (0, 0)
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
// Vértice superior derecho: posición (logicalW, 0)
glTexCoord2f(1.0f, 1.0f);
glVertex2f(static_cast<GLfloat>(logicalW), 0.0f);
// Vértice inferior izquierdo: posición (0, logicalH)
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, static_cast<GLfloat>(logicalH));
// Vértice inferior derecho: posición (logicalW, logicalH)
glTexCoord2f(1.0f, 0.0f);
glVertex2f(static_cast<GLfloat>(logicalW), static_cast<GLfloat>(logicalH));
glEnd();
SDL_GL_SwapWindow(win);
if (programId != 0)
@@ -241,7 +267,7 @@ namespace shader
}
else
{
SDL_RenderCopy(renderer, backBuffer, NULL, NULL);
SDL_RenderCopy(renderer, backBuffer, nullptr, nullptr);
SDL_RenderPresent(renderer);
}
}

View File

@@ -29,7 +29,7 @@ namespace section
QUIT_WITH_CONTROLLER,
QUIT_FROM_EVENT,
RELOAD,
HI_SCORE_AFTER_GAME_OVER,
HI_SCORE_AFTER_PLAYING,
NONE,
};