8 Commits

22 changed files with 831 additions and 227 deletions

BIN
data/test.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

View File

@@ -277,6 +277,16 @@ void Director::initInput()
void Director::initJailAudio()
{
JA_Init(48000, AUDIO_S16, 2);
if (options.audio.enabled)
{
JA_SetMusicVolume(options.audio.music.volume);
JA_SetSoundVolume(options.audio.sound.volume);
}
else
{
JA_SetMusicVolume(0);
JA_SetSoundVolume(0);
}
}
// Arranca SDL y crea la ventana
@@ -395,6 +405,9 @@ bool Director::setFileList()
// Datos
Asset::get()->add(prefix + "/data/input/gamecontrollerdb.txt", AssetType::DATA);
// Test
Asset::get()->add(prefix + "/data/test.gif", AssetType::DATA);
// Ficheros de sistema
Asset::get()->add(system_folder_ + "/config.txt", AssetType::DATA, false, true);

View File

@@ -24,6 +24,7 @@
#include "notifier.h"
#include "global_inputs.h"
#include "global_events.h"
//#include "surface.h"
// Constructor
Game::Game()
@@ -36,6 +37,7 @@ Game::Game()
cheevos_(Cheevos::get())
{
// Inicia algunas variables
//test_surface_ = std::make_shared<Surface>(Screen::get()->getSurface(), "test.gif");
board_ = std::make_shared<ScoreboardData>();
board_->ini_clock = SDL_GetTicks();
#ifdef DEBUG
@@ -260,6 +262,7 @@ void Game::render()
{
// Prepara para dibujar el frame
screen_->start();
//test_surface_->render(0, 0, 10, 10, 64, 64);
// Dibuja los elementos del juego en orden
room_->renderMap();

View File

@@ -8,6 +8,7 @@
#include "player.h" // Para playerSpawn_t
#include "scoreboard.h" // Para board_t
#include "room.h"
//#include "surface.h"
class Asset;
class Cheevos;
class Debug;
@@ -42,6 +43,7 @@ private:
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas
SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación
//std::shared_ptr<Surface> test_surface_;
// Variables
JA_Music_t *music_; // Musica que suena durante el juego

View File

@@ -1,94 +1,9 @@
#include "gif.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#define EXTENSION_INTRODUCER 0x21
#define IMAGE_DESCRIPTOR 0x2C
#define TRAILER 0x3B
#define GRAPHIC_CONTROL 0xF9
#define APPLICATION_EXTENSION 0xFF
#define COMMENT_EXTENSION 0xFE
#define PLAINTEXT_EXTENSION 0x01
#define READ(dst, size) memcpy(dst, buffer, size); buffer += size
typedef struct
{
unsigned short width;
unsigned short height;
unsigned char fields;
unsigned char background_color_index;
unsigned char pixel_aspect_ratio;
}
screen_descriptor_t;
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
}
rgb;
typedef struct
{
unsigned short image_left_position;
unsigned short image_top_position;
unsigned short image_width;
unsigned short image_height;
unsigned char fields;
}
image_descriptor_t;
typedef struct
{
unsigned char byte;
int prev;
int len;
}
dictionary_entry_t;
typedef struct
{
unsigned char extension_code;
unsigned char block_size;
}
extension_t;
typedef struct
{
unsigned char fields;
unsigned short delay_time;
unsigned char transparent_color_index;
}
graphic_control_extension_t;
typedef struct
{
unsigned char application_id[ 8 ];
unsigned char version[ 3 ];
}
application_extension_t;
typedef struct
{
unsigned short left;
unsigned short top;
unsigned short width;
unsigned short height;
unsigned char cell_width;
unsigned char cell_height;
unsigned char foreground_color;
unsigned char background_color;
}
plaintext_extension_t;
//static unsigned short width = 0;
//static unsigned short height = 0;
//static unsigned char* uncompressed_data = NULL;
void uncompress( int code_length,
const unsigned char *input,
int input_length,

65
source/gif.h Normal file
View File

@@ -0,0 +1,65 @@
#pragma once
#include <stdint.h>
#define EXTENSION_INTRODUCER 0x21
#define IMAGE_DESCRIPTOR 0x2C
#define TRAILER 0x3B
#define GRAPHIC_CONTROL 0xF9
#define APPLICATION_EXTENSION 0xFF
#define COMMENT_EXTENSION 0xFE
#define PLAINTEXT_EXTENSION 0x01
#define READ(dst, size) memcpy(dst, buffer, size); buffer += size
typedef struct {
unsigned short width;
unsigned short height;
unsigned char fields;
unsigned char background_color_index;
unsigned char pixel_aspect_ratio;
} screen_descriptor_t;
typedef struct {
unsigned char r, g, b;
} rgb;
typedef struct {
unsigned short image_left_position;
unsigned short image_top_position;
unsigned short image_width;
unsigned short image_height;
unsigned char fields;
} image_descriptor_t;
typedef struct {
unsigned char byte;
int prev;
int len;
} dictionary_entry_t;
typedef struct {
unsigned char extension_code;
unsigned char block_size;
} extension_t;
typedef struct {
unsigned char fields;
unsigned short delay_time;
unsigned char transparent_color_index;
} graphic_control_extension_t;
typedef struct {
unsigned char application_id[8];
unsigned char version[3];
} application_extension_t;
typedef struct {
unsigned short left, top, width, height;
unsigned char cell_width, cell_height;
unsigned char foreground_color, background_color;
} plaintext_extension_t;
void uncompress(int code_length, const unsigned char *input, int input_length, unsigned char *out);
uint32_t* LoadPalette(unsigned char *buffer);
unsigned char* LoadGif(unsigned char *buffer, unsigned short* w, unsigned short* h);

View File

@@ -14,6 +14,7 @@
#include "sprite.h" // for Sprite
#include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette
#include <iostream>
// Constructor
LoadingScreen::LoadingScreen()
@@ -40,6 +41,16 @@ LoadingScreen::LoadingScreen()
loading_sound2_ = resource_->getMusic("loading_sound2.ogg");
loading_sound3_ = resource_->getMusic("loading_sound3.ogg");
texture_ = SDL_CreateTexture(renderer_, 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;
@@ -71,6 +82,7 @@ LoadingScreen::LoadingScreen()
LoadingScreen::~LoadingScreen()
{
JA_StopMusic();
SDL_DestroyTexture(texture_);
}
// Comprueba el manejador de eventos
@@ -165,8 +177,8 @@ void LoadingScreen::renderBorder()
// 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);
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;
int rowSize = 1;
@@ -193,6 +205,7 @@ void LoadingScreen::update()
checkInput();
updateCounter();
updateLoad();
fillTexture();
screen_->update();
}
}
@@ -212,8 +225,8 @@ void LoadingScreen::render()
// Prepara para empezar a dibujar en la textura de juego
screen_->start();
// Dibuja la pantalla de carga
renderLoad();
// Copila la textura a la pantalla
SDL_RenderCopy(renderer_, texture_, nullptr, nullptr);
// Vuelca el contenido del renderizador en pantalla
screen_->render();
@@ -278,4 +291,33 @@ void LoadingScreen::recreateLoadingScreen()
// Vuelca el contenido del renderizador en pantalla
screen_->render();
}
// Dibuja sobre la textura
void LoadingScreen::fillTexture()
{
// Empieza a dibujar en la textura
auto temp = SDL_GetRenderTarget(renderer_);
SDL_SetRenderTarget(renderer_, texture_);
// Dibuja la pantalla de carga
renderLoad();
// Deja el renderizador como estaba
SDL_SetRenderTarget(renderer_, temp);
}
// Limpia la textura
void LoadingScreen::clearTexture()
{
// Empieza a dibujar en la textura
auto temp = SDL_GetRenderTarget(renderer_);
SDL_SetRenderTarget(renderer_, texture_);
// Limpia
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(renderer_);
// Deja el renderizador como estaba
SDL_SetRenderTarget(renderer_, temp);
}

View File

@@ -1,16 +1,16 @@
#pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr
class Asset; // lines 8-8
class Input; // lines 9-9
class Resource; // lines 10-10
class Screen; // lines 11-11
class Sprite; // lines 12-12
class Texture; // lines 13-13
struct JA_Music_t; // lines 14-14
#include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr
class Asset; // lines 8-8
class Input; // lines 9-9
class Resource; // lines 10-10
class Screen; // lines 11-11
class Sprite; // lines 12-12
class Texture; // lines 13-13
struct JA_Music_t; // lines 14-14
class LoadingScreen
{
@@ -37,6 +37,7 @@ private:
JA_Music_t *loading_sound3_; // Sonidos para imitar la carga tipo spectrum
int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga
SDL_Rect load_rect_ = {0, 0, 51, 1}; // Rectangulo para dibujar la pantalla de carga
SDL_Texture *texture_; // Textura para dibujar la pantalla de carga
// Actualiza las variables
void update();
@@ -65,6 +66,12 @@ private:
// Reconstruye la pantalla de carga
void recreateLoadingScreen();
// Dibuja sobre la textura
void fillTexture();
// Limpia la textura
void clearTexture();
public:
// Constructor
LoadingScreen();

View File

@@ -84,8 +84,9 @@ void Notifier::update()
// Comprueba los estados
if (notifications_[i].state == NotificationStatus::RISING)
{
const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist);
const int alpha = 255 * step;
//const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist);
//const int alpha = 255 * step;
constexpr int ALPHA = 255;
if (options.notifications.getVerticalPosition() == NotificationPosition::TOP)
{
@@ -95,7 +96,7 @@ void Notifier::update()
{
notifications_[i].rect.y--;
}
notifications_[i].texture->setAlpha(alpha);
notifications_[i].texture->setAlpha(ALPHA);
if (notifications_[i].rect.y == notifications_[i].y)
{
@@ -116,8 +117,10 @@ void Notifier::update()
else if (notifications_[i].state == NotificationStatus::VANISHING)
{
const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist);
const int alpha = 255 * (1 - step);
//const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist);
//const int ALPHA = 255 * (1 - step);
constexpr int ALPHA = 255;
if (options.notifications.getVerticalPosition() == NotificationPosition::TOP)
{
@@ -127,7 +130,7 @@ void Notifier::update()
{
notifications_[i].rect.y++;
}
notifications_[i].texture->setAlpha(alpha);
notifications_[i].texture->setAlpha(ALPHA);
if (notifications_[i].rect.y == notifications_[i].y - notifications_[i].travel_dist)
{
@@ -185,7 +188,6 @@ void Notifier::show(std::vector<std::string> texts, NotificationText text_is, in
const auto padding_in_v = text_->getCharacterSize() / 2;
const int icon_space = icon >= 0 ? ICON_SIZE_ + padding_in_h : 0;
text_is = icon_space > 0 ? NotificationText::LEFT : text_is;
// const int width = text_->lenght(longest) + (padding_in_h * 2) + icon_space;
const int width = options.game.width - (PADDING_OUT_ * 2);
const int height = (text_->getCharacterSize() * texts.size()) + (padding_in_v * 2);
const auto shape = NotificationShape::SQUARED;

View File

@@ -4,6 +4,7 @@
#include <string> // for string, basic_string
#include "screen.h" // for ScreenFilter
#include "utils.h" // for Color, Palette
#include <algorithm>
// Secciones del programa
enum class Section
@@ -68,6 +69,12 @@ constexpr bool DEFAULT_VIDEO_KEEP_ASPECT = true;
constexpr bool DEFAULT_BORDER_ENABLED = true; // Borde activado por defecto
constexpr int DEFAULT_BORDER_WIDTH = 32; // Ancho del borde por defecto
constexpr int DEFAULT_BORDER_HEIGHT = 24; // Alto del borde por defecto
constexpr int DEFAULT_SOUND_VOLUME = 100; // Volumen por defecto de los efectos de sonido
constexpr bool DEFAULT_SOUND_ENABLED = true; // Sonido habilitado por defecto
constexpr int DEFAULT_MUSIC_VOLUME = 80; // Volumen por defecto de la musica
constexpr bool DEFAULT_MUSIC_ENABLED = true; // Musica habilitada por defecto
constexpr int DEFAULT_AUDIO_VOLUME = 100; // Volumen por defecto
constexpr bool DEFAULT_AUDIO_ENABLED = true; // Audio por defecto
constexpr Palette DEFAULT_PALETTE = Palette::ZXSPECTRUM; // Paleta por defecto
constexpr Section DEFAULT_SECTION = Section::LOGO; // Sección por defecto
constexpr Subsection DEFAULT_SUBSECTION = Subsection::LOGO_TO_INTRO; // Subsección por defecto
@@ -283,6 +290,89 @@ struct OptionsVideo
palette(p) {}
};
// Estructura para las opciones de musica
struct OptionsMusic
{
bool enabled; // Indica si la música suena o no
int volume; // Volumen al que suena la música (0 a 128 internamente)
// Constructor por defecto
OptionsMusic()
: enabled(DEFAULT_MUSIC_ENABLED),
volume(convertVolume(DEFAULT_MUSIC_VOLUME)) {} // Usa el método estático para la conversión
// Constructor con parámetros
OptionsMusic(bool e, int v)
: enabled(e),
volume(convertVolume(v)) {} // Convierte el volumen usando el método estático
// Método para establecer el volumen
void setVolume(int v)
{
v = std::clamp(v, 0, 100); // Ajusta v al rango [0, 100]
volume = convertVolume(v); // Convierte al rango interno
}
// Método estático para convertir de 0-100 a 0-128
static int convertVolume(int v)
{
return (v * 128) / 100;
}
};
// Estructura para las opciones de sonido
struct OptionsSound
{
bool enabled; // Indica si los sonidos suenan o no
int volume; // Volumen al que suenan los sonidos (0 a 128 internamente)
// Constructor por defecto
OptionsSound()
: enabled(DEFAULT_SOUND_ENABLED),
volume(convertVolume(DEFAULT_SOUND_VOLUME)) {} // Usa el método estático para la conversión
// Constructor con parámetros
OptionsSound(bool e, int v)
: enabled(e),
volume(convertVolume(v)) {} // También lo integra aquí
// Método para establecer el volumen
void setVolume(int v)
{
v = std::clamp(v, 0, 100); // Ajusta v al rango [0, 100]
volume = convertVolume(v); // Convierte al rango interno
}
// Método estático para convertir de 0-100 a 0-128
static int convertVolume(int v)
{
return (v * 128) / 100;
}
};
// Estructura para las opciones de audio
struct OptionsAudio
{
OptionsMusic music; // Opciones para la música
OptionsSound sound; // Opciones para los efectos de sonido
bool enabled; // Indica si el audio está activo o no
int volume; // Volumen al que suenan el audio
// Constructor por defecto
OptionsAudio()
: music(OptionsMusic()),
sound(OptionsSound()),
enabled(DEFAULT_AUDIO_ENABLED),
volume(DEFAULT_AUDIO_VOLUME) {}
// Constructor
OptionsAudio(OptionsMusic m, OptionsSound s, bool e, int v)
: music(m),
sound(s),
enabled(e),
volume(v) {}
};
// Estructura para las opciones de juego
struct OptionsGame
{
@@ -311,6 +401,7 @@ struct Options
OptionsStats stats; // Datos con las estadisticas de juego
OptionsNotification notifications; // Opciones relativas a las notificaciones;
OptionsWindow window; // Opciones relativas a la ventana
OptionsAudio audio; // Opciones relativas al audio
ControlScheme keys; // Teclas usadas para jugar
SectionState section; // Sección actual del programa
@@ -324,11 +415,12 @@ struct Options
stats(OptionsStats()),
notifications(OptionsNotification()),
window(OptionsWindow()),
audio(OptionsAudio()),
keys(DEFAULT_CONTROL_SCHEME),
section(SectionState()) {}
// Constructor
Options(std::string cv, bool c, Cheat ch, OptionsGame g, OptionsVideo v, OptionsStats s, OptionsNotification n, OptionsWindow sw, ControlScheme k, SectionState sec)
Options(std::string cv, bool c, Cheat ch, OptionsGame g, OptionsVideo v, OptionsStats s, OptionsNotification n, OptionsWindow sw, OptionsAudio a, ControlScheme k, SectionState sec)
: version(cv),
console(c),
cheats(ch),
@@ -337,6 +429,7 @@ struct Options
stats(s),
notifications(n),
window(sw),
audio(a),
keys(k),
section(sec) {}
};

View File

@@ -4,7 +4,7 @@
#include <fcntl.h> // Para SEEK_END, SEEK_SET
#include <stdio.h> // Para NULL, fseek, fclose, fopen, fread, ftell
#include <stdlib.h> // Para malloc, free
#include "gif.c" // Para LoadGif, LoadPalette
#include "gif.h" // Para LoadGif, LoadPalette
struct jSurface_s
{

View File

@@ -9,6 +9,7 @@
#include "screen.h" // for Screen
#include "text.h" // for Text
#include "texture.h" // for Texture
#include <iostream>
// Constructor
Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
@@ -17,6 +18,9 @@ Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
asset_(Asset::get()),
data_(data)
{
const int TEXTURE_WIDTH_ = options.game.width;
constexpr int TEXTURE_HEIGHT_ = 6 * BLOCK;
// Reserva memoria para los objetos
item_texture_ = resource_->getTexture("items.png");
auto player_texture = resource_->getTexture(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png");
@@ -25,6 +29,16 @@ Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
player_sprite_->setCurrentAnimation("walk_menu");
text_ = resource_->getText("smb2");
texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, TEXTURE_WIDTH_, TEXTURE_HEIGHT_);
if (texture_ == nullptr)
{
if (options.console)
{
std::cout << "Scorebard::texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
texture_dest_ = {0, options.game.height - TEXTURE_HEIGHT_, TEXTURE_WIDTH_, TEXTURE_HEIGHT_};
// Inicializa las variables
counter_ = 0;
change_color_speed_ = 4;
@@ -41,51 +55,16 @@ Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
}
}
// Destructor
Scoreboard::~Scoreboard()
{
SDL_DestroyTexture(texture_);
}
// Pinta el objeto en pantalla
void Scoreboard::render()
{
// Anclas
const int line1 = 19 * BLOCK;
const int line2 = line1 + (2 * BLOCK);
// Dibuja el fondo del marcador
const SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255);
SDL_RenderFillRect(renderer_, &rect);
// Dibuja las vidas
const int desp = (counter_ / 40) % 8;
const int frame = desp % 4;
player_sprite_->setCurrentAnimationFrame(frame);
player_sprite_->setPosY(line2);
for (int i = 0; i < data_->lives; ++i)
{
player_sprite_->setPosX(8 + (16 * i) + desp);
const int index = i % color_.size();
player_sprite_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b);
player_sprite_->render();
}
// Muestra si suena la música
if (data_->music)
{
const Color c = data_->color;
SDL_Rect clip = {0, 8, 8, 8};
item_texture_->setColor(c.r, c.g, c.b);
item_texture_->render(20 * BLOCK, line2, &clip);
}
// Escribe los textos
const std::string timeTxt = std::to_string((clock_.minutes % 100) / 10) + std::to_string(clock_.minutes % 10) + clock_.separator + std::to_string((clock_.seconds % 60) / 10) + std::to_string(clock_.seconds % 10);
const std::string itemsTxt = std::to_string(data_->items / 100) + std::to_string((data_->items % 100) / 10) + std::to_string(data_->items % 10);
this->text_->writeColored(BLOCK, line1, "Items collected ", data_->color);
this->text_->writeColored(17 * BLOCK, line1, itemsTxt, items_color_);
this->text_->writeColored(20 * BLOCK, line1, " Time ", data_->color);
this->text_->writeColored(26 * BLOCK, line1, timeTxt, stringToColor(options.video.palette, "white"));
const std::string roomsTxt = std::to_string(data_->rooms / 100) + std::to_string((data_->rooms % 100) / 10) + std::to_string(data_->rooms % 10);
this->text_->writeColored(22 * BLOCK, line2, "Rooms", stringToColor(options.video.palette, "white"));
this->text_->writeColored(28 * BLOCK, line2, roomsTxt, stringToColor(options.video.palette, "white"));
SDL_RenderCopy(renderer_, texture_, nullptr, &texture_dest_);
}
// Actualiza las variables del objeto
@@ -97,6 +76,9 @@ void Scoreboard::update()
// Actualiza el color de la cantidad de items recogidos
updateItemsColor();
// Dibuja la textura
fillTexture();
if (!is_paused_)
{
// Si está en pausa no se actualiza el reloj
@@ -175,4 +157,57 @@ void Scoreboard::updateItemsColor()
int Scoreboard::getMinutes()
{
return getTime().minutes;
}
// Dibuja los elementos del marcador en la textura
void Scoreboard::fillTexture()
{
// Empieza a dibujar en la textura
auto temp = SDL_GetRenderTarget(renderer_);
SDL_SetRenderTarget(renderer_, texture_);
// Limpia la textura
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255);
SDL_RenderFillRect(renderer_, nullptr);
// Anclas
constexpr int LINE1 = BLOCK;
constexpr int LINE2 = 3 * BLOCK;
// Dibuja las vidas
const int desp = (counter_ / 40) % 8;
const int frame = desp % 4;
player_sprite_->setCurrentAnimationFrame(frame);
player_sprite_->setPosY(LINE2);
for (int i = 0; i < data_->lives; ++i)
{
player_sprite_->setPosX(8 + (16 * i) + desp);
const int index = i % color_.size();
player_sprite_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b);
player_sprite_->render();
}
// Muestra si suena la música
if (data_->music)
{
const Color c = data_->color;
SDL_Rect clip = {0, 8, 8, 8};
item_texture_->setColor(c.r, c.g, c.b);
item_texture_->render(20 * BLOCK, LINE2, &clip);
}
// Escribe los textos
const std::string timeTxt = std::to_string((clock_.minutes % 100) / 10) + std::to_string(clock_.minutes % 10) + clock_.separator + std::to_string((clock_.seconds % 60) / 10) + std::to_string(clock_.seconds % 10);
const std::string itemsTxt = std::to_string(data_->items / 100) + std::to_string((data_->items % 100) / 10) + std::to_string(data_->items % 10);
text_->writeColored(BLOCK, LINE1, "Items collected ", data_->color);
text_->writeColored(17 * BLOCK, LINE1, itemsTxt, items_color_);
text_->writeColored(20 * BLOCK, LINE1, " Time ", data_->color);
text_->writeColored(26 * BLOCK, LINE1, timeTxt, stringToColor(options.video.palette, "white"));
const std::string roomsTxt = std::to_string(data_->rooms / 100) + std::to_string((data_->rooms % 100) / 10) + std::to_string(data_->rooms % 10);
text_->writeColored(22 * BLOCK, LINE2, "Rooms", stringToColor(options.video.palette, "white"));
text_->writeColored(28 * BLOCK, LINE2, roomsTxt, stringToColor(options.video.palette, "white"));
// Deja el renderizador como estaba
SDL_SetRenderTarget(renderer_, temp);
}

View File

@@ -46,6 +46,7 @@ private:
std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite para mostrar las vidas en el marcador
std::shared_ptr<Texture> item_texture_; // Textura con los graficos para las vidas
std::shared_ptr<ScoreboardData> data_; // Contiene las variables a mostrar en el marcador
SDL_Texture *texture_; // Textura donde dibujar el marcador;
// Variables
std::vector<Color> color_; // Vector con los colores del objeto
@@ -56,6 +57,7 @@ private:
Uint32 paused_time_elapsed_; // Tiempo acumulado en pausa
ClockData clock_; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida
Color items_color_; // Color de la cantidad de items recogidos
SDL_Rect texture_dest_; // Rectangulo donde dibujar la textura del marcador
// Obtiene el tiempo transcurrido de partida
ClockData getTime();
@@ -63,12 +65,15 @@ private:
// Actualiza el color de la cantidad de items recogidos
void updateItemsColor();
// Dibuja los elementos del marcador en la textura
void fillTexture();
public:
// Constructor
Scoreboard(std::shared_ptr<ScoreboardData> data);
// Destructor
~Scoreboard() = default;
~Scoreboard();
// Pinta el objeto en pantalla
void render();

View File

@@ -13,6 +13,7 @@
#include "notifier.h" // Para Notify
#include "options.h"
#include "mouse.h"
//#include "surface.h"
// [SINGLETON]
Screen *Screen::screen_ = nullptr;
@@ -50,27 +51,42 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
// Establece el modo de escalado
SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE);
// Crea la textura donde se dibujan los graficos del juego
game_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height);
if (game_canvas_ == nullptr)
// Crea la textura donde se vuelcan las surfaces
surface_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width, options.game.height);
if (surface_texture_ == nullptr)
{
if (options.console)
{
std::cout << "gameCanvas could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
std::cout << "surface_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
//SDL_SetTextureBlendMode(surface_texture_, SDL_BLENDMODE_BLEND);
// Crea la textura donde se dibujan los graficos del juego
game_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height);
if (game_texture_ == nullptr)
{
if (options.console)
{
std::cout << "game_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
// Crea la textura donde se dibuja el borde que rodea el area de juego
border_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2);
if (border_canvas_ == nullptr)
border_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2);
if (border_texture_ == nullptr)
{
if (options.console)
{
std::cout << "borderCanvas could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
std::cout << "border_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
setBorderColor(border_color_);
// Crea la surface donde se pinta el juego
//surface_ = std::make_shared<Surface>(nullptr, options.game.width, options.game.height);
//surface_->loadPalette(Asset::get()->get("test.gif"));
// Establece el modo de video
setVideoMode(options.video.mode);
@@ -82,8 +98,9 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
// Destructor
Screen::~Screen()
{
SDL_DestroyTexture(game_canvas_);
SDL_DestroyTexture(border_canvas_);
SDL_DestroyTexture(surface_texture_);
SDL_DestroyTexture(game_texture_);
SDL_DestroyTexture(border_texture_);
}
// Limpia la pantalla
@@ -96,13 +113,14 @@ void Screen::clean(Color color)
// Prepara para empezar a dibujar en la textura de juego
void Screen::start()
{
SDL_SetRenderTarget(renderer_, game_canvas_);
//surface_->clear(surface_->getSurface(), surface_->getTransparentColor());
SDL_SetRenderTarget(renderer_, game_texture_);
}
// Prepara para empezar a dibujar en la textura del borde
void Screen::startDrawOnBorder()
{
SDL_SetRenderTarget(renderer_, border_canvas_);
SDL_SetRenderTarget(renderer_, border_texture_);
}
// Vuelca el contenido del renderizador en pantalla
@@ -111,6 +129,10 @@ void Screen::render()
// Renderiza sobre gameCanvas los overlays
renderNotifications();
//fillTextureWithColor(renderer_, surface_texture_, 0xFF, 0x00, 0xFF, 0xFF);
//surface_->copyToTexture(renderer_, surface_texture_);
//SDL_RenderCopy(renderer_, surface_texture_, nullptr, nullptr);
// Si está el borde activo, vuelca gameCanvas sobre borderCanvas
if (options.video.border.enabled)
{
@@ -174,11 +196,11 @@ void Screen::setVideoMode(int videoMode)
if (options.video.border.enabled)
{
shader::init(window_, border_canvas_, source.c_str());
shader::init(window_, border_texture_, source.c_str());
}
else
{
shader::init(window_, game_canvas_, source.c_str());
shader::init(window_, game_texture_, source.c_str());
}
}
}
@@ -233,7 +255,7 @@ void Screen::setBorderColor(Color color)
{
border_color_ = color;
auto temp = SDL_GetRenderTarget(renderer_);
SDL_SetRenderTarget(renderer_, border_canvas_);
SDL_SetRenderTarget(renderer_, border_texture_);
SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
SDL_RenderClear(renderer_);
SDL_SetRenderTarget(renderer_, temp);
@@ -279,10 +301,8 @@ void Screen::renderNotifications()
void Screen::gameCanvasToBorderCanvas()
{
auto temp = SDL_GetRenderTarget(renderer_);
SDL_SetRenderTarget(renderer_, border_canvas_);
SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
SDL_RenderClear(renderer_);
SDL_RenderCopy(renderer_, game_canvas_, nullptr, &game_canvas_rect_);
SDL_SetRenderTarget(renderer_, border_texture_);
SDL_RenderCopy(renderer_, game_texture_, nullptr, &game_texture_rect_);
SDL_SetRenderTarget(renderer_, temp);
}
@@ -302,11 +322,11 @@ void Screen::renderPresent()
{
if (options.video.border.enabled)
{
SDL_RenderCopy(renderer_, border_canvas_, nullptr, nullptr);
SDL_RenderCopy(renderer_, border_texture_, nullptr, nullptr);
}
else
{
SDL_RenderCopy(renderer_, game_canvas_, nullptr, &game_canvas_rect_);
SDL_RenderCopy(renderer_, game_texture_, nullptr, &game_texture_rect_);
}
SDL_RenderPresent(renderer_);
}
@@ -366,7 +386,7 @@ void Screen::adjustWindowSize()
// Ajusta game_canvas_rect_
void Screen::adjustGameCanvasRect()
{
game_canvas_rect_ = {
game_texture_rect_ = {
options.video.border.enabled ? options.video.border.width : 0,
options.video.border.enabled ? options.video.border.height : 0,
options.game.width,
@@ -390,7 +410,7 @@ int Screen::getMaxZoom()
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla
const int max_zoom = std::min(DM.w / window_width_, (DM.h - WINDOWS_DECORATIONS_) / window_height_);
// Normaliza los valores de zoom
options.window.zoom = std::min(options.window.zoom, max_zoom);

View File

@@ -6,7 +6,9 @@
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_video.h> // for SDL_Window
#include <vector> // for vector
#include <memory> // for shared_ptr
#include "utils.h" // for Color
//#include "surface.h"
// Tipos de filtro
enum class ScreenFilter : Uint32
@@ -25,16 +27,18 @@ private:
static Screen *screen_;
// Objetos y punteros
SDL_Window *window_; // Ventana de la aplicación
SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *game_canvas_; // Textura donde se dibuja el juego
SDL_Texture *border_canvas_; // Textura donde se dibuja el borde del juego
SDL_Window *window_; // Ventana de la aplicación
SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *surface_texture_; // Textura donde se dibuja el juego
SDL_Texture *game_texture_; // Textura donde se dibuja el juego
SDL_Texture *border_texture_; // Textura donde se dibuja el borde del juego
//std::shared_ptr<Surface> surface_; // Objeto para trabajar con surfaces
// Variables
int window_width_; // Ancho de la pantalla o ventana
int window_height_; // Alto de la pantalla o ventana
SDL_Rect game_canvas_rect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla
int window_width_; // Ancho de la pantalla o ventana
int window_height_; // Alto de la pantalla o ventana
SDL_Rect game_texture_rect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla
// Dibuja las notificaciones
void renderNotifications();
@@ -131,4 +135,7 @@ public:
// Getters
SDL_Renderer *getRenderer() { return renderer_; }
//std::shared_ptr<SurfaceData> getSurface() { return surface_->getSurface(); }
SDL_Texture *getGameTexture() { return game_texture_; };
SDL_Texture *getBorderTexture() { return border_texture_; }
};

243
source/surface.cpp Normal file
View File

@@ -0,0 +1,243 @@
#include "surface.h"
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_ARGB8888
#include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <fstream> // Para std::ifstream
#include <iostream> // Para std::cerr
#include <vector> // Para std::vector
#include <stdexcept> // For exceptions
#include "gif.h" // Para LoadGif, LoadPalette
#include <memory> // Para std::shared_ptr
#include <algorithm> // Para std::copy
#include "asset.h"
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h)
: surface_dest_(surface_dest),
surface_(std::make_shared<SurfaceData>(w, h)),
transparent_color_(0) {}
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, std::string file_path)
: surface_dest_(surface_dest),
surface_(std::make_shared<SurfaceData>(loadSurface(Asset::get()->get(file_path)))),
transparent_color_(0) {
std::cout << "surface loaded: "<< surface_->width << "x" << surface_->height << std::endl;
}
Surface::~Surface() {}
// Carga una superficie desde un archivo
SurfaceData Surface::loadSurface(const std::string &file_path)
{
std::ifstream file(file_path, std::ios::binary | std::ios::ate);
if (!file.is_open())
{
std::cerr << "Error opening file: " << file_path << std::endl;
throw std::runtime_error("Error opening file");
}
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<Uint8> buffer(size);
if (!file.read((char *)buffer.data(), size))
{
std::cerr << "Error reading file: " << file_path << std::endl;
throw std::runtime_error("Error reading file");
}
Uint16 w, h;
Uint8 *pixels = LoadGif(buffer.data(), &w, &h);
if (pixels == nullptr)
{
std::cerr << "Error loading GIF from file: " << file_path << std::endl;
throw std::runtime_error("Error loading GIF");
}
// Crear y devolver directamente el objeto SurfaceData
return SurfaceData(w, h, pixels);
}
// Carga una paleta desde un archivo
void Surface::loadPalette(const std::string &file_path)
{
// Abrir el archivo en modo binario
std::ifstream file(file_path, std::ios::binary | std::ios::ate);
if (!file.is_open())
{
throw std::runtime_error("Error opening file: " + file_path);
}
// Leer el contenido del archivo en un buffer
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<Uint8> buffer(size);
if (!file.read(reinterpret_cast<char *>(buffer.data()), size))
{
throw std::runtime_error("Error reading file: " + file_path);
}
// Cargar la paleta usando los datos del buffer
std::unique_ptr<Uint32[]> pal(LoadPalette(buffer.data()));
if (pal == nullptr)
{
throw std::runtime_error("Error loading palette from file: " + file_path);
}
// Copiar los datos de la paleta al std::array
std::copy(pal.get(), pal.get() + palette_.size(), palette_.begin());
for (auto p : palette_)
{
std::cout << std::hex << p << " ";
}
std::cout << std::endl;
}
// Establece un color en la paleta
void Surface::setColor(int index, Uint32 color)
{
palette_.at(index) = color;
}
// Limpia la superficie de destino con un color
void Surface::clear(std::shared_ptr<SurfaceData> surface, Uint8 color)
{
const size_t total_pixels = surface->width * surface->height;
std::fill(surface->data, surface->data + total_pixels, color);
}
// Pone un pixel en la superficie de destino
void Surface::putPixel(int x, int y, Uint8 color)
{
if (color == transparent_color_)
{
return; // Color transparente, no dibujar
}
if (x < 0 || y < 0 || x >= surface_dest_->width || y >= surface_dest_->height)
{
return; // Coordenadas fuera de rango
}
const int index = x + y * surface_dest_->width;
surface_dest_->data[index] = color;
}
// Obtiene el color de un pixel de la superficie de origen
Uint8 Surface::getPixel(int x, int y)
{
return surface_->data[x + y * surface_->width];
}
// Copia una región de la superficie de origen a la de destino
void Surface::render(int dx, int dy, int sx, int sy, int w, int h)
{
if (!surface_ || !surface_dest_)
{
throw std::runtime_error("Surface source or destination is null.");
}
// Limitar la región para evitar accesos fuera de rango
w = std::min(w, surface_->width - sx);
h = std::min(h, surface_->height - sy);
w = std::min(w, surface_dest_->width - dx);
h = std::min(h, surface_dest_->height - dy);
for (int iy = 0; iy < h; ++iy)
{
for (int ix = 0; ix < w; ++ix)
{
Uint8 color = surface_->data[(sx + ix) + (sy + iy) * surface_->width];
if (color != transparent_color_) // Opcional: Ignorar píxeles transparentes
{
surface_dest_->data[(dx + ix) + (dy + iy) * surface_dest_->width] = color;
}
}
}
}
/*
// Vuelca la superficie a una textura
void Surface::flip(SDL_Renderer *renderer, SDL_Texture *texture)
{
Uint32 *pixels;
int pitch;
SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch);
for (int i = 0; i < surface_.width * surface_.height; ++i)
{
pixels[i] = palette_[surface_.data[i]];
}
SDL_UnlockTexture(texture);
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
}
*/
// Vuelca la superficie a una textura
void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
if (!renderer || !texture)
{
throw std::runtime_error("Renderer or texture is null.");
}
if (surface_->width <= 0 || surface_->height <= 0 || !surface_->data)
{
throw std::runtime_error("Invalid surface dimensions or data.");
}
Uint32 *pixels = nullptr;
int pitch = 0;
// Bloquea la textura para modificar los píxeles directamente
if (SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch) != 0)
{
throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError()));
}
// Convertir `pitch` de bytes a Uint32 (asegurando alineación correcta en hardware)
int row_stride = pitch / sizeof(Uint32);
for (int y = 0; y < surface_->height; ++y)
{
for (int x = 0; x < surface_->width; ++x)
{
// Calcular la posición correcta en la textura teniendo en cuenta el stride
int texture_index = y * row_stride + x;
int surface_index = y * surface_->width + x;
pixels[texture_index] = palette_[surface_->data[surface_index]];
}
}
SDL_UnlockTexture(texture); // Desbloquea la textura
// Renderiza la textura en la pantalla completa
if (SDL_RenderCopy(renderer, texture, nullptr, nullptr) != 0)
{
throw std::runtime_error("Failed to copy texture to renderer: " + std::string(SDL_GetError()));
}
}
// Realiza un efecto de fundido en la paleta
bool Surface::fadePalette()
{
// Verificar que el tamaño mínimo de palette_ sea adecuado
static constexpr int palette_size = 19;
if (sizeof(palette_) / sizeof(palette_[0]) < palette_size)
{
throw std::runtime_error("Palette size is insufficient for fadePalette operation.");
}
// Desplazar colores (pares e impares)
for (int i = 18; i > 1; --i)
{
palette_[i] = palette_[i - 2];
}
// Ajustar el primer color
palette_[1] = palette_[0];
// Devolver si el índice 15 coincide con el índice 0
return palette_[15] == palette_[0];
}

108
source/surface.h Normal file
View File

@@ -0,0 +1,108 @@
#pragma once
#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <SDL2/SDL_stdinc.h> // Para Uint8, Uint32
#include <array>
#include <memory>
#include <string>
struct SurfaceData
{
Uint8 *data;
Uint16 width;
Uint16 height;
// Constructor por defecto
SurfaceData() : data(nullptr), width(0), height(0) {}
// Constructor que inicializa dimensiones y asigna memoria
SurfaceData(Uint16 w, Uint16 h)
: data(new Uint8[w * h]()), width(w), height(h) {}
// Constructor para inicializar directamente con datos
SurfaceData(Uint16 w, Uint16 h, Uint8 *pixels)
: data(pixels), width(w), height(h) {}
// Destructor para liberar memoria
~SurfaceData() { delete[] data; }
// Evita copias accidentales (opcional para mayor seguridad)
SurfaceData(const SurfaceData &) = delete;
SurfaceData &operator=(const SurfaceData &) = delete;
// Permite movimiento para evitar copias costosas
SurfaceData(SurfaceData &&other) noexcept
: data(other.data), width(other.width), height(other.height)
{
other.data = nullptr;
other.width = 0;
other.height = 0;
}
SurfaceData &operator=(SurfaceData &&other) noexcept
{
if (this != &other)
{
delete[] data;
data = other.data;
width = other.width;
height = other.height;
other.data = nullptr;
other.width = 0;
other.height = 0;
}
return *this;
}
};
class Surface
{
private:
std::shared_ptr<SurfaceData> surface_dest_;
std::shared_ptr<SurfaceData> surface_;
std::array<Uint32, 256> palette_;
int transparent_color_;
// Pone un pixel en la superficie de destino
void putPixel(int x, int y, Uint8 color);
// Obtiene el color de un pixel de la superficie de origen
Uint8 getPixel(int x, int y);
public:
// Constructor
Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h);
Surface(std::shared_ptr<SurfaceData> surface_dest, std::string file_path);
// Destructor
~Surface();
// Carga una superficie desde un archivo
SurfaceData loadSurface(const std::string &file_path);
// Carga una paleta desde un archivo
void loadPalette(const std::string &file_path);
// Copia una región de la superficie de origen a la de destino
void render(int dx, int dy, int sx, int sy, int w, int h);
// Establece un color en la paleta
void setColor(int index, Uint32 color);
// Limpia la superficie de destino con un color
void clear(std::shared_ptr<SurfaceData> surface, Uint8 color);
// Vuelca la superficie a una textura
void copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture);
// Realiza un efecto de fundido en la paleta
bool fadePalette();
// Getters
std::shared_ptr<SurfaceData> getSurface() const { return surface_; }
// std::shared_ptr<SurfaceData> getSurfaceDest() const { return surface_dest_; }
// std::array<Uint32, 256> getPalette() const { return palette_; }
int getTransparentColor() const { return transparent_color_; }
};

View File

@@ -11,7 +11,7 @@
struct Color;
// Definiciones de tipos
struct Surface
/*struct Surface
{
std::shared_ptr<Uint8[]> data;
Uint16 w, h;
@@ -19,7 +19,7 @@ struct Surface
// Constructor
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels)
: data(pixels), w(width), h(height) {}
};
};*/
class Texture
{
@@ -27,7 +27,7 @@ private:
// Objetos y punteros
SDL_Renderer *renderer_; // Renderizador donde dibujar la textura
SDL_Texture *texture_ = nullptr; // La textura
std::shared_ptr<Surface> surface_ = nullptr; // Surface para usar imagenes en formato gif con paleta
//std::shared_ptr<Surface> surface_ = nullptr; // Surface para usar imagenes en formato gif con paleta
// Variables
std::string path_; // Ruta de la imagen de la textura

View File

@@ -1,24 +1,25 @@
#include "title.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_scancode.h> // for SDL_SCANCODE_1, SDL_SCANCODE_2
#include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <iostream> // for basic_ostream, operator<<, cout, endl
#include "asset.h" // for Asset
#include "cheevos.h" // for Achievement, Cheevos
#include "defines.h" // for PLAY_AREA_CENTER_X, GAMECANVAS_WIDTH
#include "global_events.h" // for check
#include "global_inputs.h" // for check
#include "input.h" // for Input, inputs_e, REPEAT_FALSE, REPEA...
#include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource
#include "screen.h" // for Screen
#include "sprite.h" // for Sprite
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
#include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_scancode.h> // for SDL_SCANCODE_1, SDL_SCANCODE_2
#include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <iostream> // for basic_ostream, operator<<, cout, endl
#include "asset.h" // for Asset
#include "cheevos.h" // for Achievement, Cheevos
#include "defines.h" // for PLAY_AREA_CENTER_X, GAMECANVAS_WIDTH
#include "global_events.h" // for check
#include "global_inputs.h" // for check
#include "input.h" // for Input, inputs_e, REPEAT_FALSE, REPEA...
#include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource
#include "screen.h" // for Screen
#include "sprite.h" // for Sprite
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
#include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette
#include "paleta.h"
// Constructor
Title::Title()
@@ -71,6 +72,9 @@ Title::Title()
// Rellena la textura de fondo con todos los gráficos
fillTexture();
// Inicia la musica
playMusic("title.ogg");
}
// Destructor

View File

@@ -1,18 +1,18 @@
#pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr
#include <string> // for string
#include <vector> // for vector
#include "paleta.h" // for jSurface
class Input; // lines 13-13
class Resource; // lines 14-14
class Screen; // lines 15-15
class Sprite; // lines 16-16
class Text; // lines 17-17
class Texture; // lines 18-18
#include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr
#include <string> // for string
#include <vector> // for vector
#include "paleta.h" // for jSurface
class Input; // lines 13-13
class Resource; // lines 14-14
class Screen; // lines 15-15
class Sprite; // lines 16-16
class Text; // lines 17-17
class Texture; // lines 18-18
class Title
{
@@ -32,13 +32,13 @@ private:
};
// Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource_; // Objeto con los recursos
Input *input_; // Objeto pata gestionar la entrada
Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource_; // Objeto con los recursos
Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Texture> texture_; // Textura con los graficos
std::shared_ptr<Sprite> sprite_; // Sprite para manejar la textura
SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla
SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
std::shared_ptr<Text> info_text_; // Objeto para escribir texto en pantalla
std::shared_ptr<Texture> cheevos_texture_; // Textura con la lista de logros
@@ -53,7 +53,7 @@ private:
bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros
SDL_Rect cheevos_texture_view_; // Zona visible de la textura con el listado de logros
states_e state_; // Estado en el que se encuentra el bucle principal
jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga
jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga
// Actualiza las variables
void update();

View File

@@ -8,6 +8,8 @@
#include <iostream> // for basic_ostream, cout, basic_ios, ios, endl
#include <unordered_map> // for unordered_map
#include <string> // for string
#include "jail_audio.h"
#include "resource.h"
// Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2)
@@ -524,4 +526,33 @@ void printWithDots(const std::string &text1, const std::string &text2, const std
bool stringInVector(const std::vector<std::string> &vec, const std::string &str)
{
return std::find(vec.begin(), vec.end(), str) != vec.end();
}
}
// Hace sonar la música
void playMusic(const std::string &music_path)
{
// Si la música no está sonando
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED)
{
JA_PlayMusic(Resource::get()->getMusic(music_path));
}
}
// Rellena una textura de un color
void fillTextureWithColor(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
// Guardar el render target actual
SDL_Texture* previous_target = SDL_GetRenderTarget(renderer);
// Establecer la textura como el render target
SDL_SetRenderTarget(renderer, texture);
// Establecer el color deseado
SDL_SetRenderDrawColor(renderer, r, g, b, a);
// Pintar toda el área
SDL_RenderClear(renderer);
// Restaurar el render target previo
SDL_SetRenderTarget(renderer, previous_target);
}

View File

@@ -4,6 +4,9 @@
#include <SDL2/SDL_stdinc.h> // for Uint8
#include <string> // for string
#include <vector>
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL.h> // for SDL_Texture
// Tipos de paleta
enum class Palette : int
@@ -126,4 +129,10 @@ std::string getPath(const std::string &full_path);
void printWithDots(const std::string &text1, const std::string &text2, const std::string &text3);
// Comprueba si una vector contiene una cadena
bool stringInVector(const std::vector<std::string> &vec, const std::string &str);
bool stringInVector(const std::vector<std::string> &vec, const std::string &str);
// Hace sonar la música
void playMusic(const std::string &music_path);
// Rellena una textura de un color
void fillTextureWithColor(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a);