42 Commits

Author SHA1 Message Date
b092d3f86a Trabajando en la reescritura del código 2022-09-26 14:06:44 +02:00
837bcbd1da menudo berenjenal. sigo con la integracion con las ultimas versiones de mis librerias 2022-09-26 11:18:50 +02:00
26bc47d9f6 Actualizando las librerias a la ultima versión 2022-09-26 10:34:45 +02:00
9e089e9092 Añadiendo la clase asset 2022-09-26 10:17:54 +02:00
25616e1e6c Ya permite continuar 2022-09-25 23:16:20 +02:00
ed67e429d8 Trabajando en poder continuar la partida al morir 2022-09-25 22:45:09 +02:00
4ebd034b59 Cambiado un poco el outline de la fuente nokia_big2 2022-09-25 22:24:41 +02:00
38f3e2e4d3 Limpieza de código no usado 2022-09-25 21:27:12 +02:00
6493b73f4f Cambiados NULL por nullptr 2022-09-25 21:22:59 +02:00
6637ba9f10 Actualizado a la última versión de ltexture 2022-09-25 21:11:17 +02:00
a74c8d5122 Eliminado codigo sin usar 2022-09-25 20:17:06 +02:00
4df0db088f Organización de código 2022-09-25 20:10:31 +02:00
27cb772933 corregido el offset de la m en nokia_big2 2022-09-25 19:40:39 +02:00
778b07cce1 Modificado el texto al cambiar de pantalla. Quitado texto no usado 2022-09-25 19:38:03 +02:00
1fa5c75466 Actualizado README.md 2022-09-25 19:01:13 +02:00
0b00acf31b Cambiado el numero de versión 2022-09-25 18:59:35 +02:00
2979a6752c Limpieza de código. Añadida la última versión de jail_audio 2022-09-25 18:44:58 +02:00
f6494e69c8 Cambiado el idioma por defecto a valenciano 2022-08-21 10:10:09 +02:00
5167a5857d Cambiada la frecuencia a 48000Hz de dos pistas de audio 2022-08-21 10:05:38 +02:00
28fe1130cf Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/coffee_crisis 2022-08-07 12:53:41 +02:00
e92b7eab4e limpieza de archivos 2022-08-07 12:53:14 +02:00
14f7a79927 Actualizar 'README.md' 2022-08-05 23:13:55 +02:00
4f6a6a4918 Actualizar 'Makefile' 2021-09-20 13:48:59 +02:00
f5b35cee6b Trabajando en la versión de opendingux 2021-09-17 20:55:36 +02:00
454791fe96 Añadidos modos en pantalla completa para el escalado entero y mantener la relación de aspecto 2021-09-15 11:48:57 +02:00
3f165be114 Commit para seguir en otro ordenador 2021-09-15 06:37:54 +02:00
778672a6f5 Commit para seguir en otro ordenador 2021-09-14 22:52:25 +02:00
8c919abc9d Trabajando en el escalado entero y el tamaño personalizable de la ventana de renderizado a traves de las opciones 2021-09-14 21:15:52 +02:00
7e37da3999 Restituido ballong.png a los colores originales 2021-09-14 17:03:13 +02:00
842d5dd56b Limpieza de código 2021-09-11 09:06:53 +02:00
ea3f16b8ac Añadida la clase screen al código 2021-09-10 23:52:58 +02:00
3fe0861e4f Trabajando en integrar la clase screen 2021-09-10 23:04:52 +02:00
b28d798545 Actualizado el numero de versión 2021-09-10 20:55:46 +02:00
bdf092d46e Limpieza de código. Modificada la fuente nokiabig2. Puestas ayudas para los dos jugadores. Cambiado el tamaño del mensaje de juego completado 2021-09-10 20:46:24 +02:00
09421a093d Limpieza de código 2021-09-10 14:02:29 +02:00
a7d7cdd047 Modificados los graficos de los globos y del jugador 1. Rebajada la dificultad de las últimas pantallas descendiendo el nivel de amenaza 2021-09-10 10:55:01 +02:00
bffefcad77 clean up and fixes 2021-09-06 18:05:40 +02:00
b408de5fa0 new makefile 2021-09-06 17:29:23 +02:00
f70145a0bf new makefile 2021-09-06 17:21:54 +02:00
02c7790835 updated nokia_big2.png 2021-09-06 17:00:35 +02:00
2d10e640bd updated stb_image.h 2021-09-03 20:00:40 +02:00
737829cb68 fixing warnings 2021-09-03 19:53:22 +02:00
67 changed files with 3793 additions and 2609 deletions

11
.gitignore vendored
View File

@@ -1,12 +1,5 @@
.vscode .vscode
*.DS_Store
bin bin
data/config.bin data/config.bin
data/score.bin data/score.bin
dll
docs
icon
releases
resources
scripts
*.opk
*.DS_Store

View File

@@ -1,6 +1,13 @@
executable = coffee_crisis
macos: macos:
mkdir -p bin mkdir -p bin
g++ -std=c++11 -Wall -O2 source/*.cpp -o bin/coffee_crisis_macos -lSDL2 g++ -std=c++11 -Wall -O2 source/*.cpp -o bin/$(executable)_macos -lSDL2
linux: linux:
mkdir -p bin mkdir -p bin
g++ -std=c++11 -Wall -O2 source/*.cpp -o bin/coffee_crisis_linux -lSDL2 g++ source/*.cpp -std=c++11 -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o bin/$(executable)_linux
strip -s -R .comment -R .gnu.version bin/$(executable)_linux --strip-unneeded
opendingux:
mkdir -p bin
/opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -D GCWZERO -O2 -std=c++11 -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -lSDL2_mixer -lstdc++ source/*.cpp -o bin/$(executable)_opendingux
/opt/gcw0-toolchain/usr/bin/mksquashfs ./default.gcw0.desktop ./icon.png ./bin ./data ./media coffee_crisis.opk -all-root -noappend -no-exports -no-xattrs

View File

@@ -1,6 +1,6 @@
# Coffee Crisis # Coffee Crisis
Coffe Crisis es un juego arcade que pondrá a prueba tus reflejos. Empezado el verano de 2020 y terminado el verano de 2021. Intenta conseguir todos los puntos que puedas con una sola vida y ayuda a Bal1 a defender la UPV ante la invasión de la cafeína durante 10 estresantes oleadas. Coffee Crisis es un juego arcade que pondrá a prueba tus reflejos. Empezado durante el verano de 2020 y terminado un año despues, en el verano de 2021. Intenta conseguir todos los puntos que puedas con una sola vida a traves de los 10 niveles de juego y ayuda a Bal1 a defender la UPV de la invasión de la cafeína esférica y saltarina.
## Compilar ## Compilar

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -157,7 +157,7 @@
# 108 l # 108 l
8 8
# 109 m # 109 m
10 20
# 110 n # 110 n
14 14
# 111 o # 111 o

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -75,21 +75,21 @@ Temps detes:
## 37 - TEXTOS DEL JUEGO ## 37 - TEXTOS DEL JUEGO
D E M O D E M O
## 38 - TEXTOS DEL JUEGO ## 38 - TEXTOS DEL JUEGO
Pantalla fases mes!
## 39 - MARCADOR ## 39 -
PUNTS
## 40 - MARCADOR ## 40 -
MAX.PUNT.
## 41 - MARCADOR ## 41 -
MULT
## 42 - MARCADOR ## 42 -
PANTALLA
## 43 - PANTALLA DE GAME OVER ## 43 - PANTALLA DE GAME OVER
FI DEL JOC FI DEL JOC
## 44 - PANTALLA DE GAME OVER ## 44 - PANTALLA DE GAME OVER
ELS TEUS PUNTS: ELS TEUS PUNTS:
## 45 - PANTALLA DE GAME OVER ## 45 - PANTALLA DE GAME OVER
REINTENTAR? CONTINUAR?
## 46 - MENU DE PAUSA ## 46 - MENU DE PAUSA
CONTINUAR CONTINUAR
## 47 - MENU DE PAUSA ## 47 - MENU DE PAUSA
@@ -113,7 +113,7 @@ mult
## 56 MARCADOR ## 56 MARCADOR
max. puntuacio max. puntuacio
## 57 MARCADOR ## 57 MARCADOR
pantalla fase
## 58 - MENU DE OPCIONES ## 58 - MENU DE OPCIONES
MODE DE VISUALITZACIO MODE DE VISUALITZACIO
## 59 - MENU DE OPCIONES ## 59 - MENU DE OPCIONES
@@ -126,10 +126,10 @@ SINC. VERTICAL
CONTROLS DEL JUGADOR 1 CONTROLS DEL JUGADOR 1
## 63 - MENU DE OPCIONES ## 63 - MENU DE OPCIONES
CONTROLS DEL JUGADOR 2 CONTROLS DEL JUGADOR 2
## 64 - MENU DE OPCIONES ## 64 -
TECLAT
## 65 - MENU DE OPCIONES ## 65 -
MANDO
## 66 - MENU DE OPCIONES ## 66 - MENU DE OPCIONES
FACIL FACIL
## 67 - MENU DE OPCIONES ## 67 - MENU DE OPCIONES
@@ -155,4 +155,6 @@ Endavant!
## 77 - PANTALLA DE GAME OVER ## 77 - PANTALLA DE GAME OVER
PUNTS J1: PUNTS J1:
## 78 - PANTALLA DE GAME OVER ## 78 - PANTALLA DE GAME OVER
PUNTS J2: PUNTS J2:
## 79 - TEXTOS DEL JUEGO
Ultima fase!

View File

@@ -75,21 +75,21 @@ Time stopped:
## 37 - TEXTOS DEL JUEGO ## 37 - TEXTOS DEL JUEGO
D E M O D E M O
## 38 - TEXTOS DEL JUEGO ## 38 - TEXTOS DEL JUEGO
Stage stages left!
## 39 - MARCADOR ## 39 -
SCORE
## 40 - MARCADOR ## 40 -
HI-SCORE
## 41 - MARCADOR ## 41 -
MULT
## 42 - MARCADOR ## 42 -
STAGE
## 43 - PANTALLA DE GAME OVER ## 43 - PANTALLA DE GAME OVER
GAME OVER GAME OVER
## 44 - PANTALLA DE GAME OVER ## 44 - PANTALLA DE GAME OVER
YOUR SCORE: YOUR SCORE:
## 45 - PANTALLA DE GAME OVER ## 45 - PANTALLA DE GAME OVER
RETRY? CONTINUE?
## 46 - MENU DE PAUSA ## 46 - MENU DE PAUSA
CONTINUE CONTINUE
## 47 - MENU DE PAUSA ## 47 - MENU DE PAUSA
@@ -126,10 +126,10 @@ VSYNC
PLAYER 1 CONTROLS PLAYER 1 CONTROLS
## 63 - MENU DE OPCIONES ## 63 - MENU DE OPCIONES
PLAYER 2 CONTROLS PLAYER 2 CONTROLS
## 64 - MENU DE OPCIONES ## 64 -
KEYBOARD
## 65 - MENU DE OPCIONES ## 65 -
GAME CONTROLLER
## 66 - MENU DE OPCIONES ## 66 - MENU DE OPCIONES
EASY EASY
## 67 - MENU DE OPCIONES ## 67 - MENU DE OPCIONES
@@ -155,4 +155,6 @@ Get Ready!
## 77 - PANTALLA DE GAME OVER ## 77 - PANTALLA DE GAME OVER
PLAYER1 SCORE: PLAYER1 SCORE:
## 78 - PANTALLA DE GAME OVER ## 78 - PANTALLA DE GAME OVER
PLAYER2 SCORE: PLAYER2 SCORE:
## 79 - TEXTOS DEL JUEGO
Last stage!

View File

@@ -75,21 +75,21 @@ Tiempo:
## 37 - TEXTOS DEL JUEGO ## 37 - TEXTOS DEL JUEGO
D E M O D E M O
## 38 - TEXTOS DEL JUEGO ## 38 - TEXTOS DEL JUEGO
Fase fases mas!
## 39 - MARCADOR ## 39 -
PUNTOS
## 40 - MARCADOR ## 40 -
MAX.PUNT.
## 41 - MARCADOR ## 41 -
MULT
## 42 - MARCADOR ## 42 -
FASE
## 43 - PANTALLA DE GAME OVER ## 43 - PANTALLA DE GAME OVER
FIN DE JUEGO FIN DE JUEGO
## 44 - PANTALLA DE GAME OVER ## 44 - PANTALLA DE GAME OVER
TU PUNTUACION: TU PUNTUACION:
## 45 - PANTALLA DE GAME OVER ## 45 - PANTALLA DE GAME OVER
REINTENTAR? CONTINUAR?
## 46 - MENU DE PAUSA ## 46 - MENU DE PAUSA
CONTINUAR CONTINUAR
## 47 - MENU DE PAUSA ## 47 - MENU DE PAUSA
@@ -113,7 +113,7 @@ mult
## 56 - MARCADOR ## 56 - MARCADOR
max. puntuacion max. puntuacion
## 57 - MARCADOR ## 57 - MARCADOR
fase FASE
## 58 - MENU DE OPCIONES ## 58 - MENU DE OPCIONES
MODO DE VISUALIZACION MODO DE VISUALIZACION
## 59 - MENU DE OPCIONES ## 59 - MENU DE OPCIONES
@@ -126,10 +126,10 @@ SINC. VERTICAL
CONTROLES DEL JUGADOR 1 CONTROLES DEL JUGADOR 1
## 63 - MENU DE OPCIONES ## 63 - MENU DE OPCIONES
CONTROLES DEL JUGADOR 2 CONTROLES DEL JUGADOR 2
## 64 - MENU DE OPCIONES ## 64 -
TECLADO
## 65 - MENU DE OPCIONES ## 65 -
MANDO
## 66 - MENU DE OPCIONES ## 66 - MENU DE OPCIONES
FACIL FACIL
## 67 - MENU DE OPCIONES ## 67 - MENU DE OPCIONES
@@ -155,4 +155,6 @@ Adelante!
## 77 - PANTALLA DE GAME OVER ## 77 - PANTALLA DE GAME OVER
PUNTUACION J1: PUNTUACION J1:
## 78 - PANTALLA DE GAME OVER ## 78 - PANTALLA DE GAME OVER
PUNTUACION J2: PUNTUACION J2:
## 79 - TEXTOS DEL JUEGO
Ultima fase!

Binary file not shown.

Binary file not shown.

View File

@@ -1,123 +1,333 @@
#include "const.h"
#include "animatedsprite.h" #include "animatedsprite.h"
// Constructor // Constructor
AnimatedSprite::AnimatedSprite() AnimatedSprite::AnimatedSprite(LTexture *texture, SDL_Renderer *renderer, std::string file)
{ {
//init(nullptr, nullptr); // Copia los punteros
setTexture(texture);
setRenderer(renderer);
// Carga las animaciones
load(file);
// Inicializa variables
currentAnimation = 0;
} }
// Destructor // Destructor
AnimatedSprite::~AnimatedSprite() AnimatedSprite::~AnimatedSprite()
{ {
//init(nullptr, nullptr); for (auto &a : animation)
{
a.frames.clear();
}
animation.clear();
} }
// Iniciador // Obtiene el indice de la animación a partir del nombre
void AnimatedSprite::init(LTexture *texture, SDL_Renderer *renderer) int AnimatedSprite::getIndex(std::string name)
{ {
mRenderer = renderer; int index = -1;
mTexture = texture;
for (int i = 0; i < 20; i++) for (auto a : animation)
{ {
mAnimation[i].numFrames = 0; index++;
mAnimation[i].speed = 0; if (a.name == name)
mAnimation[i].loop = true;
mAnimation[i].completed = false;
for (int j = 0; i < 20; i++)
{ {
mAnimation[i].frames[j].x = 0; return index;
mAnimation[i].frames[j].y = 0;
mAnimation[i].frames[j].w = 0;
mAnimation[i].frames[j].h = 0;
} }
} }
mCurrentFrame = 0;
mAnimationCounter = 0; printf("** Warning: could not find \"%s\" animation\n", name.c_str());
return -1;
} }
// Calcula el frame correspondiente a la animación // Calcula el frame correspondiente a la animación
void AnimatedSprite::animate(int index) void AnimatedSprite::animate()
{ {
if (mEnabled) if (!enabled || animation[currentAnimation].speed == 0)
{ {
// Calculamos el frame actual a partir del contador return;
mCurrentFrame = mAnimationCounter / mAnimation[index].speed; }
// Si alcanzamos el final de la animación, reiniciamos el contador de la animación // Calcula el frame actual a partir del contador
// en función de la variable loop animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed;
if (mCurrentFrame >= mAnimation[index].numFrames)
{ // Si alcanza el final de la animación, reinicia el contador de la animación
if (mAnimation[index].loop) // en función de la variable loop y coloca el nuevo frame
mAnimationCounter = 0; if (animation[currentAnimation].currentFrame >= (int)animation[currentAnimation].frames.size())
else {
mCurrentFrame = mAnimation[index].numFrames; if (animation[currentAnimation].loop == -1)
{ // Si no hay loop, deja el último frame
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size();
animation[currentAnimation].completed = true;
} }
// En caso contrario
else else
{ { // Si hay loop, vuelve al frame indicado
// Escogemos el frame correspondiente de la animación animation[currentAnimation].counter = 0;
setSpriteClip(mAnimation[index].frames[mCurrentFrame]); animation[currentAnimation].currentFrame = animation[currentAnimation].loop;
// Incrementamos el contador de la animacion
mAnimationCounter++;
} }
} }
// En caso contrario
else
{
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
// Incrementa el contador de la animacion
animation[currentAnimation].counter++;
}
} }
// Establece el frame actual de la animación // Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(Uint8 num) void AnimatedSprite::setCurrentFrame(int num)
{ {
mCurrentFrame = num; // Descarta valores fuera de rango
if (num >= (int)animation[currentAnimation].frames.size())
{
num = 0;
}
// Cambia el valor de la variable
animation[currentAnimation].counter = animation[currentAnimation].speed * num;
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
} }
// Establece el valor del contador // Establece el valor del contador
void AnimatedSprite::setAnimationCounter(Uint16 num) void AnimatedSprite::setAnimationCounter(std::string name, int num)
{ {
mAnimationCounter = num; animation[getIndex(name)].counter = num;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(std::string name, int speed)
{
animation[getIndex(name)].counter = speed;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(int index, int speed)
{
animation[index].counter = speed;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(std::string name, int loop)
{
animation[getIndex(name)].loop = loop;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(int index, int loop)
{
animation[index].loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(std::string name, bool value)
{
animation[getIndex(name)].completed = value;
}
// OLD - Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(int index, bool value)
{
animation[index].completed = value;
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::animationIsCompleted()
{
return animation[currentAnimation].completed;
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(std::string name, Uint8 index)
{
return animation[getIndex(name)].frames[index];
}
// Carga la animación desde un fichero
bool AnimatedSprite::load(std::string filePath)
{
int frames_per_row = 0;
int frame_width = 0;
int frame_height = 0;
// Indicador de éxito en la carga
bool success = true;
const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1);
std::ifstream file(filePath);
std::string line;
// El fichero se puede abrir
if (file.good())
{
// Procesa el fichero linea a linea
printf("Reading file %s\n", filename.c_str());
while (std::getline(file, line))
{
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]")
{
t_animation buffer;
buffer.counter = 0;
buffer.currentFrame = 0;
buffer.completed = false;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "name")
{
buffer.name = line.substr(pos + 1, line.length());
}
else if (line.substr(0, pos) == "speed")
{
buffer.speed = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "loop")
{
buffer.loop = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frames")
{
// Se introducen los valores separados por comas en un vector
std::stringstream ss(line.substr(pos + 1, line.length()));
std::string tmp;
SDL_Rect rect = {0, 0, frame_width, frame_height};
while (getline(ss, tmp, ','))
{
int num_tile = std::stoi(tmp);
rect.x = (num_tile % frames_per_row) * frame_width;
rect.y = (num_tile / frames_per_row) * frame_height;
buffer.frames.push_back(rect);
}
}
else
{
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
}
} while (line != "[/animation]");
// Añade la animación al vector de animaciones
animation.push_back(buffer);
}
// En caso contrario se parsea el fichero para buscar las variables y los valores
else
{
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "frames_per_row")
{
frames_per_row = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frame_width")
{
frame_width = std::stoi(line.substr(pos + 1, line.length()));
// Normaliza valores
if (frames_per_row == 0)
{
frames_per_row = texture->getWidth() / frame_width;
}
}
else if (line.substr(0, pos) == "frame_height")
{
frame_height = std::stoi(line.substr(pos + 1, line.length()));
}
else
{
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
}
}
}
// Cierra el fichero
printf("Closing file %s\n\n", filename.c_str());
file.close();
}
// El fichero no se puede abrir
else
{
printf("Warning: Unable to open %s file\n", filename.c_str());
success = false;
}
// Pone un valor por defecto
setPos({0, 0, frame_width, frame_height});
return success;
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(std::string name)
{
const int newAnimation = getIndex(name);
if (currentAnimation != newAnimation)
{
currentAnimation = newAnimation;
animation[currentAnimation].currentFrame = 0;
animation[currentAnimation].counter = 0;
animation[currentAnimation].completed = false;
}
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(int index)
{
const int newAnimation = index;
if (currentAnimation != newAnimation)
{
currentAnimation = newAnimation;
animation[currentAnimation].currentFrame = 0;
animation[currentAnimation].counter = 0;
animation[currentAnimation].completed = false;
}
}
// Actualiza las variables del objeto
void AnimatedSprite::update()
{
animate();
MovingSprite::update();
} }
// Establece el rectangulo para un frame de una animación // Establece el rectangulo para un frame de una animación
void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h) void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h)
{ {
mAnimation[index_animation].frames[index_frame].x = x; animation[index_animation].frames.push_back({x, y, w, h});
mAnimation[index_animation].frames[index_frame].y = y;
mAnimation[index_animation].frames[index_frame].w = w;
mAnimation[index_animation].frames[index_frame].h = h;
} }
// Establece la velocidad de una animación // OLD - Establece el contador para todas las animaciones
void AnimatedSprite::setAnimationSpeed(Uint8 index, Uint8 speed) void AnimatedSprite::setAnimationCounter(int value)
{ {
mAnimation[index].speed = speed; for (auto &a:animation)
} {
a.counter = value;
// Establece el numero de frames de una animación }
void AnimatedSprite::setAnimationNumFrames(Uint8 index, Uint8 num)
{
mAnimation[index].numFrames = num;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(Uint8 index, bool loop)
{
mAnimation[index].loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setCompleted(Uint8 index, bool value)
{
mAnimation[index].completed = value;
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::isCompleted(Uint8 index)
{
return mAnimation[index].completed;
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(Uint8 index_animation, Uint8 index_frame)
{
return mAnimation[index_animation].frames[index_frame];
} }

View File

@@ -1,69 +1,84 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "movingsprite.h" #include "movingsprite.h"
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#ifndef ANIMATEDSPRITE_H #ifndef ANIMATEDSPRITE_H
#define ANIMATEDSPRITE_H #define ANIMATEDSPRITE_H
#define MAX_FRAMES 30
#define MAX_ANIMATIONS 20
// Clase AnimatedSprite // Clase AnimatedSprite
class AnimatedSprite : public MovingSprite class AnimatedSprite : public MovingSprite
{ {
private: private:
struct sAnimation struct t_animation
{ {
SDL_Rect frames[MAX_FRAMES]; // Cada uno de los frames que componen la animación std::string name; // Nombre de la animacion
Uint8 numFrames; // Numero de frames que componen la animación std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
Uint8 speed; // Velocidad de la animación int speed; // Velocidad de la animación
bool loop; // Indica si la animación se reproduce en bucle int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
bool completed; // Indica si ha finalizado la animación bool completed; // Indica si ha finalizado la animación
int currentFrame; // Frame actual
int counter; // Contador para las animaciones
}; };
sAnimation mAnimation[MAX_ANIMATIONS]; // Vector con las diferentes animaciones std::vector<t_animation> animation; // Vector con las diferentes animaciones
int currentAnimation; // Animacion activa
Uint8 mCurrentFrame; // Frame actual
Uint16 mAnimationCounter; // Contador para las animaciones
public: public:
// Constructor // Constructor
AnimatedSprite(); AnimatedSprite(LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "");
// Destructor // Destructor
~AnimatedSprite(); ~AnimatedSprite();
// Iniciador // Calcula el frame correspondiente a la animación actual
void init(LTexture *texture, SDL_Renderer *renderer); void animate();
// Calcula el frame correspondiente a la animación
void animate(int index);
// Establece el frame actual de la animación // Establece el frame actual de la animación
void setCurrentFrame(Uint8 num); void setCurrentFrame(int num);
// Establece el valor del contador // Establece el valor del contador
void setAnimationCounter(Uint16 num); void setAnimationCounter(std::string name, int num);
// Establece el rectangulo para un frame de una animación
void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h);
// Establece la velocidad de una animación // Establece la velocidad de una animación
void setAnimationSpeed(Uint8 index, Uint8 speed); void setAnimationSpeed(std::string name, int speed);
void setAnimationSpeed(int index, int speed);
// Establece el numero de frames de una animación // Establece el frame al que vuelve la animación al finalizar
void setAnimationNumFrames(Uint8 index, Uint8 num); void setAnimationLoop(std::string name, int loop);
void setAnimationLoop(int index, int loop);
// Establece si la animación se reproduce en bucle
void setAnimationLoop(Uint8 index, bool loop);
// Establece el valor de la variable // Establece el valor de la variable
void setCompleted(Uint8 index, bool value); void setAnimationCompleted(std::string name, bool value);
void setAnimationCompleted(int index, bool value);
// Comprueba si ha terminado la animación // Comprueba si ha terminado la animación
bool isCompleted(Uint8 index); bool animationIsCompleted();
// Devuelve el rectangulo de una animación y frame concreto // Devuelve el rectangulo de una animación y frame concreto
SDL_Rect getAnimationClip(Uint8 index_animation, Uint8 index_frame); SDL_Rect getAnimationClip(std::string name, Uint8 index);
// Obtiene el indice de la animación a partir del nombre
int getIndex(std::string name);
// Carga la animación desde un fichero
bool load(std::string filePath);
// Establece la animacion actual
void setCurrentAnimation(std::string name = "default");
void setCurrentAnimation(int index = 0);
// Actualiza las variables del objeto
void update();
// OLD - Establece el rectangulo para un frame de una animación
void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h);
// OLD - Establece el contador para todas las animaciones
void setAnimationCounter(int value);
}; };
#endif #endif

160
source/asset.cpp Normal file
View File

@@ -0,0 +1,160 @@
#include "asset.h"
// Constructor
Asset::Asset(std::string path)
{
executablePath = path;
longest_name = 0;
}
// Destructor
Asset::~Asset()
{
}
// Añade un elemento a la lista
void Asset::add(std::string file, enum assetType type, bool required)
{
item_t temp;
temp.file = executablePath + file;
temp.type = type;
temp.required = required;
fileList.push_back(temp);
const std::string filename = file.substr(file.find_last_of("\\/") + 1);
longest_name = SDL_max(longest_name, filename.size());
}
// Devuelve el fichero de un elemento de la lista a partir de una cadena
std::string Asset::get(std::string text)
{
for (auto f : fileList)
{
if (f.file.find(text) != std::string::npos)
{
return f.file;
}
}
printf("Warning: file %s not found\n", text.c_str());
return "";
}
// Comprueba que existen todos los elementos
bool Asset::check()
{
bool success = true;
printf("\n** Checking files.\n");
// Comprueba la lista de ficheros clasificandolos por tipo
for (int type = 0; type < maxAssetType; ++type)
{
// Comprueba si hay ficheros de ese tipo
bool any = false;
for (auto f : fileList)
{
if ((f.required) && (f.type == type))
{
any = true;
}
}
// Si hay ficheros de ese tipo, comprueba si existen
if (any)
{
printf("\n>> %s FILES\n", getTypeName(type).c_str());
for (auto f : fileList)
{
if ((f.required) && (f.type == type))
{
success &= checkFile(f.file);
}
}
}
}
// Resultado
if (success)
{
printf("\n** All files OK.\n\n");
}
else
{
printf("\n** A file is missing. Exiting.\n\n");
}
return success;
}
// Comprueba que existe un fichero
bool Asset::checkFile(std::string path)
{
bool success = false;
std::string result = "ERROR";
// Comprueba si existe el fichero
const std::string filename = path.substr(path.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(path.c_str(), "r+b");
if (file != nullptr)
{
result = "OK";
success = true;
SDL_RWclose(file);
}
const std::string s = "Checking file %-" + std::to_string(longest_name) + "s [" + result + "]\n";
printf(s.c_str(), filename.c_str());
return success;
}
// Devuelve el nombre del tipo de recurso
std::string Asset::getTypeName(int type)
{
switch (type)
{
case bitmap:
return "BITMAP";
break;
case music:
return "MUSIC";
break;
case sound:
return "SOUND";
break;
case font:
return "FONT";
break;
case lang:
return "LANG";
break;
case data:
return "DATA";
break;
case room:
return "ROOM";
break;
case enemy:
return "ENEMY";
break;
case item:
return "ITEM";
break;
default:
return "ERROR";
break;
}
}

64
source/asset.h Normal file
View File

@@ -0,0 +1,64 @@
#pragma once
#include <SDL2/SDL.h>
#include <string>
#include <vector>
#ifndef ASSET_H
#define ASSET_H
enum assetType
{
bitmap,
music,
sound,
font,
lang,
data,
room,
enemy,
item,
maxAssetType
};
// Clase Asset
class Asset
{
private:
// Estructura para definir un item
struct item_t
{
std::string file; // Ruta del fichero desde la raiz del directorio
enum assetType type; // Indica el tipo de recurso
bool required; // Indica si es un fichero que debe de existir
};
int longest_name; // Contiene la longitud del nombre de fichero mas largo
std::vector<item_t> fileList;
std::string executablePath;
// Comprueba que existe un fichero
bool checkFile(std::string path);
// Devuelve el nombre del tipo de recurso
std::string getTypeName(int type);
public:
// Constructor
Asset(std::string path);
// Destructor
~Asset();
// Añade un elemento a la lista
void add(std::string file, enum assetType type, bool required = true);
// Devuelve un elemento de la lista a partir de una cadena
std::string get(std::string text);
// Comprueba que existen todos los elementos
bool check();
};
#endif

View File

@@ -55,13 +55,19 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
// Establece los frames de cada animación // Establece los frames de cada animación
for (int i = 0; i < NUM_FRAMES_BALLON; i++) for (int i = 0; i < NUM_FRAMES_BALLON; i++)
{
mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, 50 + OFFSET_ORANGE_BALLOONS, 21 + (37 * i), getWidth(), getHeight()); mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, 50 + OFFSET_ORANGE_BALLOONS, 21 + (37 * i), getWidth(), getHeight());
}
for (int i = 0; i < NUM_FRAMES_BALLON_BORN; i++) for (int i = 0; i < NUM_FRAMES_BALLON_BORN; i++)
{
mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, 50 + OFFSET_BLUE_BALLOONS, 21 + (37 * i), getWidth(), getHeight()); mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, 50 + OFFSET_BLUE_BALLOONS, 21 + (37 * i), getWidth(), getHeight());
}
for (int i = 0; i < NUM_FRAMES_BALLON_POP; i++) for (int i = 0; i < NUM_FRAMES_BALLON_POP; i++)
{
mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, 50 + OFFSET_EXPLOSIONS, 21 + (37 * i), getWidth(), getHeight()); mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, 50 + OFFSET_EXPLOSIONS, 21 + (37 * i), getWidth(), getHeight());
}
break; break;
@@ -351,13 +357,16 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mPosX = x; mPosX = x;
mPosY = y; mPosY = y;
mBouncing.enabled = false; // Si el efecto está activo // Valores para el efecto de rebote
mBouncing.counter = 0; // Countador para el efecto mBouncing.enabled = false;
mBouncing.speed = 0; // Velocidad a la que transcurre el efecto mBouncing.counter = 0;
mBouncing.zoomW = 1.0f; // Zoom aplicado a la anchura mBouncing.speed = 0;
mBouncing.zoomH = 1.0f; // Zoom aplicado a la altura mBouncing.zoomW = 1.0f;
mBouncing.despX = 0.0f; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom mBouncing.zoomH = 1.0f;
mBouncing.despX = 0.0f;
mBouncing.despY = 0.0f; mBouncing.despY = 0.0f;
mBouncing.w = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f};
mBouncing.h = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
// Textura con los gráficos del sprite // Textura con los gráficos del sprite
mSprite->setTexture(texture); mSprite->setTexture(texture);
@@ -404,13 +413,13 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mKind = kind; mKind = kind;
// Inicializa las variables para la animación // Inicializa las variables para la animación
mSprite->setCurrentFrame(0); // mSprite->setCurrentFrame(0);
mSprite->setAnimationCounter(0); // mSprite->setAnimationCounter(0);
// Establece el numero de frames de cada animacion // Establece el numero de frames de cada animacion
mSprite->setAnimationNumFrames(BALLOON_MOVING_ANIMATION, NUM_FRAMES_BALLON); // mSprite->setAnimationNumFrames(BALLOON_MOVING_ANIMATION, NUM_FRAMES_BALLON);
mSprite->setAnimationNumFrames(BALLOON_POP_ANIMATION, NUM_FRAMES_BALLON_POP); // mSprite->setAnimationNumFrames(BALLOON_POP_ANIMATION, NUM_FRAMES_BALLON_POP);
mSprite->setAnimationNumFrames(BALLOON_BORN_ANIMATION, NUM_FRAMES_BALLON_BORN); // mSprite->setAnimationNumFrames(BALLOON_BORN_ANIMATION, NUM_FRAMES_BALLON_BORN);
// Establece la velocidad de cada animación // Establece la velocidad de cada animación
mSprite->setAnimationSpeed(BALLOON_MOVING_ANIMATION, 10); mSprite->setAnimationSpeed(BALLOON_MOVING_ANIMATION, 10);
@@ -432,13 +441,9 @@ void Balloon::allignTo(int x)
mPosX = float(x - (mWidth / 2)); mPosX = float(x - (mWidth / 2));
if (mPosX < PLAY_AREA_LEFT) if (mPosX < PLAY_AREA_LEFT)
{
mPosX = PLAY_AREA_LEFT + 1; mPosX = PLAY_AREA_LEFT + 1;
}
else if ((mPosX + mWidth) > PLAY_AREA_RIGHT) else if ((mPosX + mWidth) > PLAY_AREA_RIGHT)
{
mPosX = float(PLAY_AREA_RIGHT - mWidth - 1); mPosX = float(PLAY_AREA_RIGHT - mWidth - 1);
}
// Posición X,Y del sprite // Posición X,Y del sprite
mSprite->setPosX(getPosX()); mSprite->setPosX(getPosX());
@@ -531,10 +536,12 @@ void Balloon::move()
} }
/* /*
Para aplicar la gravedad, el diseño original la aplicaba en cada iteración del bucle Para aplicar la gravedad, el diseño original la aplicaba en cada iteración del bucle
Al añadir el modificador de velocidad se reduce la distancia que recorre el objeto y por Al añadir el modificador de velocidad se reduce la distancia que recorre el objeto y por
tanto recibe mas gravedad. Para solucionarlo se va a aplicar la gravedad cuando se haya tanto recibe mas gravedad. Para solucionarlo se va a aplicar la gravedad cuando se haya
recorrido una distancia igual a la velocidad en Y, que era el cálculo inicial recorrido una distancia igual a la velocidad en Y, que era el cálculo inicial
*/ */
// Incrementa la variable que calcula la distancia acumulada en Y // Incrementa la variable que calcula la distancia acumulada en Y
@@ -550,11 +557,6 @@ void Balloon::move()
mVelY += mGravity; mVelY += mGravity;
std::min(mVelY, mMaxVelY); std::min(mVelY, mMaxVelY);
} }
// Aplica la gravedad al objeto
//if (mVelY > mMaxVelY)
// mVelY = mMaxVelY;
//else if (mCounter % 1 == 0)
// mVelY += mGravity;
// Actualiza la posición del sprite // Actualiza la posición del sprite
mSprite->setPosX(getPosX()); mSprite->setPosX(getPosX());
@@ -603,7 +605,7 @@ void Balloon::disable()
void Balloon::pop() void Balloon::pop()
{ {
setPopping(true); setPopping(true);
mSprite->setAnimationCounter(0); mSprite->setAnimationCounter(0);
mSprite->disableRotate(); mSprite->disableRotate();
setTimeToLive(120); setTimeToLive(120);
setStop(true); setStop(true);
@@ -635,9 +637,9 @@ void Balloon::updateState()
{ {
setInvulnerable(true); setInvulnerable(true);
setStop(true); setStop(true);
if (mSprite->isCompleted(BALLOON_POP_ANIMATION)) if (mSprite->animationIsCompleted())
{ {
mSprite->setCompleted(BALLOON_POP_ANIMATION, false); mSprite->setAnimationCompleted(BALLOON_POP_ANIMATION, false);
mTimeToLive = 0; mTimeToLive = 0;
disable(); disable();
} }
@@ -679,12 +681,6 @@ void Balloon::updateState()
updateColliders(); updateColliders();
} }
// Hace visible el globo de forma intermitente
//if (mCreationCounter > 100)
// setVisible(mCreationCounter / 10 % 2 == 0);
//else
// setVisible(mCreationCounter / 5 % 2 == 0);
mCreationCounter--; mCreationCounter--;
} }
// El contador ha llegado a cero // El contador ha llegado a cero
@@ -709,10 +705,14 @@ void Balloon::updateState()
{ {
// Si está detenido, reduce el contador // Si está detenido, reduce el contador
if (mStoppedCounter > 0) if (mStoppedCounter > 0)
{
mStoppedCounter--; mStoppedCounter--;
}
// Si el contador ha llegado a cero, ya no está detenido // Si el contador ha llegado a cero, ya no está detenido
else if (!isPopping()) // Quitarles el estado "detenido" si no estan explosionandoxq else if (!isPopping())
{ // Quitarles el estado "detenido" si no estan explosionando
setStop(false); setStop(false);
}
} }
} }
@@ -721,11 +721,19 @@ void Balloon::updateAnimation()
{ {
// Establece el frame de animación // Establece el frame de animación
if (isPopping()) if (isPopping())
mSprite->animate(BALLOON_POP_ANIMATION); {
mSprite->setCurrentAnimation(BALLOON_POP_ANIMATION);
}
else if (isBeingCreated()) else if (isBeingCreated())
mSprite->animate(BALLOON_BORN_ANIMATION); {
mSprite->setCurrentAnimation(BALLOON_BORN_ANIMATION);
}
else else
mSprite->animate(BALLOON_MOVING_ANIMATION); {
mSprite->setCurrentAnimation(BALLOON_MOVING_ANIMATION);
}
mSprite->animate();
} }
// Comprueba si el globo está habilitado // Comprueba si el globo está habilitado
@@ -910,7 +918,6 @@ circle_t &Balloon::getCollider()
// Alinea el circulo de colisión con la posición del objeto globo // Alinea el circulo de colisión con la posición del objeto globo
void Balloon::updateColliders() void Balloon::updateColliders()
{ {
// Align collider to center of balloon
mCollider.x = Uint16(mPosX + mCollider.r); mCollider.x = Uint16(mPosX + mCollider.r);
mCollider.y = mPosY + mCollider.r; mCollider.y = mPosY + mCollider.r;
} }
@@ -940,6 +947,7 @@ void Balloon::bounceStart()
mBouncing.despX = 0; mBouncing.despX = 0;
mBouncing.despY = 0; mBouncing.despY = 0;
} }
void Balloon::bounceStop() void Balloon::bounceStop()
{ {
mBouncing.enabled = false; mBouncing.enabled = false;
@@ -951,6 +959,7 @@ void Balloon::bounceStop()
mBouncing.despX = 0.0f; mBouncing.despX = 0.0f;
mBouncing.despY = 0.0f; mBouncing.despY = 0.0f;
} }
void Balloon::updateBounce() void Balloon::updateBounce()
{ {
if (mBouncing.enabled) if (mBouncing.enabled)

View File

@@ -1,16 +1,90 @@
#pragma once #pragma once
#include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#include "animatedsprite.h" #include "animatedsprite.h"
#include <vector>
#ifndef BALLOON_H #ifndef BALLOON_H
#define BALLOON_H #define BALLOON_H
// Cantidad de elementos del vector con los valores de la deformación del globo al rebotar
#define MAX_BOUNCE 10 #define MAX_BOUNCE 10
// Clase globo // Tipos de globo
#define BALLOON_1 1
#define BALLOON_2 2
#define BALLOON_3 3
#define BALLOON_4 4
#define HEXAGON_1 5
#define HEXAGON_2 6
#define HEXAGON_3 7
#define HEXAGON_4 8
#define POWER_BALL 9
// Puntos de globo
#define BALLOON_SCORE_1 50
#define BALLOON_SCORE_2 100
#define BALLOON_SCORE_3 200
#define BALLOON_SCORE_4 400
// Tamaños de globo
#define BALLOON_SIZE_1 1
#define BALLOON_SIZE_2 2
#define BALLOON_SIZE_3 3
#define BALLOON_SIZE_4 4
// Clases de globo
#define BALLOON_CLASS 0
#define HEXAGON_CLASS 1
// Velocidad del globo
#define BALLOON_VELX_POSITIVE 0.7f
#define BALLOON_VELX_NEGATIVE -0.7f
// Indice para las animaciones de los globos
#define BALLOON_MOVING_ANIMATION 0
#define BALLOON_POP_ANIMATION 1
#define BALLOON_BORN_ANIMATION 2
// Cantidad posible de globos
#define MAX_BALLOONS 100
// Velocidades a las que se mueven los globos
#define BALLOON_SPEED_1 0.60f
#define BALLOON_SPEED_2 0.70f
#define BALLOON_SPEED_3 0.80f
#define BALLOON_SPEED_4 0.90f
#define BALLOON_SPEED_5 1.00f
// Tamaño de los globos
#define BALLOON_WIDTH_1 8
#define BALLOON_WIDTH_2 13
#define BALLOON_WIDTH_3 21
#define BALLOON_WIDTH_4 37
// PowerBall
#define POWERBALL_SCREENPOWER_MINIMUM 10
#define POWERBALL_COUNTER 8
// Clase Balloon
class Balloon class Balloon
{ {
private: private:
// Estructura para las variables para el efecto de los rebotes
struct bouncing
{
bool enabled; // Si el efecto está activo
Uint8 counter; // Countador para el efecto
Uint8 speed; // Velocidad a la que transcurre el efecto
float zoomW; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
float despY; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom
std::vector<float> w; // Vector con los valores de zoom para el ancho del globo
std::vector<float> h; // Vector con los valores de zoom para el alto del globo
};
float mPosX; // Posición en el eje X float mPosX; // Posición en el eje X
float mPosY; // Posición en el eje Y float mPosY; // Posición en el eje Y
Uint8 mWidth; // Ancho Uint8 mWidth; // Ancho
@@ -41,32 +115,34 @@ private:
float mSpeed; // Velocidad a la que se mueven los globos float mSpeed; // Velocidad a la que se mueven los globos
Uint8 mSize; // Tamaño del globo Uint8 mSize; // Tamaño del globo
Uint8 mPower; // Cantidad de poder que alberga el globo Uint8 mPower; // Cantidad de poder que alberga el globo
bouncing mBouncing; // Contiene las variables para el efecto de rebote
struct bouncing // Estructura para las variables para el efecto de los rebotes // Alinea el circulo de colisión con la posición del objeto globo
{ void updateColliders();
bool enabled; // Si el efecto está activo
Uint8 counter; // Countador para el efecto
Uint8 speed; // Velocidad a la que transcurre el efecto
float zoomW; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
float despY; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom
// Vector con los valores de zoom para el ancho y alto del globo // Activa el efecto
float w[MAX_BOUNCE] = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f}; void bounceStart();
float h[MAX_BOUNCE] = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
};
bouncing mBouncing;
void updateColliders(); // Alinea el circulo de colisión con la posición del objeto globo // Detiene el efecto
void bounceStart(); // Activa el efecto void bounceStop();
void bounceStop(); // Detiene el efecto
void updateBounce(); // Aplica el efecto // Aplica el efecto
void updateState(); // Actualiza los estados del globo void updateBounce();
void updateAnimation(); // Establece la animación correspondiente
void setBeingCreated(bool state); // Establece el valor de la variable // Actualiza los estados del globo
void setTimeToLive(Uint16 time); // Establece el valor de la variable void updateState();
Uint16 getTimeToLive(); // Obtiene del valor de la variable
// Establece la animación correspondiente
void updateAnimation();
// Establece el valor de la variable
void setBeingCreated(bool state);
// Establece el valor de la variable
void setTimeToLive(Uint16 time);
// Obtiene del valor de la variable
Uint16 getTimeToLive();
public: public:
// Constructor // Constructor

View File

@@ -11,7 +11,6 @@ Bullet::Bullet()
// Destructor // Destructor
Bullet::~Bullet() Bullet::~Bullet()
{ {
//init(0, 0, NO_KIND, nullptr, nullptr);
delete mSprite; delete mSprite;
mSprite = nullptr; mSprite = nullptr;
} }
@@ -107,7 +106,7 @@ void Bullet::render()
Uint8 Bullet::move() Uint8 Bullet::move()
{ {
// Variable con el valor de retorno // Variable con el valor de retorno
Uint8 msg = MSG_OK; Uint8 msg = BULLET_MOVE_OK;
// Mueve el objeto a su nueva posición // Mueve el objeto a su nueva posición
mPosX += mVelX; mPosX += mVelX;
@@ -119,7 +118,7 @@ Uint8 Bullet::move()
mKind = NO_KIND; mKind = NO_KIND;
// Mensaje de salida // Mensaje de salida
msg = MSG_BULLET_OUT; msg = BULLET_MOVE_OUT;
} }
// Mueve el objeto a su nueva posición en vertical // Mueve el objeto a su nueva posición en vertical
@@ -132,7 +131,7 @@ Uint8 Bullet::move()
mKind = NO_KIND; mKind = NO_KIND;
// Mensaje de salida // Mensaje de salida
msg = MSG_BULLET_OUT; msg = BULLET_MOVE_OUT;
} }
// Actualiza la posición del sprite // Actualiza la posición del sprite
@@ -145,18 +144,6 @@ Uint8 Bullet::move()
return msg; return msg;
} }
#ifdef TEST
void Bullet::testMove()
{
// Update sprite position
mSprite->setPosX(mPosX);
mSprite->setPosY(mPosY);
// Update circle colliders
shiftColliders();
}
#endif
// Deshabilita el objeto // Deshabilita el objeto
void Bullet::erase() void Bullet::erase()
{ {
@@ -167,13 +154,9 @@ void Bullet::erase()
bool Bullet::isActive() bool Bullet::isActive()
{ {
if (mKind == NO_KIND) if (mKind == NO_KIND)
{
return false; return false;
}
else else
{
return true; return true;
}
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable

View File

@@ -1,11 +1,22 @@
#pragma once #pragma once
#include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#include "sprite.h" #include "sprite.h"
#ifndef BULLET_H #ifndef BULLET_H
#define BULLET_H #define BULLET_H
// Clase bala // Tipos de bala
#define BULLET_UP 1
#define BULLET_LEFT 2
#define BULLET_RIGHT 3
// Tipos de retorno de la funcion move de la bala
#define BULLET_MOVE_OK 0
#define BULLET_MOVE_OUT 1
// Clase Bullet
class Bullet class Bullet
{ {
private: private:

View File

@@ -1,4 +1,6 @@
#pragma once #pragma once
#include <SDL2/SDL.h>
#include "sprite.h" #include "sprite.h"
#ifndef COFFEEDROP_H #ifndef COFFEEDROP_H

View File

@@ -1,85 +1,19 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#include "lang.h" #include "lang.h"
#include <string>
#ifndef CONST_H #ifndef CONST_H
#define CONST_H #define CONST_H
// Textos
#define WINDOW_CAPTION "Coffee Crisis"
#define TEXT_COPYRIGHT "@2020,2021 JailDesigner (v2.0)"
// Recursos
#define BINFILE_SCORE 0
#define BINFILE_DEMO 1
#define BINFILE_CONFIG 2
#define TOTAL_BINFILE 3
#define MUSIC_INTRO 0
#define MUSIC_PLAYING 1
#define MUSIC_TITLE 2
#define TOTAL_MUSIC 3
#define SOUND_BALLOON 0
#define SOUND_BUBBLE1 1
#define SOUND_BUBBLE2 2
#define SOUND_BUBBLE3 3
#define SOUND_BUBBLE4 4
#define SOUND_BULLET 5
#define SOUND_COFFEE_OUT 6
#define SOUND_HISCORE 7
#define SOUND_ITEM_DROP 8
#define SOUND_ITEM_PICKUP 9
#define SOUND_MENU_CANCEL 10
#define SOUND_MENU_MOVE 11
#define SOUND_MENU_SELECT 12
#define SOUND_PLAYER_COLLISION 13
#define SOUND_STAGE_CHANGE 14
#define SOUND_TITLE 15
#define SOUND_CLOCK 16
#define SOUND_POWERBALL 17
#define TOTAL_SOUND 18
#define TEXTURE_BALLOON 0
#define TEXTURE_BULLET 1
#define TEXTURE_FONT_BLACK 2
#define TEXTURE_FONT_BLACK_X2 3
#define TEXTURE_FONT_NOKIA 4
#define TEXTURE_FONT_WHITE 5
#define TEXTURE_FONT_WHITE_X2 6
#define TEXTURE_GAME_BG 7
#define TEXTURE_GAME_TEXT 8
#define TEXTURE_INTRO 9
#define TEXTURE_ITEMS 10
#define TEXTURE_LOGO 11
#define TEXTURE_MENU 12
#define TEXTURE_PLAYER_BODY 13
#define TEXTURE_PLAYER_DEATH 14
#define TEXTURE_PLAYER_LEGS 15
#define TEXTURE_TITLE 16
#define TOTAL_TEXTURE 17
// Tamaño de bloque // Tamaño de bloque
#define BLOCK 8 #define BLOCK 8
#define HALF_BLOCK BLOCK / 2 #define HALF_BLOCK BLOCK / 2
// Tamaño de la pantalla real // Tamaño de la pantalla de juego
#define SCREEN_WIDTH 256 #define SCREEN_WIDTH 256
const int SCREEN_HEIGHT = SCREEN_WIDTH * 3 / 4; #define SCREEN_HEIGHT 192
// Tamaño de la pantalla que se muestra
const int VIEW_WIDTH = SCREEN_WIDTH * 3;
const int VIEW_HEIGHT = SCREEN_HEIGHT * 3;
// Cantidad de enteros a escribir en los ficheros de datos
#define TOTAL_SCORE_DATA 3
#define TOTAL_DEMO_DATA 2000
// Zona de juego // Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK); const int PLAY_AREA_TOP = (0 * BLOCK);
@@ -103,48 +37,6 @@ const int SCREEN_CENTER_Y = SCREEN_HEIGHT / 2;
const int SCREEN_FIRST_QUARTER_Y = SCREEN_HEIGHT / 4; const int SCREEN_FIRST_QUARTER_Y = SCREEN_HEIGHT / 4;
const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3; const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
// Opciones de menu
#define MENU_NO_OPTION -1
#define MENU_OPTION_START 0
#define MENU_OPTION_QUIT 1
#define MENU_OPTION_TOTAL 2
// Tipos de fondos para el menu
#define MENU_BACKGROUND_TRANSPARENT 0
#define MENU_BACKGROUND_SOLID 1
// Estados del jugador
#define PLAYER_STATUS_WALKING_LEFT 0
#define PLAYER_STATUS_WALKING_RIGHT 1
#define PLAYER_STATUS_WALKING_STOP 2
#define PLAYER_STATUS_FIRING_UP 0
#define PLAYER_STATUS_FIRING_LEFT 1
#define PLAYER_STATUS_FIRING_RIGHT 2
#define PLAYER_STATUS_FIRING_NO 3
#define PLAYER_ANIMATION_LEGS_WALKING_LEFT 0
#define PLAYER_ANIMATION_LEGS_WALKING_RIGHT 1
#define PLAYER_ANIMATION_LEGS_WALKING_STOP 2
#define PLAYER_ANIMATION_BODY_WALKING_LEFT 0
#define PLAYER_ANIMATION_BODY_FIRING_LEFT 1
#define PLAYER_ANIMATION_BODY_WALKING_RIGHT 2
#define PLAYER_ANIMATION_BODY_FIRING_RIGHT 3
#define PLAYER_ANIMATION_BODY_WALKING_STOP 4
#define PLAYER_ANIMATION_BODY_FIRING_UP 5
#define PLAYER_ANIMATION_HEAD_WALKING_LEFT 0
#define PLAYER_ANIMATION_HEAD_FIRING_LEFT 1
#define PLAYER_ANIMATION_HEAD_WALKING_RIGHT 2
#define PLAYER_ANIMATION_HEAD_FIRING_RIGHT 3
#define PLAYER_ANIMATION_HEAD_WALKING_STOP 4
#define PLAYER_ANIMATION_HEAD_FIRING_UP 5
// Variables del jugador
#define PLAYER_INVULNERABLE_COUNTER 200
#define PLAYER_POWERUP_COUNTER 1500
// Secciones del programa // Secciones del programa
#define PROG_SECTION_LOGO 0 #define PROG_SECTION_LOGO 0
#define PROG_SECTION_INTRO 1 #define PROG_SECTION_INTRO 1
@@ -162,197 +54,17 @@ const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
#define TITLE_SECTION_3 5 #define TITLE_SECTION_3 5
#define TITLE_SECTION_INSTRUCTIONS 6 #define TITLE_SECTION_INSTRUCTIONS 6
// Modo para las instrucciones
#define INSTRUCTIONS_MODE_MANUAL 0
#define INSTRUCTIONS_MODE_AUTO 1
// Estados de cada elemento que pertenece a un evento // Estados de cada elemento que pertenece a un evento
#define EVENT_WAITING 1 #define EVENT_WAITING 1
#define EVENT_RUNNING 2 #define EVENT_RUNNING 2
#define EVENT_COMPLETED 3 #define EVENT_COMPLETED 3
// Cantidad de eventos de la intro
#define INTRO_TOTAL_BITMAPS 6
#define INTRO_TOTAL_TEXTS 9
const int INTRO_TOTAL_EVENTS = INTRO_TOTAL_BITMAPS + INTRO_TOTAL_TEXTS;
// Cantidad de eventos de la pantalla de titulo
#define TITLE_TOTAL_EVENTS 2
// Relaciones de Id con nomnbres
#define BITMAP0 0
#define BITMAP1 1
#define BITMAP2 2
#define BITMAP3 3
#define BITMAP4 4
#define BITMAP5 5
#define TEXT0 6
#define TEXT1 7
#define TEXT2 8
#define TEXT3 9
#define TEXT4 10
#define TEXT5 11
#define TEXT6 12
#define TEXT7 13
#define TEXT8 14
// Anclajes para el marcador de puntos
const int SCORE_WORD_X = (SCREEN_WIDTH / 4) - ((5 * BLOCK) / 2);
const int SCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int SCORE_NUMBER_X = (SCREEN_WIDTH / 4) - ((6 * BLOCK) / 2);
const int SCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int HISCORE_WORD_X = ((SCREEN_WIDTH / 4) * 3) - ((8 * BLOCK) / 2);
const int HISCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int HISCORE_NUMBER_X = ((SCREEN_WIDTH / 4) * 3) - ((6 * BLOCK) / 2);
const int HISCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int MULTIPLIER_WORD_X = (SCREEN_WIDTH / 2) - ((4 * BLOCK) / 2);
const int MULTIPLIER_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int MULTIPLIER_NUMBER_X = (SCREEN_WIDTH / 2) - ((3 * BLOCK) / 2);
const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
// Ningun tipo // Ningun tipo
#define NO_KIND 0 #define NO_KIND 0
// Tipos de globo
#define BALLOON_1 1
#define BALLOON_2 2
#define BALLOON_3 3
#define BALLOON_4 4
#define HEXAGON_1 5
#define HEXAGON_2 6
#define HEXAGON_3 7
#define HEXAGON_4 8
#define POWER_BALL 9
// Puntos de globo
#define BALLOON_SCORE_1 50
#define BALLOON_SCORE_2 100
#define BALLOON_SCORE_3 200
#define BALLOON_SCORE_4 400
// Tamaños de globo
#define BALLOON_SIZE_1 1
#define BALLOON_SIZE_2 2
#define BALLOON_SIZE_3 3
#define BALLOON_SIZE_4 4
// Clases de globo
#define BALLOON_CLASS 0
#define HEXAGON_CLASS 1
// Velocidad del globo
#define BALLOON_VELX_POSITIVE 0.7f
#define BALLOON_VELX_NEGATIVE -0.7f
// Indice para las animaciones de los globos
#define BALLOON_MOVING_ANIMATION 0
#define BALLOON_POP_ANIMATION 1
#define BALLOON_BORN_ANIMATION 2
// Cantidad posible de globos
#define MAX_BALLOONS 100
// Velocidades a las que se mueven los enemigos
#define BALLOON_SPEED_1 0.60f
#define BALLOON_SPEED_2 0.70f
#define BALLOON_SPEED_3 0.80f
#define BALLOON_SPEED_4 0.90f
#define BALLOON_SPEED_5 1.00f
// Tamaño de los globos
#define BALLOON_WIDTH_1 8
#define BALLOON_WIDTH_2 13
#define BALLOON_WIDTH_3 21
#define BALLOON_WIDTH_4 37
// PowerBall
#define POWERBALL_SCREENPOWER_MINIMUM 10
#define POWERBALL_COUNTER 8
// Tipos de bala
#define BULLET_UP 1
#define BULLET_LEFT 2
#define BULLET_RIGHT 3
// Cantidad posible de globos
#define MAX_BULLETS 50
// Tipos de objetos
#define ITEM_POINTS_1_DISK 1
#define ITEM_POINTS_2_GAVINA 2
#define ITEM_POINTS_3_PACMAR 3
#define ITEM_CLOCK 4
#define ITEM_COFFEE 5
#define ITEM_POWER_BALL 6
#define ITEM_COFFEE_MACHINE 7
// Porcentaje de aparición de los objetos
#define ITEM_POINTS_1_DISK_ODDS 10
#define ITEM_POINTS_2_GAVINA_ODDS 6
#define ITEM_POINTS_3_PACMAR_ODDS 3
#define ITEM_CLOCK_ODDS 5
#define ITEM_COFFEE_ODDS 5
#define ITEM_POWER_BALL_ODDS 0
#define ITEM_COFFEE_MACHINE_ODDS 4
// Cantidad de objetos simultaneos
#define MAX_ITEMS 10
// Valores para las variables asociadas a los objetos
#define REMAINING_EXPLOSIONS 3
#define REMAINING_EXPLOSIONS_COUNTER 50
#define TIME_STOPPED_COUNTER 300
// Estados de entrada
#define NO_INPUT 0
#define INPUT_FIRE_LEFT 7
#define INPUT_FIRE_UP 8
#define INPUT_FIRE_RIGHT 9
#define INPUT_PAUSE 10
// Zona muerta del mando analógico
#define JOYSTICK_DEAD_ZONE 8000
// Tipos de mensajes para el retorno de las funciones
#define MSG_OK 0
#define MSG_BULLET_OUT 1
// Tipos de texto
#define TEXT_FIXED 0
#define TEXT_VARIABLE 1
// Cantidad de elementos del vector de SmartSprites
#define MAX_SMART_SPRITES 10
// Cantidad máxima de gotas de café
#define MAX_COFFEE_DROPS 100
// Contadores
#define TITLE_COUNTER 800
#define STAGE_COUNTER 200
#define INSTRUCTIONS_COUNTER 600
#define DEATH_COUNTER 350
#define SHAKE_COUNTER 10
#define HELP_COUNTER 1000
// Colores // Colores
const color_t bgColor = {0x27, 0x27, 0x36}; const color_t bgColor = {0x27, 0x27, 0x36};
const color_t noColor = {0xFF, 0xFF, 0xFF}; const color_t noColor = {0xFF, 0xFF, 0xFF};
const color_t shdwTxtColor = {0x43, 0x43, 0x4F}; const color_t shdwTxtColor = {0x43, 0x43, 0x4F};
// Formaciones enemigas
#define NUMBER_OF_ENEMY_FORMATIONS 100
#define MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION 50
// Dificultad del juego
#define DIFFICULTY_EASY 0
#define DIFFICULTY_NORMAL 1
#define DIFFICULTY_HARD 2
// Tipo de filtro
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
#endif #endif

View File

@@ -3,68 +3,43 @@
#include "director.h" #include "director.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#endif
// Constructor // Constructor
Director::Director(std::string path) Director::Director(std::string path)
{ {
// Inicializa la ruta
setExecutablePath(path);
// Crea el objeto que controla los ficheros de recursos
mAsset = new Asset(path.substr(0, path.find_last_of("\\/")) + "../");
// Establece la lista de ficheros // Establece la lista de ficheros
setFileList();
// Si falta algún fichero no inicies el programa
Uint8 section = PROG_SECTION_LOGO; Uint8 section = PROG_SECTION_LOGO;
if (!checkFileList()) if (!setFileList())
{// Si falta algún fichero no inicies el programa
section = PROG_SECTION_QUIT; section = PROG_SECTION_QUIT;
}
// Inicializa el objeto de idioma // Crea el objeto de idioma
mLang = new Lang(mFileList); mLang = new Lang(mAsset);
// Crea el puntero a la estructura y carga el fichero de configuración // Crea el puntero a la estructura y carga el fichero de configuración
mOptions = new options_t; mOptions = new options_t;
if (!loadConfigFile()) loadConfigFile();
{
mOptions->fullScreenMode = 0;
mOptions->windowSize = 3;
mOptions->language = en_UK;
mOptions->difficulty = DIFFICULTY_NORMAL;
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
mOptions->filter = FILTER_NEAREST;
mOptions->vSync = true;
}
// Crea los objetos // Crea los objetos
mInput = new Input(mFileList[53]); mInput = new Input(mAsset->get("controllerdb.txt"));
// Inicializa SDL // Inicializa SDL
initSDL(); initSDL();
// Crea el objeto para dibujar en pantalla (Requiere initSDL)
mScreen = new Screen(mWindow, mRenderer, mOptions);
// Inicializa JailAudio // Inicializa JailAudio
initJailAudio(); initJailAudio();
// Aplica las opciones // Aplica las opciones
SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode);
SDL_SetWindowSize(mWindow, SCREEN_WIDTH * mOptions->windowSize, SCREEN_HEIGHT * mOptions->windowSize);
mLang->setLang(mOptions->language); mLang->setLang(mOptions->language);
#ifdef __MIPSEL__
DIR *dir = opendir("/media/data/local/home/.coffee_crisis");
if (dir)
{
closedir(dir);
}
else if (ENOENT == errno)
{
int status = mkdir("/media/data/local/home/.coffee_crisis", 755);
}
#endif
// Inicializa el resto de variables // Inicializa el resto de variables
init(section); init(section);
} }
@@ -73,9 +48,15 @@ Director::~Director()
{ {
saveConfigFile(); saveConfigFile();
delete mAsset;
mAsset = nullptr;
delete mInput; delete mInput;
mInput = nullptr; mInput = nullptr;
delete mScreen;
mScreen = nullptr;
delete mLang; delete mLang;
mLang = nullptr; mLang = nullptr;
@@ -107,15 +88,9 @@ void Director::init(Uint8 name)
mInput->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT); mInput->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT);
mInput->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN); mInput->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN);
mInput->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE); mInput->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE);
#ifdef __MIPSEL__
mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_LSHIFT);
mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_SPACE);
mInput->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_LCTRL);
#else
mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_Q); mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_Q);
mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W); mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W);
mInput->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E); mInput->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E);
#endif
mInput->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); // PAUSE mInput->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); // PAUSE
mInput->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); // ESCAPE mInput->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); // ESCAPE
@@ -145,8 +120,7 @@ bool Director::initSDL()
bool success = true; bool success = true;
// Inicializa SDL // Inicializa SDL
//if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0)
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{ {
printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError()); printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError());
success = false; success = false;
@@ -156,15 +130,15 @@ bool Director::initSDL()
// Inicia el generador de numeros aleatorios // Inicia el generador de numeros aleatorios
std::srand(static_cast<unsigned int>(SDL_GetTicks())); std::srand(static_cast<unsigned int>(SDL_GetTicks()));
// Establece el filtro de la textura a nearest // Establece el filtro de la textura
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(mOptions->filter).c_str())) if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(mOptions->filter).c_str()))
{ {
printf("Warning: Nearest texture filtering not enabled!\n"); printf("Warning: Nearest texture filtering not enabled!\n");
} }
// Crea la ventana // Crea la ventana
mWindow = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, VIEW_WIDTH, VIEW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); mWindow = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, mOptions->screenWidth * mOptions->windowSize, mOptions->screenHeight * mOptions->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (mWindow == NULL) if (mWindow == nullptr)
{ {
printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError()); printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false; success = false;
@@ -177,7 +151,7 @@ bool Director::initSDL()
else else
mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED); mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED);
if (mRenderer == NULL) if (mRenderer == nullptr)
{ {
printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError()); printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false; success = false;
@@ -188,7 +162,7 @@ bool Director::initSDL()
SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF); SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado // Establece el tamaño del buffer de renderizado
SDL_RenderSetLogicalSize(mRenderer, SCREEN_WIDTH, SCREEN_HEIGHT); SDL_RenderSetLogicalSize(mRenderer, mOptions->screenWidth, mOptions->screenHeight);
// Establece el modo de mezcla // Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND);
@@ -201,22 +175,88 @@ bool Director::initSDL()
} }
// Crea el indice de ficheros // Crea el indice de ficheros
void Director::setFileList() bool Director::setFileList()
{ {
// Ficheros binarios
mAsset->add("data/score.bin", data, false);
mAsset->add("data/demo.bin", data);
mAsset->add("data/config.bin", data, false);
// Musicas
mAsset->add("media/music/intro.ogg", music);
mAsset->add("media/music/playing.ogg", music);
mAsset->add("media/music/title.ogg", music);
// Sonidos
mAsset->add("media/sound/balloon.wav", sound);
mAsset->add("media/sound/bubble1.wav", sound);
mAsset->add("media/sound/bubble2.wav", sound);
mAsset->add("media/sound/bubble3.wav", sound);
mAsset->add("media/sound/bubble4.wav", sound);
mAsset->add("media/sound/bullet.wav", sound);
mAsset->add("media/sound/coffeeout.wav", sound);
mAsset->add("media/sound/hiscore.wav", sound);
mAsset->add("media/sound/itemdrop.wav", sound);
mAsset->add("media/sound/itempickup.wav", sound);
mAsset->add("media/sound/menu_cancel.wav", sound);
mAsset->add("media/sound/menu_move.wav", sound);
mAsset->add("media/sound/menu_select.wav", sound);
mAsset->add("media/sound/player_collision.wav", sound);
mAsset->add("media/sound/stage_change.wav", sound);
mAsset->add("media/sound/title.wav", sound);
mAsset->add("media/sound/clock.wav", sound);
mAsset->add("media/sound/powerball.wav", sound);
// Texturas
mAsset->add("media/gfx/balloon.png", bitmap);
mAsset->add("media/gfx/bullet.png", bitmap);
mAsset->add("media/gfx/game_bg.png", bitmap);
mAsset->add("media/gfx/game_text.png", bitmap);
mAsset->add("media/gfx/intro.png", bitmap);
mAsset->add("media/gfx/items.png", bitmap);
mAsset->add("media/gfx/logo.png", bitmap);
mAsset->add("media/gfx/player1_body.png", bitmap);
mAsset->add("media/gfx/player1_death.png", bitmap);
mAsset->add("media/gfx/player1_legs.png", bitmap);
mAsset->add("media/gfx/title.png", bitmap);
mAsset->add("media/gfx/player1_head.png", bitmap);
mAsset->add("media/gfx/player2_body.png", bitmap);
mAsset->add("media/gfx/player2_death.png", bitmap);
mAsset->add("media/gfx/player2_legs.png", bitmap);
mAsset->add("media/gfx/player2_head.png", bitmap);
// Fuentes
mAsset->add("media/font/8bithud.png", font);
mAsset->add("media/font/8bithud.txt", font);
mAsset->add("media/font/nokia.png", font);
mAsset->add("media/font/nokia_big2.png", font);
mAsset->add("media/font/nokia.txt", font);
mAsset->add("media/font/nokia2.png", font);
mAsset->add("media/font/nokia2.txt", font);
mAsset->add("media/font/nokia_big2.txt", font);
mAsset->add("media/font/smb2_big.png", font);
mAsset->add("media/font/smb2_big.txt", font);
mAsset->add("media/font/smb2.png", font);
mAsset->add("media/font/smb2.txt", font);
// Textos
mAsset->add("media/lang/es_ES.txt", lang);
mAsset->add("media/lang/en_UK.txt", lang);
mAsset->add("media/lang/ba_BA.txt", lang);
// DATA
mAsset->add("data/gamecontrollerdb.txt", data);
return mAsset->check();
// Inicializa el vector // Inicializa el vector
for (int i = 0; i < MAX_FILE_LIST; i++) /*for (int i = 0; i < MAX_FILE_LIST; i++)
mFileList[i] = ""; mFileList[i] = "";
// Ficheros binarios // Ficheros binarios
#ifdef __MIPSEL__
mFileList[0] = "/media/data/local/home/.coffee_crisis/score.bin";
mFileList[1] = "/media/data/local/home/.coffee_crisis/demo.bin";
mFileList[2] = "/media/data/local/home/.coffee_crisis/config.bin";
#else
mFileList[0] = mExecutablePath + "/" + "../data/score.bin"; mFileList[0] = mExecutablePath + "/" + "../data/score.bin";
mFileList[1] = mExecutablePath + "/" + "../data/demo.bin"; mFileList[1] = mExecutablePath + "/" + "../data/demo.bin";
mFileList[2] = mExecutablePath + "/" + "../data/config.bin"; mFileList[2] = mExecutablePath + "/" + "../data/config.bin";
#endif
// Musicas // Musicas
mFileList[3] = mExecutablePath + "/" + "../media/music/intro.ogg"; mFileList[3] = mExecutablePath + "/" + "../media/music/intro.ogg";
@@ -282,69 +322,7 @@ void Director::setFileList()
// DATA // DATA
mFileList[53] = mExecutablePath + "/" + "../data/gamecontrollerdb.txt"; mFileList[53] = mExecutablePath + "/" + "../data/gamecontrollerdb.txt";
} */
// Comprueba los ficheros del vector de ficheros que coinciden con una ruta dada
bool Director::checkFolder(std::string name, std::string path)
{
bool success = true;
std::string p;
std::string filename;
SDL_RWops *file;
// Comprueba los ficheros de la carpeta
printf("\n>> %s FILES\n", name.c_str());
for (int i = 3; i < MAX_FILE_LIST; i++)
{
if (mFileList[i].find(path.c_str()) != std::string::npos)
{
p = mFileList[i].c_str();
filename = p.substr(p.find_last_of("\\/") + 1);
file = SDL_RWFromFile(p.c_str(), "r+b");
if (file != NULL)
{
printf("Checking file %-20s [OK]\n", filename.c_str());
}
else
{
printf("Checking file %-20s [ERROR]\n", filename.c_str());
success = false;
break;
}
SDL_RWclose(file);
}
}
return success;
}
// Comprueba que todos los ficheros existen
bool Director::checkFileList()
{
bool success = true;
printf("Checking files...\n");
if (success)
success &= checkFolder("MUSIC", "/media/music/");
if (success)
success &= checkFolder("SOUND", "/media/sound/");
if (success)
success &= checkFolder("BITMAP", "/media/gfx/");
if (success)
success &= checkFolder("FONT", "/media/font/");
if (success)
success &= checkFolder("LANG", "/media/lang/");
// Resultado
if (success)
printf("\n** All files OK.\n\n");
else
printf("\n** A file is missing. Exiting.\n\n");
return success;
} }
// Carga el fichero de configuración // Carga el fichero de configuración
@@ -353,28 +331,32 @@ bool Director::loadConfigFile()
// Pone unos valores por defecto // Pone unos valores por defecto
mOptions->fullScreenMode = 0; mOptions->fullScreenMode = 0;
mOptions->windowSize = 3; mOptions->windowSize = 3;
mOptions->language = en_UK; mOptions->language = ba_BA;
mOptions->difficulty = DIFFICULTY_NORMAL; mOptions->difficulty = DIFFICULTY_NORMAL;
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD; mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER; mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
mOptions->filter = FILTER_NEAREST; mOptions->filter = FILTER_NEAREST;
mOptions->vSync = true; mOptions->vSync = true;
mOptions->screenWidth = SCREEN_WIDTH;
mOptions->screenHeight = SCREEN_HEIGHT;
mOptions->integerScale = true;
mOptions->keepAspect = true;
// Indicador de éxito en la carga // Indicador de éxito en la carga
bool success = true; bool success = true;
const std::string p = mFileList[2]; const std::string p = mAsset->get("config.bin");
std::string filename = p.substr(p.find_last_of("\\/") + 1); std::string filename = p.substr(p.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(p.c_str(), "r+b"); SDL_RWops *file = SDL_RWFromFile(p.c_str(), "r+b");
// El fichero no existe // El fichero no existe
if (file == NULL) if (file == nullptr)
{ {
printf("Warning: Unable to open %s file\n", filename.c_str()); printf("Warning: Unable to open %s file\n", filename.c_str());
// Crea el fichero para escritura // Crea el fichero para escritura
file = SDL_RWFromFile(p.c_str(), "w+b"); file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != NULL) if (file != nullptr)
{ {
printf("New file (%s) created!\n", filename.c_str()); printf("New file (%s) created!\n", filename.c_str());
@@ -387,6 +369,10 @@ bool Director::loadConfigFile()
SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1); SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWwrite(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1);
SDL_RWwrite(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1);
SDL_RWwrite(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1);
SDL_RWwrite(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1);
// Cierra el fichero // Cierra el fichero
SDL_RWclose(file); SDL_RWclose(file);
@@ -410,6 +396,10 @@ bool Director::loadConfigFile()
SDL_RWread(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); SDL_RWread(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWread(file, &mOptions->filter, sizeof(mOptions->filter), 1); SDL_RWread(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWread(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); SDL_RWread(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWread(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1);
SDL_RWread(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1);
SDL_RWread(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1);
SDL_RWread(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1);
// Normaliza los valores // Normaliza los valores
if (!((mOptions->fullScreenMode == 0) || if (!((mOptions->fullScreenMode == 0) ||
@@ -432,10 +422,10 @@ bool Director::loadConfigFile()
bool Director::saveConfigFile() bool Director::saveConfigFile()
{ {
bool success = true; bool success = true;
const std::string p = mFileList[2]; const std::string p = mAsset->get("config.bin");
std::string filename = p.substr(p.find_last_of("\\/") + 1); std::string filename = p.substr(p.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(p.c_str(), "w+b"); SDL_RWops *file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != NULL) if (file != nullptr)
{ {
// Guarda los datos // Guarda los datos
SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1); SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1);
@@ -446,6 +436,10 @@ bool Director::saveConfigFile()
SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1); SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWwrite(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1);
SDL_RWwrite(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1);
SDL_RWwrite(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1);
SDL_RWwrite(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1);
printf("Writing file %s\n", filename.c_str()); printf("Writing file %s\n", filename.c_str());
@@ -459,12 +453,6 @@ bool Director::saveConfigFile()
return success; return success;
} }
// Establece el valor de la variable
void Director::setExecutablePath(std::string path)
{
mExecutablePath = path.substr(0, path.find_last_of("\\/"));
}
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint8 Director::getSubsection() Uint8 Director::getSubsection()
{ {
@@ -485,21 +473,21 @@ void Director::setSection(section_t section)
void Director::runLogo() void Director::runLogo()
{ {
mLogo = new Logo(mRenderer, mFileList); mLogo = new Logo(mRenderer, mScreen, mAsset);
setSection(mLogo->run()); setSection(mLogo->run());
delete mLogo; delete mLogo;
} }
void Director::runIntro() void Director::runIntro()
{ {
mIntro = new Intro(mRenderer, mFileList, mLang); mIntro = new Intro(mRenderer, mScreen, mAsset, mLang);
setSection(mIntro->run()); setSection(mIntro->run());
delete mIntro; delete mIntro;
} }
void Director::runTitle() void Director::runTitle()
{ {
mTitle = new Title(mWindow, mRenderer, mInput, mFileList, mOptions, mLang); mTitle = new Title(mWindow, mRenderer, mScreen, mInput, mAsset, mOptions, mLang);
setSection(mTitle->run(mSection.subsection)); setSection(mTitle->run(mSection.subsection));
delete mTitle; delete mTitle;
} }
@@ -507,9 +495,15 @@ void Director::runTitle()
void Director::runGame() void Director::runGame()
{ {
if (mSection.subsection == GAME_SECTION_PLAY_1P) if (mSection.subsection == GAME_SECTION_PLAY_1P)
mGame = new Game(1, mRenderer, mFileList, mLang, mInput, false, mOptions); {
if (mSection.subsection == GAME_SECTION_PLAY_2P) mGame = new Game(1, 0, mRenderer, mScreen, mAsset, mLang, mInput, false, mOptions);
mGame = new Game(2, mRenderer, mFileList, mLang, mInput, false, mOptions); }
else if (mSection.subsection == GAME_SECTION_PLAY_2P)
{
mGame = new Game(2, 0, mRenderer, mScreen, mAsset, mLang, mInput, false, mOptions);
}
setSection(mGame->run()); setSection(mGame->run());
delete mGame; delete mGame;
} }
@@ -524,12 +518,15 @@ void Director::run()
case PROG_SECTION_LOGO: case PROG_SECTION_LOGO:
runLogo(); runLogo();
break; break;
case PROG_SECTION_INTRO: case PROG_SECTION_INTRO:
runIntro(); runIntro();
break; break;
case PROG_SECTION_TITLE: case PROG_SECTION_TITLE:
runTitle(); runTitle();
break; break;
case PROG_SECTION_GAME: case PROG_SECTION_GAME:
runGame(); runGame();
break; break;

View File

@@ -1,49 +1,50 @@
#pragma once #pragma once
#include "ifdefs.h"
#include "sprite.h" #include <SDL2/SDL.h>
#include "movingsprite.h" #include "asset.h"
#include "smartsprite.h"
#include "player.h"
#include "balloon.h" #include "balloon.h"
#include "bullet.h" #include "bullet.h"
#include "coffeedrop.h" #include "coffeedrop.h"
#include "item.h"
#include "text.h"
#include "writer.h"
#include "menu.h"
#include "const.h" #include "const.h"
#include "jail_audio.h" #include "fade.h"
#include "utils.h"
#include "logo.h"
#include "intro.h"
#include "title.h"
#include "game.h" #include "game.h"
#include "input.h" #include "input.h"
#include "fade.h" #include "intro.h"
//#include <math.h> #include "item.h"
#include "jail_audio.h"
#include "logo.h"
#include "menu.h"
#include "movingsprite.h"
#include "player.h"
#include "screen.h"
#include "smartsprite.h"
#include "sprite.h"
#include "text.h"
#include "title.h"
#include "utils.h"
#include "writer.h"
#ifndef DIRECTOR_H #ifndef DIRECTOR_H
#define DIRECTOR_H #define DIRECTOR_H
#define MAX_FILE_LIST 100 // Textos
#define WINDOW_CAPTION "Coffee Crisis"
// Director // Clase Director
class Director class Director
{ {
private: private:
SDL_Window *mWindow; // La ventana donde dibujamos SDL_Window *mWindow; // La ventana donde dibujamos
SDL_Renderer *mRenderer; // El renderizador de la ventana SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
Logo *mLogo; // Objeto para la sección del logo Logo *mLogo; // Objeto para la sección del logo
Intro *mIntro; // Objeto para la sección de la intro Intro *mIntro; // Objeto para la sección de la intro
Title *mTitle; // Objeto para la sección del titulo y el menu de opciones Title *mTitle; // Objeto para la sección del titulo y el menu de opciones
Game *mGame; // Objeto para la sección del juego Game *mGame; // Objeto para la sección del juego
Input *mInput; // Objeto Input para gestionar las entradas Input *mInput; // Objeto Input para gestionar las entradas
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
std::string mFileList[MAX_FILE_LIST]; // Vector con las rutas a los ficheros de recursos struct options_t *mOptions; // Variable con todas las opciones del programa
struct options_t *mOptions; // Variable con todas las opciones del programa
std::string mExecutablePath; // Path del ejecutable std::string mExecutablePath; // Path del ejecutable
section_t mSection; // Sección y subsección actual del programa; section_t mSection; // Sección y subsección actual del programa;
@@ -54,10 +55,7 @@ private:
bool initSDL(); bool initSDL();
// Crea el indice de ficheros // Crea el indice de ficheros
void setFileList(); bool setFileList();
// Comprueba que todos los ficheros existen
bool checkFileList();
// Carga el fichero de configuración // Carga el fichero de configuración
bool loadConfigFile(); bool loadConfigFile();
@@ -65,9 +63,6 @@ private:
// Guarda el fichero de configuración // Guarda el fichero de configuración
bool saveConfigFile(); bool saveConfigFile();
// Establece el valor de la variable
void setExecutablePath(std::string path);
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint8 getSubsection(); Uint8 getSubsection();
@@ -89,9 +84,6 @@ private:
// Ejecuta la seccion de juego donde se juega // Ejecuta la seccion de juego donde se juega
void runGame(); void runGame();
// Comprueba los ficheros del vector de ficheros que coinciden con una ruta dada
bool checkFolder(std::string name, std::string path);
public: public:
// Constructor // Constructor
Director(std::string path); Director(std::string path);

View File

@@ -7,7 +7,7 @@ Fade::Fade(SDL_Renderer *renderer)
mRenderer = renderer; mRenderer = renderer;
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT); mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT);
if (mBackbuffer == NULL) if (mBackbuffer == nullptr)
printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError()); printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError());
} }
@@ -25,9 +25,6 @@ void Fade::init(Uint8 r, Uint8 g, Uint8 b)
mEnabled = false; mEnabled = false;
mFinished = false; mFinished = false;
mCounter = 0; mCounter = 0;
//mR = 0x27;
//mG = 0x27;
//mB = 0x36;
mR = r; mR = r;
mG = g; mG = g;
mB = b; mB = b;
@@ -46,10 +43,10 @@ void Fade::render()
for (int i = 0; i < 256; i += 4) for (int i = 0; i < 256; i += 4)
{ {
// Dibujamos sobre el renderizador // Dibujamos sobre el renderizador
SDL_SetRenderTarget(mRenderer, NULL); SDL_SetRenderTarget(mRenderer, nullptr);
// Copia el backbuffer con la imagen que había al renderizador // Copia el backbuffer con la imagen que había al renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL); SDL_RenderCopy(mRenderer, mBackbuffer, nullptr, nullptr);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, i); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, i);
SDL_RenderFillRect(mRenderer, &mRect1); SDL_RenderFillRect(mRenderer, &mRect1);
@@ -63,7 +60,7 @@ void Fade::render()
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
SDL_RenderClear(mRenderer); SDL_RenderClear(mRenderer);
SDL_SetRenderTarget(mRenderer, NULL); SDL_SetRenderTarget(mRenderer, nullptr);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
SDL_RenderClear(mRenderer); SDL_RenderClear(mRenderer);
break; break;
@@ -106,10 +103,10 @@ void Fade::render()
SDL_RenderFillRect(mRenderer, &mRect1); SDL_RenderFillRect(mRenderer, &mRect1);
// Volvemos a usar el renderizador de forma normal // Volvemos a usar el renderizador de forma normal
SDL_SetRenderTarget(mRenderer, NULL); SDL_SetRenderTarget(mRenderer, nullptr);
// Copiamos el backbuffer al renderizador // Copiamos el backbuffer al renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL); SDL_RenderCopy(mRenderer, mBackbuffer, nullptr, nullptr);
// Volcamos el renderizador en pantalla // Volcamos el renderizador en pantalla
SDL_RenderPresent(mRenderer); SDL_RenderPresent(mRenderer);
@@ -121,7 +118,7 @@ void Fade::render()
break; break;
} }
} }
if (mFinished) if (mFinished)
{ {
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
@@ -153,16 +150,7 @@ bool Fade::isEnabled()
// Comprueba si ha terminado la transicion // Comprueba si ha terminado la transicion
bool Fade::hasEnded() bool Fade::hasEnded()
{ {
if (mFinished) return mFinished;
{
//mEnabled = false;
//mFinished = false;
return true;
}
else
{
return false;
}
} }
// Establece el tipo de fade // Establece el tipo de fade

View File

@@ -1,15 +1,17 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "ltexture.h" #include "ltexture.h"
#ifndef FADE_H #ifndef FADE_H
#define FADE_H #define FADE_H
// Tipos de fundido
#define FADE_FULLSCREEN 0 #define FADE_FULLSCREEN 0
#define FADE_CENTER 1 #define FADE_CENTER 1
#define FADE_RANDOM_SQUARE 2 #define FADE_RANDOM_SQUARE 2
// Fade // Clase Fade
class Fade class Fade
{ {
private: private:

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,62 @@
#pragma once #pragma once
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include "sprite.h" #include <SDL2/SDL.h>
#include "movingsprite.h" #include "asset.h"
#include "smartsprite.h"
#include "player.h"
#include "balloon.h" #include "balloon.h"
#include "bullet.h" #include "bullet.h"
#include "item.h" #include "const.h"
#include "text.h"
#include "writer.h"
#include "menu.h"
#include "input.h"
#include "fade.h" #include "fade.h"
#include "input.h"
#include "item.h"
#include "jail_audio.h" #include "jail_audio.h"
#include "menu.h"
#include "movingsprite.h"
#include "player.h"
#include "screen.h"
#include "smartsprite.h"
#include "sprite.h"
#include "text.h"
#include "utils.h"
#include "writer.h"
#ifndef GAME_H #ifndef GAME_H
#define GAME_H #define GAME_H
// Game // Cantidad de elementos a escribir en los ficheros de datos
#define TOTAL_SCORE_DATA 3
#define TOTAL_DEMO_DATA 2000
// Contadores
#define STAGE_COUNTER 200
#define SHAKE_COUNTER 10
#define HELP_COUNTER 1000
// Formaciones enemigas
#define NUMBER_OF_ENEMY_FORMATIONS 100
#define MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION 50
// Cantidad de elementos del vector de SmartSprites
#define MAX_SMART_SPRITES 10
// Cantidad máxima posible de balas
#define MAX_BULLETS 50
// Porcentaje de aparición de los objetos
#define ITEM_POINTS_1_DISK_ODDS 10
#define ITEM_POINTS_2_GAVINA_ODDS 6
#define ITEM_POINTS_3_PACMAR_ODDS 3
#define ITEM_CLOCK_ODDS 5
#define ITEM_COFFEE_ODDS 5
#define ITEM_POWER_BALL_ODDS 0
#define ITEM_COFFEE_MACHINE_ODDS 4
// Cantidad de objetos simultaneos
#define MAX_ITEMS 10
// Valores para las variables asociadas a los objetos
#define TIME_STOPPED_COUNTER 300
// Clase Game
class Game class Game
{ {
private: private:
@@ -40,13 +74,11 @@ private:
Uint8 numberOfEnemies; // Cantidad de enemigos que forman la formación Uint8 numberOfEnemies; // Cantidad de enemigos que forman la formación
enemyInits_t init[MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION]; // Vector con todas las inicializaciones de los enemigos de la formación enemyInits_t init[MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION]; // Vector con todas las inicializaciones de los enemigos de la formación
}; };
enemyFormation_t mEnemyFormation[NUMBER_OF_ENEMY_FORMATIONS]; // Vector con todas las formaciones enemigas
struct enemyPool_t struct enemyPool_t
{ {
enemyFormation_t *set[10]; // Conjunto de formaciones enemigas enemyFormation_t *set[10]; // Conjunto de formaciones enemigas
}; };
enemyPool_t mEnemyPool[10]; // Variable con los diferentes conjuntos de formaciones enemigas
struct stage_t // Contiene todas las variables relacionadas con una fase struct stage_t // Contiene todas las variables relacionadas con una fase
{ {
@@ -79,8 +111,26 @@ private:
int itemCoffeeMachineOdds; // Probabilidad de aparición del objeto int itemCoffeeMachineOdds; // Probabilidad de aparición del objeto
}; };
struct demo_t
{
bool enabled; // Indica si está activo el modo demo
bool recording; // Indica si está activado el modo para grabar la demo
Uint16 counter; // Contador para el modo demo
demoKeys_t keys; // Variable con las pulsaciones de teclas del modo demo
demoKeys_t dataFile[TOTAL_DEMO_DATA]; // Datos del fichero con los movimientos para la demo
};
struct debug_t
{
bool enabled; // Indica si se va a mostrar la información de debug
Uint8 enemySet; // Escoge el set enemigo a generar
Uint8 gradR, gradG, gradB; // Colores RGB para modificar el color del gradiente de fondo
float hudW, hudH; // Multiplica el tamaño del hud de debug;
};
SDL_Renderer *mRenderer; // El renderizador de la ventana SDL_Renderer *mRenderer; // El renderizador de la ventana
std::string *mFileList; // Lista de ficheros con los recursos Screen *mScreen; // Objeto encargado de dibujar en pantalla
Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
int mNumPlayers; // Numero de jugadores int mNumPlayers; // Numero de jugadores
@@ -105,17 +155,12 @@ private:
LTexture *mTexturePlayer2Body; // Textura para el cuerpo del jugador2 LTexture *mTexturePlayer2Body; // Textura para el cuerpo del jugador2
LTexture *mTexturePlayer2Death; // Textura para la animación de muerte del jugador2 LTexture *mTexturePlayer2Death; // Textura para la animación de muerte del jugador2
LTexture *mTexturePlayer2Legs; // Textura para las piernas del jugador LTexture *mTexturePlayer2Legs; // Textura para las piernas del jugador
LTexture *mTextureText; // Textura para el texto del juego
LTexture *mTextureTextScoreBoard; // Textura para el texto del marcador
LTexture *mTextureTextBig; // Textura para el texto grande
LTexture *mTextureTextNokia2; // Textura para la fuente de texto Nokia
LTexture *mTextureTextNokiaBig2; // Textura para la fuente de texto Nokia grande
Text *mText; // Fuente para los textos del juego Text *mText; // Fuente para los textos del juego
Text *mTextBig; // Fuente de texto grande Text *mTextBig; // Fuente de texto grande
Text *mTextScoreBoard; // Fuente para el marcador del juego Text *mTextScoreBoard; // Fuente para el marcador del juego
Text *mTextNokia2; // Otra fuente de texto para mesajes Text *mTextNokia2; // Otra fuente de texto para mesajes
Text *mTextNokiaBig2; // Y la versión en grande Text *mTextNokiaBig2; // Y la versión en grande
Menu *mMenuGameOver; // Menú de la pantalla de game over Menu *mMenuGameOver; // Menú de la pantalla de game over
Menu *mMenuPause; // Menú de la pantalla de pausa Menu *mMenuPause; // Menú de la pantalla de pausa
@@ -158,63 +203,47 @@ private:
Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa
Uint8 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa Uint8 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa
Uint32 mHiScore; // Puntuación máxima Uint32 mHiScore; // Puntuación máxima
bool mHiScoreAchieved; // Indica si se ha superado la puntuación máxima bool mHiScoreAchieved; // Indica si se ha superado la puntuación máxima
section_t mSection; // Seccion actual dentro del juego section_t mSection; // Seccion actual dentro del juego
stage_t mStage[10]; // Variable con los datos de cada pantalla stage_t mStage[10]; // Variable con los datos de cada pantalla
Uint8 mCurrentStage; // Indica la fase actual Uint8 mCurrentStage; // Indica la fase actual
Uint8 mStageBitmapCounter; // Contador para el tiempo visible del texto de Stage Uint8 mStageBitmapCounter; // Contador para el tiempo visible del texto de Stage
float mStageBitmapPath[STAGE_COUNTER]; // Vector con los puntos Y por donde se desplaza el texto float mStageBitmapPath[STAGE_COUNTER]; // Vector con los puntos Y por donde se desplaza el texto
float mGetReadyBitmapPath[STAGE_COUNTER]; // Vector con los puntos X por donde se desplaza el texto float mGetReadyBitmapPath[STAGE_COUNTER]; // Vector con los puntos X por donde se desplaza el texto
Uint16 mDeathCounter; // Contador para la animación de muerte del jugador Uint16 mDeathCounter; // Contador para la animación de muerte del jugador
Uint8 mDeathIndex; // Indice del vector de smartsprites que contiene el sprite del jugador Uint8 mDeathIndex; // Indice del vector de smartsprites que contiene el sprite del jugador
Uint8 mMenaceCurrent; // Nivel de amenaza actual Uint8 mMenaceCurrent; // Nivel de amenaza actual
Uint8 mMenaceThreshold; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el numero de globos Uint8 mMenaceThreshold; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el numero de globos
bool mTimeStopped; // Indica si el tiempo está detenido bool mTimeStopped; // Indica si el tiempo está detenido
Uint16 mTimeStoppedCounter; // Temporizador para llevar la cuenta del tiempo detenido Uint16 mTimeStoppedCounter; // Temporizador para llevar la cuenta del tiempo detenido
Uint8 mRemainingExplosions; // Cantidad de explosiones restantes Uint32 mCounter; // Contador para el juego
Uint16 mRemainingExplosionsCounter; // Temporizador para la cantidad de explosiones restantes Uint32 mScoreDataFile[TOTAL_SCORE_DATA]; // Datos del fichero de puntos
bool mExplosionTime; // Indica si las explosiones estan en marcha SDL_Rect mGradientRect[4]; // Vector con las coordenadas de los 4 gradientes
Uint32 mCounter; // Contador para el juego Uint16 mBalloonsPopped; // Lleva la cuenta de los globos explotados
Uint32 mScoreDataFile[TOTAL_SCORE_DATA]; // Datos del fichero de puntos Uint8 mLastEnemyDeploy; // Guarda cual ha sido la última formación desplegada para no repetir;
SDL_Rect mGradientRect[4]; // Vector con las coordenadas de los 4 gradientes int mEnemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
Uint16 mBalloonsPopped; // Lleva la cuenta de los globos explotados float mEnemySpeed; // Velocidad a la que se mueven los enemigos
Uint8 mLastEnemyDeploy; // Guarda cual ha sido la última formación desplegada para no repetir; float mDefaultEnemySpeed; // Velocidad base de los enemigos, sin incrementar
Uint8 mEnemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero effect_t mEffect; // Variable para gestionar los efectos visuales
float mEnemySpeed; // Velocidad a la que se mueven los enemigos helper_t mHelper; // Variable para gestionar las ayudas
float mDefaultEnemySpeed; // Velocidad base de los enemigos, sin incrementar bool mPowerBallEnabled; // Indica si hay una powerball ya activa
effect_t mEffect; // Variable para gestionar los efectos visuales Uint8 mPowerBallCounter; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
helper_t mHelper; // Variable para gestionar las ayudas bool mCoffeeMachineEnabled; // Indica si hay una máquina de café en el terreno de juego
bool mPowerBallEnabled; // Indica si hay una powerball ya activa Uint8 mPostFade; // Qué hacer al acabar el fade
Uint8 mPowerBallCounter; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra float mSin[360]; // Vector con los valores del seno para 360 grados
bool mCoffeeMachineEnabled; // Indica si hay una máquina de café en el terreno de juego bool mGameCompleted; // Indica si se ha completado la partida, llegando al final de la ultima pantalla
Uint8 mPostFade; // Qué hacer al acabar el fade int mGameCompletedCounter; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos
float mSin[360]; // Vector con los valores del seno para 360 grados Uint8 mDifficulty; // Dificultad del juego
bool mGameCompleted; // Indica si se ha completado la partida, llegando al final de la ultima pantalla float mDifficultyScoreMultiplier; // Multiplicador de puntos en función de la dificultad
int mGameCompletedCounter; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos struct options_t *mOptions; // Variable con todas las variables de las opciones del programa
Uint8 mDifficulty; // Dificultad del juego Uint8 mOnePlayerControl; // Variable para almacenar el valor de las opciones
float mDifficultyScoreMultiplier; // Multiplicador de puntos en función de la dificultad enemyFormation_t mEnemyFormation[NUMBER_OF_ENEMY_FORMATIONS]; // Vector con todas las formaciones enemigas
struct options_t *mOptions; // Variable con todas las variables de las opciones del programa enemyPool_t mEnemyPool[10]; // Variable con los diferentes conjuntos de formaciones enemigas
Uint8 mOnePlayerControl; // Variable para almacenar el valor de las opciones Uint8 mLastStageReached; // Contiene el numero de la última pantalla que se ha alcanzado
struct demo_t demo_t mDemo; // Variable con todas las variables relacionadas con el modo demo
{ debug_t mDebug; // Variable con las opciones de debug
bool enabled; // Indica si está activo el modo demo
bool recording; // Indica si está activado el modo para grabar la demo
Uint16 counter; // Contador para el modo demo
demoKeys_t keys; // Variable con las pulsaciones de teclas del modo demo
demoKeys_t dataFile[TOTAL_DEMO_DATA]; // Datos del fichero con los movimientos para la demo
};
demo_t mDemo; // Variable con todas las variables relacionadas con el modo demo
struct debug_t
{
bool enabled; // Indica si se va a mostrar la información de debug
Uint8 enemySet; // Escoge el set enemigo a generar
Uint8 gradR, gradG, gradB; // Colores RGB para modificar el color del gradiente de fondo
float hudW, hudH; // Multiplica el tamaño del hud de debug;
};
debug_t mDebug;
// Inicializa el vector con los valores del seno // Inicializa el vector con los valores del seno
void initSin(); void initSin();
@@ -426,18 +455,6 @@ private:
// Actualiza y comprueba el valor de la variable // Actualiza y comprueba el valor de la variable
void updateTimeStoppedCounter(); void updateTimeStoppedCounter();
// Establece el valor de la variable
void setExplosionTime(bool value);
// Obtiene el valor de la variable
bool isExplosionTime();
// Establece el valor de la variable
void setRemainingExplosions(Uint8 value);
// Actualiza y comprueba el valor de la variable
void updateRemainingExplosionsCounter();
// Gestiona el nivel de amenaza // Gestiona el nivel de amenaza
void updateMenace(); void updateMenace();
@@ -453,9 +470,6 @@ private:
// Dibuja el campo de juego // Dibuja el campo de juego
void renderPlayField(); void renderPlayField();
// Gestiona las entradas desde el mando de juego
bool checkGameController(Uint8 state);
// Gestiona la entrada durante el juego // Gestiona la entrada durante el juego
void checkGameInput(); void checkGameInput();
@@ -500,7 +514,7 @@ private:
public: public:
// Constructor // Constructor
Game(int numPlayers, SDL_Renderer *renderer, std::string *filelist, Lang *lang, Input *input, bool demo, options_t *options); Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang, Input *input, bool demo, options_t *options);
// Destructor // Destructor
~Game(); ~Game();

View File

@@ -1,21 +0,0 @@
#ifdef _WIN64
#include "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++\SDL2\SDL.h"
#endif
#ifdef _WIN32
#include "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++\SDL2\SDL.h"
#endif
#ifdef __APPLE__
#include "/Library/Frameworks/SDL2.framework/Versions/A/Headers/SDL.h"
#endif
#ifdef __linux__
#ifdef __MIPSEL__
#include "SDL.h"
#else
#include <SDL2/SDL.h>
#endif
#endif
#define UNUSED

View File

@@ -1,9 +1,6 @@
#include "input.h" #include "input.h"
#include <iostream> #include <iostream>
// Contestar cuantos joystics ha detectado
// Preguntarlepor los joystics que ha encontrado para ir poniendolos en la variable de opciones
// Constructor // Constructor
Input::Input(std::string file) Input::Input(std::string file)
{ {
@@ -53,7 +50,7 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
if ((device == INPUT_USE_KEYBOARD) || (device == INPUT_USE_ANY)) if ((device == INPUT_USE_KEYBOARD) || (device == INPUT_USE_ANY))
{ {
const Uint8 *mKeystates = SDL_GetKeyboardState(NULL); const Uint8 *mKeystates = SDL_GetKeyboardState(nullptr);
if (repeat) if (repeat)
{ {

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -49,11 +50,10 @@ private:
}; };
GameControllerBindings_t mGameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos GameControllerBindings_t mGameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
//SDL_GameController *mGameController; // Manejador para el mando std::vector<SDL_GameController *> mConnectedControllers; // Vector con todos los mandos conectados
std::vector<SDL_GameController*> mConnectedControllers; std::vector<std::string> mControllerNames; // Vector con los nombres de los mandos
std::vector<std::string> mControllerNames; int mNumGamepads; // Numero de mandos conectados
int mNumGamepads; std::string mDBpath; // Ruta al archivo gamecontrollerdb.txt
std::string mDBpath; // Ruta al archivo gamecontrollerdb.txt
// Comprueba si hay un mando conectado // Comprueba si hay un mando conectado
bool discoverGameController(); bool discoverGameController();
@@ -72,7 +72,7 @@ public:
void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button); void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button);
// Comprueba si un input esta activo // Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat, int device=INPUT_USE_ANY, int index=0); bool checkInput(Uint8 input, bool repeat, int device = INPUT_USE_ANY, int index = 0);
// Comprueba si hay algun mando conectado // Comprueba si hay algun mando conectado
bool gameControllerFound(); bool gameControllerFound();

View File

@@ -1,43 +1,42 @@
#include "instructions.h" #include "instructions.h"
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#endif
const Uint8 SELF = 0; const Uint8 SELF = 0;
// Constructor // Constructor
Instructions::Instructions(SDL_Renderer *renderer, std::string *fileList, Lang *lang) Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang)
{ {
// Copia los punteros // Copia los punteros
mRenderer = renderer; mRenderer = renderer;
mFileList = fileList; mScreen = screen;
this->mAsset = mAsset;
mLang = lang; mLang = lang;
// Reserva memoria para los punteros // Reserva memoria para los punteros
mEventHandler = new SDL_Event(); mEventHandler = new SDL_Event();
mItemTexture = new LTexture(); mItemTexture = new LTexture(mRenderer);
mTextTexture = new LTexture(); mSprite = new Sprite(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, mItemTexture, mRenderer);
mSprite = new Sprite(); mText = new Text(mAsset->get("smb2.png"), mAsset->get("smb2.txt"), mRenderer);
mText = new Text(mFileList[48], mTextTexture, mRenderer);
// Crea un backbuffer para el renderizador // Crea un backbuffer para el renderizador
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT); mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT);
if (mBackbuffer == NULL) if (mBackbuffer == nullptr)
{
printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError()); printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError());
}
} }
// Destructor // Destructor
Instructions::~Instructions() Instructions::~Instructions()
{ {
mRenderer = nullptr;
mScreen = nullptr;
mAsset = nullptr;
mLang = nullptr;
mItemTexture->unload(); mItemTexture->unload();
delete mItemTexture; delete mItemTexture;
mItemTexture = nullptr; mItemTexture = nullptr;
mTextTexture->unload();
delete mTextTexture;
mTextTexture = nullptr;
delete mSprite; delete mSprite;
mSprite = nullptr; mSprite = nullptr;
@@ -56,8 +55,7 @@ bool Instructions::loadMedia()
{ {
bool success = true; bool success = true;
success &= loadTextureFromFile(mItemTexture, mFileList[34], mRenderer); success &= loadTextureFromFile(mItemTexture, mAsset->get("items.png"), mRenderer);
success &= loadTextureFromFile(mTextTexture, mFileList[30], mRenderer);
return success; return success;
} }
@@ -70,7 +68,6 @@ void Instructions::init()
// Inicializa variables // Inicializa variables
mSection.name = SELF; mSection.name = SELF;
mSprite->init(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, mItemTexture, mRenderer);
mTicks = 0; mTicks = 0;
mTicksSpeed = 15; mTicksSpeed = 15;
mManualQuit = false; mManualQuit = false;
@@ -172,35 +169,35 @@ void Instructions::run(Uint8 mode)
mText->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, SCREEN_HEIGHT - 12, mLang->getText(22), 1, orangeColor, 1, shdwTxtColor); mText->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, SCREEN_HEIGHT - 12, mLang->getText(22), 1, orangeColor, 1, shdwTxtColor);
// Disquito // Disquito
mSprite->init(destRect1, mItemTexture, mRenderer); mSprite->setPos(destRect1);
srcRect.x = 0; srcRect.x = 0;
srcRect.y = 16 * (((mCounter + 12) / 36) % 2); srcRect.y = 16 * (((mCounter + 12) / 36) % 2);
mSprite->setSpriteClip(srcRect); mSprite->setSpriteClip(srcRect);
mSprite->render(); mSprite->render();
// Gavineixon // Gavineixon
mSprite->init(destRect2, mItemTexture, mRenderer); mSprite->setPos(destRect2);
srcRect.x += srcRect.w; srcRect.x += srcRect.w;
srcRect.y = 16 * (((mCounter + 9) / 36) % 2); srcRect.y = 16 * (((mCounter + 9) / 36) % 2);
mSprite->setSpriteClip(srcRect); mSprite->setSpriteClip(srcRect);
mSprite->render(); mSprite->render();
// Pacmar // Pacmar
mSprite->init(destRect3, mItemTexture, mRenderer); mSprite->setPos(destRect3);
srcRect.x += srcRect.w; srcRect.x += srcRect.w;
srcRect.y = 16 * (((mCounter + 6) / 36) % 2); srcRect.y = 16 * (((mCounter + 6) / 36) % 2);
mSprite->setSpriteClip(srcRect); mSprite->setSpriteClip(srcRect);
mSprite->render(); mSprite->render();
// Time Stopper // Time Stopper
mSprite->init(destRect4, mItemTexture, mRenderer); mSprite->setPos(destRect4);
srcRect.x += srcRect.w; srcRect.x += srcRect.w;
srcRect.y = 16 * (((mCounter + 3) / 36) % 2); srcRect.y = 16 * (((mCounter + 3) / 36) % 2);
mSprite->setSpriteClip(srcRect); mSprite->setSpriteClip(srcRect);
mSprite->render(); mSprite->render();
// Coffee // Coffee
mSprite->init(destRect5, mItemTexture, mRenderer); mSprite->setPos(destRect5);
srcRect.x += (srcRect.w * 2); // Se salta el icono del TNT srcRect.x += (srcRect.w * 2); // Se salta el icono del TNT
srcRect.y = 16 * (((mCounter + 0) / 36) % 2); srcRect.y = 16 * (((mCounter + 0) / 36) % 2);
mSprite->setSpriteClip(srcRect); mSprite->setSpriteClip(srcRect);
@@ -209,9 +206,11 @@ void Instructions::run(Uint8 mode)
// Cambia el destino de renderizado // Cambia el destino de renderizado
SDL_SetRenderTarget(mRenderer, nullptr); SDL_SetRenderTarget(mRenderer, nullptr);
// Limpia el renderizador // Prepara para empezar a dibujar en la textura de juego
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); mScreen->start();
SDL_RenderClear(mRenderer);
// Limpia la pantalla
mScreen->clean(bgColor);
// Establece la ventana del backbuffer // Establece la ventana del backbuffer
if (mode == INSTRUCTIONS_MODE_AUTO) if (mode == INSTRUCTIONS_MODE_AUTO)
@@ -220,9 +219,9 @@ void Instructions::run(Uint8 mode)
window.y = 0; window.y = 0;
// Copia el backbuffer al renderizador // Copia el backbuffer al renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, &window); SDL_RenderCopy(mRenderer, mBackbuffer, nullptr, &window);
// Dibuja el renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
SDL_RenderPresent(mRenderer); mScreen->blit();
} }
} }

View File

@@ -1,26 +1,35 @@
#pragma once #pragma once
#include "ifdefs.h"
#include "utils.h"
#include "const.h"
#include <SDL2/SDL.h>
#include "asset.h"
#include "const.h"
#include "jail_audio.h"
#include "screen.h"
#include "sprite.h" #include "sprite.h"
#include "text.h" #include "text.h"
#include "jail_audio.h" #include "utils.h"
#ifndef INSTRUCTIONS_H #ifndef INSTRUCTIONS_H
#define INSTRUCTIONS_H #define INSTRUCTIONS_H
// Instructions // Contadores
#define INSTRUCTIONS_COUNTER 600
// Modo para las instrucciones
#define INSTRUCTIONS_MODE_MANUAL 0
#define INSTRUCTIONS_MODE_AUTO 1
// Clase Instructions
class Instructions class Instructions
{ {
private: private:
LTexture *mItemTexture; // Textura con los graficos
LTexture *mTextTexture; // Textura con los graficos
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Renderer *mRenderer; // El renderizador de la ventana SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
LTexture *mItemTexture; // Textura con los graficos
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Texture *mBackbuffer; // Textura para usar como backbuffer SDL_Texture *mBackbuffer; // Textura para usar como backbuffer
Sprite *mSprite; // Sprite con la textura de las instrucciones Sprite *mSprite; // Sprite con la textura de las instrucciones
std::string *mFileList; // Lista de ficheros Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
Text *mText; // Objeto para escribir texto Text *mText; // Objeto para escribir texto
Uint16 mCounter; // Contador Uint16 mCounter; // Contador
@@ -43,7 +52,7 @@ private:
public: public:
// Constructor // Constructor
Instructions(SDL_Renderer *renderer, std::string *fileList, Lang *lang); Instructions(SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang);
// Destructor // Destructor
~Instructions(); ~Instructions();

View File

@@ -1,33 +1,38 @@
#include "intro.h" #include "intro.h"
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#endif
// Constructor // Constructor
Intro::Intro(SDL_Renderer *renderer, std::string *fileList, Lang *lang) Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang)
{ {
// Copia los punteros // Copia los punteros
mRenderer = renderer; mRenderer = renderer;
mFileList = fileList; mScreen = screen;
mLang = lang; mLang = lang;
this->mAsset = mAsset;
// Reserva memoria para los punteros // Reserva memoria para los punteros
mEventHandler = new SDL_Event(); mEventHandler = new SDL_Event();
mBitmapTexture = new LTexture(); mBitmapTexture = new LTexture(mRenderer);
mTextTexture = new LTexture(); mText = new Text(mAsset->get("nokia.png"), mAsset->get("nokia.txt"), mRenderer);
mText = new Text(mFileList[52], mTextTexture, mRenderer);
for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++) for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++)
{
mBitmap[i] = new SmartSprite(); mBitmap[i] = new SmartSprite();
}
for (int i = 0; i < INTRO_TOTAL_TEXTS; i++) for (int i = 0; i < INTRO_TOTAL_TEXTS; i++)
{
mWriter[i] = new Writer(mText); mWriter[i] = new Writer(mText);
}
} }
// Destructor // Destructor
Intro::~Intro() Intro::~Intro()
{ {
mRenderer = nullptr;
mScreen = nullptr;
mAsset = nullptr;
mLang = nullptr;
delete mEventHandler; delete mEventHandler;
mEventHandler = nullptr; mEventHandler = nullptr;
@@ -35,15 +40,12 @@ Intro::~Intro()
delete mBitmapTexture; delete mBitmapTexture;
mBitmapTexture = nullptr; mBitmapTexture = nullptr;
mTextTexture->unload();
delete mTextTexture;
mTextTexture = nullptr;
for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++) for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++)
{ {
delete mBitmap[i]; delete mBitmap[i];
mBitmap[i] = nullptr; mBitmap[i] = nullptr;
} }
for (int i = 0; i < INTRO_TOTAL_TEXTS; i++) for (int i = 0; i < INTRO_TOTAL_TEXTS; i++)
{ {
delete mWriter[i]; delete mWriter[i];
@@ -181,9 +183,7 @@ void Intro::init()
mWriter[8]->setSpeed(20); mWriter[8]->setSpeed(20);
for (int i = 0; i < INTRO_TOTAL_TEXTS; i++) for (int i = 0; i < INTRO_TOTAL_TEXTS; i++)
{
mWriter[i]->center(SCREEN_CENTER_X); mWriter[i]->center(SCREEN_CENTER_X);
}
} }
// Carga los recursos // Carga los recursos
@@ -192,11 +192,10 @@ bool Intro::loadMedia()
bool success = true; bool success = true;
// Texturas // Texturas
success &= loadTextureFromFile(mBitmapTexture, mFileList[33], mRenderer); success &= loadTextureFromFile(mBitmapTexture, mAsset->get("intro.png"), mRenderer);
success &= loadTextureFromFile(mTextTexture, mFileList[28], mRenderer);
// Musicas // Musicas
mMusic = JA_LoadMusic(mFileList[3].c_str()); mMusic = JA_LoadMusic(mAsset->get("intro.ogg").c_str());
return success; return success;
} }
@@ -206,42 +205,46 @@ section_t Intro::run()
{ {
init(); init();
// Si la música no está sonando // Si la música no está sonando la hace sonar
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED)) if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{ {
// Reproduce la música
JA_PlayMusic(mMusic, 0); JA_PlayMusic(mMusic, 0);
} }
while (mSection.name == PROG_SECTION_INTRO) while (mSection.name == PROG_SECTION_INTRO)
{ {
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(mEventHandler) != 0)
{
// Evento de salida de la aplicación
if (mEventHandler->type == SDL_QUIT)
{
mSection.name = PROG_SECTION_QUIT;
break;
}
if ((mEventHandler->type == SDL_KEYDOWN) || (mEventHandler->type == SDL_JOYBUTTONDOWN))
{
JA_StopMusic();
mSection = {PROG_SECTION_TITLE, TITLE_SECTION_1};
}
}
// Actualiza las variables
if (SDL_GetTicks() - mTicks > mTicksSpeed) if (SDL_GetTicks() - mTicks > mTicksSpeed)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
mTicks = SDL_GetTicks(); mTicks = SDL_GetTicks();
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(mEventHandler) != 0)
{
// Evento de salida de la aplicación
if (mEventHandler->type == SDL_QUIT)
{
mSection.name = PROG_SECTION_QUIT;
break;
}
if ((mEventHandler->type == SDL_KEYDOWN) || (mEventHandler->type == SDL_JOYBUTTONDOWN))
{
JA_StopMusic();
mSection = {PROG_SECTION_TITLE, TITLE_SECTION_1};
}
}
// Actualiza los objetos // Actualiza los objetos
for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++) for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++)
{
mBitmap[i]->update(); mBitmap[i]->update();
}
for (int i = 0; i < INTRO_TOTAL_TEXTS; i++) for (int i = 0; i < INTRO_TOTAL_TEXTS; i++)
{
mWriter[i]->update(); mWriter[i]->update();
}
// Guión de eventos // Guión de eventos
// Primera imagen - UPV // Primera imagen - UPV
@@ -356,18 +359,24 @@ section_t Intro::run()
} }
} }
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla // Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 0xFF); mScreen->clean(bgColor);
SDL_RenderClear(mRenderer);
// Dibuja los objetos // Dibuja los objetos
for (int i = 0; i < INTRO_TOTAL_BITMAPS; i++) for (int i = 0; i < INTRO_TOTAL_BITMAPS; ++i)
{
mBitmap[i]->render(); mBitmap[i]->render();
for (int i = 0; i < INTRO_TOTAL_TEXTS; i++) }
for (int i = 0; i < INTRO_TOTAL_TEXTS; ++i)
{
mWriter[i]->render(); mWriter[i]->render();
}
// Actualiza la pantalla // Vuelca el contenido del renderizador en pantalla
SDL_RenderPresent(mRenderer); mScreen->blit();
} }
return mSection; return mSection;

View File

@@ -1,24 +1,48 @@
#pragma once #pragma once
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include "smartsprite.h" #include <SDL2/SDL.h>
#include "writer.h" #include "asset.h"
#include "const.h"
#include "jail_audio.h" #include "jail_audio.h"
#include "screen.h"
#include "smartsprite.h"
#include "utils.h"
#include "writer.h"
#ifndef INTRO_H #ifndef INTRO_H
#define INTRO_H #define INTRO_H
// Intro // Cantidad de eventos de la intro
#define INTRO_TOTAL_BITMAPS 6
#define INTRO_TOTAL_TEXTS 9
const int INTRO_TOTAL_EVENTS = INTRO_TOTAL_BITMAPS + INTRO_TOTAL_TEXTS;
// Relaciones de Id con nombres
#define BITMAP0 0
#define BITMAP1 1
#define BITMAP2 2
#define BITMAP3 3
#define BITMAP4 4
#define BITMAP5 5
#define TEXT0 6
#define TEXT1 7
#define TEXT2 8
#define TEXT3 9
#define TEXT4 10
#define TEXT5 11
#define TEXT6 12
#define TEXT7 13
#define TEXT8 14
// Clase Intro
class Intro class Intro
{ {
private: private:
LTexture *mBitmapTexture; // Textura con los graficos
LTexture *mTextTexture; // Textura con los caracteres de texto
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Renderer *mRenderer; // El renderizador de la ventana SDL_Renderer *mRenderer; // El renderizador de la ventana
std::string *mFileList; // Lista de ficheros Screen *mScreen; // Objeto encargado de dibujar en pantalla
LTexture *mBitmapTexture; // Textura con los graficos
SDL_Event *mEventHandler; // Manejador de eventos
Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
section_t mSection; // Estado del bucle principal para saber si continua o se sale section_t mSection; // Estado del bucle principal para saber si continua o se sale
Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa
@@ -29,9 +53,12 @@ private:
Uint8 mEvents[INTRO_TOTAL_EVENTS]; // Vector para coordinar los eventos de la intro Uint8 mEvents[INTRO_TOTAL_EVENTS]; // Vector para coordinar los eventos de la intro
JA_Music mMusic; // Musica para la intro JA_Music mMusic; // Musica para la intro
// Carga los recursos
bool loadMedia();
public: public:
// Constructor // Constructor
Intro(SDL_Renderer *renderer, std::string *fileList, Lang *lang); Intro(SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang);
// Destructor // Destructor
~Intro(); ~Intro();
@@ -39,9 +66,6 @@ public:
// Inicializa las variables // Inicializa las variables
void init(); void init();
// Carga los recursos
bool loadMedia();
// Bucle principal // Bucle principal
section_t run(); section_t run();
}; };

View File

@@ -1,24 +1,12 @@
#include "const.h" #include "const.h"
#include "item.h" #include "item.h"
#include <stdio.h>
// Constructor // Constructor
Item::Item() Item::Item(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *renderer)
{ {
mSprite = new AnimatedSprite(); mSprite = new AnimatedSprite(texture, renderer);
mClass = NO_KIND; mClass = NO_KIND;
}
// Destructor
Item::~Item()
{
delete mSprite;
mSprite = nullptr;
}
// Iniciador
void Item::init(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *renderer)
{
mClass = value; mClass = value;
mEnabled = true; mEnabled = true;
mTimeToLive = 600; mTimeToLive = 600;
@@ -34,12 +22,10 @@ void Item::init(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *
mCollider.r = mWidth / 2; mCollider.r = mWidth / 2;
shiftColliders(); shiftColliders();
mSprite->init(texture, renderer);
mSprite->setAnimationFrames(0, 0, 0, 48, mWidth, mHeight); mSprite->setAnimationFrames(0, 0, 0, 48, mWidth, mHeight);
mSprite->setAnimationFrames(0, 1, 0, 64, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 0, 64, mWidth, mHeight);
mSprite->setCurrentFrame(0); mSprite->setCurrentFrame(0);
mSprite->setAnimationCounter(0); mSprite->setAnimationCounter(0);
mSprite->setAnimationNumFrames(0, 2);
mSprite->setAnimationSpeed(0, 10); mSprite->setAnimationSpeed(0, 10);
mSprite->setAnimationLoop(0, true); mSprite->setAnimationLoop(0, true);
mSprite->setSpriteClip(mSprite->getAnimationClip(0, 0)); mSprite->setSpriteClip(mSprite->getAnimationClip(0, 0));
@@ -92,7 +78,6 @@ void Item::init(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *
mVelX = 0.0f; mVelX = 0.0f;
mVelY = -0.1f; mVelY = -0.1f;
mAccelY = 0.1f; mAccelY = 0.1f;
mSprite->setAnimationNumFrames(0, 4);
mSprite->setAnimationFrames(0, 0, 32 * 0, 16 * 2, mWidth, mHeight); mSprite->setAnimationFrames(0, 0, 32 * 0, 16 * 2, mWidth, mHeight);
mSprite->setAnimationFrames(0, 1, 32 * 1, 16 * 2, mWidth, mHeight); mSprite->setAnimationFrames(0, 1, 32 * 1, 16 * 2, mWidth, mHeight);
mSprite->setAnimationFrames(0, 2, 32 * 2, 16 * 2, mWidth, mHeight); mSprite->setAnimationFrames(0, 2, 32 * 2, 16 * 2, mWidth, mHeight);
@@ -108,6 +93,13 @@ void Item::init(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *
} }
} }
// Destructor
Item::~Item()
{
delete mSprite;
mSprite = nullptr;
}
// Centra el objeto en la posición X // Centra el objeto en la posición X
void Item::allignTo(int x) void Item::allignTo(int x)
{ {
@@ -203,7 +195,7 @@ void Item::move()
// Pone a cero todos los valores del objeto // Pone a cero todos los valores del objeto
void Item::erase() void Item::erase()
{ {
init(NO_KIND, 0, 0, nullptr, nullptr); //init(NO_KIND, 0, 0, nullptr, nullptr);
} }
// Actualiza el objeto a su posicion, animación y controla los contadores // Actualiza el objeto a su posicion, animación y controla los contadores
@@ -286,8 +278,6 @@ circle_t &Item::getCollider()
// Alinea el circulo de colisión con la posición del objeto // Alinea el circulo de colisión con la posición del objeto
void Item::shiftColliders() void Item::shiftColliders()
{ {
//mCollider.x = int(mPosX + mCollider.r);
//mCollider.y = int(mPosY + mCollider.r);
mCollider.x = int(mPosX + (mWidth / 2)); mCollider.x = int(mPosX + (mWidth / 2));
mCollider.y = int(mPosY + (mHeight / 2)); mCollider.y = int(mPosY + (mHeight / 2));
} }

View File

@@ -1,24 +1,34 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "animatedsprite.h" #include "animatedsprite.h"
#include "utils.h" #include "utils.h"
#ifndef ITEM_H #ifndef ITEM_H
#define ITEM_H #define ITEM_H
// Clase AnimatedSprite // Tipos de objetos
#define ITEM_POINTS_1_DISK 1
#define ITEM_POINTS_2_GAVINA 2
#define ITEM_POINTS_3_PACMAR 3
#define ITEM_CLOCK 4
#define ITEM_COFFEE 5
#define ITEM_POWER_BALL 6
#define ITEM_COFFEE_MACHINE 7
// Clase Item
class Item class Item
{ {
private: private:
float mPosX; // Posición X del objeto float mPosX; // Posición X del objeto
float mPosY; // Posición Y del objeto float mPosY; // Posición Y del objeto
Uint8 mWidth; // Ancho del objeto Uint8 mWidth; // Ancho del objeto
Uint8 mHeight; // Alto del objeto Uint8 mHeight; // Alto del objeto
float mVelX; // Velocidad en el eje X float mVelX; // Velocidad en el eje X
float mVelY; // Velocidad en el eje Y float mVelY; // Velocidad en el eje Y
float mAccelX; // Aceleración en el eje X float mAccelX; // Aceleración en el eje X
float mAccelY; // Aceleración en el eje Y float mAccelY; // Aceleración en el eje Y
bool mFloorCollision; // Indica si el objeto colisiona con el suelo bool mFloorCollision; // Indica si el objeto colisiona con el suelo
AnimatedSprite *mSprite; // Sprite con los graficos del objeto AnimatedSprite *mSprite; // Sprite con los graficos del objeto
@@ -30,15 +40,14 @@ private:
void shiftColliders(); void shiftColliders();
public: public:
Uint16 mTimeToLive; // Temporizador con el tiempo que el objeto está presente
// Constructor // Constructor
Item(); Item(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *renderer);
// Destructor // Destructor
~Item(); ~Item();
// Iniciador
void init(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *renderer);
// Centra el objeto en la posición X // Centra el objeto en la posición X
void allignTo(int x); void allignTo(int x);
@@ -84,9 +93,6 @@ public:
// Obtiene el circulo de colisión // Obtiene el circulo de colisión
circle_t &getCollider(); circle_t &getCollider();
// Temporizador con el tiempo que el objeto está presente
Uint16 mTimeToLive;
// Informa si el objeto ha colisionado con el suelo // Informa si el objeto ha colisionado con el suelo
bool floorCollision(); bool floorCollision();
}; };

View File

@@ -1,6 +1,7 @@
#ifndef __MIPSEL__
#include "jail_audio.h" #include "jail_audio.h"
#include "stb_vorbis.c" #include "stb_vorbis.c"
#include <SDL2/SDL.h>
#include <stdio.h>
#define JA_MAX_SIMULTANEOUS_CHANNELS 5 #define JA_MAX_SIMULTANEOUS_CHANNELS 5
@@ -30,16 +31,17 @@ JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000}; int JA_freq {48000};
SDL_AudioFormat JA_format {AUDIO_S16}; SDL_AudioFormat JA_format {AUDIO_S16};
Uint8 JA_channels {2}; Uint8 JA_channels {2};
int JA_volume = 128;
void audioCallback(void * userdata, uint8_t * stream, int len) { void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memset(stream, 0, len); SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) { if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
const int size = SDL_min(len, current_music->samples*2-current_music->pos); const int size = SDL_min(len, current_music->samples*2-current_music->pos);
SDL_memcpy(stream, current_music->output+current_music->pos, size); SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_volume);
current_music->pos += size/2; current_music->pos += size/2;
if (size < len) { if (size < len) {
if (current_music->times != 0) { if (current_music->times != 0) {
SDL_memcpy(stream+size, current_music->output, len-size); SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, JA_volume);
current_music->pos = (len-size)/2; current_music->pos = (len-size)/2;
if (current_music->times > 0) current_music->times--; if (current_music->times > 0) current_music->times--;
} else { } else {
@@ -52,11 +54,11 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].state == JA_CHANNEL_PLAYING) { if (channels[i].state == JA_CHANNEL_PLAYING) {
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos); const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, 64); SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_volume/2);
channels[i].pos += size; channels[i].pos += size;
if (size < len) { if (size < len) {
if (channels[i].times != 0) { if (channels[i].times != 0) {
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, 64); SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_volume/2);
channels[i].pos = len-size; channels[i].pos = len-size;
if (channels[i].times > 0) channels[i].times--; if (channels[i].times > 0) channels[i].times--;
} else { } else {
@@ -79,7 +81,19 @@ void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
JA_Music JA_LoadMusic(const char* filename) { JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate; int chan, samplerate;
JA_Music music = new JA_Music_t(); JA_Music music = new JA_Music_t();
music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
FILE *f = fopen(filename, "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
Uint8 *buffer = (Uint8*)malloc(fsize + 1);
fread(buffer, fsize, 1, f);
fclose(f);
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
free(buffer);
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
SDL_AudioCVT cvt; SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq); SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
@@ -134,6 +148,13 @@ void JA_DeleteMusic(JA_Music music) {
delete music; delete music;
} }
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length) {
JA_Sound sound = new JA_Sound_t();
sound->buffer = buffer;
sound->length = length;
return sound;
}
JA_Sound JA_LoadSound(const char* filename) { JA_Sound JA_LoadSound(const char* filename) {
JA_Sound sound = new JA_Sound_t(); JA_Sound sound = new JA_Sound_t();
SDL_AudioSpec wavSpec; SDL_AudioSpec wavSpec;
@@ -210,4 +231,8 @@ JA_Channel_state JA_GetChannelState(const int channel) {
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID; if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state; return channels[channel].state;
} }
#endif
int JA_SetVolume(int volume) {
JA_volume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return JA_volume;
}

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED }; enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED };
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED }; enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED };
@@ -17,6 +17,7 @@ void JA_StopMusic();
JA_Music_state JA_GetMusicState(); JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music music); void JA_DeleteMusic(JA_Music music);
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound JA_LoadSound(const char* filename); JA_Sound JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound sound, const int loop = 0); int JA_PlaySound(JA_Sound sound, const int loop = 0);
void JA_PauseChannel(const int channel); void JA_PauseChannel(const int channel);
@@ -24,3 +25,5 @@ void JA_ResumeChannel(const int channel);
void JA_StopChannel(const int channel); void JA_StopChannel(const int channel);
JA_Channel_state JA_GetChannelState(const int channel); JA_Channel_state JA_GetChannelState(const int channel);
void JA_DeleteSound(JA_Sound sound); void JA_DeleteSound(JA_Sound sound);
int JA_SetVolume(int volume);

View File

@@ -1,106 +0,0 @@
#ifdef __MIPSEL__
#include "jail_audio.h"
#include "SDL_mixer.h"
struct JA_Sound_t {
Mix_Chunk *mix_chunk;
};
struct JA_Music_t {
Mix_Music* mix_music;
};
JA_Music current_music{NULL};
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
Mix_AllocateChannels(8);
}
JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate;
JA_Music music = new JA_Music_t();
music->mix_music = Mix_LoadMUS(filename);
return music;
}
void JA_PlayMusic(JA_Music music, const int loop) {
if (current_music == music) return;
if (current_music != NULL) {
Mix_HaltMusic();
}
current_music = music;
Mix_PlayMusic(music->mix_music, loop);
}
void JA_PauseMusic() {
Mix_PauseMusic();
}
void JA_ResumeMusic() {
Mix_ResumeMusic();
}
void JA_StopMusic() {
Mix_HaltMusic();
}
JA_Music_state JA_GetMusicState() {
if (current_music == NULL) return JA_MUSIC_INVALID;
if (Mix_PausedMusic()) {
return JA_MUSIC_PAUSED;
} else if (Mix_PlayingMusic()) {
return JA_MUSIC_PLAYING;
} else {
return JA_MUSIC_STOPPED;
}
}
void JA_DeleteMusic(JA_Music music) {
if (current_music == music) {
Mix_HaltMusic();
current_music = NULL;
}
Mix_FreeMusic(music->mix_music);
delete music;
}
JA_Sound JA_LoadSound(const char* filename) {
JA_Sound sound = new JA_Sound_t();
sound->mix_chunk = Mix_LoadWAV(filename);
return sound;
}
int JA_PlaySound(JA_Sound sound, const int loop) {
int channel = Mix_PlayChannel(-1, sound->mix_chunk, loop);
return channel;
}
void JA_DeleteSound(JA_Sound sound) {
Mix_FreeChunk(sound->mix_chunk);
delete sound;
}
void JA_PauseChannel(const int channel) {
Mix_Pause(channel);
}
void JA_ResumeChannel(const int channel) {
Mix_Resume(channel);
}
void JA_StopChannel(const int channel) {
Mix_HaltChannel(channel);
}
JA_Channel_state JA_GetChannelState(const int channel) {
if (Mix_Paused(channel)) {
return JA_CHANNEL_PAUSED;
} else if (Mix_Playing(channel)) {
return JA_CHANNEL_PLAYING;
} else {
return JA_CHANNEL_FREE;
}
}
#endif

View File

@@ -3,9 +3,9 @@
#include <fstream> #include <fstream>
// Constructor // Constructor
Lang::Lang(std::string *fileList) Lang::Lang(Asset *mAsset)
{ {
mFileList = fileList; this->mAsset = mAsset;
} }
// Destructor // Destructor
@@ -21,19 +21,19 @@ bool Lang::setLang(Uint8 lang)
switch (lang) switch (lang)
{ {
case es_ES: case es_ES:
file = mFileList[49]; file = mAsset->get("es_ES.txt");
break; break;
case en_UK: case en_UK:
file = mFileList[50]; file = mAsset->get("en_UK.txt");
break; break;
case ba_BA: case ba_BA:
file = mFileList[51]; file = mAsset->get("ba_BA.txt");
break; break;
default: default:
file = mFileList[50]; file = mAsset->get("en_UK.txt");
break; break;
} }

View File

@@ -1,11 +1,13 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "asset.h"
#include <string> #include <string>
#ifndef LANG_H #ifndef LANG_H
#define LANG_H #define LANG_H
// Lang codes // Códigos de idioma
#define es_ES 0 #define es_ES 0
#define ba_BA 1 #define ba_BA 1
#define en_UK 2 #define en_UK 2
@@ -18,15 +20,15 @@
class Lang class Lang
{ {
private: private:
std::string *mFileList; // Lista de ficheros con los recursos Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
std::string mTextStrings[MAX_TEXT_STRINGS]; std::string mTextStrings[MAX_TEXT_STRINGS]; // Vector con los textos
public: public:
// Constructor // Constructor
Lang(std::string *fileList); Lang(Asset *mAsset);
// Destructor // Destructor
~Lang(); ~Lang();
// Inicializa los textos del juego en el idioma seleccionado // Inicializa los textos del juego en el idioma seleccionado
bool setLang(Uint8 lang); bool setLang(Uint8 lang);

View File

@@ -1,146 +1,157 @@
#include "logo.h" #include "logo.h"
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#endif
# define INIT_FADE 100 #define INIT_FADE 100
# define END_LOGO 200 #define END_LOGO 200
// Constructor // Constructor
Logo::Logo(SDL_Renderer *renderer, std::string *fileList) Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset)
{ {
// Copia la dirección del renderizador // Copia la dirección de los objetos
mRenderer = renderer; this->renderer = renderer;
this->screen = screen;
// Copia la dirección del la lista de ficheros this->asset = asset;
mFileList = fileList;
// Reserva memoria para los punteros // Reserva memoria para los punteros
mEventHandler = new SDL_Event(); eventHandler = new SDL_Event();
mTexture = new LTexture(); texture = new LTexture(renderer,asset->get("logo.png");
mSprite = new Sprite(); sprite = new Sprite(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, texture, renderer);
// Crea un backbuffer para el renderizador // Crea un backbuffer para el renderizador
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT); backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT);
if (mBackbuffer == NULL) if (backbuffer == nullptr)
{
printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError()); printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError());
}
// Inicializa variables
counter = 0;
section.name = PROG_SECTION_LOGO;
section.subsection = 0;
ticks = 0;
ticksSpeed = 15;
} }
// Destructor // Destructor
Logo::~Logo() Logo::~Logo()
{ {
mTexture->unload(); SDL_DestroyTexture(backbuffer);
delete mTexture;
mTexture = nullptr;
delete mSprite; texture->unload();
mSprite = nullptr; delete texture;
delete mEventHandler; delete sprite;
mEventHandler = nullptr; delete eventHandler;
SDL_DestroyTexture(mBackbuffer);
mBackbuffer = nullptr;
} }
// Inicializa las variables necesarias para la sección 'Logo' // Comprueba si ha terminado el logo
void Logo::init() void Logo::checkLogoEnd()
{ {
// Carga los recursos if (counter == 0)
loadMedia(); {
if (JA_GetMusicState() == JA_MUSIC_PLAYING)
{
JA_StopMusic();
}
}
// Inicializa variables if (counter == END_LOGO + 20)
mCounter = 0; {
mSection.name = PROG_SECTION_LOGO; counter = 0;
mSection.subsection = 0; section.name = PROG_SECTION_INTRO;
mSprite->init(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, mTexture, mRenderer); section.subsection = 0;
mTicks = 0; }
mTicksSpeed = 15; else
{
counter++;
}
} }
// Carga los recursos necesarios para la sección 'Logo' // Comprueba los eventos
bool Logo::loadMedia() void Logo::checkEventHandler()
{ {
bool success = true; // Comprueba los eventos que hay en la cola
while (SDL_PollEvent(eventHandler) != 0)
{
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = PROG_SECTION_QUIT;
break;
}
success &= loadTextureFromFile(mTexture, mFileList[35], mRenderer); // Cualquier tecla pulsada
if ((eventHandler->type == SDL_KEYDOWN) || (eventHandler->type == SDL_JOYBUTTONDOWN))
{
section.name = PROG_SECTION_TITLE;
section.subsection = TITLE_SECTION_1;
}
}
}
return success; // Dibuja el fade
void Logo::renderFade()
{
const SDL_Rect rect = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
const int fadeLenght = END_LOGO - INIT_FADE;
// Dibuja el fade
if (counter >= INIT_FADE)
{
const Uint16 alpha = (255 * (counter - INIT_FADE)) / fadeLenght;
if (alpha < 256)
{
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, alpha);
}
else
{
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255);
}
SDL_RenderFillRect(renderer, &rect);
}
}
// Actualiza las variables del objeto
void Logo::update()
{
checkEventHandler();
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba si ha terminado el logo
checkLogoEnd();
}
}
// Dibuja el objeto en pantalla
void Logo::render()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean(bgColor);
// Dibuja los objetos
sprite->render();
// Dibuja el fade
renderFade();
// Vuelca el contenido del renderizador en pantalla
screen->blit();
} }
// Bucle para el logo del juego // Bucle para el logo del juego
section_t Logo::run() section_t Logo::run()
{ {
init(); while (section.name == PROG_SECTION_LOGO)
const SDL_Rect rect = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
const int fadeLenght = END_LOGO - INIT_FADE;
while (mSection.name == PROG_SECTION_LOGO)
{ {
// Comprueba los eventos que hay en la cola update();
while (SDL_PollEvent(mEventHandler) != 0) render();
{
// Evento de salida de la aplicación
if (mEventHandler->type == SDL_QUIT)
{
mSection.name = PROG_SECTION_QUIT;
break;
}
// Cualquier tecla pulsada
if ((mEventHandler->type == SDL_KEYDOWN) || (mEventHandler->type == SDL_JOYBUTTONDOWN))
{
mSection.name = PROG_SECTION_TITLE;
mSection.subsection = TITLE_SECTION_1;
}
}
// Limpia el destino
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(mRenderer);
// Dibuja los objetos
mSprite->render();
// Dibuja el fade
if (mCounter >= INIT_FADE)
{
Uint16 alpha = (255 * (mCounter - INIT_FADE)) / fadeLenght;
if (alpha < 256)
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, alpha);
else
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderFillRect(mRenderer, &rect);
}
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
// Comprueba si ha terminado el logo
if (SDL_GetTicks() - mTicks > mTicksSpeed)
{
// Actualiza el contador de ticks
mTicks = SDL_GetTicks();
if (mCounter == 0)
{
if (JA_GetMusicState() == JA_MUSIC_PLAYING)
JA_StopMusic();
}
if (mCounter == END_LOGO + 20)
{
mCounter = 0;
mSection.name = PROG_SECTION_INTRO;
mSection.subsection = 0;
}
else
{
mCounter++;
}
}
} }
return mSection; return section;
} }

View File

@@ -1,42 +1,54 @@
#pragma once #pragma once
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include "sprite.h" #include <SDL2/SDL.h>
#include "asset.h"
#include "const.h"
#include "jail_audio.h" #include "jail_audio.h"
#include "screen.h"
#include "sprite.h"
#include "utils.h"
#ifndef LOGO_H #ifndef LOGO_H
#define LOGO_H #define LOGO_H
// Logo // Clase Logo
class Logo class Logo
{ {
private: private:
LTexture *mTexture; // Textura con los graficos SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Event *mEventHandler; // Manejador de eventos Screen *screen; // Objeto encargado de dibujar en pantalla
SDL_Renderer *mRenderer; // El renderizador de la ventana Asset *asset; // Objeto que gestiona todos los ficheros de recursos
SDL_Texture *mBackbuffer; // Textura para usar como backbuffer LTexture *texture; // Textura con los graficos
Sprite *mSprite; // Sprite con la textura del logo SDL_Event *eventHandler; // Manejador de eventos
std::string *mFileList; // Lista de ficheros SDL_Texture *backbuffer; // Textura para usar como backbuffer
Uint16 mCounter; // Contador Sprite *sprite; // Sprite con la textura del logo
section_t mSection; // Estado del bucle principal para saber si continua o se sale int counter; // Contador
Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa section_t section; // Estado del bucle principal para saber si continua o se sale
Uint8 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
// Actualiza las variables del objeto
void update();
// Dibuja el objeto en pantalla
void render();
// Comprueba si ha terminado el logo
void checkLogoEnd();
// Comprueba los eventos
void checkEventHandler();
// Dibuja el fade
void renderFade();
public: public:
// Constructor // Constructor
Logo(SDL_Renderer *renderer, std::string *fileList); Logo(SDL_Renderer *renderer, Screen *screen, Asset *mAsset);
// Destructor // Destructor
~Logo(); ~Logo();
// Inicializa las variables
void init();
// Carga los recursos
bool loadMedia();
// Bucle principal // Bucle principal
section_t run(); section_t run();
}; };

View File

@@ -1,28 +1,41 @@
#include "const.h"
#include "ltexture.h" #include "ltexture.h"
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"
LTexture::LTexture() // Constructor
LTexture::LTexture(SDL_Renderer *renderer, std::string path)
{ {
// Initialize // Copia punteros
mTexture = NULL; this->renderer = renderer;
mWidth = 0; this->path = path;
mHeight = 0;
// Inicializa
texture = nullptr;
width = 0;
height = 0;
// Carga el fichero en la textura
if (path != "")
{
loadFromFile(path, renderer);
}
} }
// Destructor
LTexture::~LTexture() LTexture::~LTexture()
{ {
// Deallocate // Libera memoria
unload(); unload();
} }
// Carga una imagen desde un fichero
bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer) bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
{ {
int req_format = STBI_rgb_alpha; int req_format = STBI_rgb_alpha;
int width, height, orig_format; int width, height, orig_format;
unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format); unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format);
if (data == NULL) if (data == nullptr)
{ {
SDL_Log("Loading image failed: %s", stbi_failure_reason()); SDL_Log("Loading image failed: %s", stbi_failure_reason());
exit(1); exit(1);
@@ -33,7 +46,7 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
if (req_format == STBI_rgb) if (req_format == STBI_rgb)
{ {
depth = 24; depth = 24;
pitch = 3 * width; // 3 bytes per pixel * pixels per row pitch = 3 * width; // 3 bytes por pixel * pixels per linea
pixel_format = SDL_PIXELFORMAT_RGB24; pixel_format = SDL_PIXELFORMAT_RGB24;
} }
else else
@@ -43,100 +56,99 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
pixel_format = SDL_PIXELFORMAT_RGBA32; pixel_format = SDL_PIXELFORMAT_RGBA32;
} }
// Get rid of preexisting texture // Limpia
unload(); unload();
// The final texture // La textura final
SDL_Texture *newTexture = NULL; SDL_Texture *newTexture = nullptr;
// Load image at specified path // Carga la imagen desde una ruta específica
//SDL_Surface *loadedSurface = IMG_Load(path.c_str());
SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format); SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format);
if (loadedSurface == NULL) if (loadedSurface == nullptr)
{ {
printf("Unable to load image %s!\n", path.c_str()); printf("Unable to load image %s!\n", path.c_str());
} }
else else
{ {
// Color key image // Crea la textura desde los pixels de la surface
//SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, COLOR_KEY_R, COLOR_KEY_G, COLOR_KEY_B));
// Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if (newTexture == NULL) if (newTexture == nullptr)
{ {
printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
} }
else else
{ {
// Get image dimensions // Obtiene las dimensiones de la imagen
mWidth = loadedSurface->w; this->width = loadedSurface->w;
mHeight = loadedSurface->h; this->height = loadedSurface->h;
} }
// Get rid of old loaded surface // Elimina la textura cargada
SDL_FreeSurface(loadedSurface); SDL_FreeSurface(loadedSurface);
} }
// Return success // Return success
mTexture = newTexture; texture = newTexture;
return mTexture != NULL; return texture != nullptr;
} }
// Crea una textura en blanco
bool LTexture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) bool LTexture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access)
{ {
// Create uninitialized texture // Crea una textura sin inicializar
mTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
if (mTexture == NULL) if (texture == nullptr)
{ {
printf("Unable to create blank texture! SDL Error: %s\n", SDL_GetError()); printf("Unable to create blank texture! SDL Error: %s\n", SDL_GetError());
} }
else else
{ {
mWidth = width; this->width = width;
mHeight = height; this->height = height;
} }
return mTexture != NULL; return texture != nullptr;
} }
// Libera la memoria de la textura
void LTexture::unload() void LTexture::unload()
{ {
// Free texture if it exists // Libera la textura si existe
if (mTexture != NULL) if (texture != nullptr)
{ {
SDL_DestroyTexture(mTexture); SDL_DestroyTexture(texture);
mTexture = NULL; texture = nullptr;
mWidth = 0; width = 0;
mHeight = 0; height = 0;
} }
} }
// Establece el color para la modulacion
void LTexture::setColor(Uint8 red, Uint8 green, Uint8 blue) void LTexture::setColor(Uint8 red, Uint8 green, Uint8 blue)
{ {
// Modulate texture rgb SDL_SetTextureColorMod(texture, red, green, blue);
SDL_SetTextureColorMod(mTexture, red, green, blue);
} }
// Establece el blending
void LTexture::setBlendMode(SDL_BlendMode blending) void LTexture::setBlendMode(SDL_BlendMode blending)
{ {
// Set blending function SDL_SetTextureBlendMode(texture, blending);
SDL_SetTextureBlendMode(mTexture, blending);
} }
// Establece el alpha para la modulación
void LTexture::setAlpha(Uint8 alpha) void LTexture::setAlpha(Uint8 alpha)
{ {
// Modulate texture alpha SDL_SetTextureAlphaMod(texture, alpha);
SDL_SetTextureAlphaMod(mTexture, alpha);
} }
// Renderiza la textura en un punto específico
void LTexture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float zoomW, float zoomH, double angle, SDL_Point *center, SDL_RendererFlip flip) void LTexture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float zoomW, float zoomH, double angle, SDL_Point *center, SDL_RendererFlip flip)
{ {
// Set rendering space and render to screen // Establece el destini de renderizado en la pantalla
SDL_Rect renderQuad = {x, y, mWidth, mHeight}; SDL_Rect renderQuad = {x, y, width, height};
// Set clip rendering dimensions // Obtiene las dimesiones del clip de renderizado
if (clip != NULL) if (clip != nullptr)
{ {
renderQuad.w = clip->w; renderQuad.w = clip->w;
renderQuad.h = clip->h; renderQuad.h = clip->h;
@@ -145,22 +157,30 @@ void LTexture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, floa
renderQuad.w = renderQuad.w * zoomW; renderQuad.w = renderQuad.w * zoomW;
renderQuad.h = renderQuad.h * zoomH; renderQuad.h = renderQuad.h * zoomH;
// Render to screen // Renderiza a pantalla
SDL_RenderCopyEx(renderer, mTexture, clip, &renderQuad, angle, center, flip); SDL_RenderCopyEx(renderer, texture, clip, &renderQuad, angle, center, flip);
} }
// Establece la textura como objetivo de renderizado
void LTexture::setAsRenderTarget(SDL_Renderer *renderer) void LTexture::setAsRenderTarget(SDL_Renderer *renderer)
{ {
// Make self render target SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderTarget(renderer, mTexture);
} }
// Obtiene el ancho de la imagen
int LTexture::getWidth() int LTexture::getWidth()
{ {
return mWidth; return width;
} }
// Obtiene el alto de la imagen
int LTexture::getHeight() int LTexture::getHeight()
{ {
return mHeight; return height;
} }
// Recarga la textura
bool LTexture::reLoad()
{
return loadFromFile(path, renderer);
}

View File

@@ -1,66 +1,61 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#ifndef LTEXTURE_H #ifndef LTEXTURE_H
#define LTEXTURE_H #define LTEXTURE_H
// Texture wrapper class // Clase LTexture
class LTexture class LTexture
{ {
public: private:
// Initializes variables SDL_Texture *texture; // La textura
LTexture(); SDL_Renderer *renderer; // Renderizador donde dibujar la textura
int width; // Ancho de la imagen
int height; // Alto de la imagen
std::string path; // Ruta de la imagen de la textura
// Deallocates memory public:
// Constructor
LTexture(SDL_Renderer *renderer, std::string path = "");
// Destructor
~LTexture(); ~LTexture();
// Loads image at specified path // Carga una imagen desde un fichero
bool loadFromFile(std::string path, SDL_Renderer *renderer); bool loadFromFile(std::string path, SDL_Renderer *renderer);
// Creates blank texture // Crea una textura en blanco
bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING); bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING);
// Deallocates texture // Libera la memoria de la textura
void unload(); void unload();
// Set color modulation // Establece el color para la modulacion
void setColor(Uint8 red, Uint8 green, Uint8 blue); void setColor(Uint8 red, Uint8 green, Uint8 blue);
// Set blending // Establece el blending
void setBlendMode(SDL_BlendMode blending); void setBlendMode(SDL_BlendMode blending);
// Set alpha modulation // Establece el alpha para la modulación
void setAlpha(Uint8 alpha); void setAlpha(Uint8 alpha);
// Renders texture at given point // Renderiza la textura en un punto específico
void render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip = NULL, float zoomW = 1, float zoomH = 1, double angle = 0.0, SDL_Point *center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE); void render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip = nullptr, float zoomW = 1, float zoomH = 1, double angle = 0.0, SDL_Point *center = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE);
// Set self as render target // Establece la textura como objetivo de renderizado
void setAsRenderTarget(SDL_Renderer *renderer); void setAsRenderTarget(SDL_Renderer *renderer);
// Gets image dimensions // Obtiene el ancho de la imagen
int getWidth(); int getWidth();
// Obtiene el alto de la imagen
int getHeight(); int getHeight();
// Pixel manipulators // Recarga la textura
bool lockTexture(); bool reLoad();
bool unlockTexture();
void *getPixels();
void copyPixels(void *pixels);
int getPitch();
Uint32 getPixel32(unsigned int x, unsigned int y);
private:
// The actual hardware texture
SDL_Texture *mTexture;
void *mPixels;
int mPitch;
// Image dimensions
int mWidth;
int mHeight;
}; };
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,95 +1,112 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <vector>
#include "sprite.h" #include "sprite.h"
#include "text.h" #include "text.h"
#include "asset.h"
#include "input.h" #include "input.h"
#include "utils.h"
#include "jail_audio.h" #include "jail_audio.h"
#include <sstream>
#include <fstream>
#ifndef MENU_H #ifndef MENU_H
#define MENU_H #define MENU_H
#define MENU_MAX_ITEMS 50 // Tipos de fondos para el menu
#define MENU_BACKGROUND_TRANSPARENT 0
#define MENU_BACKGROUND_SOLID 1
// Clase menu // Tipos de archivos de audio
#define SOUND_ACCEPT 0
#define SOUND_MOVE 1
#define SOUND_CANCEL 2
// Opciones de menu
#define MENU_NO_OPTION -1
// Clase Menu
class Menu class Menu
{ {
private: private:
std::string mName; // Nombre del menu struct rectangle_t
int mPosX; // Posición en el eje X de la primera letra del primer elemento
int mPosY; // Posición en el eje Y de la primera letra del primer elemento
Uint16 mHeight; // Altura del menu
Uint16 mWidth; // Anchura del menu
Uint8 mTotalItems; // Numero total de items del menu
int mItemSelected; // Índice del item del menu que ha sido seleccionado
Uint8 mDefaultActionWhenCancel; // Indice del item del menu que se selecciona cuando se cancela el menu
Uint8 mBackgroundType; // Tipo de fondo para el menu
bool mIsCenteredOnX; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X
bool mIsCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y
int mCenterX; // Centro del menu en el eje X
int mCenterY; // Centro del menu en el eje Y
bool mAreElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X
Uint16 mWidestItem; // Anchura del elemento más ancho
JA_Sound mSoundAccept; // Sonido al aceptar o elegir una opción del menu
JA_Sound mSoundCancel; // Sonido al cancelar el menu
JA_Sound mSoundMove; // Sonido al mover el selector
SDL_Renderer *mRenderer; // Puntero al renderizador de la ventana
std::string *mFileList; // Lista de ficheros
Text *mText; // Texto para poder escribir los items del menu
Input *mInput; // Gestor de eventos de entrada de teclado o gamepad
color_t mColorGreyed; // Color para los elementos agrisados
struct rectangle
{ {
SDL_Rect rect; // Rectangulo SDL_Rect rect; // Rectangulo
Uint8 r; // Rojo color_t color; // Color
Uint8 g; // Verde int a; // Transparencia
Uint8 b; // Azul
Uint8 a; // Transparencia
}; };
rectangle mRectBG; // Rectangulo de fondo del menu
struct item struct item_t
{ {
std::string label; // Texto std::string label; // Texto
SDL_Rect rect; // Rectangulo que delimita el elemento SDL_Rect rect; // Rectangulo que delimita el elemento
Uint8 hPaddingDown; // Espaciado bajo el elemento int hPaddingDown; // Espaciado bajo el elemento
bool selectable; // Indica si se puede seleccionar bool selectable; // Indica si se puede seleccionar
bool greyed; // Indica si ha de aparecer con otro color mas oscuro bool greyed; // Indica si ha de aparecer con otro color mas oscuro
bool linkedDown; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector bool linkedDown; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector
bool linkedUp; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector bool linkedUp; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector
}; };
item mItem[MENU_MAX_ITEMS]; // Estructura para cada elemento del menu
struct selector struct selector_t
{ {
float originY; // Coordenada de origen float originY; // Coordenada de origen
float targetY; // Coordenada de destino float targetY; // Coordenada de destino
float despY; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps float despY; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps
bool moving; // Indica si el selector está avanzando hacia el destino bool moving; // Indica si el selector está avanzando hacia el destino
float originH; // Altura de origen float originH; // Altura de origen
float targetH; // Altura de destino float targetH; // Altura de destino
float incH; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto float incH; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto
bool resizing; // Indica si el selector está cambiando de tamaño bool resizing; // Indica si el selector está cambiando de tamaño
float y; // Coordenada actual, usado para el desplazamiento float y; // Coordenada actual, usado para el desplazamiento
float h; // Altura actual, usado para el cambio de tamaño float h; // Altura actual, usado para el cambio de tamaño
Uint8 numJumps; // Numero de pasos preestablecido para llegar al destino int numJumps; // Numero de pasos preestablecido para llegar al destino
Uint8 index; // Elemento del menu que tiene el foco int index; // Elemento del menu que tiene el foco
SDL_Rect rect; // Rectangulo del selector SDL_Rect rect; // Rectangulo del selector
Uint8 r; // Cantidad de color rojo para el rectangulo del selector color_t color; // Color del selector
Uint8 g; // Cantidad de color verde para el rectangulo del selector color_t itemColor; // Color del item
Uint8 b; // Cantidad de color azul para el rectangulo del selector int a; // Cantidad de transparencia para el rectangulo del selector
Uint8 a; // Cantidad de transparencia para el rectangulo del selector
Uint8 itemR; // Cantidad de color rojo para el texto del elemento seleccionado
Uint8 itemG; // Cantidad de color verde para el texto del elemento seleccionado
Uint8 itemB; // Cantidad de color azul para el texto del elemento seleccionado
}; };
selector mSelector; // Variables para pintar el selector del menu
// Carga los recursos necesarios para la sección 'Title' std::string name; // Nombre del menu
bool loadMedia(); int x; // Posición en el eje X de la primera letra del primer elemento
int y; // Posición en el eje Y de la primera letra del primer elemento
int h; // Altura del menu
int w; // Anchura del menu
int itemSelected; // Índice del item del menu que ha sido seleccionado
int defaultActionWhenCancel; // Indice del item del menu que se selecciona cuando se cancela el menu
int backgroundType; // Tipo de fondo para el menu
int centerX; // Centro del menu en el eje X
int centerY; // Centro del menu en el eje Y
bool isCenteredOnX; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X
bool isCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y
bool areElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X
int widestItem; // Anchura del elemento más ancho
JA_Sound soundAccept; // Sonido al aceptar o elegir una opción del menu
JA_Sound soundCancel; // Sonido al cancelar el menu
JA_Sound soundMove; // Sonido al mover el selector
SDL_Renderer *renderer; // Puntero al renderizador de la ventana
Text *text; // Texto para poder escribir los items del menu
Input *input; // Gestor de eventos de entrada de teclado o gamepad
Asset *asset; // Objeto para gestionar los ficheros de recursos
color_t colorGreyed; // Color para los elementos agrisados
rectangle_t rectBG; // Rectangulo de fondo del menu
std::vector<item_t> item; // Estructura para cada elemento del menu
selector_t selector; // Variables para pintar el selector del menu
std::string font_png;
std::string font_txt;
// Establece el valor de la variable // Carga la configuración del menu desde un archivo de texto
void setTotalItems(int num); bool load(std::string file_path);
// Asigna variables a partir de dos cadenas
bool setVars(std::string var, std::string value);
// Asigna variables a partir de dos cadenas
bool setItem(item_t *item, std::string var, std::string value);
// Inicializa las variables
void init();
// Establece el rectangulo de fondo del menu // Establece el rectangulo de fondo del menu
void setRectSize(); void setRectSize();
@@ -107,16 +124,16 @@ private:
void updateSelector(); void updateSelector();
// Obtiene la anchura del elemento más ancho del menu // Obtiene la anchura del elemento más ancho del menu
Uint16 getWidestItem(); int getWidestItem();
// Gestiona la entrada de teclado y mando durante el menu // Gestiona la entrada de teclado y mando durante el menu
void checkMenuInput(Menu *menu); void checkMenuInput(Menu *menu);
// Calcula el ancho del menu // Calcula el ancho del menu
Uint16 findWidth(); int findWidth();
// Calcula el alto del menu // Calcula el alto del menu
Uint16 findHeight(); int findHeight();
// Recoloca los elementos del menu en el eje Y // Recoloca los elementos del menu en el eje Y
void replaceElementsOnY(); void replaceElementsOnY();
@@ -126,19 +143,19 @@ private:
public: public:
// Constructor // Constructor
Menu(SDL_Renderer *renderer, Text *text, Input *input, std::string *fileList); Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file="");
// Destructor // Destructor
~Menu(); ~Menu();
// Inicializador // Carga los ficheros de audio
void init(std::string name, int x, int y, int backgroundType); void loadAudioFile(std::string file, int sound);
// Obtiene el nombre del menu // Obtiene el nombre del menu
std::string getName(); std::string getName();
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint8 getItemSelected(); int getItemSelected();
// Deja el menu apuntando al primer elemento // Deja el menu apuntando al primer elemento
void reset(); void reset();
@@ -153,13 +170,13 @@ public:
void render(); void render();
// Establece el color del rectangulo de fondo // Establece el color del rectangulo de fondo
void setBackgroundColor(int r, int g, int b, int alpha); void setBackgroundColor(color_t color, int alpha);
// Establece el color del rectangulo del selector // Establece el color del rectangulo del selector
void setSelectorColor(int r, int g, int b, int alpha); void setSelectorColor(color_t color, int alpha);
// Establece el color del texto del selector // Establece el color del texto del selector
void setSelectorTextColor(int r, int g, int b); void setSelectorTextColor(color_t color);
// Centra el menu respecto a un punto en el eje X // Centra el menu respecto a un punto en el eje X
void centerMenuOnX(int value); void centerMenuOnX(int value);
@@ -171,25 +188,37 @@ public:
void centerMenuElementsOnX(); void centerMenuElementsOnX();
// Añade un item al menu // Añade un item al menu
void addItem(std::string text, Uint8 hPaddingDown = 1, bool selectable = true, bool greyed = false, bool linkedDown = false); void addItem(std::string text, int hPaddingDown = 1, bool selectable = true, bool greyed = false, bool linkedDown = false);
// Cambia el texto de un item // Cambia el texto de un item
void setItemCaption(Uint8 index, std::string text); void setItemCaption(int index, std::string text);
// Establece el indice del item que se usará por defecto al cancelar el menu // Establece el indice del item que se usará por defecto al cancelar el menu
void setDefaultActionWhenCancel(Uint8 item); void setDefaultActionWhenCancel(int item);
// Coloca el selector en una posición específica // Coloca el selector en una posición específica
void setSelectorPos(Uint8 index); void setSelectorPos(int index);
// Establece el estado seleccionable de un item // Establece el estado seleccionable de un item
void setSelectable(Uint8 index, bool value); void setSelectable(int index, bool value);
// Establece el estado agrisado de un item // Establece el estado agrisado de un item
void setGreyed(Uint8 index, bool value); void setGreyed(int index, bool value);
// Establece el estado de enlace de un item // Establece el estado de enlace de un item
void setLinkedDown(Uint8 index, bool value); void setLinkedDown(int index, bool value);
// Establece el nombre del menu
void setName(std::string name);
// Establece la posición del menu
void setPos(int x, int y);
// Establece el tipo de fondo del menu
void setBackgroundType(int value);
// hacer procedimientos para establecer el titulo, la x, la y, la tipografia y el tipo de fondo
}; };
#endif #endif

View File

@@ -2,244 +2,256 @@
#include "movingsprite.h" #include "movingsprite.h"
// Constructor // Constructor
MovingSprite::MovingSprite() MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, LTexture *texture, SDL_Renderer *renderer)
{ {
clear(); // Copia los punteros
} this->texture = texture;
this->renderer = renderer;
// Establece el alto y el ancho del sprite
this->w = w;
this->h = h;
// Establece la posición X,Y del sprite
this->x = x;
this->y = y;
xPrev = x;
yPrev = y;
// Establece la velocidad X,Y del sprite
vx = velx;
vy = vely;
// Establece la aceleración X,Y del sprite
ax = accelx;
ay = accely;
// Establece el zoom W,H del sprite
zoomW = 1;
zoomH = 1;
// Establece el angulo con el que se dibujará
angle = (double)0;
// Establece los valores de rotacion
rotateEnabled = false;
rotateSpeed = 0;
rotateAmount = (double)0;
// Contador interno
counter = 0;
// Establece el rectangulo de donde coger la imagen
spriteClip = {0, 0, w, h};
// Establece el centro de rotación
center = {0, 0};
// Establece el tipo de volteado
currentFlip = SDL_FLIP_NONE;
};
// Destructor // Destructor
MovingSprite::~MovingSprite() MovingSprite::~MovingSprite()
{ {
clear();
} }
// Reinicia todas las variables // Reinicia todas las variables
void MovingSprite::clear() void MovingSprite::clear()
{ {
mPosX = 0.0f; // Posición en el eje X x = 0.0f; // Posición en el eje X
mPosY = 0.0f; // Posición en el eje Y y = 0.0f; // Posición en el eje Y
mVelX = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse vx = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
mVelY = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse vy = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
mAccelX = 0.0f; // Aceleración en el eje X. Variación de la velocidad ax = 0.0f; // Aceleración en el eje X. Variación de la velocidad
mAccelY = 0.0f; // Aceleración en el eje Y. Variación de la velocidad ay = 0.0f; // Aceleración en el eje Y. Variación de la velocidad
mZoomW = 1.0f; // Zoom aplicado a la anchura zoomW = 1.0f; // Zoom aplicado a la anchura
mZoomH = 1.0f; // Zoom aplicado a la altura zoomH = 1.0f; // Zoom aplicado a la altura
mAngle = 0.0; // Angulo para dibujarlo angle = 0.0; // Angulo para dibujarlo
mRotate = false; // Indica si ha de rotar rotateEnabled = false; // Indica si ha de rotar
mRotateSpeed = 0; // Velocidad de giro center = {0, 0}; // Centro de rotación
mRotateAmount = 0.0; // Cantidad de grados a girar en cada iteración rotateSpeed = 0; // Velocidad de giro
mCounter = 0; // Contador interno rotateAmount = 0.0; // Cantidad de grados a girar en cada iteración
} counter = 0; // Contador interno
// Iniciador currentFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
void MovingSprite::init(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, LTexture *texture, SDL_Renderer *renderer)
{
// Establece el alto y el ancho del sprite
setWidth(w);
setHeight(h);
// Establece la posición X,Y del sprite
setPosX(x);
setPosY(y);
// Establece la velocidad X,Y del sprite
setVelX(velx);
setVelY(vely);
// Establece la aceleración X,Y del sprite
setAccelX(accelx);
setAccelY(accely);
// Establece el zoom W,H del sprite
setZoomW(1);
setZoomH(1);
// Establece el angulo con el que se dibujará
setAngle(0.0);
// Establece los valores de rotacion
setRotate(false);
setRotateSpeed(0);
setRotateAmount(0.0);
// Contador interno
mCounter = 0;
// Establece la textura donde están los gráficos para el sprite
setTexture(texture);
// Establece el renderizador
setRenderer(renderer);
// Establece el rectangulo de donde coger la imagen
setSpriteClip(0, 0, w, h);
} }
// Mueve el sprite // Mueve el sprite
void MovingSprite::move() void MovingSprite::move()
{ {
if (mEnabled) if (enabled)
{ {
mPosX += mVelX; xPrev = x;
mPosY += mVelY; yPrev = y;
mVelX += mAccelX; x += vx;
mVelY += mAccelY; y += vy;
vx += ax;
vy += ay;
} }
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void MovingSprite::render() void MovingSprite::render()
{ {
if (mEnabled) if (enabled)
mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle); texture->render(renderer, (int)x, (int)y, &spriteClip, zoomW, zoomH, angle, &center, currentFlip);
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getPosX() float MovingSprite::getPosX()
{ {
return mPosX; return x;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getPosY() float MovingSprite::getPosY()
{ {
return mPosY; return y;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getVelX() float MovingSprite::getVelX()
{ {
return mVelX; return vx;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getVelY() float MovingSprite::getVelY()
{ {
return mVelY; return vy;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getAccelX() float MovingSprite::getAccelX()
{ {
return mAccelX; return ax;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getAccelY() float MovingSprite::getAccelY()
{ {
return mAccelY; return ay;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getZoomW() float MovingSprite::getZoomW()
{ {
return mZoomW; return zoomW;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getZoomH() float MovingSprite::getZoomH()
{ {
return mZoomH; return zoomH;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
double MovingSprite::getAngle() double MovingSprite::getAngle()
{ {
return mAngle; return angle;
}
// Establece la posición del objeto
void MovingSprite::setPos(SDL_Rect rect)
{
x = (float)rect.x;
y = (float)rect.y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setPosX(float x) void MovingSprite::setPosX(float value)
{ {
mPosX = x; x = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setPosY(float y) void MovingSprite::setPosY(float value)
{ {
mPosY = y; y = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setVelX(float x) void MovingSprite::setVelX(float value)
{ {
mVelX = x; vx = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setVelY(float y) void MovingSprite::setVelY(float value)
{ {
mVelY = y; vy = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAccelX(float x) void MovingSprite::setAccelX(float value)
{ {
mAccelX = x; ax = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAccelY(float y) void MovingSprite::setAccelY(float value)
{ {
mAccelY = y; ay = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setZoomW(float w) void MovingSprite::setZoomW(float value)
{ {
mZoomW = w; zoomW = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setZoomH(float h) void MovingSprite::setZoomH(float value)
{ {
mZoomH = h; zoomH = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAngle(double a) void MovingSprite::setAngle(double value)
{ {
mAngle = a; angle = value;
} }
// Incrementa el valor de la variable // Incrementa el valor de la variable
void MovingSprite::incAngle(double inc) void MovingSprite::incAngle(double value)
{ {
mAngle += inc; angle += value;
} }
// Decrementa el valor de la variable // Decrementa el valor de la variable
void MovingSprite::decAngle(double dec) void MovingSprite::decAngle(double value)
{ {
mAngle -= dec; angle -= value;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool MovingSprite::getRotate() bool MovingSprite::getRotate()
{ {
return mRotate; return rotateEnabled;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 MovingSprite::getRotateSpeed() Uint16 MovingSprite::getRotateSpeed()
{ {
return mRotateSpeed; return rotateSpeed;
} }
// Establece la rotacion // Establece la rotacion
void MovingSprite::rotate() void MovingSprite::rotate()
{ {
if (mEnabled) if (enabled)
if (mRotate) if (rotateEnabled)
{ {
if (mCounter % mRotateSpeed == 0) if (counter % rotateSpeed == 0)
{ {
incAngle(mRotateAmount); incAngle(rotateAmount);
} }
} }
} }
@@ -247,26 +259,26 @@ void MovingSprite::rotate()
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotate(bool value) void MovingSprite::setRotate(bool value)
{ {
mRotate = value; rotateEnabled = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotateSpeed(Uint16 value) void MovingSprite::setRotateSpeed(int value)
{ {
mRotateSpeed = value; rotateSpeed = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotateAmount(double value) void MovingSprite::setRotateAmount(double value)
{ {
mRotateAmount = value; rotateAmount = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::disableRotate() void MovingSprite::disableRotate()
{ {
mRotate = false; rotateEnabled = false;
mAngle = 0; angle = (double)0;
} }
// Actualiza las variables internas del objeto // Actualiza las variables internas del objeto
@@ -275,12 +287,79 @@ void MovingSprite::update()
move(); move();
rotate(); rotate();
if (mEnabled) if (enabled)
++mCounter %= 60000; {
++counter %= 60000;
}
} }
// Cambia el sentido de la rotación // Cambia el sentido de la rotación
void MovingSprite::switchRotate() void MovingSprite::switchRotate()
{ {
mRotateAmount *= -1; rotateAmount *= -1;
}
// Establece el valor de la variable
void MovingSprite::setFlip(SDL_RendererFlip flip)
{
currentFlip = flip;
}
// Gira el sprite horizontalmente
void MovingSprite::flip()
{
currentFlip = (currentFlip == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL;
}
// Obtiene el valor de la variable
SDL_RendererFlip MovingSprite::getFlip()
{
return currentFlip;
}
// Devuelve el rectangulo donde está el sprite
SDL_Rect MovingSprite::getRect()
{
const SDL_Rect rect = {(int)x, (int)y, w, h};
return rect;
}
// Establece los valores de posición y tamaño del sprite
void MovingSprite::setRect(SDL_Rect rect)
{
x = (float)rect.x;
y = (float)rect.y;
w = rect.w;
h = rect.h;
}
// Deshace el último movimiento
void MovingSprite::undoMove()
{
x = xPrev;
y = yPrev;
}
// Deshace el último movimiento en el eje X
void MovingSprite::undoMoveX()
{
x = xPrev;
}
// Deshace el último movimiento en el eje Y
void MovingSprite::undoMoveY()
{
y = yPrev;
}
// Pone a cero las velocidades de desplacamiento
void MovingSprite::clearVel()
{
vx = vy = 0.0f;
}
// Devuelve el incremento en el eje X en pixels
int MovingSprite::getIncX()
{
return (int)x - (int)xPrev;
} }

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "sprite.h" #include "sprite.h"
#ifndef MOVINGSPRITE_H #ifndef MOVINGSPRITE_H
@@ -9,34 +10,36 @@
class MovingSprite : public Sprite class MovingSprite : public Sprite
{ {
protected: protected:
float mPosX; // Posición en el eje X float x; // Posición en el eje X
float mPosY; // Posición en el eje Y float y; // Posición en el eje Y
float mVelX; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float xPrev; // Posición anterior en el eje X
float mVelY; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse float yPrev; // Posición anterior en el eje Y
float mAccelX; // Aceleración en el eje X. Variación de la velocidad float vx; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float mAccelY; // Aceleración en el eje Y. Variación de la velocidad float vy; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float mZoomW; // Zoom aplicado a la anchura float ax; // Aceleración en el eje X. Variación de la velocidad
float mZoomH; // Zoom aplicado a la altura float ay; // Aceleración en el eje Y. Variación de la velocidad
double mAngle; // Angulo para dibujarlo float zoomW; // Zoom aplicado a la anchura
bool mRotate; // Indica si ha de rotar float zoomH; // Zoom aplicado a la altura
Uint16 mRotateSpeed; // Velocidad de giro
double mRotateAmount; // Cantidad de grados a girar en cada iteración double angle; // Angulo para dibujarlo
Uint16 mCounter; // Contador interno bool rotateEnabled; // Indica si ha de rotar
int rotateSpeed; // Velocidad de giro
double rotateAmount; // Cantidad de grados a girar en cada iteración
int counter; // Contador interno
SDL_Point center; // Centro de rotación
SDL_RendererFlip currentFlip; // Indica como se voltea el sprite
public: public:
// Constructor // Constructor
MovingSprite(); MovingSprite(float x = 0, float y = 0, int w = 0, int h = 0, float velx = 0, float vely = 0, float accelx = 0, float accely = 0, LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr);
// Destructor // Destructor
~MovingSprite(); ~MovingSprite();
// Iniciador
void init(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, LTexture *texture, SDL_Renderer *renderer);
// Mueve el sprite // Mueve el sprite
void move(); void move();
@@ -85,44 +88,47 @@ public:
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 getRotateSpeed(); Uint16 getRotateSpeed();
// Establece el valor de la variable // Establece la posición del objeto
void setPosX(float x); void setPos(SDL_Rect rect);
// Establece el valor de la variable // Establece el valor de la variable
void setPosY(float y); void setPosX(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setVelX(float x); void setPosY(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setVelY(float y); void setVelX(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setAccelX(float x); void setVelY(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setAccelY(float y); void setAccelX(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setZoomW(float w); void setAccelY(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setZoomH(float h); void setZoomW(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setAngle(double a); void setZoomH(float value);
// Establece el valor de la variable
void setAngle(double vaue);
// Incrementa el valor de la variable // Incrementa el valor de la variable
void incAngle(double inc); void incAngle(double value);
// Decrementa el valor de la variable // Decrementa el valor de la variable
void decAngle(double dec); void decAngle(double value);
// Establece el valor de la variable // Establece el valor de la variable
void setRotate(bool value); void setRotate(bool value);
// Establece el valor de la variable // Establece el valor de la variable
void setRotateSpeed(Uint16 value); void setRotateSpeed(int value);
// Establece el valor de la variable // Establece el valor de la variable
void setRotateAmount(double value); void setRotateAmount(double value);
@@ -132,6 +138,36 @@ public:
// Cambia el sentido de la rotación // Cambia el sentido de la rotación
void switchRotate(); void switchRotate();
// Establece el valor de la variable
void setFlip(SDL_RendererFlip flip);
// Gira el sprite horizontalmente
void flip();
// Obtiene el valor de la variable
SDL_RendererFlip getFlip();
// Devuelve el rectangulo donde está el sprite
SDL_Rect getRect();
// Establece los valores de posición y tamaño del sprite
void setRect(SDL_Rect rect);
// Deshace el último movimiento
void undoMove();
// Deshace el último movimiento en el eje X
void undoMoveX();
// Deshace el último movimiento en el eje Y
void undoMoveY();
// Pone a cero las velocidades de desplacamiento
void clearVel();
// Devuelve el incremento en el eje X en pixels
int getIncX();
}; };
#endif #endif

View File

@@ -74,7 +74,7 @@ void Player::init(float x, int y, LTexture *textureLegs, LTexture *textureBody,
mCooldown = 10; mCooldown = 10;
// Inicia el sprite // Inicia el sprite
mSpriteLegs->init(textureLegs, renderer); mSpriteLegs->init();
mSpriteBody->init(textureBody, renderer); mSpriteBody->init(textureBody, renderer);
mSpriteHead->init(textureHead, renderer); mSpriteHead->init(textureHead, renderer);
@@ -262,15 +262,15 @@ void Player::setInput(Uint8 input)
setWalkingStatus(PLAYER_STATUS_WALKING_RIGHT); setWalkingStatus(PLAYER_STATUS_WALKING_RIGHT);
break; break;
case INPUT_FIRE_UP: case INPUT_BUTTON_2:
setFiringStatus(PLAYER_STATUS_FIRING_UP); setFiringStatus(PLAYER_STATUS_FIRING_UP);
break; break;
case INPUT_FIRE_LEFT: case INPUT_BUTTON_1:
setFiringStatus(PLAYER_STATUS_FIRING_LEFT); setFiringStatus(PLAYER_STATUS_FIRING_LEFT);
break; break;
case INPUT_FIRE_RIGHT: case INPUT_BUTTON_3:
setFiringStatus(PLAYER_STATUS_FIRING_RIGHT); setFiringStatus(PLAYER_STATUS_FIRING_RIGHT);
break; break;
@@ -291,10 +291,7 @@ void Player::move()
// Si el jugador abandona el area de juego por los laterales // Si el jugador abandona el area de juego por los laterales
if ((mPosX < PLAY_AREA_LEFT - 5) || (mPosX + mWidth > PLAY_AREA_RIGHT + 5)) if ((mPosX < PLAY_AREA_LEFT - 5) || (mPosX + mWidth > PLAY_AREA_RIGHT + 5))
{ mPosX -= mVelX; // Restaura su posición
// Restaura su posición
mPosX -= mVelX;
}
// Actualiza la posición del sprite // Actualiza la posición del sprite
mSpriteLegs->setPosX(getPosX()); mSpriteLegs->setPosX(getPosX());
@@ -509,13 +506,9 @@ bool Player::canFire()
{ {
// Si el contador a llegado a cero, podemos disparar. En caso contrario decrementamos el contador // Si el contador a llegado a cero, podemos disparar. En caso contrario decrementamos el contador
if (mCooldown > 0) if (mCooldown > 0)
{
return false; return false;
}
else else
{
return true; return true;
}
} }
// Establece el valor de la variable // Establece el valor de la variable

View File

@@ -1,4 +1,6 @@
#pragma once #pragma once
#include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#include "input.h" #include "input.h"
#include "animatedsprite.h" #include "animatedsprite.h"
@@ -6,7 +8,42 @@
#ifndef PLAYER_H #ifndef PLAYER_H
#define PLAYER_H #define PLAYER_H
// The player // Contadores
#define DEATH_COUNTER 350
// Estados del jugador
#define PLAYER_STATUS_WALKING_LEFT 0
#define PLAYER_STATUS_WALKING_RIGHT 1
#define PLAYER_STATUS_WALKING_STOP 2
#define PLAYER_STATUS_FIRING_UP 0
#define PLAYER_STATUS_FIRING_LEFT 1
#define PLAYER_STATUS_FIRING_RIGHT 2
#define PLAYER_STATUS_FIRING_NO 3
#define PLAYER_ANIMATION_LEGS_WALKING_RIGHT 1
#define PLAYER_ANIMATION_LEGS_WALKING_STOP 2
#define PLAYER_ANIMATION_BODY_WALKING_LEFT 0
#define PLAYER_ANIMATION_BODY_FIRING_LEFT 1
#define PLAYER_ANIMATION_BODY_WALKING_RIGHT 2
#define PLAYER_ANIMATION_BODY_FIRING_RIGHT 3
#define PLAYER_ANIMATION_BODY_WALKING_STOP 4
#define PLAYER_ANIMATION_BODY_FIRING_UP 5
#define PLAYER_ANIMATION_HEAD_WALKING_LEFT 0
#define PLAYER_ANIMATION_HEAD_FIRING_LEFT 1
#define PLAYER_ANIMATION_HEAD_WALKING_RIGHT 2
#define PLAYER_ANIMATION_HEAD_FIRING_RIGHT 3
#define PLAYER_ANIMATION_HEAD_WALKING_STOP 4
#define PLAYER_ANIMATION_HEAD_FIRING_UP 5
#define PLAYER_ANIMATION_LEGS_WALKING_LEFT 0
// Variables del jugador
#define PLAYER_INVULNERABLE_COUNTER 200
#define PLAYER_POWERUP_COUNTER 1500
// Clase Player
class Player class Player
{ {
private: private:

133
source/screen.cpp Normal file
View File

@@ -0,0 +1,133 @@
#include "screen.h"
#include "const.h"
#include <string>
#include <stdio.h>
// Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options)
{
// Inicializa variables
mWindow = window;
mRenderer = renderer;
mOptions = options;
mGameCanvasWidth = SCREEN_WIDTH;
mGameCanvasHeight = SCREEN_HEIGHT;
// Establece el modo de video
setVideoMode(mOptions->fullScreenMode);
// Define el color del borde para el modo de pantalla completa
mBorderColor = {0x27, 0x27, 0x36};
mBorderColor = {0x00, 0x00, 0x00};
// Crea la textura donde se dibujan los graficos del juego
mGameCanvas = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, mGameCanvasWidth, mGameCanvasHeight);
if (mGameCanvas == nullptr)
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError());
}
// Destructor
Screen::~Screen()
{
mRenderer = nullptr;
}
// Limpia la pantalla
void Screen::clean(color_t color)
{
SDL_SetRenderDrawColor(mRenderer, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(mRenderer);
}
// Prepara para empezar a dibujar en la textura de juego
void Screen::start()
{
SDL_SetRenderTarget(mRenderer, mGameCanvas);
}
// Vuelca el contenido del renderizador en pantalla
void Screen::blit()
{
// Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(mRenderer, nullptr);
// Borra el contenido previo
SDL_SetRenderDrawColor(mRenderer, mBorderColor.r, mBorderColor.g, mBorderColor.b, 0xFF);
SDL_RenderClear(mRenderer);
// Copia la textura de juego en el renderizador en la posición adecuada
SDL_RenderCopy(mRenderer, mGameCanvas, nullptr, &mDest);
// Muestra por pantalla el renderizador
SDL_RenderPresent(mRenderer);
}
// Establece el modo de video
void Screen::setVideoMode(int fullScreenMode)
{
// Aplica el modo de video
SDL_SetWindowFullscreen(mWindow, fullScreenMode);
// Si está activo el modo ventana quita el borde
if (fullScreenMode == 0)
{
mScreenWidth = mGameCanvasWidth;
mScreenHeight = mGameCanvasHeight;
mDest = {0, 0, mGameCanvasWidth, mGameCanvasHeight};
// Modifica el tamaño del renderizador y de la ventana
SDL_RenderSetLogicalSize(mRenderer, mScreenWidth, mScreenHeight);
SDL_SetWindowSize(mWindow, mScreenWidth * mOptions->windowSize, mScreenHeight * mOptions->windowSize);
}
// Si está activo el modo de pantalla completa añade el borde
if (fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
// Obten el alto y el ancho de la ventana
SDL_GetWindowSize(mWindow, &mScreenWidth, &mScreenHeight);
// Aplica el escalado al rectangulo donde se pinta la textura del juego
if (mOptions->integerScale)
{
// Calcula el tamaño de la escala máxima
int scale = 0;
while (((mGameCanvasWidth * (scale + 1)) <= mScreenWidth) && ((mGameCanvasHeight * (scale + 1)) <= mScreenHeight))
{
scale++;
}
mDest.w = mGameCanvasWidth * scale;
mDest.h = mGameCanvasHeight * scale;
mDest.x = (mScreenWidth - mDest.w) / 2;
mDest.y = (mScreenHeight - mDest.h) / 2;
}
else if (mOptions->keepAspect)
{
float ratio = (float)mGameCanvasWidth / (float)mGameCanvasHeight;
if ((mScreenWidth - mGameCanvasWidth) >= (mScreenHeight - mGameCanvasHeight))
{
mDest.h = mScreenHeight;
mDest.w = (int)((mScreenHeight * ratio) + 0.5f);
mDest.x = (mScreenWidth - mDest.w) / 2;
mDest.y = (mScreenHeight - mDest.h) / 2;
}
else
{
mDest.w = mScreenWidth;
mDest.h = (int)((mScreenWidth / ratio) + 0.5f);
mDest.x = (mScreenWidth - mDest.w) / 2;
mDest.y = (mScreenHeight - mDest.h) / 2;
}
}
else
{
mDest.w = mScreenWidth;
mDest.h = mScreenHeight;
mDest.x = mDest.y = 0;
}
// Modifica el tamaño del renderizador
SDL_RenderSetLogicalSize(mRenderer, mScreenWidth, mScreenHeight);
}
}

45
source/screen.h Normal file
View File

@@ -0,0 +1,45 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#ifndef SCREEN_H
#define SCREEN_H
// Clase Screen
class Screen
{
private:
SDL_Window *mWindow; // Ventana de la aplicación
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Texture *mGameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
options_t *mOptions; // Variable con todas las opciones del programa
int mScreenWidth; // Ancho de la pantalla
int mScreenHeight; // Alto de la pantalla
int mGameCanvasWidth; // Ancho de la textura donde se dibuja el juego
int mGameCanvasHeight; // Alto de la textura donde se dibuja el juego
SDL_Rect mDest; // Coordenadas donde se va a dibujar la textura del juego
color_t mBorderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
public:
// Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options);
// Destructor
~Screen();
// Limpia la pantalla
void clean(color_t color);
// Prepara para empezar a dibujar en la textura de juego
void start();
// Vuelca el contenido del renderizador en pantalla
void blit();
// Establece el modo de video
void setVideoMode(int fullScreenMode);
};
#endif

View File

@@ -4,13 +4,11 @@
// Constructor // Constructor
SmartSprite::SmartSprite() SmartSprite::SmartSprite()
{ {
//init(nullptr, nullptr);
} }
// Destructor // Destructor
SmartSprite::~SmartSprite() SmartSprite::~SmartSprite()
{ {
//init(nullptr, nullptr);
} }
// Inicializador // Inicializador
@@ -114,7 +112,7 @@ bool SmartSprite::update()
// Comprueba si se desplaza en el eje X hacia la derecha // Comprueba si se desplaza en el eje X hacia la derecha
if ((getAccelX() > 0) || ((getAccelX() == 0) && (getVelX() > 0))) if ((getAccelX() > 0) || ((getAccelX() == 0) && (getVelX() > 0)))
{ {
// Comprueba si hemos llegado al destino // Comprueba si ha llegado al destino
if (getPosX() > mDestX) if (getPosX() > mDestX)
{ {
// Lo coloca en posición // Lo coloca en posición
@@ -128,7 +126,7 @@ bool SmartSprite::update()
// Comprueba si se desplaza en el eje X hacia la izquierda // Comprueba si se desplaza en el eje X hacia la izquierda
else if ((getAccelX() < 0) || ((getAccelX() == 0) && (getVelX() < 0))) else if ((getAccelX() < 0) || ((getAccelX() == 0) && (getVelX() < 0)))
{ {
// Comprueba si hemos llegado al destino // Comprueba si ha llegado al destino
if (getPosX() < mDestX) if (getPosX() < mDestX)
{ {
// Lo coloca en posición // Lo coloca en posición
@@ -143,7 +141,7 @@ bool SmartSprite::update()
// Comprueba si se desplaza en el eje Y hacia abajo // Comprueba si se desplaza en el eje Y hacia abajo
if ((getAccelY() > 0) || ((getAccelY() == 0) && (getVelY() > 0))) if ((getAccelY() > 0) || ((getAccelY() == 0) && (getVelY() > 0)))
{ {
// Comprueba si hemos llegado al destino // Comprueba si ha llegado al destino
if (getPosY() > mDestY) if (getPosY() > mDestY)
{ {
// Lo coloca en posición // Lo coloca en posición
@@ -157,7 +155,7 @@ bool SmartSprite::update()
// Comprueba si se desplaza en el eje Y hacia arriba // Comprueba si se desplaza en el eje Y hacia arriba
else if ((getAccelY() < 0) || ((getAccelY() == 0) && (getVelY() < 0))) else if ((getAccelY() < 0) || ((getAccelY() == 0) && (getVelY() < 0)))
{ {
// Comprueba si hemos llegado al destino // Comprueba si ha llegado al destino
if (getPosY() < mDestY) if (getPosY() < mDestY)
{ {
// Lo coloca en posición // Lo coloca en posición
@@ -171,13 +169,9 @@ bool SmartSprite::update()
// Comprueba si ha llegado a su destino // Comprueba si ha llegado a su destino
if ((getPosX() == mDestX) && (getPosY() == mDestY)) if ((getPosX() == mDestX) && (getPosY() == mDestY))
{
mIsOnDestination = true; mIsOnDestination = true;
}
else else
{
mIsOnDestination = false; mIsOnDestination = false;
}
// Si esta en el destino comprueba su contador // Si esta en el destino comprueba su contador
if (mIsOnDestination) if (mIsOnDestination)
@@ -185,7 +179,7 @@ bool SmartSprite::update()
// Si el contador es mayor que cero, lo decrementa // Si el contador es mayor que cero, lo decrementa
if (mEnabledCounter > 0) if (mEnabledCounter > 0)
{ {
--mEnabledCounter; mEnabledCounter--;
} }
// Si ha llegado a cero, deshabilita el objeto o manda el aviso en función de si tiene Id // Si ha llegado a cero, deshabilita el objeto o manda el aviso en función de si tiene Id
else if (mEnabledCounter == 0) else if (mEnabledCounter == 0)
@@ -215,9 +209,7 @@ bool SmartSprite::isOnDestination()
void SmartSprite::render() void SmartSprite::render()
{ {
if (mEnabled) if (mEnabled)
{
MovingSprite::render(); MovingSprite::render();
}
} }
// Establece el valor de la variable // Establece el valor de la variable

View File

@@ -1,4 +1,6 @@
#pragma once #pragma once
#include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#include "animatedsprite.h" #include "animatedsprite.h"

View File

@@ -1,165 +1,183 @@
#include "sprite.h" #include "sprite.h"
// Constructor // Constructor
Sprite::Sprite() Sprite::Sprite(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer)
{ {
init(0, 0, 0, 0, nullptr, nullptr); // Establece la posición X,Y del sprite
this->x = x;
this->y = y;
// Establece el alto y el ancho del sprite
this->w = w;
this->h = h;
// Establece el puntero al renderizador de la ventana
this->renderer = renderer;
// Establece la textura donde están los gráficos para el sprite
this->texture = texture;
// Establece el rectangulo de donde coger la imagen
spriteClip = {x, y, w, h};
// Inicializa variables
enabled = true;
}
Sprite::Sprite(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer)
{
// Establece la posición X,Y del sprite
x = rect.x;
y = rect.y;
// Establece el alto y el ancho del sprite
w = rect.w;
h = rect.h;
// Establece el puntero al renderizador de la ventana
this->renderer = renderer;
// Establece la textura donde están los gráficos para el sprite
this->texture = texture;
// Establece el rectangulo de donde coger la imagen
spriteClip = {x, y, w, h};
// Inicializa variables
enabled = true;
} }
// Destructor // Destructor
Sprite::~Sprite() Sprite::~Sprite()
{ {
mTexture = nullptr; texture = nullptr;
mRenderer = nullptr; renderer = nullptr;
}
// Inicializador
void Sprite::init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer)
{
// Establece la posición X,Y del sprite
setPosX(x);
setPosY(y);
// Establece el alto y el ancho del sprite
setWidth(w);
setHeight(h);
// Establece el puntero al renderizador de la ventana
setRenderer(renderer);
// Establece la textura donde están los gráficos para el sprite
setTexture(texture);
// Establece el rectangulo de donde coger la imagen
setSpriteClip(0, 0, w, h);
// Habilita el objeto
setEnabled(true);
}
// Inicializador
void Sprite::init(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer)
{
// Establece el alto y el ancho del sprite
mWidth = rect.w;
mHeight = rect.h;
// Establece la posición X,Y del sprite
mPosX = rect.x;
mPosY = rect.y;
// Establece el puntero al renderizador de la ventana
setRenderer(renderer);
// Establece la textura donde están los gráficos para el sprite
setTexture(texture);
// Establece el rectangulo de donde coger la imagen
setSpriteClip(rect);
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void Sprite::render() void Sprite::render()
{ {
if (mEnabled) if (enabled)
mTexture->render(mRenderer, mPosX, mPosY, &mSpriteClip); {
texture->render(renderer, x, y, &spriteClip);
}
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getPosX() int Sprite::getPosX()
{ {
return mPosX; return x;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getPosY() int Sprite::getPosY()
{ {
return mPosY; return y;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getWidth() int Sprite::getWidth()
{ {
return mWidth; return w;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getHeight() int Sprite::getHeight()
{ {
return mHeight; return h;
}
// Establece la posición del objeto
void Sprite::setPos(SDL_Rect rect)
{
x = rect.x;
y = rect.y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setPosX(int x) void Sprite::setPosX(int x)
{ {
mPosX = x; this->x = x;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setPosY(int y) void Sprite::setPosY(int y)
{ {
mPosY = y; this->y = y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setWidth(int w) void Sprite::setWidth(int w)
{ {
mWidth = w; this->w = w;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setHeight(int h) void Sprite::setHeight(int h)
{ {
mHeight = h; this->h = h;
} }
// Obten el valor de la variable // Obten el valor de la variable
SDL_Rect Sprite::getSpriteClip() SDL_Rect Sprite::getSpriteClip()
{ {
return mSpriteClip; return spriteClip;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setSpriteClip(SDL_Rect rect) void Sprite::setSpriteClip(SDL_Rect rect)
{ {
mSpriteClip = rect; spriteClip = rect;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setSpriteClip(int x, int y, int w, int h) void Sprite::setSpriteClip(int x, int y, int w, int h)
{ {
mSpriteClip.x = x; spriteClip = {x, y, w, h};
mSpriteClip.y = y;
mSpriteClip.w = w;
mSpriteClip.h = h;
} }
// Obten el valor de la variable // Obten el valor de la variable
LTexture *Sprite::getTexture() LTexture *Sprite::getTexture()
{ {
return mTexture; return texture;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setTexture(LTexture *texture) void Sprite::setTexture(LTexture *texture)
{ {
mTexture = texture; this->texture = texture;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setRenderer(SDL_Renderer *renderer) void Sprite::setRenderer(SDL_Renderer *renderer)
{ {
mRenderer = renderer; this->renderer = renderer;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setEnabled(bool value) void Sprite::setEnabled(bool value)
{ {
mEnabled = value; enabled = value;
} }
// Comprueba si el objeto está habilitado // Comprueba si el objeto está habilitado
bool Sprite::isEnabled() bool Sprite::isEnabled()
{ {
return mEnabled; return enabled;
}
// Devuelve el rectangulo donde está el sprite
SDL_Rect Sprite::getRect()
{
SDL_Rect rect = {x, y, w, h};
return rect;
}
// Establece los valores de posición y tamaño del sprite
void Sprite::setRect(SDL_Rect rect)
{
x = rect.x;
y = rect.y;
w = rect.w;
h = rect.h;
} }

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "ltexture.h" #include "ltexture.h"
#ifndef SPRITE_H #ifndef SPRITE_H
@@ -9,28 +10,25 @@
class Sprite class Sprite
{ {
protected: protected:
int mPosX; // Posición en el eje X donde dibujar el sprite int x; // Posición en el eje X donde dibujar el sprite
int mPosY; // Posición en el eje Y donde dibujar el sprite int y; // Posición en el eje Y donde dibujar el sprite
Uint16 mWidth; // Ancho del sprite int w; // Ancho del sprite
Uint16 mHeight; // Alto del sprite int h; // Alto del sprite
SDL_Renderer *mRenderer; // Puntero al renderizador de la ventana SDL_Renderer *renderer; // Puntero al renderizador de la ventana
LTexture *mTexture; // Textura donde estan todos los dibujos del sprite LTexture *texture; // Textura donde estan todos los dibujos del sprite
SDL_Rect mSpriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla SDL_Rect spriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla
bool mEnabled; // Indica si el sprite esta habilitado bool enabled; // Indica si el sprite esta habilitado
public: public:
// Constructor // Constructor
Sprite(); Sprite(int x = 0, int y = 0, int w = 0, int h = 0, LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr);
Sprite(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer);
// Destructor // Destructor
~Sprite(); ~Sprite();
// Inicializador
void init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer);
void init(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer);
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void render(); void render();
@@ -46,6 +44,9 @@ public:
// Obten el valor de la variable // Obten el valor de la variable
int getHeight(); int getHeight();
// Establece la posición del objeto
void setPos(SDL_Rect rect);
// Establece el valor de la variable // Establece el valor de la variable
void setPosX(int x); void setPosX(int x);
@@ -81,6 +82,12 @@ public:
// Comprueba si el objeto está habilitado // Comprueba si el objeto está habilitado
bool isEnabled(); bool isEnabled();
// Devuelve el rectangulo donde está el sprite
SDL_Rect getRect();
// Establece los valores de posición y tamaño del sprite
void setRect(SDL_Rect rect);
}; };
#endif #endif

View File

@@ -1,4 +1,4 @@
/* stb_image - v2.26 - public domain image loader - http://nothings.org/stb /* stb_image - v2.27 - public domain image loader - http://nothings.org/stb
no warranty implied; use at your own risk no warranty implied; use at your own risk
Do this: Do this:
@@ -48,6 +48,7 @@ LICENSE
RECENT REVISION HISTORY: RECENT REVISION HISTORY:
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
2.26 (2020-07-13) many minor fixes 2.26 (2020-07-13) many minor fixes
2.25 (2020-02-02) fix warnings 2.25 (2020-02-02) fix warnings
2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically
@@ -89,7 +90,7 @@ RECENT REVISION HISTORY:
Jeremy Sawicki (handle all ImageNet JPGs) Jeremy Sawicki (handle all ImageNet JPGs)
Optimizations & bugfixes Mikhail Morozov (1-bit BMP) Optimizations & bugfixes Mikhail Morozov (1-bit BMP)
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
Arseny Kapoulkine Arseny Kapoulkine Simon Breuss (16-bit PNM)
John-Mark Allen John-Mark Allen
Carmelo J Fdez-Aguera Carmelo J Fdez-Aguera
@@ -102,7 +103,7 @@ RECENT REVISION HISTORY:
Thomas Ruf Ronny Chevalier github:rlyeh Thomas Ruf Ronny Chevalier github:rlyeh
Janez Zemva John Bartholomew Michal Cichon github:romigrou Janez Zemva John Bartholomew Michal Cichon github:romigrou
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
Laurent Gomila Cort Stratton github:snagar Eugene Golushkov Laurent Gomila Cort Stratton github:snagar
Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex
Cass Everitt Ryamond Barbiero github:grim210 Cass Everitt Ryamond Barbiero github:grim210
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
@@ -110,11 +111,13 @@ RECENT REVISION HISTORY:
Josh Tobin Matthew Gregan github:poppolopoppo Josh Tobin Matthew Gregan github:poppolopoppo
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
Brad Weinberger Matvey Cherevko [reserved] Brad Weinberger Matvey Cherevko github:mosra
Luca Sas Alexander Veselov Zack Middleton [reserved] Luca Sas Alexander Veselov Zack Middleton [reserved]
Ryan C. Gordon [reserved] [reserved] Ryan C. Gordon [reserved] [reserved]
DO NOT ADD YOUR NAME HERE DO NOT ADD YOUR NAME HERE
Jacko Dirks
To add your name to the credits, pick a random blank space in the middle and fill it. To add your name to the credits, pick a random blank space in the middle and fill it.
80% of merge conflicts on stb PRs are due to people adding their name at the end 80% of merge conflicts on stb PRs are due to people adding their name at the end
of the credits. of the credits.
@@ -176,6 +179,32 @@ RECENT REVISION HISTORY:
// //
// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. // Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
// //
// To query the width, height and component count of an image without having to
// decode the full file, you can use the stbi_info family of functions:
//
// int x,y,n,ok;
// ok = stbi_info(filename, &x, &y, &n);
// // returns ok=1 and sets x, y, n if image is a supported format,
// // 0 otherwise.
//
// Note that stb_image pervasively uses ints in its public API for sizes,
// including sizes of memory buffers. This is now part of the API and thus
// hard to change without causing breakage. As a result, the various image
// loaders all have certain limits on image size; these differ somewhat
// by format but generally boil down to either just under 2GB or just under
// 1GB. When the decoded image would be larger than this, stb_image decoding
// will fail.
//
// Additionally, stb_image will reject image files that have any of their
// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS,
// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit,
// the only way to have an image with such dimensions load correctly
// is for it to have a rather extreme aspect ratio. Either way, the
// assumption here is that such larger images are likely to be malformed
// or malicious. If you do need to load an image with individual dimensions
// larger than that, and it still fits in the overall size limit, you can
// #define STBI_MAX_DIMENSIONS on your own to be something larger.
//
// =========================================================================== // ===========================================================================
// //
// UNICODE: // UNICODE:
@@ -281,11 +310,10 @@ RECENT REVISION HISTORY:
// //
// iPhone PNG support: // iPhone PNG support:
// //
// By default we convert iphone-formatted PNGs back to RGB, even though // We optionally support converting iPhone-formatted PNGs (which store
// they are internally encoded differently. You can disable this conversion // premultiplied BGRA) back to RGB, even though they're internally encoded
// by calling stbi_convert_iphone_png_to_rgb(0), in which case // differently. To enable this conversion, call
// you will always just get the native iphone "format" through (which // stbi_convert_iphone_png_to_rgb(1).
// is BGR stored in RGB).
// //
// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per // Call stbi_set_unpremultiply_on_load(1) as well to force a divide per
// pixel to remove any premultiplied alpha *only* if the image file explicitly // pixel to remove any premultiplied alpha *only* if the image file explicitly
@@ -489,6 +517,8 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
// as above, but only applies to images loaded on the thread that calls the function // as above, but only applies to images loaded on the thread that calls the function
// this function is only available if your compiler supports thread-local variables; // this function is only available if your compiler supports thread-local variables;
// calling it will fail to link if your compiler doesn't // calling it will fail to link if your compiler doesn't
STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply);
STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert);
STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip);
// ZLIB client - used by PNG, available for other purposes // ZLIB client - used by PNG, available for other purposes
@@ -634,7 +664,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#ifdef STBI_HAS_LROTL #ifdef STBI_HAS_LROTL
#define stbi_lrot(x,y) _lrotl(x,y) #define stbi_lrot(x,y) _lrotl(x,y)
#else #else
#define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31)))
#endif #endif
#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
@@ -748,9 +778,12 @@ static int stbi__sse2_available(void)
#ifdef STBI_NEON #ifdef STBI_NEON
#include <arm_neon.h> #include <arm_neon.h>
// assume GCC or Clang on ARM targets #ifdef _MSC_VER
#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
#else
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
#endif #endif
#endif
#ifndef STBI_SIMD_ALIGN #ifndef STBI_SIMD_ALIGN
#define STBI_SIMD_ALIGN(type, name) type name #define STBI_SIMD_ALIGN(type, name) type name
@@ -924,6 +957,7 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
static int stbi__pnm_test(stbi__context *s); static int stbi__pnm_test(stbi__context *s);
static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
static int stbi__pnm_is16(stbi__context *s);
#endif #endif
static static
@@ -998,7 +1032,7 @@ static int stbi__mad3sizes_valid(int a, int b, int c, int add)
} }
// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM)
static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
{ {
return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
@@ -1021,7 +1055,7 @@ static void *stbi__malloc_mad3(int a, int b, int c, int add)
return stbi__malloc(a*b*c + add); return stbi__malloc(a*b*c + add);
} }
#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM)
static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
{ {
if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL;
@@ -1087,9 +1121,8 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
ri->num_channels = 0; ri->num_channels = 0;
#ifndef STBI_NO_JPEG // test the formats with a very explicit header first (at least a FOURCC
if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); // or distinctive magic number first)
#endif
#ifndef STBI_NO_PNG #ifndef STBI_NO_PNG
if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri);
#endif #endif
@@ -1107,6 +1140,13 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
#ifndef STBI_NO_PIC #ifndef STBI_NO_PIC
if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
#endif #endif
// then the formats that can end up attempting to load with just 1 or 2
// bytes matching expectations; these are prone to false positives, so
// try them later
#ifndef STBI_NO_JPEG
if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
#endif
#ifndef STBI_NO_PNM #ifndef STBI_NO_PNM
if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri);
#endif #endif
@@ -1262,12 +1302,12 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
#endif #endif
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
{ {
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
@@ -1277,16 +1317,16 @@ STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wch
static FILE *stbi__fopen(char const *filename, char const *mode) static FILE *stbi__fopen(char const *filename, char const *mode)
{ {
FILE *f; FILE *f;
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
wchar_t wMode[64]; wchar_t wMode[64];
wchar_t wFilename[1024]; wchar_t wFilename[1024];
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename))) if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
return 0; return 0;
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode))) if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
return 0; return 0;
#if _MSC_VER >= 1400 #if defined(_MSC_VER) && _MSC_VER >= 1400
if (0 != _wfopen_s(&f, wFilename, wMode)) if (0 != _wfopen_s(&f, wFilename, wMode))
f = 0; f = 0;
#else #else
@@ -1662,7 +1702,8 @@ static int stbi__get16le(stbi__context *s)
static stbi__uint32 stbi__get32le(stbi__context *s) static stbi__uint32 stbi__get32le(stbi__context *s)
{ {
stbi__uint32 z = stbi__get16le(s); stbi__uint32 z = stbi__get16le(s);
return z + (stbi__get16le(s) << 16); z += (stbi__uint32)stbi__get16le(s) << 16;
return z;
} }
#endif #endif
@@ -2090,13 +2131,12 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
int sgn; int sgn;
if (j->code_bits < n) stbi__grow_buffer_unsafe(j); if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative)
k = stbi_lrot(j->code_buffer, n); k = stbi_lrot(j->code_buffer, n);
if (n < 0 || n >= (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))) return 0;
j->code_buffer = k & ~stbi__bmask[n]; j->code_buffer = k & ~stbi__bmask[n];
k &= stbi__bmask[n]; k &= stbi__bmask[n];
j->code_bits -= n; j->code_bits -= n;
return k + (stbi__jbias[n] & ~sgn); return k + (stbi__jbias[n] & (sgn - 1));
} }
// get some unsigned bits // get some unsigned bits
@@ -2146,7 +2186,7 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
t = stbi__jpeg_huff_decode(j, hdc); t = stbi__jpeg_huff_decode(j, hdc);
if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG");
// 0 all the ac values now so we can do it 32-bits at a time // 0 all the ac values now so we can do it 32-bits at a time
memset(data,0,64*sizeof(data[0])); memset(data,0,64*sizeof(data[0]));
@@ -2203,12 +2243,12 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
// first scan for DC coefficient, must be first // first scan for DC coefficient, must be first
memset(data,0,64*sizeof(data[0])); // 0 all the ac values now memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
t = stbi__jpeg_huff_decode(j, hdc); t = stbi__jpeg_huff_decode(j, hdc);
if (t == -1) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
diff = t ? stbi__extend_receive(j, t) : 0; diff = t ? stbi__extend_receive(j, t) : 0;
dc = j->img_comp[b].dc_pred + diff; dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc; j->img_comp[b].dc_pred = dc;
data[0] = (short) (dc << j->succ_low); data[0] = (short) (dc * (1 << j->succ_low));
} else { } else {
// refinement scan for DC coefficient // refinement scan for DC coefficient
if (stbi__jpeg_get_bit(j)) if (stbi__jpeg_get_bit(j))
@@ -2245,7 +2285,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
j->code_buffer <<= s; j->code_buffer <<= s;
j->code_bits -= s; j->code_bits -= s;
zig = stbi__jpeg_dezigzag[k++]; zig = stbi__jpeg_dezigzag[k++];
data[zig] = (short) ((r >> 8) << shift); data[zig] = (short) ((r >> 8) * (1 << shift));
} else { } else {
int rs = stbi__jpeg_huff_decode(j, hac); int rs = stbi__jpeg_huff_decode(j, hac);
if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
@@ -2263,7 +2303,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
} else { } else {
k += r; k += r;
zig = stbi__jpeg_dezigzag[k++]; zig = stbi__jpeg_dezigzag[k++];
data[zig] = (short) (stbi__extend_receive(j,s) << shift); data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift));
} }
} }
} while (k <= j->spec_end); } while (k <= j->spec_end);
@@ -3227,6 +3267,13 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v;
} }
// check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios
// and I've never seen a non-corrupted JPEG file actually use them
for (i=0; i < s->img_n; ++i) {
if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG");
if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG");
}
// compute interleaved mcu info // compute interleaved mcu info
z->img_h_max = h_max; z->img_h_max = h_max;
z->img_v_max = v_max; z->img_v_max = v_max;
@@ -3782,6 +3829,10 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
else else
decode_n = z->s->img_n; decode_n = z->s->img_n;
// nothing to do if no components requested; check this now to avoid
// accessing uninitialized coutput[0] later
if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; }
// resample and color-convert // resample and color-convert
{ {
int k; int k;
@@ -3924,6 +3975,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
{ {
unsigned char* result; unsigned char* result;
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
if (!j) return stbi__errpuc("outofmem", "Out of memory");
STBI_NOTUSED(ri); STBI_NOTUSED(ri);
j->s = s; j->s = s;
stbi__setup_jpeg(j); stbi__setup_jpeg(j);
@@ -3936,6 +3988,7 @@ static int stbi__jpeg_test(stbi__context *s)
{ {
int r; int r;
stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
if (!j) return stbi__err("outofmem", "Out of memory");
j->s = s; j->s = s;
stbi__setup_jpeg(j); stbi__setup_jpeg(j);
r = stbi__decode_jpeg_header(j, STBI__SCAN_type); r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
@@ -3960,6 +4013,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
{ {
int result; int result;
stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
if (!j) return stbi__err("outofmem", "Out of memory");
j->s = s; j->s = s;
result = stbi__jpeg_info_raw(j, x, y, comp); result = stbi__jpeg_info_raw(j, x, y, comp);
STBI_FREE(j); STBI_FREE(j);
@@ -3979,6 +4033,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
// fast-way is faster to check than jpeg huffman, but slow way is slower // fast-way is faster to check than jpeg huffman, but slow way is slower
#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables
#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1)
#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet
// zlib-style huffman encoding // zlib-style huffman encoding
// (jpegs packs from left, zlib from right, so can't share code) // (jpegs packs from left, zlib from right, so can't share code)
@@ -3988,8 +4043,8 @@ typedef struct
stbi__uint16 firstcode[16]; stbi__uint16 firstcode[16];
int maxcode[17]; int maxcode[17];
stbi__uint16 firstsymbol[16]; stbi__uint16 firstsymbol[16];
stbi_uc size[288]; stbi_uc size[STBI__ZNSYMS];
stbi__uint16 value[288]; stbi__uint16 value[STBI__ZNSYMS];
} stbi__zhuffman; } stbi__zhuffman;
stbi_inline static int stbi__bitreverse16(int n) stbi_inline static int stbi__bitreverse16(int n)
@@ -4120,7 +4175,7 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
if (s >= 16) return -1; // invalid code! if (s >= 16) return -1; // invalid code!
// code size is s, so: // code size is s, so:
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
if (b >= sizeof (z->size)) return -1; // some data was corrupt somewhere! if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere!
if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. if (z->size[b] != s) return -1; // was originally an assert, but report failure instead.
a->code_buffer >>= s; a->code_buffer >>= s;
a->num_bits -= s; a->num_bits -= s;
@@ -4317,7 +4372,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
return 1; return 1;
} }
static const stbi_uc stbi__zdefault_length[288] = static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] =
{ {
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
@@ -4363,7 +4418,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
} else { } else {
if (type == 1) { if (type == 1) {
// use fixed code lengths // use fixed code lengths
if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0;
if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0;
} else { } else {
if (!stbi__compute_huffman_codes(a)) return 0; if (!stbi__compute_huffman_codes(a)) return 0;
@@ -4759,6 +4814,7 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3
// de-interlacing // de-interlacing
final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
if (!final) return stbi__err("outofmem", "Out of memory");
for (p=0; p < 7; ++p) { for (p=0; p < 7; ++p) {
int xorig[] = { 0,4,0,2,0,1,0 }; int xorig[] = { 0,4,0,2,0,1,0 };
int yorig[] = { 0,0,4,0,2,0,1 }; int yorig[] = { 0,0,4,0,2,0,1 };
@@ -4879,19 +4935,46 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
return 1; return 1;
} }
static int stbi__unpremultiply_on_load = 0; static int stbi__unpremultiply_on_load_global = 0;
static int stbi__de_iphone_flag = 0; static int stbi__de_iphone_flag_global = 0;
STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
{ {
stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply;
} }
STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
{ {
stbi__de_iphone_flag = flag_true_if_should_convert; stbi__de_iphone_flag_global = flag_true_if_should_convert;
} }
#ifndef STBI_THREAD_LOCAL
#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global
#define stbi__de_iphone_flag stbi__de_iphone_flag_global
#else
static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set;
static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set;
STBIDEF void stbi__unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
{
stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply;
stbi__unpremultiply_on_load_set = 1;
}
STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert)
{
stbi__de_iphone_flag_local = flag_true_if_should_convert;
stbi__de_iphone_flag_set = 1;
}
#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \
? stbi__unpremultiply_on_load_local \
: stbi__unpremultiply_on_load_global)
#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \
? stbi__de_iphone_flag_local \
: stbi__de_iphone_flag_global)
#endif // STBI_THREAD_LOCAL
static void stbi__de_iphone(stbi__png *z) static void stbi__de_iphone(stbi__png *z)
{ {
stbi__context *s = z->s; stbi__context *s = z->s;
@@ -5272,6 +5355,32 @@ typedef struct
int extra_read; int extra_read;
} stbi__bmp_data; } stbi__bmp_data;
static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress)
{
// BI_BITFIELDS specifies masks explicitly, don't override
if (compress == 3)
return 1;
if (compress == 0) {
if (info->bpp == 16) {
info->mr = 31u << 10;
info->mg = 31u << 5;
info->mb = 31u << 0;
} else if (info->bpp == 32) {
info->mr = 0xffu << 16;
info->mg = 0xffu << 8;
info->mb = 0xffu << 0;
info->ma = 0xffu << 24;
info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
} else {
// otherwise, use defaults, which is all-0
info->mr = info->mg = info->mb = info->ma = 0;
}
return 1;
}
return 0; // error
}
static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
{ {
int hsz; int hsz;
@@ -5299,6 +5408,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
if (hsz != 12) { if (hsz != 12) {
int compress = stbi__get32le(s); int compress = stbi__get32le(s);
if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes
if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel
stbi__get32le(s); // discard sizeof stbi__get32le(s); // discard sizeof
stbi__get32le(s); // discard hres stbi__get32le(s); // discard hres
stbi__get32le(s); // discard vres stbi__get32le(s); // discard vres
@@ -5313,17 +5424,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
} }
if (info->bpp == 16 || info->bpp == 32) { if (info->bpp == 16 || info->bpp == 32) {
if (compress == 0) { if (compress == 0) {
if (info->bpp == 32) { stbi__bmp_set_mask_defaults(info, compress);
info->mr = 0xffu << 16;
info->mg = 0xffu << 8;
info->mb = 0xffu << 0;
info->ma = 0xffu << 24;
info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
} else {
info->mr = 31u << 10;
info->mg = 31u << 5;
info->mb = 31u << 0;
}
} else if (compress == 3) { } else if (compress == 3) {
info->mr = stbi__get32le(s); info->mr = stbi__get32le(s);
info->mg = stbi__get32le(s); info->mg = stbi__get32le(s);
@@ -5338,6 +5439,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
return stbi__errpuc("bad BMP", "bad BMP"); return stbi__errpuc("bad BMP", "bad BMP");
} }
} else { } else {
// V4/V5 header
int i; int i;
if (hsz != 108 && hsz != 124) if (hsz != 108 && hsz != 124)
return stbi__errpuc("bad BMP", "bad BMP"); return stbi__errpuc("bad BMP", "bad BMP");
@@ -5345,6 +5447,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
info->mg = stbi__get32le(s); info->mg = stbi__get32le(s);
info->mb = stbi__get32le(s); info->mb = stbi__get32le(s);
info->ma = stbi__get32le(s); info->ma = stbi__get32le(s);
if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs
stbi__bmp_set_mask_defaults(info, compress);
stbi__get32le(s); // discard color space stbi__get32le(s); // discard color space
for (i=0; i < 12; ++i) for (i=0; i < 12; ++i)
stbi__get32le(s); // discard color space parameters stbi__get32le(s); // discard color space parameters
@@ -5394,8 +5498,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
psize = (info.offset - info.extra_read - info.hsz) >> 2; psize = (info.offset - info.extra_read - info.hsz) >> 2;
} }
if (psize == 0) { if (psize == 0) {
STBI_ASSERT(info.offset == s->callback_already_read + (int) (s->img_buffer - s->img_buffer_original)); if (info.offset != s->callback_already_read + (s->img_buffer - s->img_buffer_original)) {
if (info.offset != s->callback_already_read + (s->img_buffer - s->buffer_start)) {
return stbi__errpuc("bad offset", "Corrupt BMP"); return stbi__errpuc("bad offset", "Corrupt BMP");
} }
} }
@@ -6342,6 +6445,7 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
// intermediate buffer is RGBA // intermediate buffer is RGBA
result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0);
if (!result) return stbi__errpuc("outofmem", "Out of memory");
memset(result, 0xff, x*y*4); memset(result, 0xff, x*y*4);
if (!stbi__pic_load_core(s,x,y,comp, result)) { if (!stbi__pic_load_core(s,x,y,comp, result)) {
@@ -6457,6 +6561,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
{ {
stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
if (!g) return stbi__err("outofmem", "Out of memory");
if (!stbi__gif_header(s, g, comp, 1)) { if (!stbi__gif_header(s, g, comp, 1)) {
STBI_FREE(g); STBI_FREE(g);
stbi__rewind( s ); stbi__rewind( s );
@@ -6766,6 +6871,17 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
} }
} }
static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays)
{
STBI_FREE(g->out);
STBI_FREE(g->history);
STBI_FREE(g->background);
if (out) STBI_FREE(out);
if (delays && *delays) STBI_FREE(*delays);
return stbi__errpuc("outofmem", "Out of memory");
}
static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
{ {
if (stbi__gif_test(s)) { if (stbi__gif_test(s)) {
@@ -6777,6 +6893,10 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
int stride; int stride;
int out_size = 0; int out_size = 0;
int delays_size = 0; int delays_size = 0;
STBI_NOTUSED(out_size);
STBI_NOTUSED(delays_size);
memset(&g, 0, sizeof(g)); memset(&g, 0, sizeof(g));
if (delays) { if (delays) {
*delays = 0; *delays = 0;
@@ -6794,26 +6914,29 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
if (out) { if (out) {
void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
if (NULL == tmp) { if (!tmp)
STBI_FREE(g.out); return stbi__load_gif_main_outofmem(&g, out, delays);
STBI_FREE(g.history);
STBI_FREE(g.background);
return stbi__errpuc("outofmem", "Out of memory");
}
else { else {
out = (stbi_uc*) tmp; out = (stbi_uc*) tmp;
out_size = layers * stride; out_size = layers * stride;
} }
if (delays) { if (delays) {
*delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers ); int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
if (!new_delays)
return stbi__load_gif_main_outofmem(&g, out, delays);
*delays = new_delays;
delays_size = layers * sizeof(int); delays_size = layers * sizeof(int);
} }
} else { } else {
out = (stbi_uc*)stbi__malloc( layers * stride ); out = (stbi_uc*)stbi__malloc( layers * stride );
if (!out)
return stbi__load_gif_main_outofmem(&g, out, delays);
out_size = layers * stride; out_size = layers * stride;
if (delays) { if (delays) {
*delays = (int*) stbi__malloc( layers * sizeof(int) ); *delays = (int*) stbi__malloc( layers * sizeof(int) );
if (!*delays)
return stbi__load_gif_main_outofmem(&g, out, delays);
delays_size = layers * sizeof(int); delays_size = layers * sizeof(int);
} }
} }
@@ -7138,9 +7261,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
info.all_a = 255; info.all_a = 255;
p = stbi__bmp_parse_header(s, &info); p = stbi__bmp_parse_header(s, &info);
stbi__rewind( s ); if (p == NULL) {
if (p == NULL) stbi__rewind( s );
return 0; return 0;
}
if (x) *x = s->img_x; if (x) *x = s->img_x;
if (y) *y = s->img_y; if (y) *y = s->img_y;
if (comp) { if (comp) {
@@ -7206,8 +7330,8 @@ static int stbi__psd_is16(stbi__context *s)
stbi__rewind( s ); stbi__rewind( s );
return 0; return 0;
} }
(void) stbi__get32be(s); STBI_NOTUSED(stbi__get32be(s));
(void) stbi__get32be(s); STBI_NOTUSED(stbi__get32be(s));
depth = stbi__get16be(s); depth = stbi__get16be(s);
if (depth != 16) { if (depth != 16) {
stbi__rewind( s ); stbi__rewind( s );
@@ -7286,7 +7410,6 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
// Known limitations: // Known limitations:
// Does not support comments in the header section // Does not support comments in the header section
// Does not support ASCII image data (formats P2 and P3) // Does not support ASCII image data (formats P2 and P3)
// Does not support 16-bit-per-channel
#ifndef STBI_NO_PNM #ifndef STBI_NO_PNM
@@ -7307,7 +7430,8 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi_uc *out; stbi_uc *out;
STBI_NOTUSED(ri); STBI_NOTUSED(ri);
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n);
if (ri->bits_per_channel == 0)
return 0; return 0;
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
@@ -7317,12 +7441,12 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
*y = s->img_y; *y = s->img_y;
if (comp) *comp = s->img_n; if (comp) *comp = s->img_n;
if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0))
return stbi__errpuc("too large", "PNM too large"); return stbi__errpuc("too large", "PNM too large");
out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0);
if (!out) return stbi__errpuc("outofmem", "Out of memory"); if (!out) return stbi__errpuc("outofmem", "Out of memory");
stbi__getn(s, out, s->img_n * s->img_x * s->img_y); stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8));
if (req_comp && req_comp != s->img_n) { if (req_comp && req_comp != s->img_n) {
out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
@@ -7398,11 +7522,19 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
stbi__pnm_skip_whitespace(s, &c); stbi__pnm_skip_whitespace(s, &c);
maxv = stbi__pnm_getinteger(s, &c); // read max value maxv = stbi__pnm_getinteger(s, &c); // read max value
if (maxv > 65535)
if (maxv > 255) return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images");
return stbi__err("max value > 255", "PPM image not 8-bit"); else if (maxv > 255)
return 16;
else else
return 1; return 8;
}
static int stbi__pnm_is16(stbi__context *s)
{
if (stbi__pnm_info(s, NULL, NULL, NULL) == 16)
return 1;
return 0;
} }
#endif #endif
@@ -7458,6 +7590,9 @@ static int stbi__is_16_main(stbi__context *s)
if (stbi__psd_is16(s)) return 1; if (stbi__psd_is16(s)) return 1;
#endif #endif
#ifndef STBI_NO_PNM
if (stbi__pnm_is16(s)) return 1;
#endif
return 0; return 0;
} }

View File

@@ -1,15 +1,16 @@
#include "const.h"
#include "text.h" #include "text.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
// Constructor // Constructor
Text::Text(std::string file, LTexture *texture, SDL_Renderer *renderer) Text::Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer)
{ {
mSprite = new Sprite(); texture = new LTexture(renderer, bitmapFile);
mSprite->setTexture(texture); sprite = new Sprite({0, 0, 0, 0}, texture, renderer);
mSprite->setRenderer(renderer); sprite->setTexture(texture);
mFile = file; sprite->setRenderer(renderer);
file = textFile;
init(); init();
} }
@@ -17,71 +18,71 @@ Text::Text(std::string file, LTexture *texture, SDL_Renderer *renderer)
// Destructor // Destructor
Text::~Text() Text::~Text()
{ {
delete mSprite; delete texture;
mSprite = nullptr; delete sprite;
} }
// Inicializador // Inicializador
void Text::init() void Text::init()
{ {
// Inicializa a cero el vector con las coordenadas // Inicializa a cero el vector con las coordenadas
for (int i = 0; i < 128; i++) for (int i = 0; i < 128; ++i)
{ {
mOffset[i].x = 0; offset[i].x = 0;
mOffset[i].y = 0; offset[i].y = 0;
mOffset[i].w = 0; offset[i].w = 0;
} }
// Carga los offsets desde el fichero // Carga los offsets desde el fichero
initOffsetFromFile(); initOffsetFromFile();
// Inicia los valores del sprite que dibuja las letras // Inicia los valores del sprite que dibuja las letras
mSprite->setWidth(mBoxWidth); sprite->setWidth(boxWidth);
mSprite->setHeight(mBoxHeight); sprite->setHeight(boxHeight);
mSprite->setPosX(0); sprite->setPosX(0);
mSprite->setPosY(0); sprite->setPosY(0);
mSprite->setSpriteClip(0, 0, mSprite->getWidth(), mSprite->getHeight()); sprite->setSpriteClip(0, 0, sprite->getWidth(), sprite->getHeight());
// Establece las coordenadas para cada caracter ascii de la cadena y su ancho // Establece las coordenadas para cada caracter ascii de la cadena y su ancho
for (int i = 32; i < 128; i++) for (int i = 32; i < 128; ++i)
{ {
mOffset[i].x = ((i - 32) % 15) * mBoxWidth; offset[i].x = ((i - 32) % 15) * boxWidth;
mOffset[i].y = ((i - 32) / 15) * mBoxHeight; offset[i].y = ((i - 32) / 15) * boxHeight;
} }
} }
// Escribe texto en pantalla // Escribe texto en pantalla
void Text::write(int x, int y, std::string text, int kerning, int lenght) void Text::write(int x, int y, std::string text, int kerning, int lenght)
{ {
Uint16 shift = 0; int shift = 0;
if (lenght == -1) if (lenght == -1)
lenght = text.length(); lenght = text.length();
for (int i = 0; i < lenght; ++i) for (int i = 0; i < lenght; ++i)
{ {
mSprite->setSpriteClip(mOffset[int(text[i])].x, mOffset[int(text[i])].y, mSprite->getWidth(), mSprite->getHeight()); sprite->setSpriteClip(offset[int(text[i])].x, offset[int(text[i])].y, sprite->getWidth(), sprite->getHeight());
mSprite->setPosX(x + shift); sprite->setPosX(x + shift);
mSprite->setPosY(y); sprite->setPosY(y);
mSprite->render(); sprite->render();
shift += (mOffset[int(text[i])].w + kerning); shift += (offset[int(text[i])].w + kerning);
} }
} }
// Escribe el texto con colores // Escribe el texto con colores
void Text::writeColored(int x, int y, std::string text, color_t color, int kerning, int lenght) void Text::writeColored(int x, int y, std::string text, color_t color, int kerning, int lenght)
{ {
mSprite->getTexture()->setColor(color.r, color.g, color.b); sprite->getTexture()->setColor(color.r, color.g, color.b);
write(x, y, text, kerning, lenght); write(x, y, text, kerning, lenght);
mSprite->getTexture()->setColor(255, 255, 255); sprite->getTexture()->setColor(255, 255, 255);
} }
// Escribe el texto con sombra // Escribe el texto con sombra
void Text::writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance, int kerning, int lenght) void Text::writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance, int kerning, int lenght)
{ {
mSprite->getTexture()->setColor(color.r, color.g, color.b); sprite->getTexture()->setColor(color.r, color.g, color.b);
write(x + shadowDistance, y + shadowDistance, text, kerning, lenght); write(x + shadowDistance, y + shadowDistance, text, kerning, lenght);
mSprite->getTexture()->setColor(255, 255, 255); sprite->getTexture()->setColor(255, 255, 255);
write(x, y, text, kerning, lenght); write(x, y, text, kerning, lenght);
} }
@@ -112,7 +113,7 @@ void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, col
writeColored(x - shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght); writeColored(x - shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght);
writeColored(x + shadowDistance, y - shadowDistance, text, shadowColor, kerning, lenght); writeColored(x + shadowDistance, y - shadowDistance, text, shadowColor, kerning, lenght);
writeColored(x - shadowDistance, y - shadowDistance, text, shadowColor, kerning, lenght); writeColored(x - shadowDistance, y - shadowDistance, text, shadowColor, kerning, lenght);
writeColored(x, y + shadowDistance, text, shadowColor, kerning, lenght); writeColored(x, y + shadowDistance, text, shadowColor, kerning, lenght);
writeColored(x, y - shadowDistance, text, shadowColor, kerning, lenght); writeColored(x, y - shadowDistance, text, shadowColor, kerning, lenght);
writeColored(x + shadowDistance, y, text, shadowColor, kerning, lenght); writeColored(x + shadowDistance, y, text, shadowColor, kerning, lenght);
@@ -126,33 +127,35 @@ void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, col
} }
// Obtiene la longitud en pixels de una cadena // Obtiene la longitud en pixels de una cadena
Uint16 Text::lenght(std::string text, int kerning) int Text::lenght(std::string text, int kerning)
{ {
Uint16 shift = 0; int shift = 0;
for (int i = 0; i < text.length(); ++i) for (int i = 0; i < (int)text.length(); ++i)
shift += (mOffset[int(text[i])].w + kerning); shift += (offset[int(text[i])].w + kerning);
return shift; // Descuenta el kerning del último caracter
return shift - kerning;
} }
// Inicializa el vector de offsets desde un fichero // Inicializa el vector de offsets desde un fichero
void Text::initOffsetFromFile() void Text::initOffsetFromFile()
{ {
std::ifstream rfile(mFile); std::ifstream rfile(file);
printf("Reading file %s\n", file.c_str());
if (rfile.is_open() && rfile.good()) if (rfile.is_open() && rfile.good())
{ {
std::string buffer; std::string buffer;
//printf("Reading %s file\n", mFile.c_str());
// Lee los dos primeros valores del fichero // Lee los dos primeros valores del fichero
std::getline(rfile, buffer); std::getline(rfile, buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
mBoxWidth = std::stoi(buffer); boxWidth = std::stoi(buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
mBoxHeight = std::stoi(buffer); boxHeight = std::stoi(buffer);
// lee el resto de datos del fichero // lee el resto de datos del fichero
int index = 32; int index = 32;
@@ -161,17 +164,33 @@ void Text::initOffsetFromFile()
{ {
// Almacena solo las lineas impares // Almacena solo las lineas impares
if (line_read % 2 == 1) if (line_read % 2 == 1)
mOffset[index++].w = std::stoi(buffer); offset[index++].w = std::stoi(buffer);
// Limpia el buffer // Limpia el buffer
buffer.clear(); buffer.clear();
line_read++; line_read++;
}; };
// Cierra el fichero
printf("Closing file %s\n\n", file.c_str());
rfile.close();
}
// El fichero no se puede abrir
else
{
printf("Warning: Unable to open %s file\n", file.c_str());
} }
} }
// Devuelve el valor de la variable // Devuelve el valor de la variable
Uint8 Text::getCharacterWidth() int Text::getCharacterSize()
{ {
return mBoxWidth; return boxWidth;
}
// Recarga la textura
void Text::reLoadTexture()
{
texture->reLoad();
} }

View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
#include "sprite.h" #include "sprite.h"
#include "utils.h" #include "utils.h"
@@ -14,33 +15,34 @@
class Text class Text
{ {
private: private:
Sprite *mSprite; // Objeto con los graficos para el texto Sprite *sprite; // Objeto con los graficos para el texto
struct Offset struct Offset
{ {
int x; int x;
int y; int y;
Uint8 w; int w;
}; };
Offset mOffset[128]; // Vector con las posiciones y ancho de cada letra Offset offset[128]; // Vector con las posiciones y ancho de cada letra
Uint8 mBoxWidth; // Anchura de la caja de cada caracter en el png int boxWidth; // Anchura de la caja de cada caracter en el png
Uint8 mBoxHeight; // Altura de la caja de cada caracter en el png int boxHeight; // Altura de la caja de cada caracter en el png
std::string mFile; // Fichero con los descriptores de la fuente std::string file; // Fichero con los descriptores de la fuente
LTexture *texture; // Textura con los bitmaps del texto
// Inicializador
void init();
// Inicializa el vector de offsets desde un fichero // Inicializa el vector de offsets desde un fichero
void initOffsetFromFile(); void initOffsetFromFile();
public: public:
// Constructor // Constructor
Text(std::string file, LTexture *texture, SDL_Renderer *renderer); Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer);
// Destructor // Destructor
~Text(); ~Text();
// Inicializador
void init();
// Escribe el texto en pantalla // Escribe el texto en pantalla
void write(int x, int y, std::string text, int kerning = 1, int lenght = -1); void write(int x, int y, std::string text, int kerning = 1, int lenght = -1);
@@ -50,17 +52,20 @@ public:
// Escribe el texto con sombra // Escribe el texto con sombra
void writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1); void writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1);
// Escribe el texto centrado en un punto x y con kerning // Escribe el texto centrado en un punto x
void writeCentered(int x, int y, std::string text, int kerning = 1, int lenght = -1); void writeCentered(int x, int y, std::string text, int kerning = 1, int lenght = -1);
// Escribe texto con extras // Escribe texto con extras
void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, color_t textColor = {255, 255, 255}, Uint8 shadowDistance = 1, color_t shadowColor = {0, 0, 0}, int lenght = -1); void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, color_t textColor = {255, 255, 255}, Uint8 shadowDistance = 1, color_t shadowColor = {0, 0, 0}, int lenght = -1);
// Obtiene la longitud en pixels de una cadena // Obtiene la longitud en pixels de una cadena
Uint16 lenght(std::string text, int kerning = 1); int lenght(std::string text, int kerning = 1);
// Devuelve el valor de la variable // Devuelve el valor de la variable
Uint8 getCharacterWidth(); int getCharacterSize();
// Recarga la textura
void reLoadTexture();
}; };
#endif #endif

View File

@@ -1,41 +1,41 @@
#include "title.h" #include "title.h"
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#endif
// Constructor // Constructor
Title::Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::string *fileList, options_t *options, Lang *lang) Title::Title(SDL_Window *window, SDL_Renderer *renderer, Screen *screen, Input *input, Asset *mAsset, options_t *options, Lang *lang)
{ {
// Copia las direcciones de los punteros // Copia las direcciones de los punteros
mWindow = window; mWindow = window;
mRenderer = renderer; mRenderer = renderer;
mScreen = screen;
mInput = input; mInput = input;
mFileList = fileList; this->mAsset = mAsset;
mOptions = options; mOptions = options;
mLang = lang; mLang = lang;
// Reserva memoria para los punteros propios // Reserva memoria para los punteros propios
mEventHandler = new SDL_Event(); mEventHandler = new SDL_Event();
mFade = new Fade(renderer); mFade = new Fade(renderer);
mTitleTexture = new LTexture(); mTitleTexture = new LTexture(mRenderer);
mItemsTexture = new LTexture(); mItemsTexture = new LTexture(mRenderer);
mTextTexture = new LTexture(); mTextTexture = new LTexture(mRenderer);
mTextTexture2 = new LTexture(); mTextTexture2 = new LTexture(mRenderer);
mCoffeeBitmap = new SmartSprite(); mCoffeeBitmap = new SmartSprite();
mCrisisBitmap = new SmartSprite(); mCrisisBitmap = new SmartSprite();
mDustBitmapL = new AnimatedSprite(); mDustBitmapL = new AnimatedSprite();
mDustBitmapR = new AnimatedSprite(); mDustBitmapR = new AnimatedSprite();
mTile = new Sprite(); mTile = new Sprite();
mGradient = new Sprite(); mGradient = new Sprite();
mText = new Text(mFileList[48], mTextTexture, mRenderer); mText = new Text(mAsset->get("smb2.txt"), mTextTexture, mRenderer);
mText2 = new Text(mFileList[46], mTextTexture2, mRenderer); mText2 = new Text(mAsset->get("8bithud.txt"), mTextTexture2, mRenderer);
mMenu.title = new Menu(mRenderer, mText, mInput, mFileList); mMenu.title = new Menu(mRenderer, mText, mInput, mAsset);
mMenu.options = new Menu(mRenderer, mText, mInput, mFileList); mMenu.options = new Menu(mRenderer, mText, mInput, mAsset);
// Crea la textura para el mosaico de fondo
mBackground = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2); mBackground = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2);
if (mBackground == NULL) if (mBackground == nullptr)
{
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError()); printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError());
}
} }
// Destructor // Destructor
@@ -43,8 +43,9 @@ Title::~Title()
{ {
mWindow = nullptr; mWindow = nullptr;
mRenderer = nullptr; mRenderer = nullptr;
mScreen = nullptr;
mInput = nullptr; mInput = nullptr;
mFileList = nullptr; mAsset = nullptr;
mOptions = nullptr; mOptions = nullptr;
mLang = nullptr; mLang = nullptr;
@@ -107,12 +108,6 @@ Title::~Title()
SDL_DestroyTexture(mBackground); SDL_DestroyTexture(mBackground);
mBackground = nullptr; mBackground = nullptr;
mWindow = nullptr;
mRenderer = nullptr;
mInput = nullptr;
mFileList = nullptr;
mOptions = nullptr;
} }
// Inicializa las variables necesarias para la sección 'Title' // Inicializa las variables necesarias para la sección 'Title'
@@ -136,22 +131,23 @@ void Title::init(bool demo, Uint8 subsection)
mFade->init(0x17, 0x17, 0x26); mFade->init(0x17, 0x17, 0x26);
mDemo = demo; mDemo = demo;
//if (!mInput->gameControllerFound()) // Pone valores por defecto a las opciones de control
{ mOptions->input[0].id = 0;
mOptions->input[0].id = 0; mOptions->input[0].name = "KEYBOARD";
mOptions->input[0].name = "KEYBOARD"; mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].id = 0; mOptions->input[1].id = 0;
mOptions->input[1].name = "GAME CONTROLLER"; mOptions->input[1].name = "GAME CONTROLLER";
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER; mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
}
// Comprueba si hay mandos conectados
checkInputDevices(); checkInputDevices();
mDeviceIndex[0] = mAvailableInputDevices.size() - 1; // Pone valores por defecto
mDeviceIndex[1] = 0; mDeviceIndex[0] = mAvailableInputDevices.size() - 1; // El último dispositivo encontrado es el teclado
mDeviceIndex[1] = 0; // El primer mando encontrado. Si no ha encontrado ninguno es el teclado
// Si ha encontrado un mando se lo asigna al segundo jugador
if (mInput->gameControllerFound()) if (mInput->gameControllerFound())
{ {
mOptions->input[1].id = mAvailableInputDevices[mDeviceIndex[1]].id; mOptions->input[1].id = mAvailableInputDevices[mDeviceIndex[1]].id;
@@ -244,6 +240,7 @@ void Title::init(bool demo, Uint8 subsection)
// Crea el mosaico de fondo del titulo // Crea el mosaico de fondo del titulo
createTiledBackground(); createTiledBackground();
// Coloca la ventana que recorre el mosaico de fondo de manera que coincida con el mosaico que hay pintado en el titulo al iniciar
mBackgroundWindow.x = 128; mBackgroundWindow.x = 128;
mBackgroundWindow.y = 96; mBackgroundWindow.y = 96;
mBackgroundWindow.w = SCREEN_WIDTH; mBackgroundWindow.w = SCREEN_WIDTH;
@@ -251,9 +248,7 @@ void Title::init(bool demo, Uint8 subsection)
// Inicializa los valores del vector con los valores del seno // Inicializa los valores del vector con los valores del seno
for (int i = 0; i < 360; i++) for (int i = 0; i < 360; i++)
{
mSin[i] = SDL_sinf((float)i * 3.14f / 180.0f); mSin[i] = SDL_sinf((float)i * 3.14f / 180.0f);
}
// Inicializa los objetos de menu // Inicializa los objetos de menu
mMenu.title->init("TITLE", 0, (14 * BLOCK) + 4, MENU_BACKGROUND_TRANSPARENT); mMenu.title->init("TITLE", 0, (14 * BLOCK) + 4, MENU_BACKGROUND_TRANSPARENT);
@@ -301,16 +296,16 @@ bool Title::loadMedia()
bool success = true; bool success = true;
// Texturas // Texturas
success &= loadTextureFromFile(mTitleTexture, mFileList[40], mRenderer); success &= loadTextureFromFile(mTitleTexture, mAsset->get("title.png"), mRenderer);
success &= loadTextureFromFile(mItemsTexture, mFileList[34], mRenderer); success &= loadTextureFromFile(mItemsTexture, mAsset->get("items.png"), mRenderer);
success &= loadTextureFromFile(mTextTexture, mFileList[30], mRenderer); success &= loadTextureFromFile(mTextTexture, mAsset->get("smb2.png"), mRenderer);
success &= loadTextureFromFile(mTextTexture2, mFileList[27], mRenderer); success &= loadTextureFromFile(mTextTexture2, mAsset->get("8bithud.png"), mRenderer);
// Sonidos // Sonidos
mSound = JA_LoadSound(mFileList[21].c_str()); mSound = JA_LoadSound(mAsset->get("title.wav").c_str());
// Musicas // Musicas
mMusic = JA_LoadMusic(mFileList[5].c_str()); mMusic = JA_LoadMusic(mAsset->get("title.ogg").c_str());
return success; return success;
} }
@@ -380,7 +375,6 @@ void Title::updateMenuLabels()
else else
{ {
mMenu.options->setGreyed(i, false); mMenu.options->setGreyed(i, false);
//mMenu.options->setItemCaption(i, mInput->getControllerName(0));
mMenu.options->setItemCaption(i, mOptions->input[0].name); mMenu.options->setItemCaption(i, mOptions->input[0].name);
} }
break; break;
@@ -410,7 +404,6 @@ void Title::updateMenuLabels()
else else
{ {
mMenu.options->setGreyed(i, false); mMenu.options->setGreyed(i, false);
//mMenu.options->setItemCaption(i, mInput->getControllerName(0));
mMenu.options->setItemCaption(i, mOptions->input[1].name); mMenu.options->setItemCaption(i, mOptions->input[1].name);
} }
break; break;
@@ -496,15 +489,18 @@ void Title::updateMenuLabels()
// CANCEL // CANCEL
mMenu.options->setItemCaption(i, mLang->getText(10)); // CANCEL mMenu.options->setItemCaption(i, mLang->getText(10)); // CANCEL
// Recoloca el menu de opciones
mMenu.options->centerMenuOnX(SCREEN_CENTER_X); mMenu.options->centerMenuOnX(SCREEN_CENTER_X);
mMenu.options->centerMenuOnY(SCREEN_CENTER_Y); mMenu.options->centerMenuOnY(SCREEN_CENTER_Y);
mMenu.options->centerMenuElementsOnX(); mMenu.options->centerMenuElementsOnX();
// Establece las etiquetas del menu de titulo
mMenu.title->setItemCaption(0, mLang->getText(51)); // 1 PLAYER mMenu.title->setItemCaption(0, mLang->getText(51)); // 1 PLAYER
mMenu.title->setItemCaption(1, mLang->getText(52)); // 2 PLAYERS mMenu.title->setItemCaption(1, mLang->getText(52)); // 2 PLAYERS
mMenu.title->setItemCaption(2, mLang->getText(1)); // OPTIONS mMenu.title->setItemCaption(2, mLang->getText(1)); // OPTIONS
mMenu.title->setItemCaption(3, mLang->getText(3)); // QUIT mMenu.title->setItemCaption(3, mLang->getText(3)); // QUIT
// Recoloca el menu de titulo
mMenu.title->centerMenuOnX(SCREEN_CENTER_X); mMenu.title->centerMenuOnX(SCREEN_CENTER_X);
mMenu.title->centerMenuElementsOnX(); mMenu.title->centerMenuElementsOnX();
} }
@@ -512,8 +508,8 @@ void Title::updateMenuLabels()
// Aplica las opciones de menu seleccionadas // Aplica las opciones de menu seleccionadas
void Title::applyOptions() void Title::applyOptions()
{ {
SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode); mScreen->setVideoMode(mOptions->fullScreenMode);
SDL_SetWindowSize(mWindow, SCREEN_WIDTH * mOptions->windowSize, SCREEN_HEIGHT * mOptions->windowSize);
mLang->setLang(mOptions->language); mLang->setLang(mOptions->language);
updateMenuLabels(); updateMenuLabels();
@@ -552,12 +548,14 @@ section_t Title::run(Uint8 subsection)
mCrisisBitmap->update(); mCrisisBitmap->update();
} }
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla // Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); mScreen->clean(bgColor);
SDL_RenderClear(mRenderer);
// Dibuja el tileado de fondo // Dibuja el tileado de fondo
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, NULL); SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, nullptr);
// Dibuja el degradado // Dibuja el degradado
mGradient->render(); mGradient->render();
@@ -566,8 +564,8 @@ section_t Title::run(Uint8 subsection)
mCoffeeBitmap->render(); mCoffeeBitmap->render();
mCrisisBitmap->render(); mCrisisBitmap->render();
// Actualiza la pantalla // Vuelca el contenido del renderizador en pantalla
SDL_RenderPresent(mRenderer); mScreen->blit();
// Si los objetos han llegado a su destino, cambiamos de Sección // Si los objetos han llegado a su destino, cambiamos de Sección
if ((mEvents[0] == EVENT_COMPLETED) && (mEvents[0] == EVENT_COMPLETED)) if ((mEvents[0] == EVENT_COMPLETED) && (mEvents[0] == EVENT_COMPLETED))
@@ -604,12 +602,14 @@ section_t Title::run(Uint8 subsection)
int b = mCrisisBitmap->getPosX(); int b = mCrisisBitmap->getPosX();
for (int n = 0; n < 11 * 3; n++) for (int n = 0; n < 11 * 3; n++)
{ {
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla // Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); mScreen->clean(bgColor);
SDL_RenderClear(mRenderer);
// Dibuja el tileado de fondo // Dibuja el tileado de fondo
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, NULL); SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, nullptr);
// Dibuja el degradado // Dibuja el degradado
mGradient->render(); mGradient->render();
@@ -624,8 +624,8 @@ section_t Title::run(Uint8 subsection)
mDustBitmapR->render(); mDustBitmapR->render();
mDustBitmapL->render(); mDustBitmapL->render();
// Actualiza la pantalla // Vuelca el contenido del renderizador en pantalla
SDL_RenderPresent(mRenderer); mScreen->blit();
} }
mSection.subsection = TITLE_SECTION_3; mSection.subsection = TITLE_SECTION_3;
@@ -655,10 +655,7 @@ section_t Title::run(Uint8 subsection)
// Si la música no está sonando // Si la música no está sonando
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED)) if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{ JA_PlayMusic(mMusic); // Reproduce la música
// Reproduce la música
JA_PlayMusic(mMusic);
}
// Calcula la lógica de los objetos // Calcula la lógica de los objetos
if (SDL_GetTicks() - mTicks > mTicksSpeed) if (SDL_GetTicks() - mTicks > mTicksSpeed)
@@ -842,17 +839,17 @@ section_t Title::run(Uint8 subsection)
} }
if (mMenu.active->getName() == "TITLE") if (mMenu.active->getName() == "TITLE")
{
mCounter--; mCounter--;
}
} }
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla // Limpia la pantalla
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); mScreen->clean(bgColor);
SDL_RenderClear(mRenderer);
// Dibuja el tileado de fondo // Dibuja el tileado de fondo
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, NULL); SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, nullptr);
// Dibuja el degradado // Dibuja el degradado
mGradient->render(); mGradient->render();
@@ -869,7 +866,9 @@ section_t Title::run(Uint8 subsection)
} }
if (mMenuVisible == true) if (mMenuVisible == true)
{
mMenu.active->render(); mMenu.active->render();
}
mDustBitmapR->animate(0); mDustBitmapR->animate(0);
mDustBitmapL->animate(0); mDustBitmapL->animate(0);
@@ -878,13 +877,15 @@ section_t Title::run(Uint8 subsection)
// PRESS ANY KEY! // PRESS ANY KEY!
if ((mCounter % 50 > 14) && (mMenuVisible == false)) if ((mCounter % 50 > 14) && (mMenuVisible == false))
{
mText->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, mLang->getText(23), 1, noColor, 1, shdwTxtColor); mText->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, mLang->getText(23), 1, noColor, 1, shdwTxtColor);
}
// Fade // Fade
mFade->render(); mFade->render();
// Actualiza la pantalla // Vuelca el contenido del renderizador en pantalla
SDL_RenderPresent(mRenderer); mScreen->blit();
} }
else if (mCounter == 0) else if (mCounter == 0)
{ {
@@ -913,7 +914,7 @@ section_t Title::run(Uint8 subsection)
// Ejecuta la parte donde se muestran las instrucciones // Ejecuta la parte donde se muestran las instrucciones
void Title::runInstructions(Uint8 mode) void Title::runInstructions(Uint8 mode)
{ {
mInstructions = new Instructions(mRenderer, mFileList, mLang); mInstructions = new Instructions(mRenderer, mScreen, mAsset, mLang);
mInstructions->run(mode); mInstructions->run(mode);
delete mInstructions; delete mInstructions;
} }
@@ -921,7 +922,7 @@ void Title::runInstructions(Uint8 mode)
// Ejecuta el juego en modo demo // Ejecuta el juego en modo demo
void Title::runDemoGame() void Title::runDemoGame()
{ {
mDemoGame = new Game(1, mRenderer, mFileList, mLang, mInput, true, mOptions); mDemoGame = new Game(1, 0, mRenderer, mScreen, mAsset, mLang, mInput, true, mOptions);
mDemoGame->run(); mDemoGame->run();
delete mDemoGame; delete mDemoGame;
} }
@@ -949,29 +950,23 @@ bool Title::updatePlayerInputs(int numPlayer)
} }
else // Si hay mas de un dispositivo, se recorre el vector else // Si hay mas de un dispositivo, se recorre el vector
{ {
printf("numplayer:%i\n",numPlayer); printf("numplayer:%i\n", numPlayer);
printf("deviceindex:%i\n",mDeviceIndex[numPlayer]); printf("deviceindex:%i\n", mDeviceIndex[numPlayer]);
// Incrementa el indice // Incrementa el indice
if (mDeviceIndex[numPlayer] < numDevices - 1) if (mDeviceIndex[numPlayer] < numDevices - 1)
mDeviceIndex[numPlayer]++; mDeviceIndex[numPlayer]++;
else else
mDeviceIndex[numPlayer] = 0; mDeviceIndex[numPlayer] = 0;
printf("deviceindex:%i\n",mDeviceIndex[numPlayer]); printf("deviceindex:%i\n", mDeviceIndex[numPlayer]);
// Si coincide con el del otro jugador, se lo intercambian // Si coincide con el del otro jugador, se lo intercambian
if (mDeviceIndex[0] == mDeviceIndex[1]) if (mDeviceIndex[0] == mDeviceIndex[1])
{ {
printf("%i:%i\n",mDeviceIndex[0],mDeviceIndex[1]);
//const int temp = mDeviceIndex[0];
//mDeviceIndex[0] = mDeviceIndex[1];
//mDeviceIndex[1] = temp;
const int theOtherPlayer = (numPlayer + 1) % 2; const int theOtherPlayer = (numPlayer + 1) % 2;
mDeviceIndex[theOtherPlayer]--; mDeviceIndex[theOtherPlayer]--;
if (mDeviceIndex[theOtherPlayer] < 0) if (mDeviceIndex[theOtherPlayer] < 0)
mDeviceIndex[theOtherPlayer]=numDevices-1; mDeviceIndex[theOtherPlayer] = numDevices - 1;
printf("%i:%i\n",mDeviceIndex[0],mDeviceIndex[1]);
} }
// Copia el dispositivo marcado por el indice a la variable de opciones de cada jugador // Copia el dispositivo marcado por el indice a la variable de opciones de cada jugador

View File

@@ -1,29 +1,41 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "asset.h"
#include "const.h" #include "const.h"
#include "utils.h"
#include "sprite.h"
#include "movingsprite.h"
#include "smartsprite.h"
#include "item.h"
#include "text.h"
#include "menu.h"
#include "fade.h" #include "fade.h"
#include "game.h"
#include "input.h" #include "input.h"
#include "instructions.h" #include "instructions.h"
#include "game.h" #include "item.h"
#include "jail_audio.h" #include "jail_audio.h"
#include "menu.h"
#include "movingsprite.h"
#include "screen.h"
#include "smartsprite.h"
#include "sprite.h"
#include "text.h"
#include "utils.h"
#ifndef TITLE_H #ifndef TITLE_H
#define TITLE_H #define TITLE_H
// Title // Textos
#define TEXT_COPYRIGHT "@2020,2022 JailDesigner (v2.1)"
// Contadores
#define TITLE_COUNTER 800
// Cantidad de eventos de la pantalla de titulo
#define TITLE_TOTAL_EVENTS 2
// Clase Title
class Title class Title
{ {
private: private:
SDL_Window *mWindow; // Ventana de la aplicación SDL_Window *mWindow; // Ventana de la aplicación
SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
AnimatedSprite *mDustBitmapL; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo AnimatedSprite *mDustBitmapL; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo
AnimatedSprite *mDustBitmapR; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo AnimatedSprite *mDustBitmapR; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo
bool mMenuVisible; // Indicador para saber si se muestra el menu del titulo o la frase intermitente bool mMenuVisible; // Indicador para saber si se muestra el menu del titulo o la frase intermitente
@@ -36,13 +48,12 @@ private:
LTexture *mTextTexture2; // Textura con los gráficos para el texto LTexture *mTextTexture2; // Textura con los gráficos para el texto
SDL_Event *mEventHandler; // Manejador de eventos SDL_Event *mEventHandler; // Manejador de eventos
SDL_Rect mBackgroundWindow; // Ventana visible para la textura de fondo del titulo SDL_Rect mBackgroundWindow; // Ventana visible para la textura de fondo del titulo
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Texture *mBackground; // Textura dibujar el fondo del titulo SDL_Texture *mBackground; // Textura dibujar el fondo del titulo
SmartSprite *mCoffeeBitmap; // Sprite con la palabra COFFEE para la pantalla de titulo SmartSprite *mCoffeeBitmap; // Sprite con la palabra COFFEE para la pantalla de titulo
SmartSprite *mCrisisBitmap; // Sprite con la palabra CRISIS para la pantalla de titulo SmartSprite *mCrisisBitmap; // Sprite con la palabra CRISIS para la pantalla de titulo
Sprite *mTile; // Sprite para dibujar el fondo de pantalla del título Sprite *mTile; // Sprite para dibujar el fondo de pantalla del título
Sprite *mGradient; // Sprite para dibujar el degradado del titulo Sprite *mGradient; // Sprite para dibujar el degradado del titulo
std::string *mFileList; // Lista de ficheros Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
Uint16 mBackgroundCounter; // Temporizador para el fondo de tiles de la pantalla de titulo Uint16 mBackgroundCounter; // Temporizador para el fondo de tiles de la pantalla de titulo
Uint16 mCounter; // Temporizador para la pantalla de titulo Uint16 mCounter; // Temporizador para la pantalla de titulo
@@ -70,10 +81,10 @@ private:
}; };
menu_t mMenu; // Variable con todos los objetos menus y sus variables menu_t mMenu; // Variable con todos los objetos menus y sus variables
struct options_t *mOptions; // Variable con todas las variables de las opciones del programa struct options_t *mOptions; // Variable con todas las variables de las opciones del programa
options_t mOptionsPrevious; // Variable de respaldo para las opciones options_t mOptionsPrevious; // Variable de respaldo para las opciones
std::vector<input_t> mAvailableInputDevices; // Vector con todos los metodos de control disponibles std::vector<input_t> mAvailableInputDevices; // Vector con todos los metodos de control disponibles
int mDeviceIndex[2]; // Indice para el jugador [i] del vector de dispositivos de entrada disponibles int mDeviceIndex[2]; // Indice para el jugador [i] del vector de dispositivos de entrada disponibles
// Carga los recursos necesarios para la sección 'Title' // Carga los recursos necesarios para la sección 'Title'
bool loadMedia(); bool loadMedia();
@@ -104,7 +115,7 @@ private:
public: public:
// Constructor // Constructor
Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::string *fileList, options_t *options, Lang *lang); Title(SDL_Window *window, SDL_Renderer *renderer, Screen *screen, Input *input, Asset *mAsset, options_t *options, Lang *lang);
// Destructor // Destructor
~Title(); ~Title();

View File

@@ -17,10 +17,7 @@ bool checkCollision(circle_t &a, circle_t &b)
// Si la distancia entre el centro de los circulos es inferior a la suma de sus radios // Si la distancia entre el centro de los circulos es inferior a la suma de sus radios
if (distanceSquared(a.x, a.y, b.x, b.y) < (totalRadiusSquared)) if (distanceSquared(a.x, a.y, b.x, b.y) < (totalRadiusSquared))
{ return true; // Los circulos han colisionado
// Los circulos han colisionado
return true;
}
// En caso contrario // En caso contrario
return false; return false;
@@ -114,11 +111,11 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
// Carga un archivo de imagen en una textura // Carga un archivo de imagen en una textura
bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer) bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer)
{ {
bool success = true; bool success = true;
if (!texture->loadFromFile(path, renderer)) if (!texture->loadFromFile(path, renderer))
{ {
printf("Failed to load %s texture!\n", path.c_str()); printf("Failed to load %s texture!\n", path.c_str());
success = false; success = false;
} }
return success; return success;
} }

View File

@@ -1,11 +1,21 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "ltexture.h" #include "ltexture.h"
#include <string> #include <string>
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
// Dificultad del juego
#define DIFFICULTY_EASY 0
#define DIFFICULTY_NORMAL 1
#define DIFFICULTY_HARD 2
// Tipo de filtro
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
// Estructura para definir un circulo // Estructura para definir un circulo
struct circle_t struct circle_t
{ {
@@ -55,9 +65,13 @@ struct options_t
input_t input[2]; // Modo de control (teclado o mando) input_t input[2]; // Modo de control (teclado o mando)
Uint8 language; // Idioma usado en el juego Uint8 language; // Idioma usado en el juego
Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa
Uint8 windowSize; // Contiene el valor del tamaño de la ventana Uint8 windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana
Uint32 filter; // Filtro usado para el escalado de la imagen Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no bool vSync; // Indica si se quiere usar vsync o no
int screenWidth; // Ancho de la pantalla/ventana
int screenHeight; // Alto de la pantalla/ventana
bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
}; };
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos

View File

@@ -134,9 +134,7 @@ void Writer::update()
void Writer::render() void Writer::render()
{ {
if (mEnabled) if (mEnabled)
{
mText->write(mPosX, mPosY, mCaption, mKerning, mIndex); mText->write(mPosX, mPosY, mCaption, mKerning, mIndex);
}
} }
// Centra la cadena de texto a un punto X // Centra la cadena de texto a un punto X

View File

@@ -1,11 +1,13 @@
#pragma once #pragma once
#include <SDL2/SDL.h>
#include "sprite.h" #include "sprite.h"
#include "text.h" #include "text.h"
#ifndef WRITER_H #ifndef WRITER_H
#define WRITER_H #define WRITER_H
// Clase texto. Pinta texto en pantalla a partir de un bitmap // Clase Writer. Pinta texto en pantalla a partir de una cadena y un bitmap
class Writer class Writer
{ {
private: private: