Compare commits

7 Commits

15 changed files with 370 additions and 194 deletions

234
data/shaders/crtpi_240.glsl Normal file
View File

@@ -0,0 +1,234 @@
/*
crt-pi - A Raspberry Pi friendly CRT shader.
Copyright (C) 2015-2016 davej
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
Notes:
This shader is designed to work well on Raspberry Pi GPUs (i.e. 1080P @ 60Hz on a game with a 4:3 aspect ratio). It pushes the Pi's GPU hard and enabling some features will slow it down so that it is no longer able to match 1080P @ 60Hz. You will need to overclock your Pi to the fastest setting in raspi-config to get the best results from this shader: 'Pi2' for Pi2 and 'Turbo' for original Pi and Pi Zero. Note: Pi2s are slower at running the shader than other Pis, this seems to be down to Pi2s lower maximum memory speed. Pi2s don't quite manage 1080P @ 60Hz - they drop about 1 in 1000 frames. You probably won't notice this, but if you do, try enabling FAKE_GAMMA.
SCANLINES enables scanlines. You'll almost certainly want to use it with MULTISAMPLE to reduce moire effects. SCANLINE_WEIGHT defines how wide scanlines are (it is an inverse value so a higher number = thinner lines). SCANLINE_GAP_BRIGHTNESS defines how dark the gaps between the scan lines are. Darker gaps between scan lines make moire effects more likely.
GAMMA enables gamma correction using the values in INPUT_GAMMA and OUTPUT_GAMMA. FAKE_GAMMA causes it to ignore the values in INPUT_GAMMA and OUTPUT_GAMMA and approximate gamma correction in a way which is faster than true gamma whilst still looking better than having none. You must have GAMMA defined to enable FAKE_GAMMA.
CURVATURE distorts the screen by CURVATURE_X and CURVATURE_Y. Curvature slows things down a lot.
By default the shader uses linear blending horizontally. If you find this too blury, enable SHARPER.
BLOOM_FACTOR controls the increase in width for bright scanlines.
MASK_TYPE defines what, if any, shadow mask to use. MASK_BRIGHTNESS defines how much the mask type darkens the screen.
*/
#pragma parameter CURVATURE_X "Screen curvature - horizontal" 0.10 0.0 1.0 0.01
#pragma parameter CURVATURE_Y "Screen curvature - vertical" 0.15 0.0 1.0 0.01
#pragma parameter MASK_BRIGHTNESS "Mask brightness" 0.70 0.0 1.0 0.01
#pragma parameter SCANLINE_WEIGHT "Scanline weight" 6.0 0.0 15.0 0.1
#pragma parameter SCANLINE_GAP_BRIGHTNESS "Scanline gap brightness" 0.12 0.0 1.0 0.01
#pragma parameter BLOOM_FACTOR "Bloom factor" 1.5 0.0 5.0 0.01
#pragma parameter INPUT_GAMMA "Input gamma" 2.4 0.0 5.0 0.01
#pragma parameter OUTPUT_GAMMA "Output gamma" 2.2 0.0 5.0 0.01
// Haven't put these as parameters as it would slow the code down.
#define SCANLINES
#define MULTISAMPLE
#define GAMMA
//#define FAKE_GAMMA
//#define CURVATURE
//#define SHARPER
// MASK_TYPE: 0 = none, 1 = green/magenta, 2 = trinitron(ish)
#define MASK_TYPE 2
#ifdef GL_ES
#define COMPAT_PRECISION mediump
precision mediump float;
#else
#define COMPAT_PRECISION
#endif
#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float CURVATURE_X;
uniform COMPAT_PRECISION float CURVATURE_Y;
uniform COMPAT_PRECISION float MASK_BRIGHTNESS;
uniform COMPAT_PRECISION float SCANLINE_WEIGHT;
uniform COMPAT_PRECISION float SCANLINE_GAP_BRIGHTNESS;
uniform COMPAT_PRECISION float BLOOM_FACTOR;
uniform COMPAT_PRECISION float INPUT_GAMMA;
uniform COMPAT_PRECISION float OUTPUT_GAMMA;
#else
#define CURVATURE_X 0.05
#define CURVATURE_Y 0.1
#define MASK_BRIGHTNESS 0.80
#define SCANLINE_WEIGHT 6.0
#define SCANLINE_GAP_BRIGHTNESS 0.12
#define BLOOM_FACTOR 3.5
#define INPUT_GAMMA 2.4
#define OUTPUT_GAMMA 2.2
#endif
/* COMPATIBILITY
- GLSL compilers
*/
//uniform vec2 TextureSize;
#if defined(CURVATURE)
varying vec2 screenScale;
#endif
varying vec2 TEX0;
varying float filterWidth;
#if defined(VERTEX)
//uniform mat4 MVPMatrix;
//attribute vec4 VertexCoord;
//attribute vec2 TexCoord;
//uniform vec2 InputSize;
//uniform vec2 OutputSize;
void main()
{
#if defined(CURVATURE)
screenScale = vec2(1.0, 1.0); //TextureSize / InputSize;
#endif
filterWidth = (768.0 / 240.0) / 3.0;
TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
#elif defined(FRAGMENT)
uniform sampler2D Texture;
#if defined(CURVATURE)
vec2 Distort(vec2 coord)
{
vec2 CURVATURE_DISTORTION = vec2(CURVATURE_X, CURVATURE_Y);
// Barrel distortion shrinks the display area a bit, this will allow us to counteract that.
vec2 barrelScale = 1.0 - (0.23 * CURVATURE_DISTORTION);
coord *= screenScale;
coord -= vec2(0.5);
float rsq = coord.x * coord.x + coord.y * coord.y;
coord += coord * (CURVATURE_DISTORTION * rsq);
coord *= barrelScale;
if (abs(coord.x) >= 0.5 || abs(coord.y) >= 0.5)
coord = vec2(-1.0); // If out of bounds, return an invalid value.
else
{
coord += vec2(0.5);
coord /= screenScale;
}
return coord;
}
#endif
float CalcScanLineWeight(float dist)
{
return max(1.0-dist*dist*SCANLINE_WEIGHT, SCANLINE_GAP_BRIGHTNESS);
}
float CalcScanLine(float dy)
{
float scanLineWeight = CalcScanLineWeight(dy);
#if defined(MULTISAMPLE)
scanLineWeight += CalcScanLineWeight(dy-filterWidth);
scanLineWeight += CalcScanLineWeight(dy+filterWidth);
scanLineWeight *= 0.3333333;
#endif
return scanLineWeight;
}
void main()
{
vec2 TextureSize = vec2(320.0, 240.0);
#if defined(CURVATURE)
vec2 texcoord = Distort(TEX0);
if (texcoord.x < 0.0)
gl_FragColor = vec4(0.0);
else
#else
vec2 texcoord = TEX0;
#endif
{
vec2 texcoordInPixels = texcoord * TextureSize;
#if defined(SHARPER)
vec2 tempCoord = floor(texcoordInPixels) + 0.5;
vec2 coord = tempCoord / TextureSize;
vec2 deltas = texcoordInPixels - tempCoord;
float scanLineWeight = CalcScanLine(deltas.y);
vec2 signs = sign(deltas);
deltas.x *= 2.0;
deltas = deltas * deltas;
deltas.y = deltas.y * deltas.y;
deltas.x *= 0.5;
deltas.y *= 8.0;
deltas /= TextureSize;
deltas *= signs;
vec2 tc = coord + deltas;
#else
float tempY = floor(texcoordInPixels.y) + 0.5;
float yCoord = tempY / TextureSize.y;
float dy = texcoordInPixels.y - tempY;
float scanLineWeight = CalcScanLine(dy);
float signY = sign(dy);
dy = dy * dy;
dy = dy * dy;
dy *= 8.0;
dy /= TextureSize.y;
dy *= signY;
vec2 tc = vec2(texcoord.x, yCoord + dy);
#endif
vec3 colour = texture2D(Texture, tc).rgb;
#if defined(SCANLINES)
#if defined(GAMMA)
#if defined(FAKE_GAMMA)
colour = colour * colour;
#else
colour = pow(colour, vec3(INPUT_GAMMA));
#endif
#endif
scanLineWeight *= BLOOM_FACTOR;
colour *= scanLineWeight;
#if defined(GAMMA)
#if defined(FAKE_GAMMA)
colour = sqrt(colour);
#else
colour = pow(colour, vec3(1.0/OUTPUT_GAMMA));
#endif
#endif
#endif
#if MASK_TYPE == 0
gl_FragColor = vec4(colour, 1.0);
#else
#if MASK_TYPE == 1
float whichMask = fract((gl_FragCoord.x*1.0001) * 0.5);
vec3 mask;
if (whichMask < 0.5)
mask = vec3(MASK_BRIGHTNESS, 1.0, MASK_BRIGHTNESS);
else
mask = vec3(1.0, MASK_BRIGHTNESS, 1.0);
#elif MASK_TYPE == 2
float whichMask = fract((gl_FragCoord.x*1.0001) * 0.3333333);
vec3 mask = vec3(MASK_BRIGHTNESS, MASK_BRIGHTNESS, MASK_BRIGHTNESS);
if (whichMask < 0.3333333)
mask.x = 1.0;
else if (whichMask < 0.6666666)
mask.y = 1.0;
else
mask.z = 1.0;
#endif
gl_FragColor = vec4(colour * mask, 1.0);
#endif
}
}
#endif

View File

@@ -97,7 +97,6 @@ void main()
#if defined(CURVATURE) #if defined(CURVATURE)
screenScale = vec2(1.0, 1.0); //TextureSize / InputSize; screenScale = vec2(1.0, 1.0); //TextureSize / InputSize;
#endif #endif
//filterWidth = (768.0 / 240.0) / 3.0;
filterWidth = (768.0 / 256.0) / 3.0; filterWidth = (768.0 / 256.0) / 3.0;
TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001; TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

View File

@@ -106,6 +106,7 @@ void Balloon::render()
SDL_Point p = {24, 24}; SDL_Point p = {24, 24};
sprite_->setRotatingCenter(&p); sprite_->setRotatingCenter(&p);
sprite_->render(); sprite_->render();
// Añade la máscara del borde y los reflejos // Añade la máscara del borde y los reflejos
auto sp = std::make_unique<Sprite>(sprite_->getTexture(), sprite_->getPosition()); auto sp = std::make_unique<Sprite>(sprite_->getTexture(), sprite_->getPosition());
sp->setSpriteClip(BALLOON_SIZE[4], 0, BALLOON_SIZE[4], BALLOON_SIZE[4]); sp->setSpriteClip(BALLOON_SIZE[4], 0, BALLOON_SIZE[4], BALLOON_SIZE[4]);
@@ -123,18 +124,8 @@ void Balloon::render()
} }
else else
{ {
if (bouncing_.enabled) // Renderizado normal
{ sprite_->render();
// Renderizado con efecto de bouncing
sprite_->setPos(x_ + bouncing_.despX, y_ + bouncing_.despY);
sprite_->render();
// sprite_->setPos(x_ - bouncing_.despX, y_ - bouncing_.despY);
}
else
{
// Renderizado normal
sprite_->render();
}
} }
} }
} }
@@ -151,7 +142,7 @@ void Balloon::move()
// Colisión en las partes laterales de la zona de juego // Colisión en las partes laterales de la zona de juego
const int clip = 2; const int clip = 2;
const float min_x = play_area_.x - clip; const float min_x = play_area_.x - clip;
const float max_x = play_area_.w - w_ + clip; const float max_x = play_area_.x + play_area_.w - w_ + clip;
if (x_ < min_x || x_ > max_x) if (x_ < min_x || x_ > max_x)
{ {
x_ = std::clamp(x_, min_x, max_x); x_ = std::clamp(x_, min_x, max_x);
@@ -195,7 +186,7 @@ void Balloon::move()
} }
// Colisión en la parte inferior de la zona de juego // Colisión en la parte inferior de la zona de juego
const int max_y = play_area_.h - h_; const int max_y = play_area_.y + play_area_.h - h_;
if (y_ > max_y) if (y_ > max_y)
{ {
y_ = max_y; y_ = max_y;
@@ -388,12 +379,10 @@ void Balloon::updateBounce()
zoomSprite(); zoomSprite();
const auto spriteClip = sprite_->getSpriteClip();
bouncing_.despX = spriteClip.w * (1.0f - bouncing_.zoomW);
bouncing_.despY = spriteClip.h * (1.0f - bouncing_.zoomH);
if (++bouncing_.counter / bouncing_.speed >= MAX_BOUNCE) if (++bouncing_.counter / bouncing_.speed >= MAX_BOUNCE)
{
disableBounce(); disableBounce();
}
} }
} }

View File

@@ -39,17 +39,20 @@ Credits::Credits()
throw std::runtime_error("Failed to create SDL texture for text."); throw std::runtime_error("Failed to create SDL texture for text.");
} }
section::name = section::Name::CREDITS; section::name = section::Name::CREDITS;
top_black_rect_ = {play_area_.x, 0, play_area_.w, black_bars_size_}; //top_black_rect_ = {play_area_.x, 0, play_area_.w, black_bars_size_};
bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_}; //bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_};
balloon_manager_->setPlayArea(play_area_); balloon_manager_->setPlayArea(play_area_);
fade_in_->setColor(fade_color.r, fade_color.g, fade_color.b); fade_in_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_in_->setType(FadeType::FULLSCREEN); fade_in_->setType(FadeType::FULLSCREEN);
fade_in_->setPost(50); fade_in_->setPost(50);
fade_in_->setMode(FadeMode::IN); fade_in_->setMode(FadeMode::IN);
fade_in_->activate(); fade_in_->activate();
fade_out_->setColor(0, 0, 0); fade_out_->setColor(0, 0, 0);
fade_out_->setType(FadeType::FULLSCREEN); fade_out_->setType(FadeType::FULLSCREEN);
fade_out_->setPost(400); fade_out_->setPost(400);
initPlayers(); initPlayers();
SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND);
fillTextTexture(); fillTextTexture();
@@ -323,7 +326,7 @@ void Credits::throwBalloons()
if (counter_ % speed == 0) if (counter_ % speed == 0)
{ {
const int index = (counter_ / speed) % sets.size(); const int index = (counter_ / speed) % sets.size();
balloon_manager_->deploySet(sets.at(index), -50); balloon_manager_->deploySet(sets.at(index), -60);
} }
if (counter_ % (speed * 4) == 0 && counter_ > 0) if (counter_ % (speed * 4) == 0 && counter_ > 0)
@@ -362,7 +365,7 @@ void Credits::initPlayers()
// Crea los dos jugadores // Crea los dos jugadores
constexpr int player_width = 30; constexpr int player_width = 30;
const int y = play_area_.h - player_width; const int y = play_area_.y + play_area_.h - player_width;
constexpr bool demo = false; constexpr bool demo = false;
constexpr int away_distance = 700; constexpr int away_distance = 700;
players_.emplace_back(std::make_unique<Player>(1, play_area_.x - away_distance - player_width, y, demo, play_area_, player_textures.at(0), player_animations)); players_.emplace_back(std::make_unique<Player>(1, play_area_.x - away_distance - player_width, y, demo, play_area_, player_textures.at(0), player_animations));

View File

@@ -10,6 +10,8 @@ class TiledBG;
class Player; class Player;
class Fade; class Fade;
constexpr int PLAY_AREA_HEIGHT = 200;
class Credits class Credits
{ {
private: private:
@@ -22,18 +24,18 @@ private:
std::vector<std::shared_ptr<Player>> players_; // Vector con los jugadores std::vector<std::shared_ptr<Player>> players_; // Vector con los jugadores
// Variables // Variables
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_ = 15; // Velocidad del bucle update Uint32 ticks_speed_ = 15; // Velocidad del bucle update
Uint32 counter_ = 0; // Contador para la lógica de la clase Uint32 counter_ = 0; // Contador para la lógica de la clase
Uint32 counter_pre_fade_ = 0; // Contador para activar el fundido final Uint32 counter_pre_fade_ = 0; // Contador para activar el fundido final
Uint32 counter_prevent_endless_ = 0; // Contador para evitar que el juego se quede para siempre en los creditos Uint32 counter_prevent_endless_ = 0; // Contador para evitar que el juego se quede para siempre en los creditos
int black_bars_size_ = 28; // Tamaño de las barras negras int black_bars_size_ = (param.game.game_area.rect.h - PLAY_AREA_HEIGHT) / 2; // Tamaño de las barras negras
int mini_logo_final_pos_ = 0; // Ubicación donde se detiene el minilogo int mini_logo_final_pos_ = 0; // Ubicación donde se detiene el minilogo
bool fading_ = false; // Indica si se está realizando el fade final bool fading_ = false; // Indica si se está realizando el fade final
bool want_to_pass_ = false; // Indica si el jugador quiere saltarse los titulos de crédito bool want_to_pass_ = false; // Indica si el jugador quiere saltarse los titulos de crédito
bool mini_logo_on_position_ = false; // Indica si el minilogo ya se ha quedado en su posición bool mini_logo_on_position_ = false; // Indica si el minilogo ya se ha quedado en su posición
int initial_volume_ = options.audio.music.volume; // Volumen actual al crear el objeto int initial_volume_ = options.audio.music.volume; // Volumen actual al crear el objeto
int steps_ = 0; // Cantidad de pasos a dar para ir reduciendo el audio int steps_ = 0; // Cantidad de pasos a dar para ir reduciendo el audio
// Rectangulos // Rectangulos
SDL_Rect credits_rect_src_ = param.game.game_area.rect; // Rectangulo con el texto de los créditos (origen) SDL_Rect credits_rect_src_ = param.game.game_area.rect; // Rectangulo con el texto de los créditos (origen)
@@ -44,8 +46,8 @@ private:
param.game.game_area.rect.x, param.game.game_area.rect.x,
param.game.game_area.rect.y + black_bars_size_, param.game.game_area.rect.y + black_bars_size_,
param.game.game_area.rect.w, param.game.game_area.rect.w,
param.game.game_area.rect.h - black_bars_size_}; // Area visible para los creditos PLAY_AREA_HEIGHT}; // Area visible para los creditos
SDL_Rect top_black_rect_ = {play_area_.x, 0, play_area_.w, black_bars_size_}; // Rectangulo negro superior SDL_Rect top_black_rect_ = {play_area_.x, param.game.game_area.rect.y, play_area_.w, black_bars_size_}; // Rectangulo negro superior
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 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 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 right_black_rect_ = {play_area_.x + play_area_.w, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la derecha

View File

@@ -54,7 +54,7 @@ Director::Director(int argc, const char *argv[])
section::name = section::Name::GAME; section::name = section::Name::GAME;
section::options = section::Options::GAME_PLAY_1P; section::options = section::Options::GAME_PLAY_1P;
#elif DEBUG #elif DEBUG
section::name = section::Name::CREDITS; section::name = section::Name::LOGO;
#else // NORMAL GAME #else // NORMAL GAME
section::name = section::Name::LOGO; section::name = section::Name::LOGO;
section::attract_mode = section::AttractMode::TITLE_TO_DEMO; section::attract_mode = section::AttractMode::TITLE_TO_DEMO;
@@ -399,7 +399,8 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/sound/logo.wav", AssetType::SOUND); Asset::get()->add(prefix + "/data/sound/logo.wav", AssetType::SOUND);
// Shaders // Shaders
Asset::get()->add(prefix + "/data/shaders/crtpi.glsl", AssetType::DATA); Asset::get()->add(prefix + "/data/shaders/crtpi_256.glsl", AssetType::DATA);
Asset::get()->add(prefix + "/data/shaders/crtpi_240.glsl", AssetType::DATA);
// Texturas // Texturas
@@ -671,6 +672,16 @@ void Director::runDemoGame()
game->run(); game->run();
} }
// Ejecuta la sección init
void Director::runInit()
{
if (section::options == section::Options::RELOAD)
{
Resource::get()->reload();
}
section::name = section::Name::LOGO;
}
int Director::run() int Director::run()
{ {
// Bucle principal // Bucle principal
@@ -679,8 +690,7 @@ int Director::run()
switch (section::name) switch (section::name)
{ {
case section::Name::INIT: case section::Name::INIT:
Resource::get()->reload(); runInit();
section::name = section::Name::LOGO;
break; break;
case section::Name::LOGO: case section::Name::LOGO:
runLogo(); runLogo();

View File

@@ -67,6 +67,9 @@ private:
// Ejecuta el juego en modo demo // Ejecuta el juego en modo demo
void runDemoGame(); void runDemoGame();
// Ejecuta la sección init
void runInit();
// Obtiene una fichero a partir de un lang::Code // Obtiene una fichero a partir de un lang::Code
std::string getLangFile(lang::Code code); std::string getLangFile(lang::Code code);
#ifdef ARCADE #ifdef ARCADE

View File

@@ -15,30 +15,24 @@ GameLogo::GameLogo(int x, int y)
coffee_texture_(Resource::get()->getTexture("title_coffee.png")), coffee_texture_(Resource::get()->getTexture("title_coffee.png")),
crisis_texture_(Resource::get()->getTexture("title_crisis.png")), crisis_texture_(Resource::get()->getTexture("title_crisis.png")),
arcade_edition_texture_(Resource::get()->getTexture("title_arcade_edition.png")), arcade_edition_texture_(Resource::get()->getTexture("title_arcade_edition.png")),
dust_left_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))), dust_left_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
dust_right_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))), dust_right_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
coffee_sprite_(std::make_unique<SmartSprite>(coffee_texture_)), coffee_sprite_(std::make_unique<SmartSprite>(coffee_texture_)),
crisis_sprite_(std::make_unique<SmartSprite>(crisis_texture_)), crisis_sprite_(std::make_unique<SmartSprite>(crisis_texture_)),
arcade_edition_sprite_(std::make_unique<Sprite>(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())), arcade_edition_sprite_(std::make_unique<Sprite>(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())),
x_(x), x_(x),
y_(y) y_(y) { }
{
// Inicializa las variables
init();
}
// Inicializa las variables // Inicializa las variables
void GameLogo::init() void GameLogo::init()
{ {
const auto xp = x_ - coffee_sprite_->getWidth() / 2; const auto xp = x_ - coffee_texture_->getWidth() / 2;
const auto desp = getInitialVerticalDesp(); const auto desp = getInitialVerticalDesp();
// Variables // Variables
status_ = Status::DISABLED; coffee_crisis_status_ = Status::DISABLED;
arcade_edition_status_ = Status::DISABLED;
shake_.desp = 1; shake_.desp = 1;
shake_.delay = 2; shake_.delay = 2;
shake_.lenght = 8; shake_.lenght = 8;
@@ -46,6 +40,8 @@ void GameLogo::init()
shake_.counter = shake_.delay; shake_.counter = shake_.delay;
shake_.origin = xp; shake_.origin = xp;
zoom_ = 3.0f;
// Inicializa el bitmap de 'Coffee' // Inicializa el bitmap de 'Coffee'
coffee_sprite_->setPosX(xp); coffee_sprite_->setPosX(xp);
coffee_sprite_->setPosY(y_ - coffee_texture_->getHeight() - desp); coffee_sprite_->setPosY(y_ - coffee_texture_->getHeight() - desp);
@@ -90,6 +86,9 @@ void GameLogo::init()
dust_left_sprite_->setPosY(y_); dust_left_sprite_->setPosY(y_);
dust_left_sprite_->setWidth(16); dust_left_sprite_->setWidth(16);
dust_left_sprite_->setHeight(16); dust_left_sprite_->setHeight(16);
// Inicializa el bitmap de 'Arcade Edition'
arcade_edition_sprite_->setZoom(zoom_);
} }
// Pinta la clase en pantalla // Pinta la clase en pantalla
@@ -99,8 +98,10 @@ void GameLogo::render()
coffee_sprite_->render(); coffee_sprite_->render();
crisis_sprite_->render(); crisis_sprite_->render();
if (status_ == Status::FINISHED) if (arcade_edition_status_ != Status::DISABLED)
{
arcade_edition_sprite_->render(); arcade_edition_sprite_->render();
}
// Dibuja el polvillo del logo // Dibuja el polvillo del logo
dust_right_sprite_->render(); dust_right_sprite_->render();
@@ -110,17 +111,18 @@ void GameLogo::render()
// Actualiza la lógica de la clase // Actualiza la lógica de la clase
void GameLogo::update() void GameLogo::update()
{ {
switch (status_) switch (coffee_crisis_status_)
{ {
case Status::MOVING: case Status::MOVING:
{ {
coffee_sprite_->update(); coffee_sprite_->update();
crisis_sprite_->update(); crisis_sprite_->update();
// Si los objetos han llegado a su destino, cambiamos de Sección // Si los objetos han llegado a su destino, cambia el estado
if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished()) if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished())
{ {
status_ = Status::SHAKING; coffee_crisis_status_ = Status::SHAKING;
arcade_edition_status_ = Status::MOVING;
// Reproduce el efecto sonoro // Reproduce el efecto sonoro
JA_PlaySound(Resource::get()->getSound("title.wav")); JA_PlaySound(Resource::get()->getSound("title.wav"));
@@ -151,7 +153,7 @@ void GameLogo::update()
{ {
coffee_sprite_->setPosX(shake_.origin); coffee_sprite_->setPosX(shake_.origin);
crisis_sprite_->setPosX(shake_.origin + 15); crisis_sprite_->setPosX(shake_.origin + 15);
status_ = Status::FINISHED; coffee_crisis_status_ = Status::FINISHED;
} }
dust_right_sprite_->update(); dust_right_sprite_->update();
@@ -171,19 +173,37 @@ void GameLogo::update()
default: default:
break; break;
} }
switch (arcade_edition_status_)
{
case Status::MOVING:
{
zoom_ -= 0.1f;
arcade_edition_sprite_->setZoom(zoom_);
if (zoom_ <= 1.0f)
{
arcade_edition_status_ = Status::FINISHED;
zoom_ = 1.0f;
}
break;
}
default:
break;
}
} }
// Activa la clase // Activa la clase
void GameLogo::enable() void GameLogo::enable()
{ {
init(); init();
status_ = Status::MOVING; coffee_crisis_status_ = Status::MOVING;
} }
// Indica si ha terminado la animación // Indica si ha terminado la animación
bool GameLogo::hasFinished() const bool GameLogo::hasFinished() const
{ {
return status_ == Status::FINISHED; return coffee_crisis_status_ == Status::FINISHED && arcade_edition_status_ == Status::FINISHED;
} }
// Recarga las texturas // Recarga las texturas
@@ -192,6 +212,7 @@ void GameLogo::reLoad()
dust_texture_->reLoad(); dust_texture_->reLoad();
coffee_texture_->reLoad(); coffee_texture_->reLoad();
crisis_texture_->reLoad(); crisis_texture_->reLoad();
arcade_edition_texture_->reLoad();
} }
// Calcula el desplazamiento vertical inicial // Calcula el desplazamiento vertical inicial

View File

@@ -43,11 +43,13 @@ private:
std::unique_ptr<Sprite> arcade_edition_sprite_; // Sprite con los graficos de "Arcade Edition" std::unique_ptr<Sprite> arcade_edition_sprite_; // Sprite con los graficos de "Arcade Edition"
// Variables // Variables
int x_; // Posición donde dibujar el logo int x_; // Posición donde dibujar el logo
int y_; // Posición donde dibujar el logo int y_; // Posición donde dibujar el logo
float zoom_; // Zoom aplicado al texto "ARCADE EDITION"
Status status_; // Estado en el que se encuentra la clase Status coffee_crisis_status_ = Status::DISABLED; // Estado en el que se encuentra el texto "COFFEE CRISIS"
Shake shake_; // Estructura para generar el efecto de agitación Status arcade_edition_status_ = Status::DISABLED; // Estado en el que se encuentra el texto "ARCADE_EDITION"
Shake shake_; // Estructura para generar el efecto de agitación
// Inicializa las variables // Inicializa las variables
void init(); void init();

View File

@@ -104,6 +104,7 @@ namespace globalInputs
options.game.language = lang::change(options.game.language); options.game.language = lang::change(options.game.language);
lang::loadFromFile(getLangFile(static_cast<lang::Code>(options.game.language))); lang::loadFromFile(getLangFile(static_cast<lang::Code>(options.game.language)));
section::name = section::Name::INIT; section::name = section::Name::INIT;
section::options = section::Options::RELOAD;
Notifier::get()->showText({getLangName(options.game.language)}); Notifier::get()->showText({getLangName(options.game.language)});
} }

View File

@@ -200,7 +200,8 @@ void Screen::setVideoMode(ScreenVideoMode videoMode)
if (options.video.shaders) if (options.video.shaders)
{ {
#ifndef NO_SHADERS #ifndef NO_SHADERS
std::ifstream f(Asset::get()->get("crtpi.glsl").c_str()); 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>()); std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
shader::init(window_, shader_canvas_, source.c_str()); shader::init(window_, shader_canvas_, source.c_str());

View File

@@ -27,7 +27,8 @@ namespace section
QUIT_WITH_KEYBOARD = 4, QUIT_WITH_KEYBOARD = 4,
QUIT_WITH_CONTROLLER = 5, QUIT_WITH_CONTROLLER = 5,
QUIT_FROM_EVENT = 6, QUIT_FROM_EVENT = 6,
NONE = 7, RELOAD = 7,
NONE = 8,
}; };
// Variables para el Attract Mode // Variables para el Attract Mode

View File

@@ -19,31 +19,7 @@ Sprite::Sprite(std::shared_ptr<Texture> texture)
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void Sprite::render() void Sprite::render()
{ {
texture_->render(pos_.x, pos_.y, &sprite_clip_); texture_->render(pos_.x, pos_.y, &sprite_clip_, zoom_, zoom_);
}
// Obten el valor de la variable
int Sprite::getX() const
{
return pos_.x;
}
// Obten el valor de la variable
int Sprite::getY() const
{
return pos_.y;
}
// Obten el valor de la variable
int Sprite::getWidth() const
{
return pos_.w;
}
// Obten el valor de la variable
int Sprite::getHeight() const
{
return pos_.h;
} }
// Establece la posición del objeto // Establece la posición del objeto
@@ -60,84 +36,6 @@ void Sprite::setPosition(SDL_Point p)
pos_.y = p.y; pos_.y = p.y;
} }
// Establece la posición del objeto
void Sprite::setPosition(SDL_Rect r)
{
pos_ = r;
}
// Establece el valor de la variable
void Sprite::setX(int x)
{
pos_.x = x;
}
// Establece el valor de la variable
void Sprite::setY(int y)
{
pos_.y = y;
}
// Establece el valor de la variable
void Sprite::setWidth(int w)
{
pos_.w = w;
}
// Establece el valor de la variable
void Sprite::setHeight(int h)
{
pos_.h = h;
}
// Obten el valor de la variable
SDL_Rect Sprite::getSpriteClip() const
{
return sprite_clip_;
}
// Establece el valor de la variable
void Sprite::setSpriteClip(SDL_Rect rect)
{
sprite_clip_ = rect;
}
// Establece el valor de la variable
void Sprite::setSpriteClip(int x, int y, int w, int h)
{
sprite_clip_ = (SDL_Rect){x, y, w, h};
}
// Obten el valor de la variable
std::shared_ptr<Texture> Sprite::getTexture() const
{
return texture_;
}
// Establece el valor de la variable
void Sprite::setTexture(std::shared_ptr<Texture> texture)
{
texture_ = texture;
}
// Devuelve el rectangulo donde está el sprite
SDL_Rect Sprite::getPosition() const
{
return pos_;
}
// Incrementa el valor de la variable
void Sprite::incX(int value)
{
pos_.x += value;
}
// Incrementa el valor de la variable
void Sprite::incY(int value)
{
pos_.y += value;
}
// Reinicia las variables a cero // Reinicia las variables a cero
void Sprite::clear() void Sprite::clear()
{ {

View File

@@ -12,6 +12,7 @@ protected:
std::shared_ptr<Texture> texture_; // Textura donde estan todos los dibujos del sprite std::shared_ptr<Texture> texture_; // Textura donde estan todos los dibujos del sprite
SDL_Rect pos_; // Posición y tamaño donde dibujar el sprite SDL_Rect pos_; // Posición y tamaño donde dibujar el sprite
SDL_Rect sprite_clip_; // Rectangulo de origen de la textura que se dibujará en pantalla SDL_Rect sprite_clip_; // Rectangulo de origen de la textura que se dibujará en pantalla
double zoom_ = 1.0f; // Zoom aplicado a la textura
public: public:
// Constructor // Constructor
@@ -28,40 +29,43 @@ public:
// Reinicia las variables a cero // Reinicia las variables a cero
virtual void clear(); virtual void clear();
// Obten el valor de la variable // Obtiene la posición y el tamaño
int getX() const; int getX() const { return pos_.x; }
int getY() const; int getY() const { return pos_.y; }
int getWidth() const; int getWidth() const { return pos_.w; }
int getHeight() const; int getHeight() const { return pos_.h; }
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
SDL_Rect getPosition() const; SDL_Rect getPosition() const { return pos_; }
// Establece el valor de la variable // Establece la posición y el tamaño
void setX(int x); void setX(int x) { pos_.x = x; }
void setY(int y); void setY(int y) { pos_.y = y; }
void setWidth(int w); void setWidth(int w) { pos_.w = w; }
void setHeight(int h); void setHeight(int h) { pos_.h = h; }
// Establece la posición del objeto // Establece la posición del objeto
void setPosition(int x, int y); void setPosition(int x, int y);
void setPosition(SDL_Point p); void setPosition(SDL_Point p);
void setPosition(SDL_Rect r); void setPosition(SDL_Rect r) { pos_ = r; }
// Incrementa el valor de la variable // Establece el nivel de zoom
void incX(int value); void setZoom(float zoom) { zoom_ = zoom; }
void incY(int value);
// Obten el valor de la variable // Aumenta o disminuye la posición
SDL_Rect getSpriteClip() const; void incX(int value) { pos_.x += value; }
void incY(int value) { pos_.y += value; }
// Establece el valor de la variable // Obtiene el rectangulo que se dibuja de la textura
void setSpriteClip(SDL_Rect rect); SDL_Rect getSpriteClip() const { return sprite_clip_; }
void setSpriteClip(int x, int y, int w, int h);
// Obten el valor de la variable // Establece el rectangulo que se dibuja de la textura
std::shared_ptr<Texture> getTexture() const; void setSpriteClip(SDL_Rect rect) { sprite_clip_ = rect; }
void setSpriteClip(int x, int y, int w, int h) { sprite_clip_ = (SDL_Rect){x, y, w, h}; }
// Establece el valor de la variable // Obtiene un puntero a la textura
void setTexture(std::shared_ptr<Texture> texture); std::shared_ptr<Texture> getTexture() const { return texture_; }
// Establece la textura a utilizar
void setTexture(std::shared_ptr<Texture> texture) { texture_ = texture; }
}; };

View File

@@ -190,8 +190,16 @@ void Texture::render(int x, int y, SDL_Rect *clip, float zoomW, float zoomH, dou
renderQuad.h = clip->h; renderQuad.h = clip->h;
} }
renderQuad.w = renderQuad.w * zoomW; // Calcula el zoom y las coordenadas
renderQuad.h = renderQuad.h * zoomH; if (zoomH != 1.0f || zoomW != 1.0f)
{
renderQuad.x = renderQuad.x + (renderQuad.w / 2);
renderQuad.y = renderQuad.y + (renderQuad.h / 2);
renderQuad.w = renderQuad.w * zoomW;
renderQuad.h = renderQuad.h * zoomH;
renderQuad.x = renderQuad.x - (renderQuad.w / 2);
renderQuad.y = renderQuad.y - (renderQuad.h / 2);
}
// Renderiza a pantalla // Renderiza a pantalla
SDL_RenderCopyEx(renderer_, texture_, clip, &renderQuad, angle, center, flip); SDL_RenderCopyEx(renderer_, texture_, clip, &renderQuad, angle, center, flip);