276 lines
8.0 KiB
C++
276 lines
8.0 KiB
C++
#include "loading_screen.h"
|
|
#include <SDL2/SDL_error.h> // for SDL_GetError
|
|
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
|
|
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
|
|
#include <SDL2/SDL_timer.h> // for SDL_GetTicks
|
|
#include <stdlib.h> // for rand
|
|
#include <iostream> // for char_traits, basic_ostream, operator<<
|
|
#include "defines.h" // for GAME_SPEED
|
|
#include "global_events.h" // for check
|
|
#include "global_inputs.h" // for check
|
|
#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()
|
|
{
|
|
// Reserva memoria para los punteros
|
|
if (options.video.palette == Palette::ZXSPECTRUM)
|
|
{
|
|
mono_loading_screen_texture_ = Resource::get()->getTexture("loading_screen_bn.png");
|
|
color_loading_screen_texture_ = Resource::get()->getTexture("loading_screen_color.png");
|
|
}
|
|
else if (options.video.palette == Palette::ZXARNE)
|
|
{
|
|
mono_loading_screen_texture_ = Resource::get()->getTexture("loading_screen_bn_zxarne.png");
|
|
color_loading_screen_texture_ = Resource::get()->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());
|
|
|
|
texture_ = SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height);
|
|
if (texture_ == nullptr)
|
|
{
|
|
if (options.console)
|
|
{
|
|
std::cout << "LoadingScreen::texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
|
}
|
|
}
|
|
clearTexture();
|
|
|
|
// 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 < 128)
|
|
{ // Segundo bloque de 2K
|
|
line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8);
|
|
}
|
|
else
|
|
{ // Tercer bloque de 2K
|
|
line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8);
|
|
}
|
|
}
|
|
|
|
// Cambia el color del borde
|
|
Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
|
|
}
|
|
|
|
// Destructor
|
|
LoadingScreen::~LoadingScreen()
|
|
{
|
|
JA_StopMusic();
|
|
SDL_DestroyTexture(texture_);
|
|
}
|
|
|
|
// 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(Resource::get()->getMusic("loading_sound3.ogg"));
|
|
}
|
|
}
|
|
// 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(Resource::get()->getMusic("loading_sound2.ogg"));
|
|
}
|
|
}
|
|
|
|
// 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(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
|
|
SDL_RenderClear(Screen::get()->getRenderer());
|
|
|
|
// Añade lineas amarillas
|
|
color = stringToColor(options.video.palette, "yellow");
|
|
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
|
|
const int WIDTH = options.game.width + (options.video.border.width * 2);
|
|
const int HEIGHT = options.game.height + (options.video.border.height * 2);
|
|
bool drawEnabled = rand() % 2 == 0 ? true : false;
|
|
|
|
int row = 0;
|
|
while (row < HEIGHT)
|
|
{
|
|
const int ROW_HEIGHT = (rand() % 4) + 3;
|
|
if (drawEnabled)
|
|
{
|
|
for (int i = row; i < row + ROW_HEIGHT; ++i)
|
|
{
|
|
SDL_RenderDrawLine(Screen::get()->getRenderer(), 0, i, WIDTH, i);
|
|
}
|
|
}
|
|
row += ROW_HEIGHT;
|
|
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_ > GAME_SPEED)
|
|
{
|
|
ticks_ = SDL_GetTicks();
|
|
checkInput();
|
|
updateCounter();
|
|
updateLoad();
|
|
fillTexture();
|
|
Screen::get()->update();
|
|
}
|
|
}
|
|
|
|
// Dibuja en pantalla
|
|
void LoadingScreen::render()
|
|
{
|
|
if (options.video.border.enabled)
|
|
{
|
|
// Prepara para empezar a dibujar en la textura del borde
|
|
Screen::get()->startDrawOnBorder();
|
|
|
|
// Dibuja el efecto de carga en el borde
|
|
renderBorder();
|
|
}
|
|
|
|
// Prepara para empezar a dibujar en la textura de juego
|
|
Screen::get()->start();
|
|
|
|
// Copila la textura a la pantalla
|
|
SDL_RenderCopy(Screen::get()->getRenderer(), texture_, nullptr, nullptr);
|
|
|
|
// Vuelca el contenido del renderizador en pantalla
|
|
Screen::get()->render();
|
|
}
|
|
|
|
// Bucle para el logo del juego
|
|
void LoadingScreen::run()
|
|
{
|
|
// Inicia el sonido de carga
|
|
JA_SetVolume(64);
|
|
JA_PlayMusic(Resource::get()->getMusic("loading_sound1.ogg"));
|
|
|
|
// Limpia la pantalla
|
|
Screen::get()->start();
|
|
Screen::get()->clean();
|
|
Screen::get()->render();
|
|
|
|
while (options.section.section == Section::LOADING_SCREEN)
|
|
{
|
|
update();
|
|
checkEvents();
|
|
render();
|
|
}
|
|
|
|
JA_SetVolume(128);
|
|
}
|
|
|
|
// Dibuja sobre la textura
|
|
void LoadingScreen::fillTexture()
|
|
{
|
|
// Empieza a dibujar en la textura
|
|
auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), texture_);
|
|
|
|
// Dibuja la pantalla de carga
|
|
renderLoad();
|
|
|
|
// Deja el renderizador como estaba
|
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
|
}
|
|
|
|
// Limpia la textura
|
|
void LoadingScreen::clearTexture()
|
|
{
|
|
// Empieza a dibujar en la textura
|
|
auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), texture_);
|
|
|
|
// Limpia
|
|
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0x00, 0x00, 0x00, 0xFF);
|
|
SDL_RenderClear(Screen::get()->getRenderer());
|
|
|
|
// Deja el renderizador como estaba
|
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
|
} |