Files
jaildoctors_dilemma/source/loading_screen.cpp

281 lines
7.7 KiB
C++

#include "loading_screen.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <stdlib.h> // for rand
#include "asset.h" // for Asset
#include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH
#include "global_events.h" // for check
#include "global_inputs.h" // for check
#include "input.h" // for Input
#include "jail_audio.h" // for JA_PlayMusic, JA_SetVolume, JA_StopMusic
#include "options.h" // for Options, options, OptionsVideo, Section...
#include "resource.h" // for Resource
#include "screen.h" // for Screen
#include "sprite.h" // for Sprite
#include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette
// Constructor
LoadingScreen::LoadingScreen()
: screen_(Screen::get()),
renderer_(Screen::get()->getRenderer()),
resource_(Resource::get()),
asset_(Asset::get()),
input_(Input::get())
{
// Reserva memoria para los punteros
if (options.video.palette == Palette::ZXSPECTRUM)
{
mono_loading_screen_texture_ = resource_->getTexture("loading_screen_bn.png");
color_loading_screen_texture_ = resource_->getTexture("loading_screen_color.png");
}
else if (options.video.palette == Palette::ZXARNE)
{
mono_loading_screen_texture_ = resource_->getTexture("loading_screen_bn_zxarne.png");
color_loading_screen_texture_ = resource_->getTexture("loading_screen_color_zxarne.png");
}
mono_loading_screen_sprite_ = std::make_shared<Sprite>(mono_loading_screen_texture_, 0, 0, mono_loading_screen_texture_->getWidth(), mono_loading_screen_texture_->getHeight());
color_loading_screen_sprite_ = std::make_shared<Sprite>(color_loading_screen_texture_, 0, 0, color_loading_screen_texture_->getWidth(), color_loading_screen_texture_->getHeight());
loading_sound1_ = resource_->getMusic("loading_sound1.ogg");
loading_sound2_ = resource_->getMusic("loading_sound2.ogg");
loading_sound3_ = resource_->getMusic("loading_sound3.ogg");
// Inicializa variables
options.section.section = Section::LOADING_SCREEN;
options.section.subsection = Subsection::NONE;
// Establece el orden de las lineas para imitar el direccionamiento de memoria del spectrum
for (int i = 0; i < 192; ++i)
{
if (i < 64)
{ // Primer bloque de 2K
line_index_[i] = ((i % 8) * 8) + (i / 8);
}
else if (i >= 64 && i < 128)
{ // Segundo bloque de 2K
line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8);
}
else if (i >= 128 && i < 192)
{ // tercer bloque de 2K
line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8);
}
}
// Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "black"));
}
// Destructor
LoadingScreen::~LoadingScreen()
{
JA_StopMusic();
}
// Comprueba el manejador de eventos
void LoadingScreen::checkEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
globalEvents::check(event);
}
}
// Comprueba las entradas
void LoadingScreen::checkInput()
{
globalInputs::check();
}
// Gestiona el contador de carga
void LoadingScreen::updateLoad()
{
// Primera parte de la carga, la parte en blanco y negro
if (loading_first_part_)
{
// Cada 5 pasos el load_counter_ se incrementa en uno
const int numSteps = 5;
const int step = 51;
load_counter_ = counter_ / numSteps;
if (load_counter_ < 192)
{
load_rect_.x = step * (counter_ % numSteps);
load_rect_.y = line_index_[load_counter_];
mono_loading_screen_sprite_->setClip(load_rect_);
mono_loading_screen_sprite_->setPosition(load_rect_);
}
// Una vez actualizadas las 192 lineas, pasa a la segunda fase de la carga
else if (load_counter_ == 192)
{
loading_first_part_ = false;
load_counter_ = 0;
load_rect_ = {0, 0, 16, 8};
color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_);
JA_PlayMusic(loading_sound3_);
}
}
// Segunda parte de la carga, la parte de los bloques en color
else
{
load_counter_ += 2;
load_rect_.x = (load_counter_ * 8) % 256;
load_rect_.y = (load_counter_ / 32) * 8;
color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_);
// Comprueba si ha terminado la intro
if (load_counter_ >= 768)
{
options.section.section = Section::TITLE;
options.section.subsection = Subsection::TITLE_WITH_LOADING_SCREEN;
JA_StopMusic();
}
}
}
// Gestiona el contador interno
void LoadingScreen::updateCounter()
{
(pre_counter_ >= 50) ? counter_++ : pre_counter_++;
if (counter_ == 1)
{
JA_PlayMusic(loading_sound2_);
}
}
// Dibuja la pantalla de carga
void LoadingScreen::renderLoad()
{
loading_first_part_ ? mono_loading_screen_sprite_->render() : color_loading_screen_sprite_->render();
}
// Dibuja el efecto de carga en el borde
void LoadingScreen::renderBorder()
{
// Pinta el borde de colro azul
Color color = stringToColor(options.video.palette, "blue");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer_);
// Añade lineas amarillas
color = stringToColor(options.video.palette, "yellow");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
const int width = GAMECANVAS_WIDTH + (options.video.border.width * 2);
const int height = GAMECANVAS_HEIGHT + (options.video.border.height * 2);
bool drawEnabled = rand() % 2 == 0 ? true : false;
int row = 0;
int rowSize = 1;
while (row < height)
{
rowSize = (rand() % 4) + 3;
if (drawEnabled)
for (int i = row; i < row + rowSize; ++i)
{
SDL_RenderDrawLine(renderer_, 0, i, width, i);
}
row += rowSize;
drawEnabled = !drawEnabled;
}
}
// Actualiza las variables
void LoadingScreen::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks_ > ticks_speed_)
{
ticks_ = SDL_GetTicks();
checkInput();
updateCounter();
updateLoad();
screen_->update();
}
}
// Dibuja en pantalla
void LoadingScreen::render()
{
if (options.video.border.enabled)
{
// Prepara para empezar a dibujar en la textura del borde
screen_->startDrawOnBorder();
// Dibuja el efecto de carga en el borde
renderBorder();
}
// Prepara para empezar a dibujar en la textura de juego
screen_->start();
// Dibuja la pantalla de carga
renderLoad();
// Vuelca el contenido del renderizador en pantalla
screen_->render();
}
// Bucle para el logo del juego
void LoadingScreen::run()
{
// Inicia el sonido de carga
JA_SetVolume(64);
JA_PlayMusic(loading_sound1_);
// Limpia la pantalla
screen_->start();
screen_->clean();
screen_->render();
while (options.section.section == Section::LOADING_SCREEN)
{
update();
checkEvents();
render();
}
JA_SetVolume(128);
}
// Reconstruye la pantalla de carga
void LoadingScreen::recreateLoadingScreen()
{
// Prepara para empezar a dibujar en la textura de juego
screen_->start();
// Primera parte de la carga, la parte en blanco y negro
if (loading_first_part_)
{
const int numSteps = 5;
const int step = 51;
for (int i = 0; i <= counter_; i++)
{
load_counter_ = i / numSteps;
load_rect_.x = step * (i % numSteps);
load_rect_.y = line_index_[load_counter_];
mono_loading_screen_sprite_->setClip(load_rect_);
mono_loading_screen_sprite_->setPosition(load_rect_);
mono_loading_screen_sprite_->render();
}
}
// Segunda parte de la carga, la parte de los bloques en color
else
{
for (int i = 0; i <= load_counter_; i++)
{
load_rect_.x = (i * 8) % 256;
load_rect_.y = (i / 32) * 8;
color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_);
color_loading_screen_sprite_->render();
}
}
// Vuelca el contenido del renderizador en pantalla
screen_->render();
}