24 Commits

Author SHA1 Message Date
d9b08cf13a Configurando el initOnline 2022-12-07 11:55:32 +01:00
bbe82d329b Los datos se guardan en la carpeta de sistema 2022-12-07 11:23:19 +01:00
c87e1e68a9 Cambiados los accesos a vector de .at a [] 2022-12-07 09:29:06 +01:00
7adb049b37 Cambiados los printf por std::cout 2022-12-07 09:12:30 +01:00
6aebb28f37 Actualizado menu.cpp 2022-12-07 08:37:16 +01:00
cbdee55148 Actualizado animatedsprite.cpp 2022-12-07 08:11:49 +01:00
3cca4373d3 Actualizado asset.cpp 2022-12-07 08:08:04 +01:00
90785d2506 Actualizado input.cpp 2022-12-07 07:58:04 +01:00
fbeea9f424 Actualizados los ficheros de release 2022-12-05 10:21:18 +01:00
5f263fa71d Cambiando printf por std::cout 2022-12-05 10:07:27 +01:00
a32582f1ec Actualizadas las librerias comunes 2022-12-05 09:55:15 +01:00
09a205a288 Actualizando las clases comunes a sus ultimas versiones 2022-12-05 09:13:04 +01:00
cdb5040b9d Actualizado Makefile y numero de version 2022-12-05 08:31:30 +01:00
ded9b40922 Actualizado a la última versión de jail_audio 2022-12-05 08:05:15 +01:00
1144fc3626 Las notificaciones se dibujan a la mitad de resolución del juego 2022-11-19 09:39:14 +01:00
ea994bcc2f Optimizado el renderizado de notificaciones 2022-11-18 19:26:31 +01:00
74d5bbddaa Quitados dos warnings de variables sin usar 2022-11-17 22:01:43 +01:00
8ec0914bb5 Si no puede conectar al servidor online, desactiva el modo online 2022-11-17 20:15:34 +01:00
6d1bc066bd La tabla de records no sale si no está el modo online activo 2022-11-17 20:13:53 +01:00
975078307f Terminada la tabla de records 2022-11-17 20:08:31 +01:00
74d3066871 Actualizado el numero de versión 2022-11-17 18:58:20 +01:00
53c6da4a37 Añadida la primera versión de la tabla de records 2022-11-17 18:57:54 +01:00
3e666689c5 Actualizado Makefile 2022-11-17 10:16:58 +01:00
ef124cf309 Actualizado Makefile 2022-11-17 10:09:25 +01:00
53 changed files with 2185 additions and 1079 deletions

View File

@@ -2,7 +2,7 @@ executable = coffee_crisis
source = source/*.cpp source/common/*.cpp source = source/*.cpp source/common/*.cpp
appName = Coffee Crisis appName = Coffee Crisis
releaseFolder = cc_release releaseFolder = cc_release
version = v2.1b version = v2.2a
# Release names # Release names
windowsRelease = $(executable)-$(version)-win32-x64.zip windowsRelease = $(executable)-$(version)-win32-x64.zip
@@ -12,27 +12,30 @@ linuxRelease = $(executable)-$(version)-linux.tar.gz
windows: windows:
@echo off @echo off
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o $(executable).exe g++ $(source) -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(executable).exe"
strip -s -R .comment -R .gnu.version $(executable).exe --strip-unneeded strip -s -R .comment -R .gnu.version "$(executable).exe" --strip-unneeded
windows_debug:
@echo off
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(executable)_debug.exe"
strip -s -R .comment -R .gnu.version "$(executable)_debug.exe" --strip-unneeded
windows_release: windows_release:
@echo off @echo off
# Remove data # Create release folder
powershell if (Test-Path $(releaseFolder)) {Remove-Item $(releaseFolder) -Recurse -Force} powershell if (Test-Path "$(releaseFolder)") {Remove-Item "$(releaseFolder)" -Recurse -Force}
powershell if (-not (Test-Path "$(releaseFolder)")) {New-Item "$(releaseFolder)" -ItemType Directory}
# Create folders # Prepare data folder
powershell if (-not (Test-Path $(releaseFolder))) {New-Item $(releaseFolder) -ItemType Directory}
# Copy data
powershell Copy-Item -Path "data" -Destination "$(releaseFolder)" -recurse -Force powershell Copy-Item -Path "data" -Destination "$(releaseFolder)" -recurse -Force
powershell Copy-Item -Path "release/config.txt" -Destination "$(releaseFolder)/data/config" -recurse -Force powershell Copy-Item "release\config.txt" -Destination "$(releaseFolder)\data\config\"
powershell Copy-Item "LICENSE" -Destination "$(releaseFolder)" powershell if (Test-Path "$(releaseFolder)\data\config\score.bin") {Remove-Item "$(releaseFolder)\data\config\score.bin" -Recurse -Force}
powershell Copy-Item "README.md" -Destination "$(releaseFolder)"
powershell Copy-Item "release/SDL2.dll" -Destination "$(releaseFolder)"
# Remove data # Copy root files
powershell if (Test-Path data\config\score.bin) {Remove-Item data\config\score.bin -Recurse -Force} powershell Copy-Item "LICENSE.txt" -Destination "$(releaseFolder)"
powershell Copy-Item "README.md" -Destination "$(releaseFolder)"
powershell Copy-Item "release\*.dll" -Destination "$(releaseFolder)"
# Build # Build
g++ $(source) -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(releaseFolder)/$(executable).exe" g++ $(source) -std=c++11 -Wall -Os -lmingw32 -lws2_32 -lSDL2main -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -Wl,-subsystem,windows -o "$(releaseFolder)/$(executable).exe"
@@ -43,13 +46,16 @@ windows_release:
powershell Compress-Archive -Path "$(releaseFolder)"/* -DestinationPath $(windowsRelease) powershell Compress-Archive -Path "$(releaseFolder)"/* -DestinationPath $(windowsRelease)
# Remove folder # Remove folder
powershell if (Test-Path $(releaseFolder)) {Remove-Item $(releaseFolder) -Recurse -Force} powershell if (Test-Path "$(releaseFolder)") {Remove-Item "$(releaseFolder)" -Recurse -Force}
macos: macos:
clang++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o $(executable)_macos clang++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o "$(executable)"
macos_debug:
clang++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o "$(executable)_debug"
macos_release: macos_release:
# Remove data and possible data # Remove data and possible data from previous builds
rm -rdf "$(releaseFolder)" rm -rdf "$(releaseFolder)"
rm -rdf Frameworks rm -rdf Frameworks
rm -f tmp.dmg rm -f tmp.dmg
@@ -62,8 +68,9 @@ macos_release:
mkdir -p "$(releaseFolder)/$(appName).app/Contents/Resources" mkdir -p "$(releaseFolder)/$(appName).app/Contents/Resources"
mkdir -p Frameworks mkdir -p Frameworks
# Copy folders # Copy folders and files
cp -R data "$(releaseFolder)/$(appName).app/Contents/Resources" cp -R data "$(releaseFolder)/$(appName).app/Contents/Resources"
cp release/config.txt "$(releaseFolder)/$(appName).app/Contents/Resources/data/config"
cp -R release/SDL2.framework "$(releaseFolder)/$(appName).app/Contents/Frameworks" cp -R release/SDL2.framework "$(releaseFolder)/$(appName).app/Contents/Frameworks"
cp -R release/SDL2.framework Frameworks cp -R release/SDL2.framework Frameworks
@@ -73,57 +80,63 @@ macos_release:
# Copy files # Copy files
cp release/*.icns "$(releaseFolder)/$(appName).app/Contents/Resources" cp release/*.icns "$(releaseFolder)/$(appName).app/Contents/Resources"
cp release/Info.plist "$(releaseFolder)/$(appName).app/Contents" cp release/Info.plist "$(releaseFolder)/$(appName).app/Contents"
cp release/config.txt "$(releaseFolder)/$(appName).app/Contents/Resources/data/config" cp LICENSE.txt "$(releaseFolder)"
cp README.md "$(releaseFolder)"
# Create links
ln -s /Applications "$(releaseFolder)"/Applications
# Build INTEL # Build INTEL
clang++ $(source) -D MACOS_BUNDLE -std=c++11 -Wall -Os -framework SDL2 -F ./Frameworks -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12 clang++ $(source) -D MACOS_BUNDLE -std=c++11 -Wall -Os -framework SDL2 -F ./Frameworks -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12
# Build INTEL DMG # Build INTEL DMG
rm -f "$(executable)_macos_intel_$(version).dmg"
hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)" hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)"
hdiutil convert tmp.dmg -format UDZO -o "$(macosIntelRelease)" hdiutil convert tmp.dmg -format UDZO -o "$(macosIntelRelease)"
rm tmp.dmg rm -f tmp.dmg
# Build APPLE SILICON # Build APPLE SILICON
clang++ $(source) -D MACOS_BUNDLE -std=c++11 -Wall -Os -framework SDL2 -F ./Frameworks -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target arm64-apple-macos11 clang++ $(source) -D MACOS_BUNDLE -std=c++11 -Wall -Os -framework SDL2 -F ./Frameworks -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target arm64-apple-macos11
# Build APPLE SILICON DMG # Build APPLE SILICON DMG
rm -f "$(executable)_macos_apple_silicon_$(version).dmg"
hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)" hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)"
hdiutil convert tmp.dmg -format UDZO -o "$(macosAppleSiliconRelease)" hdiutil convert tmp.dmg -format UDZO -o "$(macosAppleSiliconRelease)"
rm tmp.dmg rm -f tmp.dmg
# Remove data # Remove data
rm -rdf Frameworks rm -rdf Frameworks
rm -rdf "$(releaseFolder)" rm -rdf "$(releaseFolder)"
linux: linux:
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(executable)_linux g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o "$(executable)"
strip -s -R .comment -R .gnu.version $(executable)_linux --strip-unneeded strip -s -R .comment -R .gnu.version "$(executable)" --strip-unneeded
linux_debug:
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o "$(executable)_debug"
strip -s -R .comment -R .gnu.version "$(executable)_debug" --strip-unneeded
linux_release: linux_release:
# Remove data # Remove data
rm -rdf $(releaseFolder) rm -rdf "$(releaseFolder)"
# Create folders # Create folders
mkdir -p $(releaseFolder) mkdir -p "$(releaseFolder)"
# Copy data # Copy data
cp -R data $(releaseFolder) cp -R data "$(releaseFolder)"
cp -R release/config.txt $(releaseFolder)/data/config cp release/config.txt "$(releaseFolder)/data/config/"
cp LICENSE $(releaseFolder) cp LICENSE.txt "$(releaseFolder)"
cp README.md $(releaseFolder) cp README.md "$(releaseFolder)"
# Delete data # Delete data
rm -f $(releaseFolder)/data/config/score.bin rm -f "$(releaseFolder)/data/config/score.bin"
# Build # Build
g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(releaseFolder)/$(executable) g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o "$(releaseFolder)/$(executable)"
strip -s -R .comment -R .gnu.version $(releaseFolder)/$(executable) --strip-unneeded strip -s -R .comment -R .gnu.version "$(releaseFolder)/$(executable)" --strip-unneeded
# Pack files # Pack files
rm -f $(linuxRelease) rm -f "$(linuxRelease)"
cd $(releaseFolder) && tar -czvf ../$(linuxRelease) * cd "$(releaseFolder)" && tar -czvf "../$(linuxRelease)" *
# Remove data # Remove data
rm -rdf $(releaseFolder) rm -rdf "$(releaseFolder)"

View File

@@ -124,8 +124,8 @@ Enrere
## 41 - MENU DE PAUSA ## 41 - MENU DE PAUSA
Menu de pausa Menu de pausa
## 42 - ## 42 - TABLA DE RECORDS
- Millors puntuacions
## 43 - PANTALLA DE GAME OVER ## 43 - PANTALLA DE GAME OVER
FI DEL JOC FI DEL JOC

View File

@@ -124,8 +124,8 @@ Back
## 41 - MENU DE PAUSA ## 41 - MENU DE PAUSA
Pause Menu Pause Menu
## 42 - ## 42 - TABLA DE RECORDS
- Best scores
## 43 - PANTALLA DE GAME OVER ## 43 - PANTALLA DE GAME OVER
GAME OVER GAME OVER

View File

@@ -124,8 +124,8 @@ Volver
## 41 - MENU DE PAUSA ## 41 - MENU DE PAUSA
Menu de pausa Menu de pausa
## 42 - ## 42 - TABLA DE RECORDS
- Mejores puntuaciones
## 43 - PANTALLA DE GAME OVER ## 43 - PANTALLA DE GAME OVER
FIN DE JUEGO FIN DE JUEGO

BIN
data/sound/notify.wav Normal file

Binary file not shown.

View File

@@ -13,7 +13,7 @@
<key>CFBundleIconName</key> <key>CFBundleIconName</key>
<string>coffee_crisis</string> <string>coffee_crisis</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>org.jailgames.coffee_crisis</string> <string>net.jailgames.coffee_crisis</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
@@ -21,11 +21,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0.0</string> <string>2.2a</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0.0</string> <string>2.2a</string>
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View File

@@ -0,0 +1 @@
Versions/Current/Headers

View File

@@ -0,0 +1 @@
Versions/Current/Resources

1
release/SDL2.framework/SDL2 Symbolic link
View File

@@ -0,0 +1 @@
Versions/Current/SDL2

0
release/SDL2.framework/Versions/A/SDL2 Normal file → Executable file
View File

View File

@@ -0,0 +1 @@
A

View File

@@ -1,14 +1,13 @@
## VISUAL OPTIONS ## VISUAL OPTIONS
fullScreenMode=0 videoMode=0
windowSize=3 windowSize=3
filter=FILTER_NEAREST filter=FILTER_NEAREST
vSync=true vSync=true
integerScale=true integerScale=true
keepAspect=true keepAspect=true
borderEnabled=false borderEnabled=false
borderSize=0.000000 borderWidth=0
screenWidth=256 borderHeight=0
screenHeight=192
## OTHER OPTIONS ## OTHER OPTIONS
language=1 language=1

BIN
release/libgcc_s_seh-1.dll Normal file

Binary file not shown.

BIN
release/libstdc++-6.dll Normal file

Binary file not shown.

BIN
release/libwinpthread-1.dll Normal file

Binary file not shown.

View File

@@ -849,8 +849,8 @@ void Balloon::updateBounce()
{ {
if (bouncing.enabled) if (bouncing.enabled)
{ {
bouncing.zoomW = bouncing.w.at(bouncing.counter / bouncing.speed); bouncing.zoomW = bouncing.w[bouncing.counter / bouncing.speed];
bouncing.zoomH = bouncing.h.at(bouncing.counter / bouncing.speed); bouncing.zoomH = bouncing.h[bouncing.counter / bouncing.speed];
sprite->setZoomW(bouncing.zoomW); sprite->setZoomW(bouncing.zoomW);
sprite->setZoomH(bouncing.zoomH); sprite->setZoomH(bouncing.zoomH);
bouncing.despX = (sprite->getSpriteClip().w - (sprite->getSpriteClip().w * bouncing.zoomW)); bouncing.despX = (sprite->getSpriteClip().w - (sprite->getSpriteClip().w * bouncing.zoomW));

View File

@@ -1,186 +1,16 @@
#include "animatedsprite.h" #include "animatedsprite.h"
// Constructor
AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, std::string file, std::vector<std::string> *buffer)
{
// Copia los punteros
setTexture(texture);
setRenderer(renderer);
// Carga las animaciones
if (file != "")
{
loadFromFile(file);
}
else if (buffer)
{
loadFromVector(buffer);
}
// Inicializa variables
currentAnimation = 0;
}
// Destructor
AnimatedSprite::~AnimatedSprite()
{
for (auto &a : animation)
{
a.frames.clear();
}
animation.clear();
}
// Obtiene el indice de la animación a partir del nombre
int AnimatedSprite::getIndex(std::string name)
{
int index = -1;
for (auto a : animation)
{
index++;
if (a.name == name)
{
return index;
}
}
printf("** Warning: could not find \"%s\" animation\n", name.c_str());
return -1;
}
// Calcula el frame correspondiente a la animación
void AnimatedSprite::animate()
{
if (!enabled || animation.at(currentAnimation).speed == 0)
{
return;
}
// Calcula el frame actual a partir del contador
animation.at(currentAnimation).currentFrame = animation.at(currentAnimation).counter / animation.at(currentAnimation).speed;
// Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame
if (animation.at(currentAnimation).currentFrame >= (int)animation.at(currentAnimation).frames.size())
{
if (animation.at(currentAnimation).loop == -1)
{ // Si no hay loop, deja el último frame
animation.at(currentAnimation).currentFrame = animation.at(currentAnimation).frames.size();
animation.at(currentAnimation).completed = true;
}
else
{ // Si hay loop, vuelve al frame indicado
animation.at(currentAnimation).counter = 0;
animation.at(currentAnimation).currentFrame = animation.at(currentAnimation).loop;
}
}
// En caso contrario
else
{
// Escoge el frame correspondiente de la animación
setSpriteClip(animation.at(currentAnimation).frames.at(animation.at(currentAnimation).currentFrame));
// Incrementa el contador de la animacion
animation.at(currentAnimation).counter++;
}
}
// Obtiene el numero de frames de la animación actual
int AnimatedSprite::getNumFrames()
{
return (int)animation.at(currentAnimation).frames.size();
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(int num)
{
// Descarta valores fuera de rango
if (num >= (int)animation.at(currentAnimation).frames.size())
{
num = 0;
}
// Cambia el valor de la variable
animation.at(currentAnimation).counter = animation.at(currentAnimation).speed * num;
// Escoge el frame correspondiente de la animación
setSpriteClip(animation.at(currentAnimation).frames.at(animation.at(currentAnimation).currentFrame));
}
// Establece el valor del contador
void AnimatedSprite::setAnimationCounter(std::string name, int num)
{
animation.at(getIndex(name)).counter = num;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(std::string name, int speed)
{
animation.at(getIndex(name)).counter = speed;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(int index, int speed)
{
animation.at(index).counter = speed;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(std::string name, int loop)
{
animation.at(getIndex(name)).loop = loop;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(int index, int loop)
{
animation.at(index).loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(std::string name, bool value)
{
animation.at(getIndex(name)).completed = value;
}
// OLD - Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(int index, bool value)
{
animation.at(index).completed = value;
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::animationIsCompleted()
{
return animation.at(currentAnimation).completed;
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(std::string name, Uint8 index)
{
return animation.at(getIndex(name)).frames.at(index);
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF)
{
return animation.at(indexA).frames.at(indexF);
}
// Carga la animación desde un fichero // Carga la animación desde un fichero
bool AnimatedSprite::loadFromFile(std::string filePath) animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose)
{ {
// Inicializa variables
animatedSprite_t as;
as.texture = texture;
int framesPerRow = 0; int framesPerRow = 0;
int frameWidth = 0; int frameWidth = 0;
int frameHeight = 0; int frameHeight = 0;
int maxTiles = 0; int maxTiles = 0;
// Indicador de éxito en la carga
bool success = true;
const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1); const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1);
std::ifstream file(filePath); std::ifstream file(filePath);
std::string line; std::string line;
@@ -189,13 +19,16 @@ bool AnimatedSprite::loadFromFile(std::string filePath)
if (file.good()) if (file.good())
{ {
// Procesa el fichero linea a linea // Procesa el fichero linea a linea
std::cout << "Loading animation from file: " << filePath.c_str() << std::endl; if (verbose)
{
std::cout << "Animation loaded: " << filename << std::endl;
}
while (std::getline(file, line)) while (std::getline(file, line))
{ {
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación // Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]") if (line == "[animation]")
{ {
t_animation buffer; animation_t buffer;
buffer.counter = 0; buffer.counter = 0;
buffer.currentFrame = 0; buffer.currentFrame = 0;
buffer.completed = false; buffer.completed = false;
@@ -243,14 +76,13 @@ bool AnimatedSprite::loadFromFile(std::string filePath)
else else
{ {
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str()); std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
success = false;
} }
} }
} while (line != "[/animation]"); } while (line != "[/animation]");
// Añade la animación al vector de animaciones // Añade la animación al vector de animaciones
animation.push_back(buffer); as.animations.push_back(buffer);
} }
// En caso contrario se parsea el fichero para buscar las variables y los valores // En caso contrario se parsea el fichero para buscar las variables y los valores
@@ -279,8 +111,7 @@ bool AnimatedSprite::loadFromFile(std::string filePath)
else else
{ {
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str()); std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
success = false;
} }
// Normaliza valores // Normaliza valores
@@ -305,14 +136,207 @@ bool AnimatedSprite::loadFromFile(std::string filePath)
// El fichero no se puede abrir // El fichero no se puede abrir
else else
{ {
printf("Warning: Unable to open %s file\n", filename.c_str()); if (verbose)
success = false; {
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl;
}
} }
// Pone un valor por defecto return as;
setRect({0, 0, frameWidth, frameHeight}); }
return success; // Constructor
AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, std::string file, std::vector<std::string> *buffer)
{
// Copia los punteros
setTexture(texture);
setRenderer(renderer);
// Carga las animaciones
if (file != "")
{
animatedSprite_t as = loadAnimationFromFile(texture, file);
// Copia los datos de las animaciones
for (auto animation : as.animations)
{
this->animation.push_back(animation);
}
}
else if (buffer)
{
loadFromVector(buffer);
}
// Inicializa variables
currentAnimation = 0;
}
// Constructor
AnimatedSprite::AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation)
{
// Copia los punteros
setTexture(animation->texture);
setRenderer(renderer);
// Inicializa variables
currentAnimation = 0;
// Copia los datos de las animaciones
for (auto a : animation->animations)
{
this->animation.push_back(a);
}
}
// Destructor
AnimatedSprite::~AnimatedSprite()
{
for (auto &a : animation)
{
a.frames.clear();
}
animation.clear();
}
// Obtiene el indice de la animación a partir del nombre
int AnimatedSprite::getIndex(std::string name)
{
int index = -1;
for (auto a : animation)
{
index++;
if (a.name == name)
{
return index;
}
}
std::cout << "** Warning: could not find \"" << name.c_str() << "\" animation" << std::endl;
return -1;
}
// Calcula el frame correspondiente a la animación
void AnimatedSprite::animate()
{
if (!enabled || animation[currentAnimation].speed == 0)
{
return;
}
// Calcula el frame actual a partir del contador
animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed;
// Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame
if (animation[currentAnimation].currentFrame >= (int)animation[currentAnimation].frames.size())
{
if (animation[currentAnimation].loop == -1)
{ // Si no hay loop, deja el último frame
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size();
animation[currentAnimation].completed = true;
}
else
{ // Si hay loop, vuelve al frame indicado
animation[currentAnimation].counter = 0;
animation[currentAnimation].currentFrame = animation[currentAnimation].loop;
}
}
// 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++;
}
}
// Obtiene el numero de frames de la animación actual
int AnimatedSprite::getNumFrames()
{
return (int)animation[currentAnimation].frames.size();
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(int num)
{
// Descarta valores fuera de rango
if (num >= (int)animation[currentAnimation].frames.size())
{
num = 0;
}
// Cambia el valor de la variable
animation[currentAnimation].currentFrame = num;
animation[currentAnimation].counter = 0;
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
}
// Establece el valor del contador
void AnimatedSprite::setAnimationCounter(std::string name, int 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];
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF)
{
return animation[indexA].frames[indexF];
} }
// Carga la animación desde un vector // Carga la animación desde un vector
@@ -338,7 +362,7 @@ bool AnimatedSprite::loadFromVector(std::vector<std::string> *source)
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación // Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]") if (line == "[animation]")
{ {
t_animation buffer; animation_t buffer;
buffer.counter = 0; buffer.counter = 0;
buffer.currentFrame = 0; buffer.currentFrame = 0;
buffer.completed = false; buffer.completed = false;
@@ -460,9 +484,9 @@ void AnimatedSprite::setCurrentAnimation(std::string name)
if (currentAnimation != newAnimation) if (currentAnimation != newAnimation)
{ {
currentAnimation = newAnimation; currentAnimation = newAnimation;
animation.at(currentAnimation).currentFrame = 0; animation[currentAnimation].currentFrame = 0;
animation.at(currentAnimation).counter = 0; animation[currentAnimation].counter = 0;
animation.at(currentAnimation).completed = false; animation[currentAnimation].completed = false;
} }
} }
@@ -473,9 +497,9 @@ void AnimatedSprite::setCurrentAnimation(int index)
if (currentAnimation != newAnimation) if (currentAnimation != newAnimation)
{ {
currentAnimation = newAnimation; currentAnimation = newAnimation;
animation.at(currentAnimation).currentFrame = 0; animation[currentAnimation].currentFrame = 0;
animation.at(currentAnimation).counter = 0; animation[currentAnimation].counter = 0;
animation.at(currentAnimation).completed = false; animation[currentAnimation].completed = false;
} }
} }
@@ -489,7 +513,7 @@ void AnimatedSprite::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)
{ {
animation.at(index_animation).frames.push_back({x, y, w, h}); animation[index_animation].frames.push_back({x, y, w, h});
} }
// OLD - Establece el contador para todas las animaciones // OLD - Establece el contador para todas las animaciones
@@ -504,7 +528,7 @@ void AnimatedSprite::setAnimationCounter(int value)
// Reinicia la animación // Reinicia la animación
void AnimatedSprite::resetAnimation() void AnimatedSprite::resetAnimation()
{ {
animation.at(currentAnimation).currentFrame = 0; animation[currentAnimation].currentFrame = 0;
animation.at(currentAnimation).counter = 0; animation[currentAnimation].counter = 0;
animation.at(currentAnimation).completed = false; animation[currentAnimation].completed = false;
} }

View File

@@ -11,28 +11,37 @@
#ifndef ANIMATEDSPRITE_H #ifndef ANIMATEDSPRITE_H
#define ANIMATEDSPRITE_H #define ANIMATEDSPRITE_H
// Clase AnimatedSprite struct animation_t
{
std::string name; // Nombre de la animacion
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
int speed; // Velocidad de la animación
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
int currentFrame; // Frame actual
int counter; // Contador para las animaciones
};
struct animatedSprite_t
{
std::vector<animation_t> animations; // Vector con las diferentes animaciones
Texture *texture; // Textura con los graficos para el sprite
};
// Carga la animación desde un fichero
animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose = false);
class AnimatedSprite : public MovingSprite class AnimatedSprite : public MovingSprite
{ {
private: private:
struct t_animation
{
std::string name; // Nombre de la animacion
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
int speed; // Velocidad de la animación
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
int currentFrame; // Frame actual
int counter; // Contador para las animaciones
};
// Variables // Variables
std::vector<t_animation> animation; // Vector con las diferentes animaciones std::vector<animation_t> animation; // Vector con las diferentes animaciones
int currentAnimation; // Animacion activa int currentAnimation; // Animacion activa
public: public:
// Constructor // Constructor
AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "", std::vector<std::string> *buffer = nullptr); AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "", std::vector<std::string> *buffer = nullptr);
AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation);
// Destructor // Destructor
~AnimatedSprite(); ~AnimatedSprite();
@@ -65,15 +74,12 @@ public:
bool animationIsCompleted(); 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(std::string name, Uint8 index); SDL_Rect getAnimationClip(std::string name = "default", Uint8 index = 0);
SDL_Rect getAnimationClip(int indexA, Uint8 indexF); SDL_Rect getAnimationClip(int indexA = 0, Uint8 indexF = 0);
// Obtiene el indice de la animación a partir del nombre // Obtiene el indice de la animación a partir del nombre
int getIndex(std::string name); int getIndex(std::string name);
// Carga la animación desde un fichero
bool loadFromFile(std::string filePath);
// Carga la animación desde un vector // Carga la animación desde un vector
bool loadFromVector(std::vector<std::string> *source); bool loadFromVector(std::vector<std::string> *source);

View File

@@ -1,22 +1,19 @@
#include "asset.h" #include "asset.h"
#include <iostream>
// Constructor // Constructor
Asset::Asset(std::string executablePath) Asset::Asset(std::string executablePath)
{ {
this->executablePath = executablePath.substr(0, executablePath.find_last_of("\\/")); this->executablePath = executablePath.substr(0, executablePath.find_last_of("\\/"));
longestName = 0; longestName = 0;
} verbose = true;
// Destructor
Asset::~Asset()
{
} }
// Añade un elemento a la lista // Añade un elemento a la lista
void Asset::add(std::string file, enum assetType type, bool required) void Asset::add(std::string file, enum assetType type, bool required, bool absolute)
{ {
item_t temp; item_t temp;
temp.file = executablePath + file; temp.file = absolute ? file : executablePath + file;
temp.type = type; temp.type = type;
temp.required = required; temp.required = required;
fileList.push_back(temp); fileList.push_back(temp);
@@ -30,13 +27,19 @@ std::string Asset::get(std::string text)
{ {
for (auto f : fileList) for (auto f : fileList)
{ {
if (f.file.find(text) != std::string::npos) const size_t lastIndex = f.file.find_last_of("/") + 1;
const std::string file = f.file.substr(lastIndex, std::string::npos);
if (file == text)
{ {
return f.file; return f.file;
} }
} }
printf("Warning: file %s not found\n", text.c_str()); if (verbose)
{
std::cout << "Warning: file " << text.c_str() << " not found" << std::endl;
}
return ""; return "";
} }
@@ -45,7 +48,13 @@ bool Asset::check()
{ {
bool success = true; bool success = true;
printf("\n** Checking files.\n"); if (verbose)
{
std::cout << "\n** Checking files" << std::endl;
std::cout << "Executable path is: " << executablePath << std::endl;
std::cout << "Sample filepath: " << fileList.back().file << std::endl;
}
// Comprueba la lista de ficheros clasificandolos por tipo // Comprueba la lista de ficheros clasificandolos por tipo
for (int type = 0; type < t_maxAssetType; ++type) for (int type = 0; type < t_maxAssetType; ++type)
@@ -64,7 +73,10 @@ bool Asset::check()
// Si hay ficheros de ese tipo, comprueba si existen // Si hay ficheros de ese tipo, comprueba si existen
if (any) if (any)
{ {
printf("\n>> %s FILES\n", getTypeName(type).c_str()); if (verbose)
{
std::cout << "\n>> " << getTypeName(type).c_str() << " FILES" << std::endl;
}
for (auto f : fileList) for (auto f : fileList)
{ {
@@ -77,13 +89,18 @@ bool Asset::check()
} }
// Resultado // Resultado
if (success) if (verbose)
{ {
printf("\n** All files OK.\n\n"); if (success)
} {
else std::cout << "\n** All files OK.\n"
{ << std::endl;
printf("\n** A file is missing. Exiting.\n\n"); }
else
{
std::cout << "\n** A file is missing. Exiting.\n"
<< std::endl;
}
} }
return success; return success;
@@ -97,7 +114,7 @@ bool Asset::checkFile(std::string path)
// Comprueba si existe el fichero // Comprueba si existe el fichero
const std::string filename = path.substr(path.find_last_of("\\/") + 1); const std::string filename = path.substr(path.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(path.c_str(), "r+b"); SDL_RWops *file = SDL_RWFromFile(path.c_str(), "rb");
if (file != nullptr) if (file != nullptr)
{ {
@@ -106,8 +123,15 @@ bool Asset::checkFile(std::string path)
SDL_RWclose(file); SDL_RWclose(file);
} }
const std::string s = "Checking file %-" + std::to_string(longestName) + "s [" + result + "]\n"; if (verbose)
printf(s.c_str(), filename.c_str()); {
std::cout.setf(std::ios::left, std::ios::adjustfield);
std::cout << "Checking file: ";
std::cout.width(longestName + 2);
std::cout.fill('.');
std::cout << filename + " ";
std::cout << " [" + result + "]" << std::endl;
}
return success; return success;
} }
@@ -158,3 +182,9 @@ std::string Asset::getTypeName(int type)
break; break;
} }
} }
// Establece si ha de mostrar texto por pantalla
void Asset::setVerbose(bool value)
{
verbose = value;
}

View File

@@ -31,34 +31,36 @@ private:
std::string file; // Ruta del fichero desde la raiz del directorio std::string file; // Ruta del fichero desde la raiz del directorio
enum assetType type; // Indica el tipo de recurso enum assetType type; // Indica el tipo de recurso
bool required; // Indica si es un fichero que debe de existir bool required; // Indica si es un fichero que debe de existir
//bool absolute; // Indica si la ruta que se ha proporcionado es una ruta absoluta
}; };
int longestName; // Contiene la longitud del nombre de fichero mas largo // Variables
int longestName; // Contiene la longitud del nombre de fichero mas largo
std::vector<item_t> fileList; std::vector<item_t> fileList; // Listado con todas las rutas a los ficheros
std::string executablePath; std::string executablePath; // Ruta al ejecutable
bool verbose; // Indica si ha de mostrar información por pantalla
// Comprueba que existe un fichero // Comprueba que existe un fichero
bool checkFile(std::string path); bool checkFile(std::string executablePath);
// Devuelve el nombre del tipo de recurso // Devuelve el nombre del tipo de recurso
std::string getTypeName(int type); std::string getTypeName(int type);
public: public:
// Constructor // Constructor
Asset(std::string executablePath); Asset(std::string path);
// Destructor
~Asset();
// Añade un elemento a la lista // Añade un elemento a la lista
void add(std::string file, enum assetType type, bool required = true); void add(std::string file, enum assetType type, bool required = true, bool absolute = false);
// Devuelve un elemento de la lista a partir de una cadena // Devuelve un elemento de la lista a partir de una cadena
std::string get(std::string text); std::string get(std::string text);
// Comprueba que existen todos los elementos // Comprueba que existen todos los elementos
bool check(); bool check();
// Establece si ha de mostrar texto por pantalla
void setVerbose(bool value);
}; };
#endif #endif

View File

@@ -18,35 +18,48 @@ Input::Input(std::string file)
gcb.active = false; gcb.active = false;
gameControllerBindings.resize(17, gcb); gameControllerBindings.resize(17, gcb);
// Comprueba si hay un mando conectado verbose = true;
discoverGameController(); enabled = true;
numGamepads = 0;
} }
// Destructor // Actualiza el estado del objeto
Input::~Input() void Input::update()
{ {
if (disabledUntil == d_keyPressed && !checkAnyInput())
{
enable();
}
} }
// Asigna uno de los posibles inputs a una tecla del teclado // Asigna inputs a teclas
void Input::bindKey(Uint8 input, SDL_Scancode code) void Input::bindKey(Uint8 input, SDL_Scancode code)
{ {
keyBindings.at(input).scancode = code; keyBindings[input].scancode = code;
} }
// Asigna uno de los posibles inputs a un botón del mando // Asigna inputs a botones del mando
void Input::bindGameControllerButton(Uint8 input, SDL_GameControllerButton button) void Input::bindGameControllerButton(Uint8 input, SDL_GameControllerButton button)
{ {
gameControllerBindings.at(input).button = button; gameControllerBindings[input].button = button;
} }
// Comprueba si un input esta activo // Comprueba si un input esta activo
bool Input::checkInput(Uint8 input, bool repeat, int device, int index) bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
{ {
if (!enabled)
{
return false;
}
bool successKeyboard = false; bool successKeyboard = false;
bool successGameController = false; bool successGameController = false;
if (device == INPUT_USE_ANY) if (device == INPUT_USE_ANY)
{
index = 0; index = 0;
}
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY)
{ {
@@ -54,7 +67,7 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
if (repeat) if (repeat)
{ {
if (keyStates[keyBindings.at(input).scancode] != 0) if (keyStates[keyBindings[input].scancode] != 0)
{ {
successKeyboard = true; successKeyboard = true;
} }
@@ -65,11 +78,11 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
} }
else else
{ {
if (!keyBindings.at(input).active) if (!keyBindings[input].active)
{ {
if (keyStates[keyBindings.at(input).scancode] != 0) if (keyStates[keyBindings[input].scancode] != 0)
{ {
keyBindings.at(input).active = true; keyBindings[input].active = true;
successKeyboard = true; successKeyboard = true;
} }
else else
@@ -79,9 +92,9 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
} }
else else
{ {
if (keyStates[keyBindings.at(input).scancode] == 0) if (keyStates[keyBindings[input].scancode] == 0)
{ {
keyBindings.at(input).active = false; keyBindings[input].active = false;
successKeyboard = false; successKeyboard = false;
} }
else else
@@ -97,7 +110,7 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
{ {
if (repeat) if (repeat)
{ {
if (SDL_GameControllerGetButton(connectedControllers.at(index), gameControllerBindings.at(input).button) != 0) if (SDL_GameControllerGetButton(connectedControllers[index], gameControllerBindings[input].button) != 0)
{ {
successGameController = true; successGameController = true;
} }
@@ -108,11 +121,11 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
} }
else else
{ {
if (!gameControllerBindings.at(input).active) if (!gameControllerBindings[input].active)
{ {
if (SDL_GameControllerGetButton(connectedControllers.at(index), gameControllerBindings.at(input).button) != 0) if (SDL_GameControllerGetButton(connectedControllers[index], gameControllerBindings[input].button) != 0)
{ {
gameControllerBindings.at(input).active = true; gameControllerBindings[input].active = true;
successGameController = true; successGameController = true;
} }
else else
@@ -122,9 +135,9 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
} }
else else
{ {
if (SDL_GameControllerGetButton(connectedControllers.at(index), gameControllerBindings.at(input).button) == 0) if (SDL_GameControllerGetButton(connectedControllers[index], gameControllerBindings[input].button) == 0)
{ {
gameControllerBindings.at(input).active = false; gameControllerBindings[input].active = false;
successGameController = false; successGameController = false;
} }
else else
@@ -152,7 +165,7 @@ bool Input::checkAnyInput(int device, int index)
for (int i = 0; i < (int)keyBindings.size(); ++i) for (int i = 0; i < (int)keyBindings.size(); ++i)
{ {
if (mKeystates[keyBindings.at(i).scancode] != 0) if (mKeystates[keyBindings[i].scancode] != 0)
{ {
return true; return true;
} }
@@ -165,7 +178,7 @@ bool Input::checkAnyInput(int device, int index)
{ {
for (int i = 0; i < (int)gameControllerBindings.size(); ++i) for (int i = 0; i < (int)gameControllerBindings.size(); ++i)
{ {
if (SDL_GameControllerGetButton(connectedControllers.at(index), gameControllerBindings.at(i).button) != 0) if (SDL_GameControllerGetButton(connectedControllers[index], gameControllerBindings[i].button) != 0)
{ {
return true; return true;
} }
@@ -176,7 +189,7 @@ bool Input::checkAnyInput(int device, int index)
return false; return false;
} }
// Comprueba si hay un mando conectado // Busca si hay un mando conectado
bool Input::discoverGameController() bool Input::discoverGameController()
{ {
bool found = false; bool found = false;
@@ -188,7 +201,10 @@ bool Input::discoverGameController()
if (SDL_GameControllerAddMappingsFromFile(dbPath.c_str()) < 0) if (SDL_GameControllerAddMappingsFromFile(dbPath.c_str()) < 0)
{ {
printf("Error, could not load %s file: %s\n", dbPath.c_str(), SDL_GetError()); if (verbose)
{
std::cout << "Error, could not load " << dbPath.c_str() << " file: " << SDL_GetError() << std::endl;
}
} }
const int nJoysticks = SDL_NumJoysticks(); const int nJoysticks = SDL_NumJoysticks();
@@ -203,8 +219,11 @@ bool Input::discoverGameController()
} }
} }
printf("\nChecking for game controllers...\n"); if (verbose)
printf("%i joysticks found, %i are gamepads\n", nJoysticks, numGamepads); {
std::cout << "\nChecking for game controllers...\n";
std::cout << nJoysticks << " joysticks found, " << numGamepads << " are gamepads\n";
}
if (numGamepads > 0) if (numGamepads > 0)
{ {
@@ -221,12 +240,18 @@ bool Input::discoverGameController()
std::string name = SDL_GameControllerNameForIndex(i); std::string name = SDL_GameControllerNameForIndex(i);
name.resize(25); name.resize(25);
name = name + separator + std::to_string(i); name = name + separator + std::to_string(i);
std::cout << name << std::endl; if (verbose)
{
std::cout << name << std::endl;
}
controllerNames.push_back(name); controllerNames.push_back(name);
} }
else else
{ {
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl; if (verbose)
{
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
}
} }
} }
@@ -254,7 +279,7 @@ std::string Input::getControllerName(int index)
{ {
if (numGamepads > 0) if (numGamepads > 0)
{ {
return controllerNames.at(index); return controllerNames[index];
} }
else else
{ {
@@ -267,3 +292,23 @@ int Input::getNumControllers()
{ {
return numGamepads; return numGamepads;
} }
// Establece si ha de mostrar mensajes
void Input::setVerbose(bool value)
{
verbose = value;
}
// Deshabilita las entradas durante un periodo de tiempo
void Input::disableUntil(i_disable_e value)
{
disabledUntil = value;
enabled = false;
}
// Hablita las entradas
void Input::enable()
{
enabled = true;
disabledUntil = d_notDisabled;
}

View File

@@ -32,7 +32,13 @@
#define INPUT_USE_GAMECONTROLLER 1 #define INPUT_USE_GAMECONTROLLER 1
#define INPUT_USE_ANY 2 #define INPUT_USE_ANY 2
// Clase Input enum i_disable_e
{
d_notDisabled,
d_forever,
d_keyPressed
};
class Input class Input
{ {
private: private:
@@ -48,34 +54,40 @@ private:
bool active; // Indica si está activo bool active; // Indica si está activo
}; };
// Objetos y punteros
std::vector<SDL_GameController *> connectedControllers; // Vector con todos los mandos conectados
// Variables
std::vector<keyBindings_t> keyBindings; // Vector con las teclas asociadas a los inputs predefinidos std::vector<keyBindings_t> keyBindings; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<GameControllerBindings_t> gameControllerBindings; // Vector con las teclas asociadas a los inputs predefinidos std::vector<GameControllerBindings_t> gameControllerBindings; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<SDL_GameController *> connectedControllers; // Vector con todos los mandos conectados
std::vector<std::string> controllerNames; // Vector con los nombres de los mandos std::vector<std::string> controllerNames; // Vector con los nombres de los mandos
int numGamepads; // Numero de mandos conectados int numGamepads; // Numero de mandos conectados
std::string dbPath; // Ruta al archivo gamecontrollerdb.txt std::string dbPath; // Ruta al archivo gamecontrollerdb.txt
bool verbose; // Indica si ha de mostrar mensajes
// Comprueba si hay un mando conectado i_disable_e disabledUntil; // Tiempo que esta deshabilitado
bool discoverGameController(); bool enabled; // Indica si está habilitado
public: public:
// Constructor // Constructor
Input(std::string file); Input(std::string file);
// Destructor // Actualiza el estado del objeto
~Input(); void update();
// Asigna uno de los posibles inputs a una tecla del teclado // Asigna inputs a teclas
void bindKey(Uint8 input, SDL_Scancode code); void bindKey(Uint8 input, SDL_Scancode code);
// Asigna uno de los posibles inputs a un botón del mando // Asigna inputs a botones del mando
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 almenos un input activo // Comprueba si hay almenos un input activo
bool checkAnyInput(int device, int index); bool checkAnyInput(int device = INPUT_USE_ANY, int index = 0);
// Busca si hay un mando conectado
bool discoverGameController();
// Comprueba si hay algun mando conectado // Comprueba si hay algun mando conectado
bool gameControllerFound(); bool gameControllerFound();
@@ -85,6 +97,15 @@ public:
// Obten el nombre de un mando de juego // Obten el nombre de un mando de juego
std::string getControllerName(int index); std::string getControllerName(int index);
// Establece si ha de mostrar mensajes
void setVerbose(bool value);
// Deshabilita las entradas durante un periodo de tiempo
void disableUntil(i_disable_e value);
// Hablita las entradas
void enable();
}; };
#endif #endif

View File

@@ -1,3 +1,4 @@
#ifndef JA_USESDLMIXER
#include "jail_audio.h" #include "jail_audio.h"
#include "stb_vorbis.c" #include "stb_vorbis.c"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
@@ -11,7 +12,7 @@ struct JA_Sound_t {
}; };
struct JA_Channel_t { struct JA_Channel_t {
JA_Sound sound; JA_Sound_t *sound;
int pos {0}; int pos {0};
int times {0}; int times {0};
JA_Channel_state state { JA_CHANNEL_FREE }; JA_Channel_state state { JA_CHANNEL_FREE };
@@ -25,7 +26,7 @@ struct JA_Music_t {
JA_Music_state state {JA_MUSIC_INVALID}; JA_Music_state state {JA_MUSIC_INVALID};
}; };
JA_Music current_music{NULL}; JA_Music_t *current_music{NULL};
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000}; int JA_freq {48000};
@@ -86,7 +87,7 @@ void JA_Quit() {
sdlAudioDevice = 0; sdlAudioDevice = 0;
} }
JA_Music JA_LoadMusic(const char* filename) { JA_Music_t *JA_LoadMusic(const char* filename) {
int chan, samplerate; int chan, samplerate;
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid. // [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
@@ -98,7 +99,7 @@ JA_Music JA_LoadMusic(const char* filename) {
if (fread(buffer, fsize, 1, f)!=1) return NULL; if (fread(buffer, fsize, 1, f)!=1) return NULL;
fclose(f); fclose(f);
JA_Music music = new JA_Music_t(); JA_Music_t *music = new JA_Music_t();
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output); music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
free(buffer); free(buffer);
@@ -121,7 +122,7 @@ JA_Music JA_LoadMusic(const char* filename) {
return music; return music;
} }
void JA_PlayMusic(JA_Music music, const int loop) { void JA_PlayMusic(JA_Music_t *music, const int loop) {
if (current_music != NULL) { if (current_music != NULL) {
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED; current_music->state = JA_MUSIC_STOPPED;
@@ -153,21 +154,21 @@ JA_Music_state JA_GetMusicState() {
return current_music->state; return current_music->state;
} }
void JA_DeleteMusic(JA_Music music) { void JA_DeleteMusic(JA_Music_t *music) {
if (current_music == music) current_music = NULL; if (current_music == music) current_music = NULL;
free(music->output); free(music->output);
delete music; delete music;
} }
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length) { JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) {
JA_Sound sound = new JA_Sound_t(); JA_Sound_t *sound = new JA_Sound_t();
sound->buffer = buffer; sound->buffer = buffer;
sound->length = length; sound->length = length;
return sound; return sound;
} }
JA_Sound JA_LoadSound(const char* filename) { JA_Sound_t *JA_LoadSound(const char* filename) {
JA_Sound sound = new JA_Sound_t(); JA_Sound_t *sound = new JA_Sound_t();
SDL_AudioSpec wavSpec; SDL_AudioSpec wavSpec;
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length); SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
@@ -184,7 +185,7 @@ JA_Sound JA_LoadSound(const char* filename) {
return sound; return sound;
} }
int JA_PlaySound(JA_Sound sound, const int loop) { int JA_PlaySound(JA_Sound_t *sound, const int loop) {
int channel = 0; int channel = 0;
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0; if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
@@ -196,7 +197,7 @@ int JA_PlaySound(JA_Sound sound, const int loop) {
return channel; return channel;
} }
void JA_DeleteSound(JA_Sound sound) { void JA_DeleteSound(JA_Sound_t *sound) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].sound == sound) JA_StopChannel(i); if (channels[i].sound == sound) JA_StopChannel(i);
} }
@@ -247,3 +248,4 @@ int JA_SetVolume(int volume) {
JA_volume = volume > 128 ? 128 : volume < 0 ? 0 : volume; JA_volume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return JA_volume; return JA_volume;
} }
#endif

View File

@@ -4,27 +4,27 @@
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 };
typedef struct JA_Sound_t *JA_Sound; struct JA_Sound_t;
typedef struct JA_Music_t *JA_Music; struct JA_Music_t;
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels); void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
void JA_Quit(); void JA_Quit();
JA_Music JA_LoadMusic(const char* filename); JA_Music_t *JA_LoadMusic(const char* filename);
void JA_PlayMusic(JA_Music music, const int loop = -1); void JA_PlayMusic(JA_Music_t *music, const int loop = -1);
void JA_PauseMusic(); void JA_PauseMusic();
void JA_ResumeMusic(); void JA_ResumeMusic();
void JA_StopMusic(); void JA_StopMusic();
JA_Music_state JA_GetMusicState(); JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music music); void JA_DeleteMusic(JA_Music_t *music);
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length); JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound JA_LoadSound(const char* filename); JA_Sound_t *JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound sound, const int loop = 0); int JA_PlaySound(JA_Sound_t *sound, const int loop = 0);
void JA_PauseChannel(const int channel); void JA_PauseChannel(const int channel);
void JA_ResumeChannel(const int channel); 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_t *sound);
int JA_SetVolume(int volume); int JA_SetVolume(int volume);

View File

@@ -0,0 +1,101 @@
#ifdef JA_USESDLMIXER
#include "jail_audio.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <stdio.h>
struct JA_Sound_t {}; // Dummy structs
struct JA_Music_t {};
int JA_freq {48000};
SDL_AudioFormat JA_format {AUDIO_S16};
Uint8 JA_channels {2};
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
JA_freq = freq;
JA_format = format;
JA_channels = channels;
Mix_OpenAudio(JA_freq, JA_format, JA_channels, 1024);
}
void JA_Quit() {
Mix_CloseAudio();
}
JA_Music_t *JA_LoadMusic(const char* filename) {
return (JA_Music_t*)Mix_LoadMUS(filename);
}
void JA_PlayMusic(JA_Music_t *music, const int loop) {
Mix_PlayMusic((Mix_Music*)music, loop);
}
void JA_PauseMusic() {
Mix_PauseMusic();
}
void JA_ResumeMusic() {
Mix_ResumeMusic();
}
void JA_StopMusic() {
Mix_HaltMusic();
}
JA_Music_state JA_GetMusicState() {
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_t *music) {
Mix_FreeMusic((Mix_Music*)music);
}
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) {
return NULL;
}
JA_Sound_t *JA_LoadSound(const char* filename) {
JA_Sound_t *sound = (JA_Sound_t*)Mix_LoadWAV(filename);
return sound;
}
int JA_PlaySound(JA_Sound_t *sound, const int loop) {
return Mix_PlayChannel(-1, (Mix_Chunk*)sound, loop);
}
void JA_DeleteSound(JA_Sound_t *sound) {
Mix_FreeChunk((Mix_Chunk*)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;
}
}
int JA_SetVolume(int volume) {
return Mix_Volume(-1, volume);
}
#endif

View File

@@ -1,4 +1,6 @@
#include "../const.h"
#include "menu.h" #include "menu.h"
#include <iostream>
// Constructor // Constructor
Menu::Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file) Menu::Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file)
@@ -106,7 +108,7 @@ bool Menu::load(std::string file_path)
if (file.good()) if (file.good())
{ {
// Procesa el fichero linea a linea // Procesa el fichero linea a linea
printf("Reading file %s\n", filename.c_str()); std::cout << "Reading file " << filename.c_str() << std::endl;
while (std::getline(file, line)) while (std::getline(file, line))
{ {
if (line == "[item]") if (line == "[item]")
@@ -129,7 +131,7 @@ bool Menu::load(std::string file_path)
// Procesa las dos subcadenas // Procesa las dos subcadenas
if (!setItem(&item, line.substr(0, pos), line.substr(pos + 1, line.length()))) if (!setItem(&item, line.substr(0, pos), line.substr(pos + 1, line.length())))
{ {
printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str()); std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
success = false; success = false;
} }
@@ -146,7 +148,7 @@ bool Menu::load(std::string file_path)
// Procesa las dos subcadenas // Procesa las dos subcadenas
if (!setVars(line.substr(0, pos), line.substr(pos + 1, line.length()))) if (!setVars(line.substr(0, pos), line.substr(pos + 1, line.length())))
{ {
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str()); std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
success = false; success = false;
} }
@@ -160,13 +162,13 @@ bool Menu::load(std::string file_path)
} }
// Cierra el fichero // Cierra el fichero
printf("Closing file %s\n", filename.c_str()); std::cout << "Closing file " << filename.c_str() << std::endl;
file.close(); file.close();
} }
// El fichero no se puede abrir // El fichero no se puede abrir
else else
{ {
printf("Warning: Unable to open %s file\n", filename.c_str()); std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl;
success = false; success = false;
} }
@@ -457,7 +459,7 @@ void Menu::setSelectorPos(int index)
if (index < (int)item.size()) if (index < (int)item.size())
{ {
selector.index = index; selector.index = index;
selector.rect.y = selector.y = selector.originY = selector.targetY = item.at(selector.index).rect.y; selector.rect.y = selector.y = selector.originY = selector.targetY = item[selector.index].rect.y;
selector.rect.w = rectBG.rect.w; selector.rect.w = rectBG.rect.w;
selector.rect.x = rectBG.rect.x; selector.rect.x = rectBG.rect.x;
selector.originH = selector.targetH = selector.rect.h = getSelectorHeight(selector.index); selector.originH = selector.targetH = selector.rect.h = getSelectorHeight(selector.index);
@@ -485,13 +487,13 @@ void Menu::reset()
{ {
itemSelected = MENU_NO_OPTION; itemSelected = MENU_NO_OPTION;
selector.index = 0; selector.index = 0;
selector.originY = selector.targetY = selector.y = item.at(0).rect.y; selector.originY = selector.targetY = selector.y = item[0].rect.y;
selector.originH = selector.targetH = item.at(0).rect.h; selector.originH = selector.targetH = item[0].rect.h;
selector.moving = false; selector.moving = false;
selector.resizing = false; selector.resizing = false;
// Si el primer elemento no es seleccionable, incrementa el selector // Si el primer elemento no es seleccionable, incrementa el selector
if (!item.at(selector.index).selectable) if (!item[selector.index].selectable)
{ {
increaseSelectorIndex(); increaseSelectorIndex();
setSelectorPos(selector.index); setSelectorPos(selector.index);
@@ -523,18 +525,18 @@ void Menu::reorganize()
bool Menu::increaseSelectorIndex() bool Menu::increaseSelectorIndex()
{ {
// Obten las coordenadas del elemento actual // Obten las coordenadas del elemento actual
selector.y = selector.originY = item.at(selector.index).rect.y; selector.y = selector.originY = item[selector.index].rect.y;
selector.h = selector.originH = getSelectorHeight(selector.index); selector.h = selector.originH = getSelectorHeight(selector.index);
// Calcula cual es el siguiente elemento // Calcula cual es el siguiente elemento
++selector.index %= item.size(); ++selector.index %= item.size();
while (!item.at(selector.index).selectable) while (!item[selector.index].selectable)
{ {
++selector.index %= item.size(); ++selector.index %= item.size();
} }
// Establece las coordenadas y altura de destino // Establece las coordenadas y altura de destino
selector.targetY = item.at(selector.index).rect.y; selector.targetY = item[selector.index].rect.y;
selector.despY = (selector.targetY - selector.originY) / selector.numJumps; selector.despY = (selector.targetY - selector.originY) / selector.numJumps;
selector.targetH = getSelectorHeight(selector.index); selector.targetH = getSelectorHeight(selector.index);
@@ -553,7 +555,7 @@ bool Menu::increaseSelectorIndex()
bool Menu::decreaseSelectorIndex() bool Menu::decreaseSelectorIndex()
{ {
// Obten las coordenadas del elemento actual // Obten las coordenadas del elemento actual
selector.y = selector.originY = item.at(selector.index).rect.y; selector.y = selector.originY = item[selector.index].rect.y;
selector.h = selector.originH = getSelectorHeight(selector.index); selector.h = selector.originH = getSelectorHeight(selector.index);
// Calcula cual es el siguiente elemento // Calcula cual es el siguiente elemento
@@ -566,7 +568,7 @@ bool Menu::decreaseSelectorIndex()
selector.index--; selector.index--;
} }
while (!item.at(selector.index).selectable) while (!item[selector.index].selectable)
{ {
if (selector.index == 0) if (selector.index == 0)
{ {
@@ -579,7 +581,7 @@ bool Menu::decreaseSelectorIndex()
} }
// Establece las coordenadas y altura de destino // Establece las coordenadas y altura de destino
selector.targetY = item.at(selector.index).rect.y; selector.targetY = item[selector.index].rect.y;
selector.despY = (selector.targetY - selector.originY) / selector.numJumps; selector.despY = (selector.targetY - selector.originY) / selector.numJumps;
selector.targetH = getSelectorHeight(selector.index); selector.targetH = getSelectorHeight(selector.index);
@@ -629,29 +631,29 @@ void Menu::render()
if (i == selector.index) if (i == selector.index)
{ {
const color_t color = {selector.itemColor.r, selector.itemColor.g, selector.itemColor.b}; const color_t color = {selector.itemColor.r, selector.itemColor.g, selector.itemColor.b};
text->writeColored(item.at(i).rect.x, item.at(i).rect.y, item.at(i).label, color); text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, color);
} }
else if (item.at(i).selectable) else if (item[i].selectable)
{ {
text->write(item.at(i).rect.x, item.at(i).rect.y, item.at(i).label); text->write(item[i].rect.x, item[i].rect.y, item[i].label);
} }
else if (item.at(i).greyed) else if (item[i].greyed)
{ {
text->writeColored(item.at(i).rect.x, item.at(i).rect.y, item.at(i).label, colorGreyed); text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, colorGreyed);
} }
else else
{ // No seleccionable { // No seleccionable
if ((item.at(i).linkedUp) && (i == selector.index + 1)) if ((item[i].linkedUp) && (i == selector.index + 1))
{ {
const color_t color = {selector.itemColor.r, selector.itemColor.g, selector.itemColor.b}; const color_t color = {selector.itemColor.r, selector.itemColor.g, selector.itemColor.b};
text->writeColored(item.at(i).rect.x, item.at(i).rect.y, item.at(i).label, color); text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, color);
} }
else // No enlazado con el de arriba else // No enlazado con el de arriba
{ {
text->write(item.at(i).rect.x, item.at(i).rect.y, item.at(i).label); text->write(item[i].rect.x, item[i].rect.y, item[i].label);
} }
} }
} }
@@ -821,7 +823,7 @@ void Menu::addItem(std::string text, int hPaddingDown, bool selectable, bool gre
if (item.size() > 1) if (item.size() > 1)
{ {
if (item.at(item.size() - 2).linkedDown) if (item[item.size() - 2].linkedDown)
{ {
item.back().linkedUp = true; item.back().linkedUp = true;
} }
@@ -834,9 +836,9 @@ void Menu::addItem(std::string text, int hPaddingDown, bool selectable, bool gre
// Cambia el texto de un item // Cambia el texto de un item
void Menu::setItemCaption(int index, std::string text) void Menu::setItemCaption(int index, std::string text)
{ {
item.at(index).label = text; item[index].label = text;
item.at(index).rect.w = this->text->lenght(item.at(index).label); item[index].rect.w = this->text->lenght(item[index].label);
item.at(index).rect.h = this->text->getCharacterSize(); item[index].rect.h = this->text->getCharacterSize();
reorganize(); reorganize();
} }
@@ -913,42 +915,42 @@ int Menu::findHeight()
// Recoloca los elementos del menu en el eje Y // Recoloca los elementos del menu en el eje Y
void Menu::replaceElementsOnY() void Menu::replaceElementsOnY()
{ {
item.at(0).rect.y = y; item[0].rect.y = y;
for (int i = 1; i < (int)item.size(); i++) for (int i = 1; i < (int)item.size(); i++)
{ {
item.at(i).rect.y = item.at(i - 1).rect.y + item.at(i - 1).rect.h + item.at(i - 1).hPaddingDown; item[i].rect.y = item[i - 1].rect.y + item[i - 1].rect.h + item[i - 1].hPaddingDown;
} }
} }
// Establece el estado seleccionable de un item // Establece el estado seleccionable de un item
void Menu::setSelectable(int index, bool value) void Menu::setSelectable(int index, bool value)
{ {
item.at(index).selectable = value; item[index].selectable = value;
} }
// Establece el estado agrisado de un item // Establece el estado agrisado de un item
void Menu::setGreyed(int index, bool value) void Menu::setGreyed(int index, bool value)
{ {
item.at(index).greyed = value; item[index].greyed = value;
} }
// Establece el estado de enlace de un item // Establece el estado de enlace de un item
void Menu::setLinkedDown(int index, bool value) void Menu::setLinkedDown(int index, bool value)
{ {
item.at(index).linkedDown = value; item[index].linkedDown = value;
} }
// Calcula la altura del selector // Calcula la altura del selector
int Menu::getSelectorHeight(int value) int Menu::getSelectorHeight(int value)
{ {
if (item.at(value).linkedDown) if (item[value].linkedDown)
{ {
return item.at(value).rect.h + item.at(value).hPaddingDown + item.at(value + 1).rect.h; return item[value].rect.h + item[value].hPaddingDown + item[value + 1].rect.h;
} }
else else
{ {
return item.at(value).rect.h; return item[value].rect.h;
} }
} }
@@ -976,6 +978,6 @@ void Menu::setText(std::string font_png, std::string font_txt)
{ {
if (!text) if (!text)
{ {
text = new Text(font_png, font_txt, renderer); text = new Text(asset->get(font_png), asset->get(font_txt), renderer);
} }
} }

View File

@@ -70,9 +70,9 @@ private:
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer; // Puntero al renderizador de la ventana SDL_Renderer *renderer; // Puntero al renderizador de la ventana
Asset *asset; // Objeto para gestionar los ficheros de recursos
Text *text; // Texto para poder escribir los items del menu Text *text; // Texto para poder escribir los items del menu
Input *input; // Gestor de eventos de entrada de teclado o gamepad Input *input; // Gestor de eventos de entrada de teclado o gamepad
Asset *asset; // Objeto para gestionar los ficheros de recursos
// Variables // Variables
std::string name; // Nombre del menu std::string name; // Nombre del menu
@@ -89,9 +89,9 @@ private:
bool isCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y 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 bool areElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X
int widestItem; // Anchura del elemento más ancho int widestItem; // Anchura del elemento más ancho
JA_Sound soundAccept; // Sonido al aceptar o elegir una opción del menu JA_Sound_t* soundAccept; // Sonido al aceptar o elegir una opción del menu
JA_Sound soundCancel; // Sonido al cancelar el menu JA_Sound_t* soundCancel; // Sonido al cancelar el menu
JA_Sound soundMove; // Sonido al mover el selector JA_Sound_t* soundMove; // Sonido al mover el selector
color_t colorGreyed; // Color para los elementos agrisados color_t colorGreyed; // Color para los elementos agrisados
rectangle_t rectBG; // Rectangulo de fondo del menu rectangle_t rectBG; // Rectangulo de fondo del menu
std::vector<item_t> item; // Estructura para cada elemento del menu std::vector<item_t> item; // Estructura para cada elemento del menu

View File

@@ -1,24 +1,30 @@
#include "notify.h" #include "notify.h"
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
#include <iostream>
// Constructor // Constructor
Notify::Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile) Notify::Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile, std::string soundFile, options_t *options)
{ {
// Inicializa variables // Inicializa variables
this->renderer = renderer; this->renderer = renderer;
bgColor = {64, 64, 64}; this->options = options;
bgColor = options->notifications.color;
waitTime = 300; waitTime = 300;
// Crea objetos // Crea objetos
text = new Text(bitmapFile, textFile, renderer); texture = new Texture(renderer, bitmapFile);
text = new Text(textFile, texture, renderer);
sound = JA_LoadSound(soundFile.c_str());
} }
// Destructor // Destructor
Notify::~Notify() Notify::~Notify()
{ {
// Libera la memoria de los objetos // Libera la memoria de los objetos
delete texture;
delete text; delete text;
JA_DeleteSound(sound);
for (auto notification : notifications) for (auto notification : notifications)
{ {
@@ -32,7 +38,7 @@ void Notify::render()
{ {
for (int i = (int)notifications.size() - 1; i >= 0; --i) for (int i = (int)notifications.size() - 1; i >= 0; --i)
{ {
notifications.at(i).sprite->render(); notifications[i].sprite->render();
} }
} }
@@ -41,49 +47,63 @@ void Notify::update()
{ {
for (int i = 0; i < (int)notifications.size(); ++i) for (int i = 0; i < (int)notifications.size(); ++i)
{ {
notifications.at(i).counter++; notifications[i].counter++;
// Comprueba los estados // Comprueba los estados
if (notifications.at(i).state == ns_rising) if (notifications[i].state == ns_rising)
{ {
const float step = ((float)notifications.at(i).counter / notifications.at(i).travelDist); const float step = ((float)notifications[i].counter / notifications[i].travelDist);
const int alpha = 255 * step; const int alpha = 255 * step;
notifications.at(i).rect.y++; if (options->notifications.posV == pos_top)
notifications.at(i).texture->setAlpha(alpha);
if (notifications.at(i).rect.y == notifications.at(i).y)
{ {
notifications.at(i).state = ns_stay; notifications[i].rect.y++;
notifications.at(i).texture->setAlpha(255); }
notifications.at(i).counter = 0; else
{
notifications[i].rect.y--;
}
notifications[i].texture->setAlpha(alpha);
if (notifications[i].rect.y == notifications[i].y)
{
notifications[i].state = ns_stay;
notifications[i].texture->setAlpha(255);
notifications[i].counter = 0;
} }
} }
else if (notifications.at(i).state == ns_stay) else if (notifications[i].state == ns_stay)
{ {
if (notifications.at(i).counter == waitTime) if (notifications[i].counter == waitTime)
{ {
notifications.at(i).state = ns_vanishing; notifications[i].state = ns_vanishing;
notifications.at(i).counter = 0; notifications[i].counter = 0;
} }
} }
else if (notifications.at(i).state == ns_vanishing) else if (notifications[i].state == ns_vanishing)
{ {
const float step = (notifications.at(i).counter / (float)notifications.at(i).travelDist); const float step = (notifications[i].counter / (float)notifications[i].travelDist);
const int alpha = 255 * (1 - step); const int alpha = 255 * (1 - step);
notifications.at(i).rect.y--; if (options->notifications.posV == pos_top)
notifications.at(i).texture->setAlpha(alpha);
if (notifications.at(i).rect.y == notifications.at(i).y - notifications.at(i).travelDist)
{ {
notifications.at(i).state = ns_finished; notifications[i].rect.y--;
}
else
{
notifications[i].rect.y++;
}
notifications[i].texture->setAlpha(alpha);
if (notifications[i].rect.y == notifications[i].y - notifications[i].travelDist)
{
notifications[i].state = ns_finished;
} }
} }
notifications.at(i).sprite->setRect(notifications.at(i).rect); notifications[i].sprite->setRect(notifications[i].rect);
} }
clearFinishedNotifications(); clearFinishedNotifications();
@@ -94,10 +114,10 @@ void Notify::clearFinishedNotifications()
{ {
for (int i = (int)notifications.size() - 1; i >= 0; --i) for (int i = (int)notifications.size() - 1; i >= 0; --i)
{ {
if (notifications.at(i).state == ns_finished) if (notifications[i].state == ns_finished)
{ {
delete notifications.at(i).sprite; delete notifications[i].sprite;
delete notifications.at(i).texture; delete notifications[i].texture;
notifications.erase(notifications.begin() + i); notifications.erase(notifications.begin() + i);
} }
} }
@@ -106,25 +126,67 @@ void Notify::clearFinishedNotifications()
// Muestra una notificación de texto por pantalla; // Muestra una notificación de texto por pantalla;
void Notify::showText(std::string text) void Notify::showText(std::string text)
{ {
// Crea constantes // Inicializa variables
const int width = this->text->lenght(text) + (this->text->getCharacterSize() * 2); const int width = this->text->lenght(text) + (this->text->getCharacterSize() * 2);
const int height = this->text->getCharacterSize() * 2; const int height = this->text->getCharacterSize() * 2;
const int despH = this->text->getCharacterSize() / 2; const int padding = (this->text->getCharacterSize() / 2);
const int despV = despH;
const int travelDist = height + despV; // Posición horizontal
// const int offset = (int)notifications.size() * (travelDist) + despV; int despH = 0;
const int offset = (int)notifications.size() > 0 ? notifications.back().y + travelDist : despV; if (options->notifications.posH == pos_left)
{
despH = padding;
}
else if (options->notifications.posH == pos_middle)
{
despH = ((options->screen.windowWidth * options->windowSize) / 2 - (width / 2));
}
else
{
despH = (options->screen.windowWidth * options->windowSize) - width - padding;
}
// Posición vertical
int despV = 0;
if (options->notifications.posV == pos_top)
{
despV = padding;
}
else
{
despV = (options->screen.windowHeight * options->windowSize) - height - padding;
}
const int travelDist = height + padding;
// Offset
int offset = 0;
if (options->notifications.posV == pos_top)
{
offset = (int)notifications.size() > 0 ? notifications.back().y + travelDist : despV;
}
else
{
offset = (int)notifications.size() > 0 ? notifications.back().y - travelDist : despV;
}
// Crea la notificacion // Crea la notificacion
notification_t n; notification_t n;
// inicializa variables // Inicializa variables
n.y = offset; n.y = offset;
n.travelDist = travelDist; n.travelDist = travelDist;
n.counter = 0; n.counter = 0;
n.state = ns_rising; n.state = ns_rising;
n.text = text; n.text = text;
n.rect = {despH, offset - travelDist, width, height}; if (options->notifications.posV == pos_top)
{
n.rect = {despH, offset - travelDist, width, height};
}
else
{
n.rect = {despH, offset + travelDist, width, height};
}
// Crea la textura // Crea la textura
n.texture = new Texture(renderer); n.texture = new Texture(renderer);
@@ -133,11 +195,29 @@ void Notify::showText(std::string text)
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
n.texture->setBlendMode(SDL_BLENDMODE_BLEND); n.texture->setBlendMode(SDL_BLENDMODE_BLEND);
this->text->writeDX(TXT_CENTER | TXT_STROKE, width / 2, despV, text, 1, {255, 255, 255}, 1, {0, 0, 0}); this->text->writeDX(TXT_CENTER | TXT_STROKE, width / 2, padding, text, 1, {255, 255, 255}, 1, {0, 0, 0});
SDL_SetRenderTarget(renderer, nullptr);
// Crea el sprite // Crea el sprite
n.sprite = new Sprite(n.rect, n.texture, renderer); n.sprite = new Sprite(n.rect, n.texture, renderer);
// Añade la notificación a la lista // Añade la notificación a la lista
notifications.push_back(n); notifications.push_back(n);
// Reproduce el sonido de la notificación
if (options->notifications.sound)
{
JA_PlaySound(sound);
}
}
// Indica si hay notificaciones activas
bool Notify::active()
{
if ((int)notifications.size() > 0)
{
return true;
}
return false;
} }

View File

@@ -1,9 +1,10 @@
#pragma once #pragma once
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "jail_audio.h"
#include "sprite.h"
#include "text.h" #include "text.h"
#include "texture.h" #include "texture.h"
#include "sprite.h"
#include "utils.h" #include "utils.h"
#include <vector> #include <vector>
@@ -48,12 +49,15 @@ private:
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Texture *texture; // Textura para la fuente de las notificaciones
Text *text; // Objeto para dibujar texto Text *text; // Objeto para dibujar texto
options_t *options; // Variable con todas las opciones del programa
// Variables // Variables
color_t bgColor; // Color de fondo de las notificaciones color_t bgColor; // Color de fondo de las notificaciones
int waitTime; // Tiempo que se ve la notificación int waitTime; // Tiempo que se ve la notificación
std::vector<notification_t> notifications; // La lista de notificaciones activas std::vector<notification_t> notifications; // La lista de notificaciones activas
JA_Sound_t* sound; // Sonido a reproducir cuando suena la notificación
// Elimina las notificaciones finalizadas // Elimina las notificaciones finalizadas
void clearFinishedNotifications(); void clearFinishedNotifications();
@@ -66,13 +70,16 @@ public:
void update(); void update();
// Constructor // Constructor
Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile); Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile, std::string soundFile, options_t *options);
// Destructor // Destructor
~Notify(); ~Notify();
// Muestra una notificación de texto por pantalla; // Muestra una notificación de texto por pantalla;
void showText(std::string text); void showText(std::string text);
// Indica si hay notificaciones activas
bool active();
}; };
#endif #endif

View File

@@ -1,9 +1,9 @@
#include "screen.h" #include "screen.h"
#include <string> #include <string>
#include <stdio.h> #include <iostream>
// Constructor // Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options, int gameInternalResX, int gameInternalResY) Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options)
{ {
// Inicializa variables // Inicializa variables
this->window = window; this->window = window;
@@ -12,11 +12,14 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options
this->asset = asset; this->asset = asset;
// Crea los objetos // Crea los objetos
//notify = new Notify(renderer, asset->get("smb2_big.png"), asset->get("smb2_big.txt")); notify = new Notify(renderer, asset->get("smb2.png"), asset->get("smb2.txt"), asset->get("notify.wav"), options);
notify = new Notify(renderer, asset->get("smb2.png"), asset->get("smb2.txt"));
gameCanvasWidth = gameInternalResX; gameCanvasWidth = options->gameWidth;
gameCanvasHeight = gameInternalResY; gameCanvasHeight = options->gameHeight;
borderWidth = options->borderWidth * 2;
borderHeight = options->borderHeight * 2;
notificationLogicalWidth = gameCanvasWidth;
notificationLogicalHeight = gameCanvasHeight;
iniFade(); iniFade();
iniSpectrumFade(); iniSpectrumFade();
@@ -28,19 +31,17 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight); gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight);
if (gameCanvas == nullptr) if (gameCanvas == nullptr)
{ {
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError()); if (options->console)
{
std::cout << "TitleSurface could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
} }
// Establece el modo de video // Establece el modo de video
setVideoMode(options->fullScreenMode); setVideoMode(options->videoMode);
// Calcula los anclajes // Inicializa variables
anchor.left = 0; notifyActive = false;
anchor.right = gameCanvasWidth;
anchor.center = gameCanvasWidth / 2;
anchor.top = 0;
anchor.bottom = gameCanvasHeight;
anchor.middle = gameCanvasHeight / 2;
} }
// Destructor // Destructor
@@ -83,104 +84,103 @@ void Screen::blit()
} }
// Establece el modo de video // Establece el modo de video
void Screen::setVideoMode(int fullScreenMode) void Screen::setVideoMode(int videoMode)
{ {
// Muestra el puntero
SDL_ShowCursor(SDL_ENABLE);
// Aplica el modo de video // Aplica el modo de video
SDL_SetWindowFullscreen(window, fullScreenMode); SDL_SetWindowFullscreen(window, videoMode);
// Si está activo el modo ventana quita el borde // Si está activo el modo ventana quita el borde
if (fullScreenMode == 0) if (videoMode == 0)
{ {
if (options->borderEnabled) if (options->borderEnabled)
{ {
const int incWidth = gameCanvasWidth * options->borderSize; windowWidth = gameCanvasWidth + borderWidth;
const int incHeight = gameCanvasHeight * options->borderSize; windowHeight = gameCanvasHeight + borderHeight;
screenWidth = gameCanvasWidth + incWidth; dest = {0 + (borderWidth / 2), 0 + (borderHeight / 2), gameCanvasWidth, gameCanvasHeight};
screenHeight = gameCanvasHeight + incHeight;
dest = {0 + (incWidth / 2), 0 + (incHeight / 2), gameCanvasWidth, gameCanvasHeight};
} }
else else
{ {
screenWidth = gameCanvasWidth * options->windowSize; windowWidth = gameCanvasWidth;
screenHeight = gameCanvasHeight * options->windowSize; windowHeight = gameCanvasHeight;
dest = {0, 0, gameCanvasWidth, gameCanvasHeight}; dest = {0, 0, gameCanvasWidth, gameCanvasHeight};
} }
// Modifica el tamaño del renderizador y de la ventana // Modifica el tamaño del renderizador y de la ventana
// SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight); SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
// SDL_SetWindowSize(window, screenWidth * options->windowSize, screenHeight * options->windowSize); SDL_SetWindowSize(window, windowWidth * options->windowSize, windowHeight * options->windowSize);
SDL_RenderSetLogicalSize(renderer, gameCanvasWidth, gameCanvasHeight);
SDL_SetWindowSize(window, screenWidth, screenHeight);
} }
// Si está activo el modo de pantalla completa añade el borde // Si está activo el modo de pantalla completa añade el borde
else if (fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP) else if (videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{ {
// Oculta el puntero
SDL_ShowCursor(SDL_DISABLE);
// Obten el alto y el ancho de la ventana // Obten el alto y el ancho de la ventana
SDL_GetWindowSize(window, &screenWidth, &screenHeight); SDL_GetWindowSize(window, &windowWidth, &windowHeight);
// Aplica el escalado al rectangulo donde se pinta la textura del juego // Aplica el escalado al rectangulo donde se pinta la textura del juego
if (options->integerScale) if (options->integerScale)
{ {
// Calcula el tamaño de la escala máxima // Calcula el tamaño de la escala máxima
int scale = 0; int scale = 0;
while (((gameCanvasWidth * (scale + 1)) <= screenWidth) && ((gameCanvasHeight * (scale + 1)) <= screenHeight)) while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight))
{ {
scale++; scale++;
} }
dest.w = gameCanvasWidth * scale; dest.w = gameCanvasWidth * scale;
dest.h = gameCanvasHeight * scale; dest.h = gameCanvasHeight * scale;
dest.x = (screenWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} }
else if (options->keepAspect) else if (options->keepAspect)
{ {
float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight; float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight;
if ((screenWidth - gameCanvasWidth) >= (screenHeight - gameCanvasHeight)) if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight))
{ {
dest.h = screenHeight; dest.h = windowHeight;
dest.w = (int)((screenHeight * ratio) + 0.5f); dest.w = (int)((windowHeight * ratio) + 0.5f);
dest.x = (screenWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} }
else else
{ {
dest.w = screenWidth; dest.w = windowWidth;
dest.h = (int)((screenWidth / ratio) + 0.5f); dest.h = (int)((windowWidth / ratio) + 0.5f);
dest.x = (screenWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} }
} }
else else
{ {
dest.w = screenWidth; dest.w = windowWidth;
dest.h = screenHeight; dest.h = windowHeight;
dest.x = dest.y = 0; dest.x = dest.y = 0;
} }
// Modifica el tamaño del renderizador // Modifica el tamaño del renderizador
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight); SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
} }
// Actualiza el valor de la variable // Actualiza las opciones
options->fullScreenMode = fullScreenMode; options->videoMode = videoMode;
options->screen.windowWidth = windowWidth;
options->screen.windowHeight = windowHeight;
// Establece el tamaño de las notificaciones
setNotificationSize();
} }
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
void Screen::switchVideoMode() void Screen::switchVideoMode()
{ {
if (options->fullScreenMode == 0) options->videoMode = (options->videoMode == 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
{ setVideoMode(options->videoMode);
options->fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
}
else
{
options->fullScreenMode = 0;
}
setVideoMode(options->fullScreenMode);
} }
// Cambia el tamaño de la ventana // Cambia el tamaño de la ventana
@@ -203,9 +203,15 @@ void Screen::setBlendMode(SDL_BlendMode blendMode)
} }
// Establece el tamaño del borde // Establece el tamaño del borde
void Screen::setBorderSize(float s) void Screen::setBorderWidth(int s)
{ {
options->borderSize = s; options->borderWidth = s;
}
// Establece el tamaño del borde
void Screen::setBorderHeight(int s)
{
options->borderHeight = s;
} }
// Establece si se ha de ver el borde en el modo ventana // Establece si se ha de ver el borde en el modo ventana
@@ -303,30 +309,12 @@ void Screen::iniSpectrumFade()
spectrumColor.clear(); spectrumColor.clear();
color_t c; // Inicializa el vector de colores
c = stringToColor("black"); const std::vector<std::string> vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"};
spectrumColor.push_back(c); for (auto v : vColors)
{
c = stringToColor("blue"); spectrumColor.push_back(stringToColor(options->palette, v));
spectrumColor.push_back(c); }
c = stringToColor("red");
spectrumColor.push_back(c);
c = stringToColor("magenta");
spectrumColor.push_back(c);
c = stringToColor("green");
spectrumColor.push_back(c);
c = stringToColor("cyan");
spectrumColor.push_back(c);
c = stringToColor("yellow");
spectrumColor.push_back(c);
c = stringToColor("bright_white");
spectrumColor.push_back(c);
} }
// Actualiza el spectrum fade // Actualiza el spectrum fade
@@ -356,7 +344,7 @@ void Screen::renderSpectrumFade()
const float step = (float)spectrumFadeCounter / (float)spectrumFadeLenght; const float step = (float)spectrumFadeCounter / (float)spectrumFadeLenght;
const int max = spectrumColor.size() - 1; const int max = spectrumColor.size() - 1;
const int index = max + (0 - max) * step; const int index = max + (0 - max) * step;
const color_t c = spectrumColor.at(index); const color_t c = spectrumColor[index];
SDL_SetTextureColorMod(gameCanvas, c.r, c.g, c.b); SDL_SetTextureColorMod(gameCanvas, c.r, c.g, c.b);
} }
@@ -378,10 +366,11 @@ void Screen::renderFX()
void Screen::updateNotifier() void Screen::updateNotifier()
{ {
notify->update(); notify->update();
notifyActive = notify->active();
} }
// Muestra una notificación de texto por pantalla; // Muestra una notificación de texto por pantalla;
void Screen::showText(std::string text) void Screen::showNotification(std::string text)
{ {
notify->showText(text); notify->showText(text);
} }
@@ -389,7 +378,36 @@ void Screen::showText(std::string text)
// Dibuja las notificaciones // Dibuja las notificaciones
void Screen::renderNotifications() void Screen::renderNotifications()
{ {
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight); if (!notifyActive)
{
return;
}
SDL_RenderSetLogicalSize(renderer, notificationLogicalWidth, notificationLogicalHeight);
notify->render(); notify->render();
SDL_RenderSetLogicalSize(renderer, gameCanvasWidth, gameCanvasHeight); SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
}
// Establece el tamaño de las notificaciones
void Screen::setNotificationSize()
{
if (options->videoMode == 0)
{
if (options->windowSize == 3)
{
notificationLogicalWidth = (windowWidth * 3) / 2;
notificationLogicalHeight = (windowHeight * 3) / 2;
}
else
{
notificationLogicalWidth = windowWidth * 2;
notificationLogicalHeight = windowHeight * 2;
}
}
if (options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
notificationLogicalWidth = windowWidth / 3;
notificationLogicalHeight = windowHeight / 3;
}
} }

View File

@@ -12,21 +12,10 @@
#define FILTER_NEAREST 0 #define FILTER_NEAREST 0
#define FILTER_LINEAL 1 #define FILTER_LINEAL 1
struct anchor_t
{
int left; // Parte izquierda de la pantalla de juego
int right; // Parte drecha de la pantalla de juego
int center; // Parte central horizontal de la pantalla de juego
int top; // Parte superior de la pantalla de juego
int bottom; // Parte infoerior de la pantalla de juego
int middle; // Parte central vertical de la pantalla de juego
};
// Clase Screen
class Screen class Screen
{ {
private: private:
// Objetos y variables // Objetos y punteros
SDL_Window *window; // Ventana de la aplicación SDL_Window *window; // Ventana de la aplicación
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con el listado de recursos Asset *asset; // Objeto con el listado de recursos
@@ -34,15 +23,20 @@ private:
options_t *options; // Variable con todas las opciones del programa options_t *options; // Variable con todas las opciones del programa
Notify *notify; // Dibuja notificaciones por pantalla Notify *notify; // Dibuja notificaciones por pantalla
int screenWidth; // Ancho de la pantalla o ventana // Variables
int screenHeight; // Alto de la pantalla o ventana int windowWidth; // Ancho de la pantalla o ventana
int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego int windowHeight; // Alto de la pantalla o ventana
int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego
anchor_t anchor; // Variable con los anclajes de la pantalla int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego
SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana int borderWidth; // Anchura del borde
color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla int borderHeight; // Anltura del borde
SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
bool notifyActive; // Indica si hay notificaciones activas
int notificationLogicalWidth; // Ancho lógico de las notificaciones en relación al tamaño de pantalla
int notificationLogicalHeight; // Alto lógico de las notificaciones en relación al tamaño de pantalla
// EFECTOS // Variables - Efectos
bool fade; // Indica si esta activo el efecto de fade bool fade; // Indica si esta activo el efecto de fade
int fadeCounter; // Temporizador para el efecto de fade int fadeCounter; // Temporizador para el efecto de fade
int fadeLenght; // Duración del fade int fadeLenght; // Duración del fade
@@ -72,9 +66,12 @@ private:
// Dibuja las notificaciones // Dibuja las notificaciones
void renderNotifications(); void renderNotifications();
// Establece el tamaño de las notificaciones
void setNotificationSize();
public: public:
// Constructor // Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options, int gameInternalResX, int gameInternalResY); Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options);
// Destructor // Destructor
~Screen(); ~Screen();
@@ -89,7 +86,7 @@ public:
void blit(); void blit();
// Establece el modo de video // Establece el modo de video
void setVideoMode(int fullScreenMode); void setVideoMode(int videoMode);
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
void switchVideoMode(); void switchVideoMode();
@@ -104,7 +101,8 @@ public:
void setBlendMode(SDL_BlendMode blendMode); void setBlendMode(SDL_BlendMode blendMode);
// Establece el tamaño del borde // Establece el tamaño del borde
void setBorderSize(float s); void setBorderWidth(int s);
void setBorderHeight(int s);
// Establece si se ha de ver el borde en el modo ventana // Establece si se ha de ver el borde en el modo ventana
void setBorderEnabled(bool value); void setBorderEnabled(bool value);
@@ -134,7 +132,7 @@ public:
void updateNotifier(); void updateNotifier();
// Muestra una notificación de texto por pantalla; // Muestra una notificación de texto por pantalla;
void showText(std::string text); void showNotification(std::string text);
}; };
#endif #endif

View File

@@ -3,22 +3,156 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
// Llena una estructuta textFile_t desde un fichero
textFile_t LoadTextFile(std::string file, bool verbose)
{
textFile_t tf;
// Inicializa a cero el vector con las coordenadas
for (int i = 0; i < 128; ++i)
{
tf.offset[i].x = 0;
tf.offset[i].y = 0;
tf.offset[i].w = 0;
}
// Abre el fichero para leer los valores
const std::string filename = file.substr(file.find_last_of("\\/") + 1).c_str();
std::ifstream rfile(file);
if (rfile.is_open() && rfile.good())
{
std::string buffer;
// Lee los dos primeros valores del fichero
std::getline(rfile, buffer);
std::getline(rfile, buffer);
tf.boxWidth = std::stoi(buffer);
std::getline(rfile, buffer);
std::getline(rfile, buffer);
tf.boxHeight = std::stoi(buffer);
// lee el resto de datos del fichero
int index = 32;
int line_read = 0;
while (std::getline(rfile, buffer))
{
// Almacena solo las lineas impares
if (line_read % 2 == 1)
{
tf.offset[index++].w = std::stoi(buffer);
}
// Limpia el buffer
buffer.clear();
line_read++;
};
// Cierra el fichero
if (verbose)
{
std::cout << "Text loaded: " << filename.c_str() << std::endl;
}
rfile.close();
}
// El fichero no se puede abrir
else
{
if (verbose)
{
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl;
}
}
// Establece las coordenadas para cada caracter ascii de la cadena y su ancho
for (int i = 32; i < 128; ++i)
{
tf.offset[i].x = ((i - 32) % 15) * tf.boxWidth;
tf.offset[i].y = ((i - 32) / 15) * tf.boxHeight;
}
return tf;
}
// Constructor // Constructor
Text::Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer) Text::Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer)
{ {
// Carga los offsets desde el fichero // Carga los offsets desde el fichero
initOffsetFromFile(textFile); textFile_t tf = LoadTextFile(textFile);
// Inicializa variables desde la estructura
boxHeight = tf.boxHeight;
boxWidth = tf.boxWidth;
for (int i = 0; i < 128; ++i)
{
offset[i].x = tf.offset[i].x;
offset[i].y = tf.offset[i].y;
offset[i].w = tf.offset[i].w;
}
// Crea los objetos // Crea los objetos
texture = new Texture(renderer, bitmapFile); texture = new Texture(renderer, bitmapFile);
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
// Inicializa variables
fixedWidth = false;
}
// Constructor
Text::Text(std::string textFile, Texture *texture, SDL_Renderer *renderer)
{
// Carga los offsets desde el fichero
textFile_t tf = LoadTextFile(textFile);
// Inicializa variables desde la estructura
boxHeight = tf.boxHeight;
boxWidth = tf.boxWidth;
for (int i = 0; i < 128; ++i)
{
offset[i].x = tf.offset[i].x;
offset[i].y = tf.offset[i].y;
offset[i].w = tf.offset[i].w;
}
// Crea los objetos
this->texture = nullptr;
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
// Inicializa variables
fixedWidth = false;
}
// Constructor
Text::Text(textFile_t *textFile, Texture *texture, SDL_Renderer *renderer)
{
// Inicializa variables desde la estructura
boxHeight = textFile->boxHeight;
boxWidth = textFile->boxWidth;
for (int i = 0; i < 128; ++i)
{
offset[i].x = textFile->offset[i].x;
offset[i].y = textFile->offset[i].y;
offset[i].w = textFile->offset[i].w;
}
// Crea los objetos
this->texture = nullptr;
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
// Inicializa variables
fixedWidth = false;
} }
// Destructor // Destructor
Text::~Text() Text::~Text()
{ {
delete texture;
delete sprite; delete sprite;
if (texture != nullptr)
{
delete texture;
}
} }
// Escribe texto en pantalla // Escribe texto en pantalla
@@ -27,15 +161,20 @@ void Text::write(int x, int y, std::string text, int kerning, int lenght)
int shift = 0; int shift = 0;
if (lenght == -1) if (lenght == -1)
{
lenght = text.length(); lenght = text.length();
}
sprite->setPosY(y);
const int width = sprite->getWidth();
const int height = sprite->getHeight();
for (int i = 0; i < lenght; ++i) for (int i = 0; i < lenght; ++i)
{ {
sprite->setSpriteClip(offset[int(text[i])].x, offset[int(text[i])].y, sprite->getWidth(), sprite->getHeight()); const int index = text[i];
sprite->setSpriteClip(offset[index].x, offset[index].y, width, height);
sprite->setPosX(x + shift); sprite->setPosX(x + shift);
sprite->setPosY(y);
sprite->render(); sprite->render();
shift += (offset[int(text[i])].w + kerning); shift += fixedWidth ? boxWidth : (offset[int(text[i])].w + kerning);
} }
} }
@@ -72,28 +211,37 @@ void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, col
const bool stroked = ((flags & TXT_STROKE) == TXT_STROKE); const bool stroked = ((flags & TXT_STROKE) == TXT_STROKE);
if (centered) if (centered)
{
x -= (Text::lenght(text, kerning) / 2); x -= (Text::lenght(text, kerning) / 2);
}
if (shadowed) if (shadowed)
{
writeColored(x + shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght); writeColored(x + shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght);
}
if (stroked) if (stroked)
{ {
writeColored(x + shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght); for (int dist = 1; dist <= shadowDistance; ++dist)
writeColored(x - shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght); {
writeColored(x + shadowDistance, y - shadowDistance, text, shadowColor, kerning, lenght); for (int dy = -dist; dy <= dist; ++dy)
writeColored(x - shadowDistance, y - shadowDistance, text, shadowColor, kerning, lenght); {
for (int dx = -dist; dx <= dist; ++dx)
writeColored(x, y + shadowDistance, text, shadowColor, kerning, lenght); {
writeColored(x, y - shadowDistance, text, shadowColor, kerning, lenght); writeColored(x + dx, y + dy, text, shadowColor, kerning, lenght);
writeColored(x + shadowDistance, y, text, shadowColor, kerning, lenght); }
writeColored(x - shadowDistance, y, text, shadowColor, kerning, lenght); }
}
} }
if (colored) if (colored)
{
writeColored(x, y, text, textColor, kerning, lenght); writeColored(x, y, text, textColor, kerning, lenght);
}
else else
{
write(x, y, text, kerning, lenght); write(x, y, text, kerning, lenght);
}
} }
// Obtiene la longitud en pixels de una cadena // Obtiene la longitud en pixels de una cadena
@@ -108,69 +256,6 @@ int Text::lenght(std::string text, int kerning)
return shift - kerning; return shift - kerning;
} }
// Inicializa el vector de offsets desde un fichero
void Text::initOffsetFromFile(std::string file)
{
// Inicializa a cero el vector con las coordenadas
for (int i = 0; i < 128; ++i)
{
offset[i].x = 0;
offset[i].y = 0;
offset[i].w = 0;
}
// Abre el fichero para leer los valores
const std::string filename = file.substr(file.find_last_of("\\/") + 1).c_str();
std::ifstream rfile(file);
if (rfile.is_open() && rfile.good())
{
std::string buffer;
// Lee los dos primeros valores del fichero
std::getline(rfile, buffer);
std::getline(rfile, buffer);
boxWidth = std::stoi(buffer);
std::getline(rfile, buffer);
std::getline(rfile, buffer);
boxHeight = std::stoi(buffer);
// lee el resto de datos del fichero
int index = 32;
int line_read = 0;
while (std::getline(rfile, buffer))
{
// Almacena solo las lineas impares
if (line_read % 2 == 1)
{
offset[index++].w = std::stoi(buffer);
}
// Limpia el buffer
buffer.clear();
line_read++;
};
// Cierra el fichero
printf("Text loaded: %s\n", filename.c_str());
rfile.close();
}
// El fichero no se puede abrir
else
{
printf("Warning: Unable to open %s file\n", filename.c_str());
}
// Establece las coordenadas para cada caracter ascii de la cadena y su ancho
for (int i = 32; i < 128; ++i)
{
offset[i].x = ((i - 32) % 15) * boxWidth;
offset[i].y = ((i - 32) / 15) * boxHeight;
}
}
// Devuelve el valor de la variable // Devuelve el valor de la variable
int Text::getCharacterSize() int Text::getCharacterSize()
{ {
@@ -180,5 +265,11 @@ int Text::getCharacterSize()
// Recarga la textura // Recarga la textura
void Text::reLoadTexture() void Text::reLoadTexture()
{ {
texture->reLoad(); sprite->getTexture()->reLoad();
}
// Establece si se usa un tamaño fijo de letra
void Text::setFixedWidth(bool value)
{
fixedWidth = value;
} }

View File

@@ -11,32 +11,42 @@
#define TXT_CENTER 4 #define TXT_CENTER 4
#define TXT_STROKE 8 #define TXT_STROKE 8
struct offset_t
{
int x;
int y;
int w;
};
struct textFile_t
{
int boxWidth; // Anchura de la caja de cada caracter en el png
int boxHeight; // Altura de la caja de cada caracter en el png
offset_t offset[128]; // Vector con las posiciones y ancho de cada letra
};
// Llena una estructuta textFile_t desde un fichero
textFile_t LoadTextFile(std::string file, bool verbose = false);
// Clase texto. Pinta texto en pantalla a partir de un bitmap // Clase texto. Pinta texto en pantalla a partir de un bitmap
class Text class Text
{ {
private: private:
struct offset_t
{
int x;
int y;
int w;
};
// Objetos y punteros // Objetos y punteros
Sprite *sprite; // Objeto con los graficos para el texto Sprite *sprite; // Objeto con los graficos para el texto
Texture *texture; // Textura con los bitmaps del texto Texture *texture; // Textura con los bitmaps del texto
// Variables // Variables
int boxWidth; // Anchura de la caja de cada caracter en el png int boxWidth; // Anchura de la caja de cada caracter en el png
int boxHeight; // Altura de la caja de cada caracter en el png int boxHeight; // Altura de la caja de cada caracter en el png
bool fixedWidth; // Indica si el texto se ha de escribir con longitud fija en todas las letras
offset_t offset[128]; // Vector con las posiciones y ancho de cada letra offset_t offset[128]; // Vector con las posiciones y ancho de cada letra
// Inicializa el vector de offsets desde un fichero
void initOffsetFromFile(std::string file);
public: public:
// Constructor // Constructor
Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer); Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer);
Text(std::string textFile, Texture *texture, SDL_Renderer *renderer);
Text(textFile_t *textFile, Texture *texture, SDL_Renderer *renderer);
// Destructor // Destructor
~Text(); ~Text();
@@ -64,6 +74,9 @@ public:
// Recarga la textura // Recarga la textura
void reLoadTexture(); void reLoadTexture();
// Establece si se usa un tamaño fijo de letra
void setFixedWidth(bool value);
}; };
#endif #endif

View File

@@ -2,9 +2,10 @@
#include "texture.h" #include "texture.h"
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"
#include <iostream>
// Constructor // Constructor
Texture::Texture(SDL_Renderer *renderer, std::string path) Texture::Texture(SDL_Renderer *renderer, std::string path, bool verbose)
{ {
// Copia punteros // Copia punteros
this->renderer = renderer; this->renderer = renderer;
@@ -18,7 +19,7 @@ Texture::Texture(SDL_Renderer *renderer, std::string path)
// Carga el fichero en la textura // Carga el fichero en la textura
if (path != "") if (path != "")
{ {
loadFromFile(path, renderer); loadFromFile(path, renderer, verbose);
} }
} }
@@ -30,9 +31,9 @@ Texture::~Texture()
} }
// Carga una imagen desde un fichero // Carga una imagen desde un fichero
bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer) bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer, bool verbose)
{ {
const std::string filename = path.substr(path.find_last_of("\\/") + 1); const std::string filename = path.substr(path.find_last_of("\\/") + 1);
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);
@@ -43,7 +44,10 @@ bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer)
} }
else else
{ {
printf("Image loaded: %s\n", filename.c_str()); if (verbose)
{
std::cout << "Image loaded: " << filename.c_str() << std::endl;
}
} }
int depth, pitch; int depth, pitch;
@@ -71,7 +75,10 @@ bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer)
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 == nullptr) if (loadedSurface == nullptr)
{ {
printf("Unable to load image %s!\n", path.c_str()); if (verbose)
{
std::cout << "Unable to load image " << path.c_str() << std::endl;
}
} }
else else
{ {
@@ -79,7 +86,10 @@ bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer)
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if (newTexture == nullptr) if (newTexture == nullptr)
{ {
printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); if (verbose)
{
std::cout << "Unable to create texture from " << path.c_str() << "! SDL Error: " << SDL_GetError() << std::endl;
}
} }
else else
{ {
@@ -93,6 +103,7 @@ bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer)
} }
// Return success // Return success
stbi_image_free(data);
texture = newTexture; texture = newTexture;
return texture != nullptr; return texture != nullptr;
} }
@@ -104,7 +115,7 @@ bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_Tex
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
if (texture == nullptr) if (texture == nullptr)
{ {
printf("Unable to create blank texture! SDL Error: %s\n", SDL_GetError()); std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << std::endl;
} }
else else
{ {
@@ -189,3 +200,9 @@ bool Texture::reLoad()
{ {
return loadFromFile(path, renderer); return loadFromFile(path, renderer);
} }
// Obtiene la textura
SDL_Texture *Texture::getSDLTexture()
{
return texture;
}

View File

@@ -21,13 +21,13 @@ private:
public: public:
// Constructor // Constructor
Texture(SDL_Renderer *renderer, std::string path = ""); Texture(SDL_Renderer *renderer, std::string path = "", bool verbose = false);
// Destructor // Destructor
~Texture(); ~Texture();
// Carga una imagen desde un fichero // Carga una imagen desde un fichero
bool loadFromFile(std::string path, SDL_Renderer *renderer); bool loadFromFile(std::string path, SDL_Renderer *renderer, bool verbose = false);
// Crea una textura en blanco // 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);
@@ -58,6 +58,9 @@ public:
// Recarga la textura // Recarga la textura
bool reLoad(); bool reLoad();
// Obtiene la textura
SDL_Texture *getSDLTexture();
}; };
#endif #endif

View File

@@ -380,11 +380,9 @@ bool checkCollision(SDL_Point &p, d_line_t &l)
} }
// Devuelve un color_t a partir de un string // Devuelve un color_t a partir de un string
color_t stringToColor(std::string str) color_t stringToColor(palette_e pal, std::string str)
{ {
const std::string palette = "spectrum"; if (pal == p_zxspectrum)
if (palette == "spectrum")
{ {
if (str == "black") if (str == "black")
{ {
@@ -467,7 +465,7 @@ color_t stringToColor(std::string str)
} }
} }
else else if (pal == p_zxarne)
{ // zxarne { // zxarne
if (str == "black") if (str == "black")
{ {

View File

@@ -57,6 +57,23 @@ struct color_t
Uint8 b; Uint8 b;
}; };
// Tipos de paleta
enum palette_e
{
p_zxspectrum,
p_zxarne
};
// Posiciones de las notificaciones
enum not_pos_e
{
pos_top,
pos_bottom,
pos_left,
pos_middle,
pos_right
};
// Estructura para saber la seccion y subseccion del programa // Estructura para saber la seccion y subseccion del programa
struct section_t struct section_t
{ {
@@ -87,6 +104,7 @@ struct input_t
struct online_t struct online_t
{ {
bool enabled; // Indica si se quiere usar el modo online o no bool enabled; // Indica si se quiere usar el modo online o no
bool sessionEnabled; // Indica ya se ha hecho login
std::string server; // Servidor para los servicios online std::string server; // Servidor para los servicios online
int port; // Puerto del servidor int port; // Puerto del servidor
std::string gameID; // Identificador del juego para los servicios online std::string gameID; // Identificador del juego para los servicios online
@@ -94,6 +112,22 @@ struct online_t
int score; // Puntuación almacenada online int score; // Puntuación almacenada online
}; };
// Estructura con opciones de la pantalla
struct op_screen_t
{
int windowWidth; // Ancho de la ventana
int windowHeight; // Alto de la ventana
};
// Estructura para las opciones de las notificaciones
struct op_notification_t
{
not_pos_e posH; // Ubicación de las notificaciones en pantalla
not_pos_e posV; // Ubicación de las notificaciones en pantalla
bool sound; // Indica si las notificaciones suenan
color_t color; // Color de las notificaciones
};
// Estructura con todas las opciones de configuración del programa // Estructura con todas las opciones de configuración del programa
struct options_t struct options_t
{ {
@@ -101,17 +135,24 @@ struct options_t
Uint8 playerSelected; // Jugador seleccionado para el modo 1P Uint8 playerSelected; // Jugador seleccionado para el modo 1P
std::vector<input_t> input; // Modo de control (teclado o mando) std::vector<input_t> input; // 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
Uint8 windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana Uint32 videoMode; // Contiene el valor del modo de pantalla completa
Uint32 filter; // Filtro usado para el escalado de la imagen int windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana
bool vSync; // Indica si se quiere usar vsync o no Uint32 filter; // Filtro usado para el escalado de la imagen
int screenWidth; // Ancho de la pantalla/ventana bool vSync; // Indica si se quiere usar vsync o no
int screenHeight; // Alto de la pantalla/ventana int gameWidth; // Ancho de la resolucion nativa del juego
bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa int gameHeight; // Alto de la resolucion nativa del juego
bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
float borderSize; // Porcentaje de borde que se añade a lo ventana bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana
online_t online; // Datos del servicio online int borderWidth; // Cantidad de pixels que se añade en el borde de la ventana
int borderHeight; // Cantidad de pixels que se añade en el borde de la ventana
palette_e palette; // Paleta de colores a usar en el juego
bool console; // Indica si ha de mostrar información por la consola de texto
online_t online; // Datos del servicio online
op_screen_t screen; // Opciones relativas a la clase screen
op_notification_t notifications; // Opciones relativas a las notificaciones;
}; };
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos
@@ -151,7 +192,7 @@ bool checkCollision(SDL_Point &p, d_line_t &l);
void normalizeLine(d_line_t &l); void normalizeLine(d_line_t &l);
// Devuelve un color_t a partir de un string // Devuelve un color_t a partir de un string
color_t stringToColor(std::string str); color_t stringToColor(palette_e pal, std::string str);
// Convierte una cadena en un valor booleano // Convierte una cadena en un valor booleano
bool stringToBool(std::string str); bool stringToBool(std::string str);

View File

@@ -11,15 +11,15 @@
#define BLOCK 8 #define BLOCK 8
#define HALF_BLOCK BLOCK / 2 #define HALF_BLOCK BLOCK / 2
// Tamaño de la pantalla de juego // Tamaño de la pantalla virtual
#define GAME_WIDTH 256 #define GAMECANVAS_WIDTH 256
#define GAME_HEIGHT 192 #define GAMECANVAS_HEIGHT 192
// Zona de juego // Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK); const int PLAY_AREA_TOP = (0 * BLOCK);
const int PLAY_AREA_BOTTOM = GAME_HEIGHT - (4 * BLOCK); const int PLAY_AREA_BOTTOM = GAMECANVAS_HEIGHT - (4 * BLOCK);
const int PLAY_AREA_LEFT = (0 * BLOCK); const int PLAY_AREA_LEFT = (0 * BLOCK);
const int PLAY_AREA_RIGHT = GAME_WIDTH - (0 * BLOCK); const int PLAY_AREA_RIGHT = GAMECANVAS_WIDTH - (0 * BLOCK);
const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT; const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT;
const int PLAY_AREA_HEIGHT = PLAY_AREA_BOTTOM - PLAY_AREA_TOP; const int PLAY_AREA_HEIGHT = PLAY_AREA_BOTTOM - PLAY_AREA_TOP;
const int PLAY_AREA_CENTER_X = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2); const int PLAY_AREA_CENTER_X = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2);
@@ -30,12 +30,12 @@ const int PLAY_AREA_FIRST_QUARTER_Y = PLAY_AREA_HEIGHT / 4;
const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3; const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3;
// Anclajes de pantalla // Anclajes de pantalla
const int SCREEN_CENTER_X = GAME_WIDTH / 2; const int GAMECANVAS_CENTER_X = GAMECANVAS_WIDTH / 2;
const int SCREEN_FIRST_QUARTER_X = GAME_WIDTH / 4; const int GAMECANVAS_FIRST_QUARTER_X = GAMECANVAS_WIDTH / 4;
const int SCREEN_THIRD_QUARTER_X = (GAME_WIDTH / 4) * 3; const int GAMECANVAS_THIRD_QUARTER_X = (GAMECANVAS_WIDTH / 4) * 3;
const int SCREEN_CENTER_Y = GAME_HEIGHT / 2; const int GAMECANVAS_CENTER_Y = GAMECANVAS_HEIGHT / 2;
const int SCREEN_FIRST_QUARTER_Y = GAME_HEIGHT / 4; const int GAMECANVAS_FIRST_QUARTER_Y = GAMECANVAS_HEIGHT / 4;
const int SCREEN_THIRD_QUARTER_Y = (GAME_HEIGHT / 4) * 3; const int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3;
// Secciones del programa // Secciones del programa
#define PROG_SECTION_LOGO 0 #define PROG_SECTION_LOGO 0

View File

@@ -5,25 +5,38 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <sys/stat.h>
#include <unistd.h>
#ifndef _WIN32
#include <pwd.h>
#endif
// Constructor // Constructor
Director::Director(std::string path) Director::Director(int argc, char *argv[])
{ {
// Inicializa variables // Inicializa variables
section.name = PROG_SECTION_LOGO; section.name = PROG_SECTION_LOGO;
// Crea el objeto que controla los ficheros de recursos
asset = new Asset(path);
// Establece la lista de ficheros
if (!setFileList())
{ // Si falta algún fichero no inicia el programa
section.name = PROG_SECTION_QUIT;
}
// Inicializa las opciones del programa // Inicializa las opciones del programa
initOptions(); initOptions();
// Comprueba los parametros del programa
checkProgramArguments(argc, argv);
// Crea la carpeta del sistema donde guardar datos
createSystemFolder();
// Crea el objeto que controla los ficheros de recursos
asset = new Asset(executablePath);
asset->setVerbose(options->console);
// Si falta algún fichero no inicia el programa
if (!setFileList())
{
exit(EXIT_FAILURE);
}
// Carga el fichero de configuración // Carga el fichero de configuración
loadConfigFile(); loadConfigFile();
@@ -37,10 +50,10 @@ Director::Director(std::string path)
lang = new Lang(asset); lang = new Lang(asset);
lang->setLang(options->language); lang->setLang(options->language);
input = new Input(asset->get("controllerdb.txt")); input = new Input(asset->get("gamecontrollerdb.txt"));
initInput(); initInput();
screen = new Screen(window, renderer, asset, options, GAME_WIDTH, GAME_HEIGHT); screen = new Screen(window, renderer, asset, options);
// Inicializa los servicios online // Inicializa los servicios online
initOnline(); initOnline();
@@ -108,7 +121,10 @@ bool Director::initSDL()
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
// 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)
{ {
printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError()); if (options->console)
{
std::cout << "SDL could not initialize!\nSDL Error: " << SDL_GetError() << std::endl;
}
success = false; success = false;
} }
else else
@@ -119,14 +135,27 @@ bool Director::initSDL()
// Establece el filtro de la textura // Establece el filtro de la textura
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options->filter).c_str())) if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options->filter).c_str()))
{ {
printf("Warning: Nearest texture filtering not enabled!\n"); if (options->console)
{
std::cout << "Warning: Nearest texture filtering not enabled!\n";
}
} }
// Crea la ventana // Crea la ventana
window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, options->screenWidth * options->windowSize, options->screenHeight * options->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); int incW = 0;
int incH = 0;
if (options->borderEnabled)
{
incW = options->borderWidth * 2;
incH = options->borderHeight * 2;
}
window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (options->gameWidth + incW) * options->windowSize, (options->gameHeight + incH) * options->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (window == nullptr) if (window == nullptr)
{ {
printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError()); if (options->console)
{
std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
success = false; success = false;
} }
else else
@@ -143,7 +172,10 @@ bool Director::initSDL()
if (renderer == nullptr) if (renderer == nullptr)
{ {
printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError()); if (options->console)
{
std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
success = false; success = false;
} }
else else
@@ -152,7 +184,7 @@ bool Director::initSDL()
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado // Establece el tamaño del buffer de renderizado
SDL_RenderSetLogicalSize(renderer, options->screenWidth, options->screenHeight); SDL_RenderSetLogicalSize(renderer, options->gameWidth, options->gameHeight);
// Establece el modo de mezcla // Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
@@ -160,7 +192,10 @@ bool Director::initSDL()
} }
} }
printf("\n"); if (options->console)
{
std::cout << std::endl;
}
return success; return success;
} }
@@ -174,11 +209,9 @@ bool Director::setFileList()
#endif #endif
// Ficheros de configuración // Ficheros de configuración
asset->add(prefix + "/data/config/score.bin", t_data, false); asset->add(systemFolder + "/config.txt", t_data, false, true);
asset->add(systemFolder + "/score.bin", t_data, false, true);
asset->add(prefix + "/data/config/demo.bin", t_data); asset->add(prefix + "/data/config/demo.bin", t_data);
asset->add(prefix + "/data/config/config.bin", t_data, false);
asset->add(prefix + "/data/config/config.txt", t_data, false);
asset->add(prefix + "/data/config/jailer_id.txt", t_data, false);
asset->add(prefix + "/data/config/gamecontrollerdb.txt", t_data); asset->add(prefix + "/data/config/gamecontrollerdb.txt", t_data);
// Musicas // Musicas
@@ -204,6 +237,7 @@ bool Director::setFileList()
asset->add(prefix + "/data/sound/title.wav", t_sound); asset->add(prefix + "/data/sound/title.wav", t_sound);
asset->add(prefix + "/data/sound/clock.wav", t_sound); asset->add(prefix + "/data/sound/clock.wav", t_sound);
asset->add(prefix + "/data/sound/powerball.wav", t_sound); asset->add(prefix + "/data/sound/powerball.wav", t_sound);
asset->add(prefix + "/data/sound/notify.wav", t_sound);
// Texturas // Texturas
asset->add(prefix + "/data/gfx/balloon1.png", t_bitmap); asset->add(prefix + "/data/gfx/balloon1.png", t_bitmap);
@@ -314,29 +348,105 @@ void Director::initOptions()
inp.deviceType = INPUT_USE_GAMECONTROLLER; inp.deviceType = INPUT_USE_GAMECONTROLLER;
options->input.push_back(inp); options->input.push_back(inp);
options->fullScreenMode = 0; // Video
options->gameWidth = GAMECANVAS_WIDTH;
options->gameHeight = GAMECANVAS_HEIGHT;
options->videoMode = 0;
options->windowSize = 3; options->windowSize = 3;
options->language = ba_BA;
options->difficulty = DIFFICULTY_NORMAL;
options->playerSelected = 0;
options->filter = FILTER_NEAREST; options->filter = FILTER_NEAREST;
options->vSync = true; options->vSync = true;
options->screenWidth = GAME_WIDTH;
options->screenHeight = GAME_HEIGHT;
options->integerScale = true; options->integerScale = true;
options->keepAspect = true; options->keepAspect = true;
options->borderSize = 0.0f; options->borderWidth = 0;
options->borderHeight = 0;
options->borderEnabled = false; options->borderEnabled = false;
// Varios
options->playerSelected = 0;
options->difficulty = DIFFICULTY_NORMAL;
options->language = ba_BA;
options->console = false;
// Online // Online
options->online.enabled = false; options->online.enabled = false;
options->online.server = ""; options->online.server = "jaildoctor.duckdns.org";
options->online.port = 0; options->online.port = 9911;
options->online.gameID = "coffee_crisis"; options->online.gameID = "coffee_crisis";
options->online.jailerID = ""; options->online.jailerID = "";
options->online.score = 0; options->online.score = 0;
} }
// Comprueba los parametros del programa
void Director::checkProgramArguments(int argc, char *argv[])
{
// Establece la ruta del programa
executablePath = argv[0];
// Comprueba el resto de parametros
for (int i = 1; i < argc; ++i)
{
if (strcmp(argv[i], "--console") == 0)
{
options->console = true;
}
}
}
// Crea la carpeta del sistema donde guardar datos
void Director::createSystemFolder()
{
#ifdef DEBUG
const std::string folderName = "coffee_crisis_debug";
#else
const std::string folderName = "coffee_crisis";
#endif
#ifdef _WIN32
systemFolder = std::string(getenv("APPDATA")) + "/" + folderName;
#elif __APPLE__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
systemFolder = std::string(homedir) + "/Library/Application Support/" + folderName;
#elif __linux__
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
systemFolder = std::string(homedir) + "/." + folderName;
#endif
struct stat st = {0};
if (stat(systemFolder.c_str(), &st) == -1)
{
errno = 0;
#ifdef _WIN32
int ret = mkdir(systemFolder.c_str());
#else
int ret = mkdir(systemFolder.c_str(), S_IRWXU);
#endif
if (ret == -1)
{
switch (errno)
{
case EACCES:
printf("the parent directory does not allow write");
exit(EXIT_FAILURE);
case EEXIST:
printf("pathname already exists");
exit(EXIT_FAILURE);
case ENAMETOOLONG:
printf("pathname is too long");
exit(EXIT_FAILURE);
default:
perror("mkdir");
exit(EXIT_FAILURE);
}
}
}
}
// Carga el fichero de configuración // Carga el fichero de configuración
bool Director::loadConfigFile() bool Director::loadConfigFile()
{ {
@@ -344,14 +454,18 @@ bool Director::loadConfigFile()
bool success = true; bool success = true;
// Variables para manejar el fichero // Variables para manejar el fichero
const std::string filePath = "config.txt";
std::string line; std::string line;
std::ifstream file(asset->get("config.txt")); std::ifstream file(asset->get(filePath));
// Si el fichero se puede abrir // Si el fichero se puede abrir
if (file.good()) if (file.good())
{ {
// Procesa el fichero linea a linea // Procesa el fichero linea a linea
std::cout << "Reading file config.txt\n"; if (options->console)
{
std::cout << "Reading file " << filePath << std::endl;
}
while (std::getline(file, line)) while (std::getline(file, line))
{ {
// Comprueba que la linea no sea un comentario // Comprueba que la linea no sea un comentario
@@ -362,15 +476,21 @@ bool Director::loadConfigFile()
// Procesa las dos subcadenas // Procesa las dos subcadenas
if (!setOptions(options, line.substr(0, pos), line.substr(pos + 1, line.length()))) if (!setOptions(options, line.substr(0, pos), line.substr(pos + 1, line.length())))
{ {
std::cout << "Warning: file config.txt\n"; if (options->console)
std::cout << "unknown parameter " << line.substr(0, pos).c_str() << std::endl; {
std::cout << "Warning: file " << filePath << std::endl;
std::cout << "Unknown parameter " << line.substr(0, pos).c_str() << std::endl;
}
success = false; success = false;
} }
} }
} }
// Cierra el fichero // Cierra el fichero
std::cout << "Closing file config.txt\n\n"; if (options->console)
{
std::cout << "Closing file " << filePath << std::endl;
}
file.close(); file.close();
} }
@@ -381,12 +501,12 @@ bool Director::loadConfigFile()
} }
// Normaliza los valores // Normaliza los valores
const bool a = options->fullScreenMode == 0; const bool a = options->videoMode == 0;
const bool b = options->fullScreenMode == SDL_WINDOW_FULLSCREEN; const bool b = options->videoMode == SDL_WINDOW_FULLSCREEN;
const bool c = options->fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP; const bool c = options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP;
if (!(a || b || c)) if (!(a || b || c))
{ {
options->fullScreenMode = 0; options->videoMode = 0;
} }
if (options->windowSize < 1 || options->windowSize > 4) if (options->windowSize < 1 || options->windowSize > 4)
@@ -412,17 +532,17 @@ bool Director::saveConfigFile()
// Escribe en el fichero // Escribe en el fichero
file << "## VISUAL OPTIONS\n"; file << "## VISUAL OPTIONS\n";
if (options->fullScreenMode == 0) if (options->videoMode == 0)
{ {
file << "fullScreenMode=0\n"; file << "videoMode=0\n";
} }
else if (options->fullScreenMode == SDL_WINDOW_FULLSCREEN) else if (options->videoMode == SDL_WINDOW_FULLSCREEN)
{ {
file << "fullScreenMode=SDL_WINDOW_FULLSCREEN\n"; file << "fullScreenMode=SDL_WINDOW_FULLSCREEN\n";
} }
else if (options->fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP) else if (options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{ {
file << "fullScreenMode=SDL_WINDOW_FULLSCREEN_DESKTOP\n"; file << "fullScreenMode=SDL_WINDOW_FULLSCREEN_DESKTOP\n";
} }
@@ -442,15 +562,14 @@ bool Director::saveConfigFile()
file << "integerScale=" + boolToString(options->integerScale) + "\n"; file << "integerScale=" + boolToString(options->integerScale) + "\n";
file << "keepAspect=" + boolToString(options->keepAspect) + "\n"; file << "keepAspect=" + boolToString(options->keepAspect) + "\n";
file << "borderEnabled=" + boolToString(options->borderEnabled) + "\n"; file << "borderEnabled=" + boolToString(options->borderEnabled) + "\n";
file << "borderSize=" + std::to_string(options->borderSize) + "\n"; file << "borderWidth=" + std::to_string(options->borderWidth) + "\n";
file << "screenWidth=" + std::to_string(options->screenWidth) + "\n"; file << "borderHeight=" + std::to_string(options->borderHeight) + "\n";
file << "screenHeight=" + std::to_string(options->screenHeight) + "\n";
file << "\n## OTHER OPTIONS\n"; file << "\n## OTHER OPTIONS\n";
file << "language=" + std::to_string(options->language) + "\n"; file << "language=" + std::to_string(options->language) + "\n";
file << "difficulty=" + std::to_string(options->difficulty) + "\n"; file << "difficulty=" + std::to_string(options->difficulty) + "\n";
file << "input0=" + std::to_string(options->input.at(0).deviceType) + "\n"; file << "input0=" + std::to_string(options->input[0].deviceType) + "\n";
file << "input1=" + std::to_string(options->input.at(1).deviceType) + "\n"; file << "input1=" + std::to_string(options->input[1].deviceType) + "\n";
file << "\n## ONLINE OPTIONS\n"; file << "\n## ONLINE OPTIONS\n";
file << "enabled=" + boolToString(options->online.enabled) + "\n"; file << "enabled=" + boolToString(options->online.enabled) + "\n";
@@ -528,18 +647,52 @@ void Director::run()
// Inicializa los servicios online // Inicializa los servicios online
void Director::initOnline() void Director::initOnline()
{ {
if (options->online.sessionEnabled)
{ // Si ya ha iniciado la sesión, que no continue
return;
}
if (options->online.jailerID == "")
{ // Jailer ID no definido
options->online.enabled = false;
}
else
{ // Jailer ID iniciado
options->online.enabled = options->online.sessionEnabled = true;
jscore::init(options->online.server, options->online.port);
#ifdef DEBUG
const std::string caption = options->online.jailerID + " IS LOGGED IN (DEBUG)";
#else
const std::string caption = options->online.jailerID + " IS LOGGED IN";
#endif
screen->showNotification(caption);
if (options->console)
{
std::cout << caption << std::endl;
}
}
// OLD
if (!options->online.enabled) if (!options->online.enabled)
{ {
//screen->showText("Modo Offline");
//std::cout << "Modo Offline" << std::endl;
return; return;
} }
// Obten el Jailer ID // Obten el Jailer ID
if (options->online.jailerID == "") if (options->online.jailerID == "")
{ // Jailer ID no definido { // Jailer ID no definido
screen->showText("No ha especificado ningun Jailer ID"); screen->showNotification("No ha especificado ningun Jailer ID");
std::cout << "No ha especificado ningun Jailer ID" << std::endl; if (options->console)
{
std::cout << "No ha especificado ningun Jailer ID" << std::endl;
}
} }
else else
{ // Jailer ID iniciado { // Jailer ID iniciado
@@ -550,21 +703,34 @@ void Director::initOnline()
// Obtiene la información online // Obtiene la información online
if (jscore::initOnlineScore(options->online.gameID)) if (jscore::initOnlineScore(options->online.gameID))
{ {
screen->showText(options->online.jailerID + " ha iniciado sesion"); screen->showNotification(options->online.jailerID + " ha iniciado sesion");
std::cout << options->online.jailerID << " ha iniciado sesion" << std::endl; if (options->console)
{
std::cout << options->online.jailerID << " ha iniciado sesion" << std::endl;
}
} }
else else
{ {
screen->showText("Fallo al conectar a " + options->online.server); screen->showNotification("Fallo al conectar a " + options->online.server);
std::cout << "Fallo al conectar a " << options->online.server << std::endl; if (options->console)
{
std::cout << "Fallo al conectar a " << options->online.server << std::endl;
}
options->online.enabled = false;
return;
} }
// Obten la puntuación online // Obten la puntuación online
const int points = jscore::getUserPoints(options->online.gameID, options->online.jailerID); const int points = jscore::getUserPoints(options->online.gameID, options->online.jailerID);
if (points == 0) if (points == 0)
{ // Fallo de conexión o no hay registros { // Fallo de conexión o no hay registros
screen->showText("No se ha podido obtener la puntuacion online"); screen->showNotification("No se ha podido obtener la puntuacion online");
std::cout << "No se ha podido obtener la puntuacion online" << std::endl; if (options->console)
{
std::cout << "No se ha podido obtener la puntuacion online" << std::endl;
}
} }
else else
{ {
@@ -579,19 +745,19 @@ bool Director::setOptions(options_t *options, std::string var, std::string value
// Indicador de éxito en la asignación // Indicador de éxito en la asignación
bool success = true; bool success = true;
if (var == "fullScreenMode") if (var == "videoMode")
{ {
if (value == "SDL_WINDOW_FULLSCREEN_DESKTOP") if (value == "SDL_WINDOW_FULLSCREEN_DESKTOP")
{ {
options->fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP; options->videoMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
} }
else if (value == "SDL_WINDOW_FULLSCREEN") else if (value == "SDL_WINDOW_FULLSCREEN")
{ {
options->fullScreenMode = SDL_WINDOW_FULLSCREEN; options->videoMode = SDL_WINDOW_FULLSCREEN;
} }
else else
{ {
options->fullScreenMode = 0; options->videoMode = 0;
} }
} }
@@ -636,23 +802,14 @@ bool Director::setOptions(options_t *options, std::string var, std::string value
options->borderEnabled = stringToBool(value); options->borderEnabled = stringToBool(value);
} }
else if (var == "borderSize") else if (var == "borderWidth")
{ {
options->borderSize = std::stof(value); options->borderWidth = std::stoi(value);
if (options->borderSize < 0.0f || options->borderSize > 0.5f)
{
options->borderSize = 0.1f;
}
} }
else if (var == "screenWidth") else if (var == "borderHeight")
{ {
options->screenWidth = std::stoi(value); options->borderHeight = std::stoi(value);
}
else if (var == "screenHeight")
{
options->screenHeight = std::stoi(value);
} }
else if (var == "language") else if (var == "language")
@@ -667,12 +824,12 @@ bool Director::setOptions(options_t *options, std::string var, std::string value
else if (var == "input0") else if (var == "input0")
{ {
options->input.at(0).deviceType = std::stoi(value); options->input[0].deviceType = std::stoi(value);
} }
else if (var == "input1") else if (var == "input1")
{ {
options->input.at(1).deviceType = std::stoi(value); options->input[1].deviceType = std::stoi(value);
} }
else if (var == "enabled") else if (var == "enabled")

View File

@@ -45,8 +45,10 @@ private:
Asset *asset; // Objeto que gestiona todos los ficheros de recursos Asset *asset; // Objeto que gestiona todos los ficheros de recursos
// Variables // Variables
struct options_t *options; // Variable con todas las opciones del programa struct options_t *options; // Variable con todas las opciones del programa
section_t section; // Sección y subsección actual del programa; section_t section; // Sección y subsección actual del programa;
std::string executablePath; // Path del ejecutable
std::string systemFolder; // Carpeta del sistema donde guardar datos
// Inicializa jail_audio // Inicializa jail_audio
void initJailAudio(); void initJailAudio();
@@ -75,6 +77,12 @@ private:
// Guarda el fichero de configuración // Guarda el fichero de configuración
bool saveConfigFile(); bool saveConfigFile();
// Comprueba los parametros del programa
void checkProgramArguments(int argc, char *argv[]);
// Crea la carpeta del sistema donde guardar datos
void createSystemFolder();
// Establece el valor de la variable // Establece el valor de la variable
void setSection(section_t section); void setSection(section_t section);
@@ -92,7 +100,7 @@ private:
public: public:
// Constructor // Constructor
Director(std::string path); Director(int argc, char *argv[]);
// Destructor // Destructor
~Director(); ~Director();

View File

@@ -1,14 +1,17 @@
#include "fade.h" #include "fade.h"
#include "const.h" #include "const.h"
#include <iostream>
// Constructor // Constructor
Fade::Fade(SDL_Renderer *renderer) Fade::Fade(SDL_Renderer *renderer)
{ {
mRenderer = renderer; mRenderer = renderer;
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH, GAME_HEIGHT); mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (mBackbuffer == nullptr) if (mBackbuffer == nullptr)
printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError()); {
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
} }
// Destructor // Destructor
@@ -38,7 +41,7 @@ void Fade::render()
switch (mFadeType) switch (mFadeType)
{ {
case FADE_FULLSCREEN: case FADE_FULLSCREEN:
mRect1 = {0, 0, GAME_WIDTH, GAME_HEIGHT}; mRect1 = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
for (int i = 0; i < 256; i += 4) for (int i = 0; i < 256; i += 4)
{ {
@@ -66,21 +69,21 @@ void Fade::render()
break; break;
case FADE_CENTER: case FADE_CENTER:
mRect1 = {0, 0, GAME_WIDTH, 0}; mRect1 = {0, 0, GAMECANVAS_WIDTH, 0};
mRect2 = {0, 0, GAME_WIDTH, 0}; mRect2 = {0, 0, GAMECANVAS_WIDTH, 0};
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64);
for (int i = 0; i < mCounter; i++) for (int i = 0; i < mCounter; i++)
{ {
mRect1.h = mRect2.h = i * 4; mRect1.h = mRect2.h = i * 4;
mRect2.y = GAME_HEIGHT - (i * 4); mRect2.y = GAMECANVAS_HEIGHT - (i * 4);
SDL_RenderFillRect(mRenderer, &mRect1); SDL_RenderFillRect(mRenderer, &mRect1);
SDL_RenderFillRect(mRenderer, &mRect2); SDL_RenderFillRect(mRenderer, &mRect2);
} }
if ((mCounter * 4) > GAME_HEIGHT) if ((mCounter * 4) > GAMECANVAS_HEIGHT)
mFinished = true; mFinished = true;
break; break;
@@ -98,8 +101,8 @@ void Fade::render()
// Dibujamos sobre el backbuffer // Dibujamos sobre el backbuffer
SDL_SetRenderTarget(mRenderer, mBackbuffer); SDL_SetRenderTarget(mRenderer, mBackbuffer);
mRect1.x = rand() % (GAME_WIDTH - mRect1.w); mRect1.x = rand() % (GAMECANVAS_WIDTH - mRect1.w);
mRect1.y = rand() % (GAME_HEIGHT - mRect1.h); mRect1.y = rand() % (GAMECANVAS_HEIGHT - mRect1.h);
SDL_RenderFillRect(mRenderer, &mRect1); SDL_RenderFillRect(mRenderer, &mRect1);
// Volvemos a usar el renderizador de forma normal // Volvemos a usar el renderizador de forma normal

View File

@@ -42,7 +42,7 @@ Game::Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *scr
buildingsSprite = new Sprite(0, 0, 256, 160, gameBuildingsTexture, renderer); buildingsSprite = new Sprite(0, 0, 256, 160, gameBuildingsTexture, renderer);
skyColorsSprite = new Sprite(0, 0, GAME_WIDTH, GAME_HEIGHT, gameSkyColorsTexture, renderer); skyColorsSprite = new Sprite(0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT, gameSkyColorsTexture, renderer);
grassSprite = new Sprite(0, 0, 256, 6, gameGrassTexture, renderer); grassSprite = new Sprite(0, 0, 256, 6, gameGrassTexture, renderer);
powerMeterSprite = new Sprite(PLAY_AREA_CENTER_X - 20, 170, 40, 7, gamePowerMeterTexture, renderer); powerMeterSprite = new Sprite(PLAY_AREA_CENTER_X - 20, 170, 40, 7, gamePowerMeterTexture, renderer);
gameOverSprite = new Sprite(16, 80, 128, 96, gameOverTexture, renderer); gameOverSprite = new Sprite(16, 80, 128, 96, gameOverTexture, renderer);
@@ -201,14 +201,14 @@ void Game::init()
// Crea los jugadores // Crea los jugadores
if (numPlayers == 1) if (numPlayers == 1)
{ {
Player *player = new Player(PLAY_AREA_CENTER_X - 11, PLAY_AREA_BOTTOM - 24, renderer, playerTextures.at(options->playerSelected), playerAnimations); Player *player = new Player(PLAY_AREA_CENTER_X - 11, PLAY_AREA_BOTTOM - 24, renderer, playerTextures[options->playerSelected], playerAnimations);
players.push_back(player); players.push_back(player);
} }
else if (numPlayers == 2) else if (numPlayers == 2)
{ {
Player *player1 = new Player((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((0 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, renderer, playerTextures.at(0), playerAnimations); Player *player1 = new Player((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((0 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, renderer, playerTextures[0], playerAnimations);
Player *player2 = new Player((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((1 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, renderer, playerTextures.at(1), playerAnimations); Player *player2 = new Player((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((1 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, renderer, playerTextures[1], playerAnimations);
players.push_back(player1); players.push_back(player1);
players.push_back(player2); players.push_back(player2);
} }
@@ -376,17 +376,20 @@ void Game::init()
n5000Sprite->setDestY(0); n5000Sprite->setDestY(0);
// Los fondos // Los fondos
skyColorsRect[0] = {0, 0, GAME_WIDTH, GAME_HEIGHT}; skyColorsRect[0] = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
skyColorsRect[1] = {256, 0, GAME_WIDTH, GAME_HEIGHT}; skyColorsRect[1] = {256, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
skyColorsRect[2] = {0, 192, GAME_WIDTH, GAME_HEIGHT}; skyColorsRect[2] = {0, 192, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
skyColorsRect[3] = {256, 192, GAME_WIDTH, GAME_HEIGHT}; skyColorsRect[3] = {256, 192, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
} }
// Carga los recursos necesarios para la sección 'Game' // Carga los recursos necesarios para la sección 'Game'
void Game::loadMedia() void Game::loadMedia()
{ {
std::cout << std::endl if (options->console)
<< "** LOADING RESOURCES FOR GAME SECTION" << std::endl; {
std::cout << std::endl
<< "** LOADING RESOURCES FOR GAME SECTION" << std::endl;
}
// Carga ficheros // Carga ficheros
loadScoreFile(); loadScoreFile();
@@ -573,8 +576,11 @@ void Game::loadMedia()
// Musicas // Musicas
gameMusic = JA_LoadMusic(asset->get("playing.ogg").c_str()); gameMusic = JA_LoadMusic(asset->get("playing.ogg").c_str());
std::cout << "** RESOURCES FOR GAME SECTION LOADED" << std::endl if (options->console)
<< std::endl; {
std::cout << "** RESOURCES FOR GAME SECTION LOADED" << std::endl
<< std::endl;
}
} }
// Carga el fichero de puntos // Carga el fichero de puntos
@@ -589,13 +595,19 @@ bool Game::loadScoreFile()
// El fichero no existe // El fichero no existe
if (file == nullptr) if (file == nullptr)
{ {
printf("Warning: Unable to open %s file\n", filename.c_str()); if (options->console)
{
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl;
}
// Creamos el fichero para escritura // Creamos el fichero para escritura
file = SDL_RWFromFile(p.c_str(), "w+b"); file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != nullptr) if (file != nullptr)
{ {
printf("New file (%s) created!\n", filename.c_str()); if (options->console)
{
std::cout << "New file (" << filename.c_str() << ") created!" << std::endl;
}
// Inicializamos los datos // Inicializamos los datos
for (int i = 0; i < TOTAL_SCORE_DATA; ++i) for (int i = 0; i < TOTAL_SCORE_DATA; ++i)
@@ -609,7 +621,10 @@ bool Game::loadScoreFile()
} }
else else
{ {
printf("Error: Unable to create file %s\n", filename.c_str()); if (options->console)
{
std::cout << "Error: Unable to create file " << filename.c_str() << std::endl;
}
success = false; success = false;
} }
} }
@@ -617,7 +632,10 @@ bool Game::loadScoreFile()
else else
{ {
// Cargamos los datos // Cargamos los datos
printf("Reading file %s\n", filename.c_str()); if (options->console)
{
std::cout << "Reading file " << filename.c_str() << std::endl;
}
for (int i = 0; i < TOTAL_SCORE_DATA; ++i) for (int i = 0; i < TOTAL_SCORE_DATA; ++i)
SDL_RWread(file, &scoreDataFile[i], sizeof(Uint32), 1); SDL_RWread(file, &scoreDataFile[i], sizeof(Uint32), 1);
@@ -655,13 +673,19 @@ bool Game::loadDemoFile()
// El fichero no existe // El fichero no existe
if (file == nullptr) if (file == nullptr)
{ {
printf("Warning: Unable to open %s file\n", filename.c_str()); if (options->console)
{
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl;
}
// Creamos el fichero para escritura // Creamos el fichero para escritura
file = SDL_RWFromFile(p.c_str(), "w+b"); file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != nullptr) if (file != nullptr)
{ {
printf("New file (%s) created!\n", filename.c_str()); if (options->console)
{
std::cout << "New file (" << filename.c_str() << ") created!" << std::endl;
}
// Inicializamos los datos // Inicializamos los datos
for (int i = 0; i < TOTAL_DEMO_DATA; ++i) for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
@@ -681,7 +705,10 @@ bool Game::loadDemoFile()
} }
else else
{ {
printf("Error: Unable to create file %s\n", filename.c_str()); if (options->console)
{
std::cout << "Error: Unable to create file " << filename.c_str() << std::endl;
}
success = false; success = false;
} }
} }
@@ -689,7 +716,10 @@ bool Game::loadDemoFile()
else else
{ {
// Cargamos los datos // Cargamos los datos
printf("Reading file %s\n", filename.c_str()); if (options->console)
{
std::cout << "Reading file " << filename.c_str() << std::endl;
}
for (int i = 0; i < TOTAL_DEMO_DATA; ++i) for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
SDL_RWread(file, &demo.dataFile[i], sizeof(demoKeys_t), 1); SDL_RWread(file, &demo.dataFile[i], sizeof(demoKeys_t), 1);
@@ -715,14 +745,20 @@ bool Game::saveScoreFile()
SDL_RWwrite(file, &scoreDataFile[i], sizeof(Uint32), 1); SDL_RWwrite(file, &scoreDataFile[i], sizeof(Uint32), 1);
} }
printf("Writing file %s\n", filename.c_str()); if (options->console)
{
std::cout << "Writing file " << filename.c_str() << std::endl;
}
// Cerramos el fichero // Cerramos el fichero
SDL_RWclose(file); SDL_RWclose(file);
} }
else else
{ {
printf("Error: Unable to save %s file! %s\n", filename.c_str(), SDL_GetError()); if (options->console)
{
std::cout << "Error: Unable to save " << filename.c_str() << " file! " << SDL_GetError() << std::endl;
}
} }
return success; return success;
} }
@@ -735,7 +771,7 @@ bool Game::sendOnlineScore()
return true; return true;
} }
const int score = players.at(0)->getScore(); const int score = players[0]->getScore();
if (score <= options->online.score) if (score <= options->online.score)
{ {
return true; return true;
@@ -744,12 +780,12 @@ bool Game::sendOnlineScore()
if (jscore::updateUserPoints("coffee_crisis", options->online.jailerID, score)) if (jscore::updateUserPoints("coffee_crisis", options->online.jailerID, score))
{ {
options->online.score = score; options->online.score = score;
screen->showText("PUNTUACION ENVIADA: " + std::to_string(score) + " PUNTOS"); screen->showNotification("PUNTUACION ENVIADA: " + std::to_string(score) + " PUNTOS");
return true; return true;
} }
else else
{ {
screen->showText("NO SE HA PODIDO ENVIAR LA PUNTUACION"); screen->showNotification("NO SE HA PODIDO ENVIAR LA PUNTUACION");
return false; return false;
} }
} }
@@ -771,14 +807,20 @@ bool Game::saveDemoFile()
SDL_RWwrite(file, &demo.dataFile[i], sizeof(demoKeys_t), 1); SDL_RWwrite(file, &demo.dataFile[i], sizeof(demoKeys_t), 1);
} }
printf("Writing file %s\n", filename.c_str()); if (options->console)
{
std::cout << "Writing file " << filename.c_str() << std::endl;
}
// Cerramos el fichero // Cerramos el fichero
SDL_RWclose(file); SDL_RWclose(file);
} }
else else
{ {
printf("Error: Unable to save %s file! %s\n", filename.c_str(), SDL_GetError()); if (options->console)
{
std::cout << "Error: Unable to save " << filename.c_str() << " file! " << SDL_GetError() << std::endl;
}
} }
} }
return success; return success;
@@ -1648,21 +1690,21 @@ void Game::renderScoreBoard()
// PLAYER1 - SCORE // PLAYER1 - SCORE
textScoreBoard->writeCentered(offsetLeft, offset1, lang->getText(53)); textScoreBoard->writeCentered(offsetLeft, offset1, lang->getText(53));
textScoreBoard->writeCentered(offsetLeft, offset2, updateScoreText(players.at(0)->getScore())); textScoreBoard->writeCentered(offsetLeft, offset2, updateScoreText(players[0]->getScore()));
// PLAYER1 - MULT // PLAYER1 - MULT
textScoreBoard->writeCentered(offsetLeft, offset3, lang->getText(55)); textScoreBoard->writeCentered(offsetLeft, offset3, lang->getText(55));
textScoreBoard->writeCentered(offsetLeft, offset4, std::to_string(players.at(0)->getScoreMultiplier()).substr(0, 3)); textScoreBoard->writeCentered(offsetLeft, offset4, std::to_string(players[0]->getScoreMultiplier()).substr(0, 3));
if (numPlayers == 2) if (numPlayers == 2)
{ {
// PLAYER2 - SCORE // PLAYER2 - SCORE
textScoreBoard->writeCentered(offsetRight, offset1, lang->getText(54)); textScoreBoard->writeCentered(offsetRight, offset1, lang->getText(54));
textScoreBoard->writeCentered(offsetRight, offset2, updateScoreText(players.at(1)->getScore())); textScoreBoard->writeCentered(offsetRight, offset2, updateScoreText(players[1]->getScore()));
// PLAYER2 - MULT // PLAYER2 - MULT
textScoreBoard->writeCentered(offsetRight, offset3, lang->getText(55)); textScoreBoard->writeCentered(offsetRight, offset3, lang->getText(55));
textScoreBoard->writeCentered(offsetRight, offset4, std::to_string(players.at(1)->getScoreMultiplier()).substr(0, 3)); textScoreBoard->writeCentered(offsetRight, offset4, std::to_string(players[1]->getScoreMultiplier()).substr(0, 3));
} }
else else
{ {
@@ -1806,7 +1848,7 @@ void Game::updateDeath()
{ {
// Hace sonar aleatoriamente uno de los 4 sonidos de burbujas // Hace sonar aleatoriamente uno de los 4 sonidos de burbujas
const Uint8 index = rand() % 4; const Uint8 index = rand() % 4;
const JA_Sound sound[4] = {bubble1Sound, bubble2Sound, bubble3Sound, bubble4Sound}; JA_Sound_t *sound[4] = {bubble1Sound, bubble2Sound, bubble3Sound, bubble4Sound};
JA_PlaySound(sound[index], 0); JA_PlaySound(sound[index], 0);
} }
} }
@@ -1831,7 +1873,7 @@ void Game::renderDeathFade(int counter)
{ {
rect[i].x = 0; rect[i].x = 0;
rect[i].y = i * 16; rect[i].y = i * 16;
rect[i].w = GAME_WIDTH; rect[i].w = GAMECANVAS_WIDTH;
if (i == 0) if (i == 0)
{ {
rect[i].h = h; rect[i].h = h;
@@ -1845,7 +1887,7 @@ void Game::renderDeathFade(int counter)
} }
else else
{ {
SDL_Rect rect = {0, 0, GAME_WIDTH, GAME_HEIGHT}; SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer, &rect);
} }
} }
@@ -1872,7 +1914,7 @@ void Game::renderBalloons()
Uint8 Game::createBalloon(float x, int y, Uint8 kind, float velx, float speed, Uint16 creationtimer) Uint8 Game::createBalloon(float x, int y, Uint8 kind, float velx, float speed, Uint16 creationtimer)
{ {
const int index = (kind - 1) % 4; const int index = (kind - 1) % 4;
Balloon *b = new Balloon(x, y, kind, velx, speed, creationtimer, balloonTextures.at(index), balloonAnimations.at(index), renderer); Balloon *b = new Balloon(x, y, kind, velx, speed, creationtimer, balloonTextures[index], balloonAnimations[index], renderer);
balloons.push_back(b); balloons.push_back(b);
return (Uint8)(balloons.size() - 1); return (Uint8)(balloons.size() - 1);
} }
@@ -1890,7 +1932,7 @@ void Game::createPowerBall()
const int x[3] = {left, center, right}; const int x[3] = {left, center, right};
const float vx[3] = {BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_NEGATIVE}; const float vx[3] = {BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_NEGATIVE};
Balloon *b = new Balloon(x[luck], posY, POWER_BALL, vx[luck], enemySpeed, 100, balloonTextures.at(3), balloonAnimations.at(3), renderer); Balloon *b = new Balloon(x[luck], posY, POWER_BALL, vx[luck], enemySpeed, 100, balloonTextures[3], balloonAnimations[3], renderer);
balloons.push_back(b); balloons.push_back(b);
powerBallEnabled = true; powerBallEnabled = true;
@@ -2035,25 +2077,25 @@ void Game::popBalloon(Balloon *balloon)
// En cualquier otro caso, crea dos globos de un tipo inferior // En cualquier otro caso, crea dos globos de un tipo inferior
default: default:
const int index = createBalloon(0, balloon->getPosY(), balloon->getKind() - 1, BALLOON_VELX_NEGATIVE, enemySpeed, 0); const int index = createBalloon(0, balloon->getPosY(), balloon->getKind() - 1, BALLOON_VELX_NEGATIVE, enemySpeed, 0);
balloons.at(index)->allignTo(balloon->getPosX() + (balloon->getWidth() / 2)); balloons[index]->allignTo(balloon->getPosX() + (balloon->getWidth() / 2));
if (balloons.at(index)->getClass() == BALLOON_CLASS) if (balloons[index]->getClass() == BALLOON_CLASS)
{ {
balloons.at(index)->setVelY(-2.50f); balloons[index]->setVelY(-2.50f);
} }
else else
{ {
balloons.at(index)->setVelY(BALLOON_VELX_NEGATIVE); balloons[index]->setVelY(BALLOON_VELX_NEGATIVE);
} }
const int index2 = createBalloon(0, balloon->getPosY(), balloon->getKind() - 1, BALLOON_VELX_POSITIVE, enemySpeed, 0); const int index2 = createBalloon(0, balloon->getPosY(), balloon->getKind() - 1, BALLOON_VELX_POSITIVE, enemySpeed, 0);
balloons.at(index2)->allignTo(balloon->getPosX() + (balloon->getWidth() / 2)); balloons[index2]->allignTo(balloon->getPosX() + (balloon->getWidth() / 2));
if (balloons.at(index2)->getClass() == BALLOON_CLASS) if (balloons[index2]->getClass() == BALLOON_CLASS)
{ {
balloons.at(index2)->setVelY(-2.50f); balloons[index2]->setVelY(-2.50f);
} }
else else
{ {
balloons.at(index2)->setVelY(BALLOON_VELX_NEGATIVE); balloons[index2]->setVelY(BALLOON_VELX_NEGATIVE);
} }
// Elimina el globo // Elimina el globo
@@ -2201,9 +2243,9 @@ void Game::freeBalloons()
{ {
for (int i = balloons.size() - 1; i >= 0; --i) for (int i = balloons.size() - 1; i >= 0; --i)
{ {
if (balloons.at(i)->isEnabled() == false) if (balloons[i]->isEnabled() == false)
{ {
delete balloons.at(i); delete balloons[i];
balloons.erase(balloons.begin() + i); balloons.erase(balloons.begin() + i);
} }
} }
@@ -2309,8 +2351,8 @@ void Game::checkBulletBalloonCollision()
{ {
// Otorga los puntos correspondientes al globo al jugador que disparó la bala // Otorga los puntos correspondientes al globo al jugador que disparó la bala
int index = bullet->getOwner(); int index = bullet->getOwner();
players.at(index)->incScoreMultiplier(); players[index]->incScoreMultiplier();
players.at(index)->addScore(Uint32(balloon->getScore() * players.at(index)->getScoreMultiplier() * difficultyScoreMultiplier)); players[index]->addScore(Uint32(balloon->getScore() * players[index]->getScoreMultiplier() * difficultyScoreMultiplier));
updateHiScore(); updateHiScore();
// Explota el globo // Explota el globo
@@ -2336,7 +2378,7 @@ void Game::checkBulletBalloonCollision()
} }
else else
{ {
createItem(droppeditem, players.at(index)->getPosX(), 0); createItem(droppeditem, players[index]->getPosX(), 0);
coffeeMachineEnabled = true; coffeeMachineEnabled = true;
} }
} }
@@ -2357,7 +2399,7 @@ void Game::moveBullets()
{ {
if (bullet->move() == BULLET_MOVE_OUT) if (bullet->move() == BULLET_MOVE_OUT)
{ {
players.at(bullet->getOwner())->decScoreMultiplier(); players[bullet->getOwner()]->decScoreMultiplier();
} }
} }
} }
@@ -2389,9 +2431,9 @@ void Game::freeBullets()
{ {
for (int i = bullets.size() - 1; i >= 0; --i) for (int i = bullets.size() - 1; i >= 0; --i)
{ {
if (bullets.at(i)->isEnabled() == false) if (bullets[i]->isEnabled() == false)
{ {
delete bullets.at(i); delete bullets[i];
bullets.erase(bullets.begin() + i); bullets.erase(bullets.begin() + i);
} }
} }
@@ -2503,7 +2545,7 @@ Uint8 Game::dropItem()
// Crea un objeto item // Crea un objeto item
void Game::createItem(Uint8 kind, float x, float y) void Game::createItem(Uint8 kind, float x, float y)
{ {
Item *item = new Item(kind, x, y, itemTextures.at(kind), itemAnimations.at(kind), renderer); Item *item = new Item(kind, x, y, itemTextures[kind], itemAnimations[kind], renderer);
items.push_back(item); items.push_back(item);
} }
@@ -2514,9 +2556,9 @@ void Game::freeItems()
{ {
for (int i = items.size() - 1; i >= 0; --i) for (int i = items.size() - 1; i >= 0; --i)
{ {
if (items.at(i)->isEnabled() == false) if (items[i]->isEnabled() == false)
{ {
delete items.at(i); delete items[i];
items.erase(items.begin() + i); items.erase(items.begin() + i);
} }
} }
@@ -2546,9 +2588,9 @@ void Game::freeSmartSprites()
{ {
for (int i = smartSprites.size() - 1; i >= 0; --i) for (int i = smartSprites.size() - 1; i >= 0; --i)
{ {
if (smartSprites.at(i)->hasFinished()) if (smartSprites[i]->hasFinished())
{ {
delete smartSprites.at(i); delete smartSprites[i];
smartSprites.erase(smartSprites.begin() + i); smartSprites.erase(smartSprites.begin() + i);
} }
} }
@@ -2588,7 +2630,7 @@ void Game::updateShakeEffect()
// Crea un SmartSprite para arrojar el item café al recibir un impacto // Crea un SmartSprite para arrojar el item café al recibir un impacto
void Game::throwCoffee(int x, int y) void Game::throwCoffee(int x, int y)
{ {
SmartSprite *ss = new SmartSprite(itemTextures.at(4), renderer); SmartSprite *ss = new SmartSprite(itemTextures[4], renderer);
smartSprites.push_back(ss); smartSprites.push_back(ss);
ss->setPosX(x - 8); ss->setPosX(x - 8);
@@ -2600,7 +2642,7 @@ void Game::throwCoffee(int x, int y)
ss->setAccelX(0.0f); ss->setAccelX(0.0f);
ss->setAccelY(0.2f); ss->setAccelY(0.2f);
ss->setDestX(x + (ss->getVelX() * 50)); ss->setDestX(x + (ss->getVelX() * 50));
ss->setDestY(GAME_HEIGHT + 1); ss->setDestY(GAMECANVAS_HEIGHT + 1);
ss->setEnabled(true); ss->setEnabled(true);
ss->setEnabledCounter(1); ss->setEnabledCounter(1);
ss->setSpriteClip(0, 0, 16, 16); ss->setSpriteClip(0, 0, 16, 16);
@@ -2919,7 +2961,7 @@ void Game::render()
renderScoreBoard(); renderScoreBoard();
renderPlayers(); renderPlayers();
if ((deathCounter <= 150) && !players.at(0)->isAlive()) if ((deathCounter <= 150) && !players[0]->isAlive())
{ {
renderDeathFade(150 - deathCounter); renderDeathFade(150 - deathCounter);
} }
@@ -2976,45 +3018,45 @@ void Game::checkGameInput()
const int index = 0; const int index = 0;
if (demo.dataFile[demo.counter].left == 1) if (demo.dataFile[demo.counter].left == 1)
{ {
players.at(index)->setInput(INPUT_LEFT); players[index]->setInput(INPUT_LEFT);
} }
if (demo.dataFile[demo.counter].right == 1) if (demo.dataFile[demo.counter].right == 1)
{ {
players.at(index)->setInput(INPUT_RIGHT); players[index]->setInput(INPUT_RIGHT);
} }
if (demo.dataFile[demo.counter].noInput == 1) if (demo.dataFile[demo.counter].noInput == 1)
{ {
players.at(index)->setInput(INPUT_NULL); players[index]->setInput(INPUT_NULL);
} }
if (demo.dataFile[demo.counter].fire == 1) if (demo.dataFile[demo.counter].fire == 1)
{ {
if (players.at(index)->canFire()) if (players[index]->canFire())
{ {
players.at(index)->setInput(INPUT_BUTTON_2); players[index]->setInput(INPUT_BUTTON_2);
createBullet(players.at(index)->getPosX() + (players.at(index)->getWidth() / 2) - 4, players.at(index)->getPosY() + (players.at(index)->getHeight() / 2), BULLET_UP, players.at(index)->isPowerUp(), index); createBullet(players[index]->getPosX() + (players[index]->getWidth() / 2) - 4, players[index]->getPosY() + (players[index]->getHeight() / 2), BULLET_UP, players[index]->isPowerUp(), index);
players.at(index)->setFireCooldown(10); players[index]->setFireCooldown(10);
} }
} }
if (demo.dataFile[demo.counter].fireLeft == 1) if (demo.dataFile[demo.counter].fireLeft == 1)
{ {
if (players.at(index)->canFire()) if (players[index]->canFire())
{ {
players.at(index)->setInput(INPUT_BUTTON_1); players[index]->setInput(INPUT_BUTTON_1);
createBullet(players.at(index)->getPosX() + (players.at(index)->getWidth() / 2) - 4, players.at(index)->getPosY() + (players.at(index)->getHeight() / 2), BULLET_UP, players.at(index)->isPowerUp(), index); createBullet(players[index]->getPosX() + (players[index]->getWidth() / 2) - 4, players[index]->getPosY() + (players[index]->getHeight() / 2), BULLET_UP, players[index]->isPowerUp(), index);
players.at(index)->setFireCooldown(10); players[index]->setFireCooldown(10);
} }
} }
if (demo.dataFile[demo.counter].fireRight == 1) if (demo.dataFile[demo.counter].fireRight == 1)
{ {
if (players.at(index)->canFire()) if (players[index]->canFire())
{ {
players.at(index)->setInput(INPUT_BUTTON_3); players[index]->setInput(INPUT_BUTTON_3);
createBullet(players.at(index)->getPosX() + (players.at(index)->getWidth() / 2) - 4, players.at(index)->getPosY() + (players.at(index)->getHeight() / 2), BULLET_UP, players.at(index)->isPowerUp(), index); createBullet(players[index]->getPosX() + (players[index]->getWidth() / 2) - 4, players[index]->getPosY() + (players[index]->getHeight() / 2), BULLET_UP, players[index]->isPowerUp(), index);
players.at(index)->setFireCooldown(10); players[index]->setFireCooldown(10);
} }
} }
@@ -3296,7 +3338,7 @@ section_t Game::run()
// Reproduce la música // Reproduce la música
if (!gameCompleted) if (!gameCompleted)
{ {
if (players.at(0)->isAlive()) if (players[0]->isAlive())
{ {
JA_PlayMusic(gameMusic); JA_PlayMusic(gameMusic);
} }
@@ -3408,7 +3450,7 @@ void Game::renderPausedGame()
renderScoreBoard(); renderScoreBoard();
renderPlayers(); renderPlayers();
if ((deathCounter <= 150) && !players.at(0)->isAlive()) if ((deathCounter <= 150) && !players[0]->isAlive())
{ {
renderDeathFade(150 - deathCounter); renderDeathFade(150 - deathCounter);
} }
@@ -3423,7 +3465,7 @@ void Game::renderPausedGame()
if (leavingPauseMenu) if (leavingPauseMenu)
{ {
textNokiaBig2->writeCentered(SCREEN_CENTER_X, PLAY_AREA_FIRST_QUARTER_Y, std::to_string((pauseCounter / 30) + 1)); textNokiaBig2->writeCentered(GAMECANVAS_CENTER_X, PLAY_AREA_FIRST_QUARTER_Y, std::to_string((pauseCounter / 30) + 1));
} }
else else
{ {
@@ -3578,7 +3620,7 @@ void Game::renderGameOverScreen()
textBig->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 6), lang->getText(43)); textBig->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 6), lang->getText(43));
// Your Score // Your Score
text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 3), lang->getText(44) + std::to_string(players.at(0)->getScore())); text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 3), lang->getText(44) + std::to_string(players[0]->getScore()));
} }
else else
{ {
@@ -3592,10 +3634,10 @@ void Game::renderGameOverScreen()
textBig->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 7), lang->getText(43)); textBig->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 7), lang->getText(43));
// Player1 Score // Player1 Score
text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 4), lang->getText(77) + std::to_string(players.at(0)->getScore())); text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 4), lang->getText(77) + std::to_string(players[0]->getScore()));
// Player2 Score // Player2 Score
text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 2), lang->getText(78) + std::to_string(players.at(1)->getScore())); text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 2), lang->getText(78) + std::to_string(players[1]->getScore()));
} }
// Continue? // Continue?
@@ -3851,7 +3893,10 @@ void Game::loadAnimations(std::string filePath, std::vector<std::string> *buffer
if (file) if (file)
{ {
std::cout << "Animation loaded: " << filePath.substr(filePath.find_last_of("\\/") + 1).c_str() << std::endl; if (options->console)
{
std::cout << "Animation loaded: " << filePath.substr(filePath.find_last_of("\\/") + 1).c_str() << std::endl;
}
while (std::getline(file, line)) while (std::getline(file, line))
{ {
buffer->push_back(line); buffer->push_back(line);

View File

@@ -174,23 +174,23 @@ private:
Sprite *gameOverSprite; // Sprite para dibujar los graficos del game over Sprite *gameOverSprite; // Sprite para dibujar los graficos del game over
Sprite *gameOverEndSprite; // Sprite para dibujar los graficos del game over de acabar el juego Sprite *gameOverEndSprite; // Sprite para dibujar los graficos del game over de acabar el juego
JA_Sound balloonSound; // Sonido para la explosión del globo JA_Sound_t* balloonSound; // Sonido para la explosión del globo
JA_Sound bulletSound; // Sonido para los disparos JA_Sound_t* bulletSound; // Sonido para los disparos
JA_Sound playerCollisionSound; // Sonido para la colisión del jugador con un enemigo JA_Sound_t* playerCollisionSound; // Sonido para la colisión del jugador con un enemigo
JA_Sound hiScoreSound; // Sonido para cuando se alcanza la máxima puntuación JA_Sound_t* hiScoreSound; // Sonido para cuando se alcanza la máxima puntuación
JA_Sound itemDropSound; // Sonido para cuando se genera un item JA_Sound_t* itemDropSound; // Sonido para cuando se genera un item
JA_Sound itemPickUpSound; // Sonido para cuando se recoge un item JA_Sound_t* itemPickUpSound; // Sonido para cuando se recoge un item
JA_Sound coffeeOutSound; // Sonido para cuando el jugador pierde el café al recibir un impacto JA_Sound_t* coffeeOutSound; // Sonido para cuando el jugador pierde el café al recibir un impacto
JA_Sound stageChangeSound; // Sonido para cuando se cambia de fase JA_Sound_t* stageChangeSound; // Sonido para cuando se cambia de fase
JA_Sound bubble1Sound; // Sonido para cuando el jugador muere JA_Sound_t* bubble1Sound; // Sonido para cuando el jugador muere
JA_Sound bubble2Sound; // Sonido para cuando el jugador muere JA_Sound_t* bubble2Sound; // Sonido para cuando el jugador muere
JA_Sound bubble3Sound; // Sonido para cuando el jugador muere JA_Sound_t* bubble3Sound; // Sonido para cuando el jugador muere
JA_Sound bubble4Sound; // Sonido para cuando el jugador muere JA_Sound_t* bubble4Sound; // Sonido para cuando el jugador muere
JA_Sound clockSound; // Sonido para cuando se detiene el tiempo con el item reloj JA_Sound_t* clockSound; // Sonido para cuando se detiene el tiempo con el item reloj
JA_Sound powerBallSound; // Sonido para cuando se explota una Power Ball JA_Sound_t* powerBallSound; // Sonido para cuando se explota una Power Ball
JA_Sound coffeeMachineSound; // Sonido para cuando la máquina de café toca el suelo JA_Sound_t* coffeeMachineSound; // Sonido para cuando la máquina de café toca el suelo
JA_Music gameMusic; // Musica de fondo JA_Music_t* gameMusic; // Musica de fondo
// Variables // Variables
int numPlayers; // Numero de jugadores int numPlayers; // Numero de jugadores

254
source/hiscore_table.cpp Normal file
View File

@@ -0,0 +1,254 @@
#include "hiscore_table.h"
#include "common/jscore.h"
#include <iostream>
const Uint8 SELF = 0;
// Constructor
HiScoreTable::HiScoreTable(SDL_Renderer *renderer, Screen *screen, Asset *asset, Lang *lang, options_t *options)
{
// Copia los punteros
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
this->lang = lang;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
// Crea un backbuffer para el renderizador
backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (backbuffer == nullptr)
{
if (options->console)
{
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
// Inicializa variables
section.name = SELF;
ticks = 0;
ticksSpeed = 15;
manualQuit = false;
counter = 0;
counterEnd = 600;
}
// Destructor
HiScoreTable::~HiScoreTable()
{
delete eventHandler;
delete text;
SDL_DestroyTexture(backbuffer);
}
// Actualiza las variables
void HiScoreTable::update()
{
// Comprueba los eventos
checkEventHandler();
// Actualiza las variables
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
if (mode == mhst_auto)
{ // Modo automático
counter++;
if (counter == counterEnd)
{
section.name = PROG_SECTION_TITLE;
section.subsection = TITLE_SECTION_1;
}
}
else
{ // Modo manual
++counter %= 60000;
if (manualQuit)
{
section.name = PROG_SECTION_TITLE;
section.subsection = TITLE_SECTION_3;
}
}
}
}
// Pinta en pantalla
void HiScoreTable::render()
{
// Pinta en pantalla
SDL_Rect window = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
const color_t orangeColor = {0xFF, 0x7A, 0x00};
// hay 27 letras - 7 de puntos quedan 20 caracteres 20 - nameLenght 0 numDots
const int spaceBetweenHeader = 32;
const int spaceBetweenLines = text->getCharacterSize() * 1.8f;
// Pinta en el backbuffer el texto y los sprites
SDL_SetRenderTarget(renderer, backbuffer);
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(renderer);
// Escribe el texto: Mejores puntuaciones
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 8, lang->getText(42), 1, orangeColor, 1, shdwTxtColor);
// Escribe la lista de jugadores
int numUsers = jscore::getNumUsers();
for (int i = 0; i < numUsers; ++i)
{
const int nameLenght = jscore::getUserName(i).length();
const int numDots = 20 - nameLenght;
std::string dots = "";
for (int j = 0; j < numDots; ++j)
{
dots = dots + ".";
}
const std::string line = jscore::getUserName(i) + dots + scoreToString(jscore::getPoints(i));
text->writeDX(TXT_CENTER | TXT_SHADOW, GAMECANVAS_CENTER_X, (i * spaceBetweenLines) + spaceBetweenHeader, line, 1, orangeColor, 1, shdwTxtColor);
}
// Rellena la lista con otros nombres
if (numUsers < 10)
{
std::vector<std::string> names;
names.insert(names.end(), {"BRY", "USUFONDO", "G.LUCAS", "P.DELGAT", "P.ARRABALERA", "PELECHANO", "SAHUQUILLO"});
for (int i = numUsers; i < 10; ++i)
{
const int nameLenght = names[i - numUsers].length();
const int numDots = 20 - nameLenght;
std::string dots = "";
for (int j = 0; j < numDots; ++j)
{
dots = dots + ".";
}
const std::string line = names[i - numUsers] + dots + "0000000";
text->writeDX(TXT_CENTER | TXT_SHADOW, GAMECANVAS_CENTER_X, (i * spaceBetweenLines) + spaceBetweenHeader, line, 1, orangeColor, 1, shdwTxtColor);
}
}
if ((mode == mhst_manual) && (counter % 50 > 14))
{
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, GAMECANVAS_HEIGHT - 12, lang->getText(22), 1, orangeColor, 1, shdwTxtColor);
}
// Cambia el destino de renderizado
SDL_SetRenderTarget(renderer, nullptr);
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean(bgColor);
// Establece la ventana del backbuffer
if (mode == mhst_auto)
{
window.y = std::max(8, GAMECANVAS_HEIGHT - counter + 100);
}
else
{
window.y = 0;
}
// Copia el backbuffer al renderizador
SDL_RenderCopy(renderer, backbuffer, nullptr, &window);
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
// Comprueba los eventos
void HiScoreTable::checkEventHandler()
{
// 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;
}
if ((eventHandler->type == SDL_KEYUP) || (eventHandler->type == SDL_JOYBUTTONUP))
{
if (mode == mhst_auto)
{
JA_StopMusic();
section.name = PROG_SECTION_TITLE;
section.subsection = TITLE_SECTION_1;
}
else
{
if (counter > 30)
{
manualQuit = true;
}
}
}
}
}
// Bucle para la pantalla de instrucciones
section_t HiScoreTable::run(mode_hiScoreTable_e mode)
{
this->mode = mode;
while (section.name == SELF)
{
update();
render();
}
return section;
}
// Transforma un valor numérico en una cadena de 6 cifras
std::string HiScoreTable::scoreToString(Uint32 num)
{
if ((num >= 0) && (num <= 9))
{
return ("000000" + std::to_string(num));
}
if ((num >= 10) && (num <= 99))
{
return ("00000" + std::to_string(num));
}
if ((num >= 100) && (num <= 999))
{
return ("0000" + std::to_string(num));
}
if ((num >= 1000) && (num <= 9999))
{
return ("000" + std::to_string(num));
}
if ((num >= 010000) && (num <= 99999))
{
return ("00" + std::to_string(num));
}
if ((num >= 100000) && (num <= 999999))
{
return ("0" + std::to_string(num));
}
if ((num >= 1000000) && (num <= 9999999))
{
return (std::to_string(num));
}
return (std::to_string(num));
}

66
source/hiscore_table.h Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
#include <SDL2/SDL.h>
#include "common/asset.h"
#include "common/jail_audio.h"
#include "common/screen.h"
#include "common/sprite.h"
#include "common/text.h"
#include "common/utils.h"
#include "const.h"
#ifndef HISCORE_TABLE_H
#define HISCORE_TABLE_H
enum mode_hiScoreTable_e
{
mhst_manual,
mhst_auto
};
class HiScoreTable
{
private:
// Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
SDL_Event *eventHandler; // Manejador de eventos
SDL_Texture *backbuffer; // Textura para usar como backbuffer
Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Text *text; // Objeto para escribir texto
options_t *options; // Opciones y parametyros del programa
// Variables
Uint16 counter; // Contador
Uint16 counterEnd; // Valor final para el contador
section_t section; // Estado del bucle principal para saber si continua o se sale
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
bool manualQuit; // Indica si se quiere salir del modo manual
mode_hiScoreTable_e mode; // Modo en el que se van a ejecutar las instrucciones
// Actualiza las variables
void update();
// Pinta en pantalla
void render();
// Comprueba los eventos
void checkEventHandler();
// Transforma un valor numérico en una cadena de 6 cifras
std::string scoreToString(Uint32 num);
public:
// Constructor
HiScoreTable(SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang, options_t *options);
// Destructor
~HiScoreTable();
// Bucle principal
section_t run(mode_hiScoreTable_e mode);
};
#endif

View File

@@ -1,4 +1,5 @@
#include "instructions.h" #include "instructions.h"
#include <iostream>
const Uint8 SELF = 0; const Uint8 SELF = 0;
@@ -32,14 +33,14 @@ Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset,
eventHandler = new SDL_Event(); eventHandler = new SDL_Event();
sprite = new Sprite(0, 0, 16, 16, itemTextures.at(0), renderer); sprite = new Sprite(0, 0, 16, 16, itemTextures[0], renderer);
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
// Crea un backbuffer para el renderizador // Crea un backbuffer para el renderizador
backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH, GAME_HEIGHT); backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (backbuffer == nullptr) if (backbuffer == nullptr)
{ {
printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError()); std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
} }
// Inicializa variables // Inicializa variables
@@ -107,7 +108,7 @@ void Instructions::update()
void Instructions::render() void Instructions::render()
{ {
// Pinta en pantalla // Pinta en pantalla
SDL_Rect window = {0, 0, GAME_WIDTH, GAME_HEIGHT}; SDL_Rect window = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
SDL_Rect srcRect = {0, 0, 16, 16}; SDL_Rect srcRect = {0, 0, 16, 16};
const color_t orangeColor = {0xFF, 0x7A, 0x00}; const color_t orangeColor = {0xFF, 0x7A, 0x00};
@@ -124,12 +125,12 @@ void Instructions::render()
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
// Escribe el texto // Escribe el texto
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 8, lang->getText(11), 1, orangeColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 8, lang->getText(11), 1, orangeColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 24, lang->getText(12), 1, noColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 24, lang->getText(12), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 34, lang->getText(13), 1, noColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 34, lang->getText(13), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 48, lang->getText(14), 1, noColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 48, lang->getText(14), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 58, lang->getText(15), 1, noColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 58, lang->getText(15), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 75, lang->getText(16), 1, orangeColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 75, lang->getText(16), 1, orangeColor, 1, shdwTxtColor);
text->writeShadowed(84, 92, lang->getText(17), shdwTxtColor); text->writeShadowed(84, 92, lang->getText(17), shdwTxtColor);
text->writeShadowed(84, 108, lang->getText(18), shdwTxtColor); text->writeShadowed(84, 108, lang->getText(18), shdwTxtColor);
@@ -139,39 +140,39 @@ void Instructions::render()
if ((mode == m_manual) && (counter % 50 > 14)) if ((mode == m_manual) && (counter % 50 > 14))
{ {
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, GAME_HEIGHT - 12, lang->getText(22), 1, orangeColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, GAMECANVAS_HEIGHT - 12, lang->getText(22), 1, orangeColor, 1, shdwTxtColor);
} }
// Disquito // Disquito
sprite->setTexture(itemTextures.at(0)); sprite->setTexture(itemTextures[0]);
sprite->setPos(destRect1); sprite->setPos(destRect1);
srcRect.y = 16 * (((counter + 12) / 36) % 2); srcRect.y = 16 * (((counter + 12) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Gavineixon // Gavineixon
sprite->setTexture(itemTextures.at(1)); sprite->setTexture(itemTextures[1]);
sprite->setPos(destRect2); sprite->setPos(destRect2);
srcRect.y = 16 * (((counter + 9) / 36) % 2); srcRect.y = 16 * (((counter + 9) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Pacmar // Pacmar
sprite->setTexture(itemTextures.at(2)); sprite->setTexture(itemTextures[2]);
sprite->setPos(destRect3); sprite->setPos(destRect3);
srcRect.y = 16 * (((counter + 6) / 36) % 2); srcRect.y = 16 * (((counter + 6) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Time Stopper // Time Stopper
sprite->setTexture(itemTextures.at(3)); sprite->setTexture(itemTextures[3]);
sprite->setPos(destRect4); sprite->setPos(destRect4);
srcRect.y = 16 * (((counter + 3) / 36) % 2); srcRect.y = 16 * (((counter + 3) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Coffee // Coffee
sprite->setTexture(itemTextures.at(4)); sprite->setTexture(itemTextures[4]);
sprite->setPos(destRect5); sprite->setPos(destRect5);
srcRect.y = 16 * (((counter + 0) / 36) % 2); srcRect.y = 16 * (((counter + 0) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
@@ -189,7 +190,7 @@ void Instructions::render()
// Establece la ventana del backbuffer // Establece la ventana del backbuffer
if (mode == m_auto) if (mode == m_auto)
{ {
window.y = std::max(8, GAME_HEIGHT - counter + 100); window.y = std::max(8, GAMECANVAS_HEIGHT - counter + 100);
} }
else else
{ {

View File

@@ -32,59 +32,59 @@ Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, Lang *lang)
ss->setWidth(128); ss->setWidth(128);
ss->setHeight(96); ss->setHeight(96);
ss->setEnabledCounter(20); ss->setEnabledCounter(20);
ss->setDestX(SCREEN_CENTER_X - 64); ss->setDestX(GAMECANVAS_CENTER_X - 64);
ss->setDestY(SCREEN_FIRST_QUARTER_Y - 24); ss->setDestY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps.push_back(ss); bitmaps.push_back(ss);
} }
bitmaps.at(0)->setPosX(-128); bitmaps[0]->setPosX(-128);
bitmaps.at(0)->setPosY(SCREEN_FIRST_QUARTER_Y - 24); bitmaps[0]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps.at(0)->setVelX(0.0f); bitmaps[0]->setVelX(0.0f);
bitmaps.at(0)->setVelY(0.0f); bitmaps[0]->setVelY(0.0f);
bitmaps.at(0)->setAccelX(0.6f); bitmaps[0]->setAccelX(0.6f);
bitmaps.at(0)->setAccelY(0.0f); bitmaps[0]->setAccelY(0.0f);
bitmaps.at(0)->setSpriteClip(0, 0, 128, 96); bitmaps[0]->setSpriteClip(0, 0, 128, 96);
bitmaps.at(1)->setPosX(GAME_WIDTH); bitmaps[1]->setPosX(GAMECANVAS_WIDTH);
bitmaps.at(1)->setPosY(SCREEN_FIRST_QUARTER_Y - 24); bitmaps[1]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps.at(1)->setVelX(-1.0f); bitmaps[1]->setVelX(-1.0f);
bitmaps.at(1)->setVelY(0.0f); bitmaps[1]->setVelY(0.0f);
bitmaps.at(1)->setAccelX(-0.3f); bitmaps[1]->setAccelX(-0.3f);
bitmaps.at(1)->setAccelY(0.0f); bitmaps[1]->setAccelY(0.0f);
bitmaps.at(1)->setSpriteClip(128, 0, 128, 96); bitmaps[1]->setSpriteClip(128, 0, 128, 96);
bitmaps.at(2)->setPosX(SCREEN_CENTER_X - 64); bitmaps[2]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps.at(2)->setPosY(-96); bitmaps[2]->setPosY(-96);
bitmaps.at(2)->setVelX(0.0f); bitmaps[2]->setVelX(0.0f);
bitmaps.at(2)->setVelY(3.0f); bitmaps[2]->setVelY(3.0f);
bitmaps.at(2)->setAccelX(0.1f); bitmaps[2]->setAccelX(0.1f);
bitmaps.at(2)->setAccelY(0.3f); bitmaps[2]->setAccelY(0.3f);
bitmaps.at(2)->setSpriteClip(0, 96, 128, 96); bitmaps[2]->setSpriteClip(0, 96, 128, 96);
bitmaps.at(2)->setEnabledCounter(250); bitmaps[2]->setEnabledCounter(250);
bitmaps.at(3)->setPosX(SCREEN_CENTER_X - 64); bitmaps[3]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps.at(3)->setPosY(GAME_HEIGHT); bitmaps[3]->setPosY(GAMECANVAS_HEIGHT);
bitmaps.at(3)->setVelX(0.0f); bitmaps[3]->setVelX(0.0f);
bitmaps.at(3)->setVelY(-0.7f); bitmaps[3]->setVelY(-0.7f);
bitmaps.at(3)->setAccelX(0.0f); bitmaps[3]->setAccelX(0.0f);
bitmaps.at(3)->setAccelY(0.0f); bitmaps[3]->setAccelY(0.0f);
bitmaps.at(3)->setSpriteClip(128, 96, 128, 96); bitmaps[3]->setSpriteClip(128, 96, 128, 96);
bitmaps.at(4)->setPosX(SCREEN_CENTER_X - 64); bitmaps[4]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps.at(4)->setPosY(-96); bitmaps[4]->setPosY(-96);
bitmaps.at(4)->setVelX(0.0f); bitmaps[4]->setVelX(0.0f);
bitmaps.at(4)->setVelY(3.0f); bitmaps[4]->setVelY(3.0f);
bitmaps.at(4)->setAccelX(0.1f); bitmaps[4]->setAccelX(0.1f);
bitmaps.at(4)->setAccelY(0.3f); bitmaps[4]->setAccelY(0.3f);
bitmaps.at(4)->setSpriteClip(0, 192, 128, 96); bitmaps[4]->setSpriteClip(0, 192, 128, 96);
bitmaps.at(5)->setPosX(GAME_WIDTH); bitmaps[5]->setPosX(GAMECANVAS_WIDTH);
bitmaps.at(5)->setPosY(SCREEN_FIRST_QUARTER_Y - 24); bitmaps[5]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps.at(5)->setVelX(-0.7f); bitmaps[5]->setVelX(-0.7f);
bitmaps.at(5)->setVelY(0.0f); bitmaps[5]->setVelY(0.0f);
bitmaps.at(5)->setAccelX(0.0f); bitmaps[5]->setAccelX(0.0f);
bitmaps.at(5)->setAccelY(0.0f); bitmaps[5]->setAccelY(0.0f);
bitmaps.at(5)->setSpriteClip(128, 192, 128, 96); bitmaps[5]->setSpriteClip(128, 192, 128, 96);
// Inicializa los textos de la intro // Inicializa los textos de la intro
const int totalTexts = 9; const int totalTexts = 9;
@@ -92,7 +92,7 @@ Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, Lang *lang)
{ {
Writer *w = new Writer(text); Writer *w = new Writer(text);
w->setPosX(BLOCK * 0); w->setPosX(BLOCK * 0);
w->setPosY(GAME_HEIGHT - (BLOCK * 6)); w->setPosY(GAMECANVAS_HEIGHT - (BLOCK * 6));
w->setKerning(-1); w->setKerning(-1);
w->setEnabled(false); w->setEnabled(false);
w->setEnabledCounter(180); w->setEnabledCounter(180);
@@ -100,44 +100,44 @@ Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, Lang *lang)
} }
// Un dia qualsevol de l'any 2000 // Un dia qualsevol de l'any 2000
texts.at(0)->setCaption(lang->getText(27)); texts[0]->setCaption(lang->getText(27));
texts.at(0)->setSpeed(8); texts[0]->setSpeed(8);
// Tot esta tranquil a la UPV // Tot esta tranquil a la UPV
texts.at(1)->setCaption(lang->getText(28)); texts[1]->setCaption(lang->getText(28));
texts.at(1)->setSpeed(8); texts[1]->setSpeed(8);
// Fins que un desaprensiu... // Fins que un desaprensiu...
texts.at(2)->setCaption(lang->getText(29)); texts[2]->setCaption(lang->getText(29));
texts.at(2)->setSpeed(12); texts[2]->setSpeed(12);
// HEY! ME ANE A FERME UN CORTAET... // HEY! ME ANE A FERME UN CORTAET...
texts.at(3)->setCaption(lang->getText(30)); texts[3]->setCaption(lang->getText(30));
texts.at(3)->setSpeed(8); texts[3]->setSpeed(8);
// UAAAAAAAAAAAAA!!! // UAAAAAAAAAAAAA!!!
texts.at(4)->setCaption(lang->getText(31)); texts[4]->setCaption(lang->getText(31));
texts.at(4)->setSpeed(1); texts[4]->setSpeed(1);
// Espera un moment... // Espera un moment...
texts.at(5)->setCaption(lang->getText(32)); texts[5]->setCaption(lang->getText(32));
texts.at(5)->setSpeed(16); texts[5]->setSpeed(16);
// Si resulta que no tinc solt! // Si resulta que no tinc solt!
texts.at(6)->setCaption(lang->getText(33)); texts[6]->setCaption(lang->getText(33));
texts.at(6)->setSpeed(2); texts[6]->setSpeed(2);
// MERDA DE MAQUINA! // MERDA DE MAQUINA!
texts.at(7)->setCaption(lang->getText(34)); texts[7]->setCaption(lang->getText(34));
texts.at(7)->setSpeed(3); texts[7]->setSpeed(3);
// Blop... blop... blop... // Blop... blop... blop...
texts.at(8)->setCaption(lang->getText(35)); texts[8]->setCaption(lang->getText(35));
texts.at(8)->setSpeed(16); texts[8]->setSpeed(16);
for (auto text : texts) for (auto text : texts)
{ {
text->center(SCREEN_CENTER_X); text->center(GAMECANVAS_CENTER_X);
} }
} }
@@ -215,7 +215,7 @@ void Intro::checkEventHandler()
break; break;
case SDL_SCANCODE_F5: case SDL_SCANCODE_F5:
screen->showText("HOLA MAMA!"); screen->showNotification("HOLA MAMA!");
break; break;
default: default:
@@ -235,36 +235,36 @@ void Intro::updateScenes()
{ {
case 1: case 1:
// Primera imagen - UPV // Primera imagen - UPV
if (!bitmaps.at(0)->hasFinished()) if (!bitmaps[0]->hasFinished())
{ {
bitmaps.at(0)->setEnabled(true); bitmaps[0]->setEnabled(true);
} }
// Primer texto de la primera imagen // Primer texto de la primera imagen
if (bitmaps.at(0)->hasFinished() && !texts.at(0)->hasFinished()) if (bitmaps[0]->hasFinished() && !texts[0]->hasFinished())
{ {
texts.at(0)->setEnabled(true); texts[0]->setEnabled(true);
} }
// Segundo texto de la primera imagen // Segundo texto de la primera imagen
if (texts.at(0)->hasFinished() && !texts.at(1)->hasFinished()) if (texts[0]->hasFinished() && !texts[1]->hasFinished())
{ {
texts.at(0)->setEnabled(false); texts[0]->setEnabled(false);
texts.at(1)->setEnabled(true); texts[1]->setEnabled(true);
} }
// Tercer texto de la primera imagen // Tercer texto de la primera imagen
if (texts.at(1)->hasFinished() && !texts.at(2)->hasFinished()) if (texts[1]->hasFinished() && !texts[2]->hasFinished())
{ {
texts.at(1)->setEnabled(false); texts[1]->setEnabled(false);
texts.at(2)->setEnabled(true); texts[2]->setEnabled(true);
} }
// Fin de la primera escena // Fin de la primera escena
if (texts.at(2)->hasFinished()) if (texts[2]->hasFinished())
{ {
bitmaps.at(0)->setEnabled(false); bitmaps[0]->setEnabled(false);
texts.at(2)->setEnabled(false); texts[2]->setEnabled(false);
scene++; scene++;
} }
@@ -272,22 +272,22 @@ void Intro::updateScenes()
case 2: case 2:
// Segunda imagen - Máquina // Segunda imagen - Máquina
if (!bitmaps.at(1)->hasFinished()) if (!bitmaps[1]->hasFinished())
{ {
bitmaps.at(1)->setEnabled(true); bitmaps[1]->setEnabled(true);
} }
// Primer texto de la segunda imagen // Primer texto de la segunda imagen
if (bitmaps.at(1)->hasFinished() && !texts.at(3)->hasFinished()) if (bitmaps[1]->hasFinished() && !texts[3]->hasFinished())
{ {
texts.at(3)->setEnabled(true); texts[3]->setEnabled(true);
} }
// Fin de la segunda escena // Fin de la segunda escena
if (texts.at(3)->hasFinished()) if (texts[3]->hasFinished())
{ {
bitmaps.at(1)->setEnabled(false); bitmaps[1]->setEnabled(false);
texts.at(3)->setEnabled(false); texts[3]->setEnabled(false);
scene++; scene++;
} }
@@ -295,17 +295,17 @@ void Intro::updateScenes()
case 3: case 3:
// Tercera imagen junto con primer texto - GRITO // Tercera imagen junto con primer texto - GRITO
if (!bitmaps.at(2)->hasFinished() && !texts.at(4)->hasFinished()) if (!bitmaps[2]->hasFinished() && !texts[4]->hasFinished())
{ {
bitmaps.at(2)->setEnabled(true); bitmaps[2]->setEnabled(true);
texts.at(4)->setEnabled(true); texts[4]->setEnabled(true);
} }
// Fin de la tercera escena // Fin de la tercera escena
if (bitmaps.at(2)->hasFinished() && texts.at(4)->hasFinished()) if (bitmaps[2]->hasFinished() && texts[4]->hasFinished())
{ {
bitmaps.at(2)->setEnabled(false); bitmaps[2]->setEnabled(false);
texts.at(4)->setEnabled(false); texts[4]->setEnabled(false);
scene++; scene++;
} }
@@ -313,24 +313,24 @@ void Intro::updateScenes()
case 4: case 4:
// Cuarta imagen junto con primer texto - Reflexión // Cuarta imagen junto con primer texto - Reflexión
if (!bitmaps.at(3)->hasFinished() && !texts.at(5)->hasFinished()) if (!bitmaps[3]->hasFinished() && !texts[5]->hasFinished())
{ {
bitmaps.at(3)->setEnabled(true); bitmaps[3]->setEnabled(true);
texts.at(5)->setEnabled(true); texts[5]->setEnabled(true);
} }
// Segundo texto de la cuarta imagen // Segundo texto de la cuarta imagen
if (texts.at(5)->hasFinished() && !texts.at(6)->hasFinished()) if (texts[5]->hasFinished() && !texts[6]->hasFinished())
{ {
texts.at(5)->setEnabled(false); texts[5]->setEnabled(false);
texts.at(6)->setEnabled(true); texts[6]->setEnabled(true);
} }
// Fin de la cuarta escena // Fin de la cuarta escena
if (bitmaps.at(3)->hasFinished() && texts.at(6)->hasFinished()) if (bitmaps[3]->hasFinished() && texts[6]->hasFinished())
{ {
bitmaps.at(3)->setEnabled(false); bitmaps[3]->setEnabled(false);
texts.at(6)->setEnabled(false); texts[6]->setEnabled(false);
scene++; scene++;
} }
@@ -338,22 +338,22 @@ void Intro::updateScenes()
case 5: case 5:
// Quinta imagen - Patada // Quinta imagen - Patada
if (!bitmaps.at(4)->hasFinished()) if (!bitmaps[4]->hasFinished())
{ {
bitmaps.at(4)->setEnabled(true); bitmaps[4]->setEnabled(true);
} }
// Primer texto de la quinta imagen // Primer texto de la quinta imagen
if (bitmaps.at(4)->hasFinished() && !texts.at(7)->hasFinished()) if (bitmaps[4]->hasFinished() && !texts[7]->hasFinished())
{ {
texts.at(7)->setEnabled(true); texts[7]->setEnabled(true);
} }
// Fin de la quinta escena // Fin de la quinta escena
if (bitmaps.at(4)->hasFinished() && texts.at(7)->hasFinished()) if (bitmaps[4]->hasFinished() && texts[7]->hasFinished())
{ {
bitmaps.at(4)->setEnabled(false); bitmaps[4]->setEnabled(false);
texts.at(7)->setEnabled(false); texts[7]->setEnabled(false);
scene++; scene++;
} }
@@ -361,17 +361,17 @@ void Intro::updateScenes()
case 6: case 6:
// Sexta imagen junto con texto - Globos de café // Sexta imagen junto con texto - Globos de café
if (!bitmaps.at(5)->hasFinished() && !texts.at(8)->hasFinished()) if (!bitmaps[5]->hasFinished() && !texts[8]->hasFinished())
{ {
bitmaps.at(5)->setEnabled(true); bitmaps[5]->setEnabled(true);
texts.at(8)->setEnabled(true); texts[8]->setEnabled(true);
} }
// Acaba el último texto // Acaba el último texto
if (bitmaps.at(5)->hasFinished() && texts.at(8)->hasFinished()) if (bitmaps[5]->hasFinished() && texts[8]->hasFinished())
{ {
bitmaps.at(5)->setEnabled(false); bitmaps[5]->setEnabled(false);
texts.at(8)->setEnabled(false); texts[8]->setEnabled(false);
JA_StopMusic(); JA_StopMusic();
section.name = PROG_SECTION_TITLE; section.name = PROG_SECTION_TITLE;
section.subsection = TITLE_SECTION_1; section.subsection = TITLE_SECTION_1;

View File

@@ -32,7 +32,7 @@ private:
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint8 ticksSpeed; // Velocidad a la que se repiten los bucles del programa Uint8 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
section_t section; // Estado del bucle principal para saber si continua o se sale section_t section; // Estado del bucle principal para saber si continua o se sale
JA_Music music; // Musica para la intro JA_Music_t* music; // Musica para la intro
int scene; // Indica que escena está activa int scene; // Indica que escena está activa
// Actualiza las variables del objeto // Actualiza las variables del objeto

View File

@@ -88,7 +88,7 @@ void Logo::checkEventHandler()
break; break;
case SDL_SCANCODE_F5: case SDL_SCANCODE_F5:
screen->showText("Conectado a Jailers.net"); screen->showNotification("Conectado a Jailers.net");
break; break;
default: default:

View File

@@ -42,12 +42,13 @@ Reescribiendo el código el 27/09/2022
#include "director.h" #include "director.h"
#include <stdio.h> #include <stdio.h>
int main(int argc, char *args[]) int main(int argc, char *argv[])
{ {
printf("Starting the game...\n\n"); std::cout << "Starting the game..." << std::endl
<< std::endl;
// Crea el objeto Director // Crea el objeto Director
Director *director = new Director(args[0]); Director *director = new Director(argc, argv);
// Bucle principal // Bucle principal
director->run(); director->run();
@@ -55,7 +56,7 @@ int main(int argc, char *args[])
// Destruye el objeto Director // Destruye el objeto Director
delete director; delete director;
printf("\nShutting down the game...\n"); std::cout << "\nShutting down the game..." << std::endl;
return 0; return 0;
} }

View File

@@ -8,11 +8,11 @@ Player::Player(float x, int y, SDL_Renderer *renderer, std::vector<Texture *> te
this->renderer = renderer; this->renderer = renderer;
// Reserva memoria para los objetos // Reserva memoria para los objetos
headSprite = new AnimatedSprite(texture.at(0), renderer, "", animations.at(0)); headSprite = new AnimatedSprite(texture[0], renderer, "", animations[0]);
bodySprite = new AnimatedSprite(texture.at(1), renderer, "", animations.at(1)); bodySprite = new AnimatedSprite(texture[1], renderer, "", animations[1]);
legsSprite = new AnimatedSprite(texture.at(2), renderer, "", animations.at(2)); legsSprite = new AnimatedSprite(texture[2], renderer, "", animations[2]);
deathSprite = new AnimatedSprite(texture.at(3), renderer, "", animations.at(3)); deathSprite = new AnimatedSprite(texture[3], renderer, "", animations[3]);
fireSprite = new AnimatedSprite(texture.at(4), renderer, "", animations.at(4)); fireSprite = new AnimatedSprite(texture[4], renderer, "", animations[4]);
fireSprite->getTexture()->setAlpha(224); fireSprite->getTexture()->setAlpha(224);
// Establece la posición inicial del jugador // Establece la posición inicial del jugador
@@ -620,9 +620,9 @@ void Player::updatePowerUpHeadOffset()
// Pone las texturas del jugador // Pone las texturas del jugador
void Player::setPlayerTextures(std::vector<Texture *> texture) void Player::setPlayerTextures(std::vector<Texture *> texture)
{ {
headSprite->setTexture(texture.at(0)); headSprite->setTexture(texture[0]);
bodySprite->setTexture(texture.at(1)); bodySprite->setTexture(texture[1]);
legsSprite->setTexture(texture.at(2)); legsSprite->setTexture(texture[2]);
deathSprite->setTexture(texture.at(3)); deathSprite->setTexture(texture[3]);
fireSprite->setTexture(texture.at(4)); fireSprite->setTexture(texture[4]);
} }

View File

@@ -125,9 +125,9 @@ void Title::init()
// Si ha encontrado un mando se lo asigna al segundo jugador // Si ha encontrado un mando se lo asigna al segundo jugador
if (input->gameControllerFound()) if (input->gameControllerFound())
{ {
options->input.at(1).id = availableInputDevices.at(deviceIndex.at(1)).id; options->input[1].id = availableInputDevices[deviceIndex[1]].id;
options->input.at(1).name = availableInputDevices.at(deviceIndex.at(1)).name; options->input[1].name = availableInputDevices[deviceIndex[1]].name;
options->input.at(1).deviceType = availableInputDevices.at(deviceIndex.at(1)).deviceType; options->input[1].deviceType = availableInputDevices[deviceIndex[1]].deviceType;
} }
// Inicializa el bitmap de Coffee // Inicializa el bitmap de Coffee
@@ -186,8 +186,8 @@ void Title::init()
// Coloca la ventana que recorre el mosaico de fondo de manera que coincida con el mosaico que hay pintado en el titulo al iniciar // Coloca la ventana que recorre el mosaico de fondo de manera que coincida con el mosaico que hay pintado en el titulo al iniciar
backgroundWindow.x = 128; backgroundWindow.x = 128;
backgroundWindow.y = 96; backgroundWindow.y = 96;
backgroundWindow.w = GAME_WIDTH; backgroundWindow.w = GAMECANVAS_WIDTH;
backgroundWindow.h = GAME_HEIGHT; backgroundWindow.h = GAMECANVAS_HEIGHT;
// 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)
@@ -309,6 +309,10 @@ void Title::update()
{ {
runInstructions(m_auto); runInstructions(m_auto);
} }
if (section.name != PROG_SECTION_QUIT)
{
runHiScoreTable(mhst_auto);
}
} }
else else
section.name = PROG_SECTION_LOGO; section.name = PROG_SECTION_LOGO;
@@ -422,7 +426,7 @@ void Title::update()
case 6: // Display mode case 6: // Display mode
switchFullScreenModeVar(); switchFullScreenModeVar();
if (options->fullScreenMode != 0) if (options->videoMode != 0)
{ {
menu.options->setSelectable(8, false); menu.options->setSelectable(8, false);
menu.options->setGreyed(8, true); menu.options->setGreyed(8, true);
@@ -494,6 +498,10 @@ void Title::update()
{ {
runInstructions(m_auto); runInstructions(m_auto);
} }
if (section.name != PROG_SECTION_QUIT)
{
runHiScoreTable(mhst_auto);
}
init(); init();
demo = false; demo = false;
counter = TITLE_COUNTER; counter = TITLE_COUNTER;
@@ -615,7 +623,7 @@ void Title::render()
crisisBitmap->render(); crisisBitmap->render();
// Texto con el copyright y versión // Texto con el copyright y versión
text2->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, GAME_HEIGHT - (BLOCK * 2), TEXT_COPYRIGHT, 1, noColor, 1, shdwTxtColor); text2->writeDX(TXT_CENTER | TXT_SHADOW, GAMECANVAS_CENTER_X, GAMECANVAS_HEIGHT - (BLOCK * 2), TEXT_COPYRIGHT, 1, noColor, 1, shdwTxtColor);
} }
if (menuVisible == true) if (menuVisible == true)
@@ -629,7 +637,7 @@ void Title::render()
// PRESS ANY KEY! // PRESS ANY KEY!
if ((counter % 50 > 14) && (menuVisible == false)) if ((counter % 50 > 14) && (menuVisible == false))
{ {
text1->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, lang->getText(23), 1, noColor, 1, shdwTxtColor); text1->writeDX(TXT_CENTER | TXT_SHADOW, GAMECANVAS_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, lang->getText(23), 1, noColor, 1, shdwTxtColor);
} }
// Fade // Fade
@@ -658,6 +666,11 @@ void Title::checkEventHandler()
break; break;
} }
else if (eventHandler->type == SDL_RENDER_DEVICE_RESET || eventHandler->type == SDL_RENDER_TARGETS_RESET)
{
reLoadTextures();
}
else if (eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0) else if (eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0)
{ {
switch (eventHandler->key.keysym.scancode) switch (eventHandler->key.keysym.scancode)
@@ -668,27 +681,27 @@ void Title::checkEventHandler()
case SDL_SCANCODE_F: case SDL_SCANCODE_F:
screen->switchVideoMode(); screen->switchVideoMode();
reloadTextures(); reLoadTextures();
break; break;
case SDL_SCANCODE_F1: case SDL_SCANCODE_F1:
screen->setWindowSize(1); screen->setWindowSize(1);
reloadTextures(); reLoadTextures();
break; break;
case SDL_SCANCODE_F2: case SDL_SCANCODE_F2:
screen->setWindowSize(2); screen->setWindowSize(2);
reloadTextures(); reLoadTextures();
break; break;
case SDL_SCANCODE_F3: case SDL_SCANCODE_F3:
screen->setWindowSize(3); screen->setWindowSize(3);
reloadTextures(); reLoadTextures();
break; break;
case SDL_SCANCODE_F4: case SDL_SCANCODE_F4:
screen->setWindowSize(4); screen->setWindowSize(4);
reloadTextures(); reLoadTextures();
break; break;
default: default:
@@ -729,20 +742,20 @@ void Title::updateBG()
// Cambia el valor de la variable de modo de pantalla completa // Cambia el valor de la variable de modo de pantalla completa
void Title::switchFullScreenModeVar() void Title::switchFullScreenModeVar()
{ {
switch (options->fullScreenMode) switch (options->videoMode)
{ {
case 0: case 0:
options->fullScreenMode = SDL_WINDOW_FULLSCREEN; options->videoMode = SDL_WINDOW_FULLSCREEN;
break; break;
case SDL_WINDOW_FULLSCREEN: case SDL_WINDOW_FULLSCREEN:
options->fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP; options->videoMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
break; break;
case SDL_WINDOW_FULLSCREEN_DESKTOP: case SDL_WINDOW_FULLSCREEN_DESKTOP:
options->fullScreenMode = 0; options->videoMode = 0;
break; break;
default: default:
options->fullScreenMode = 0; options->videoMode = 0;
break; break;
} }
} }
@@ -856,7 +869,7 @@ void Title::updateMenuLabels()
i++; i++;
// DISPLAY MODE - OPTIONS // DISPLAY MODE - OPTIONS
switch (options->fullScreenMode) switch (options->videoMode)
{ {
case 0: case 0:
menu.options->setItemCaption(i, lang->getText(4)); // WINDOW menu.options->setItemCaption(i, lang->getText(4)); // WINDOW
@@ -906,8 +919,8 @@ void Title::updateMenuLabels()
menu.options->setItemCaption(i, lang->getText(10)); // CANCEL menu.options->setItemCaption(i, lang->getText(10)); // CANCEL
// Recoloca el menu de opciones // Recoloca el menu de opciones
menu.options->centerMenuOnX(SCREEN_CENTER_X); menu.options->centerMenuOnX(GAMECANVAS_CENTER_X);
menu.options->centerMenuOnY(SCREEN_CENTER_Y); menu.options->centerMenuOnY(GAMECANVAS_CENTER_Y);
menu.options->centerMenuElementsOnX(); menu.options->centerMenuElementsOnX();
// Establece las etiquetas del menu de titulo // Establece las etiquetas del menu de titulo
@@ -917,7 +930,7 @@ void Title::updateMenuLabels()
menu.title->setItemCaption(3, lang->getText(3)); // QUIT menu.title->setItemCaption(3, lang->getText(3)); // QUIT
// Recoloca el menu de titulo // Recoloca el menu de titulo
menu.title->centerMenuOnX(SCREEN_CENTER_X); menu.title->centerMenuOnX(GAMECANVAS_CENTER_X);
menu.title->centerMenuElementsOnX(); menu.title->centerMenuElementsOnX();
// Establece las etiquetas del menu de seleccion de jugador // Establece las etiquetas del menu de seleccion de jugador
@@ -925,14 +938,14 @@ void Title::updateMenuLabels()
menu.playerSelect->setItemCaption(3, lang->getText(40)); // BACK menu.playerSelect->setItemCaption(3, lang->getText(40)); // BACK
// Recoloca el menu de selección de jugador // Recoloca el menu de selección de jugador
menu.playerSelect->centerMenuOnX(SCREEN_CENTER_X); menu.playerSelect->centerMenuOnX(GAMECANVAS_CENTER_X);
menu.playerSelect->centerMenuElementsOnX(); menu.playerSelect->centerMenuElementsOnX();
} }
// Aplica las opciones de menu seleccionadas // Aplica las opciones de menu seleccionadas
void Title::applyOptions() void Title::applyOptions()
{ {
screen->setVideoMode(options->fullScreenMode); screen->setVideoMode(options->videoMode);
lang->setLang(options->language); lang->setLang(options->language);
@@ -962,6 +975,24 @@ section_t Title::runInstructions(mode_e mode)
return section; return section;
} }
// Ejecuta la parte donde se muestra la tabla de puntuaciones
section_t Title::runHiScoreTable(mode_hiScoreTable_e mode)
{
if (!options->online.enabled)
{
section.name = PROG_SECTION_TITLE;
section.subsection = TITLE_SECTION_1;
return section;
}
hiScoreTable = new HiScoreTable(renderer, screen, asset, lang, options);
section = hiScoreTable->run(mode);
delete hiScoreTable;
return section;
}
// Ejecuta el juego en modo demo // Ejecuta el juego en modo demo
section_t Title::runDemoGame() section_t Title::runDemoGame()
{ {
@@ -979,49 +1010,55 @@ bool Title::updatePlayerInputs(int numPlayer)
if (!input->gameControllerFound()) if (!input->gameControllerFound())
{ // Si no hay mandos se deja todo de manera prefijada { // Si no hay mandos se deja todo de manera prefijada
deviceIndex.at(0) = 0; deviceIndex[0] = 0;
deviceIndex.at(1) = 0; deviceIndex[1] = 0;
options->input.at(0).id = -1; options->input[0].id = -1;
options->input.at(0).name = "KEYBOARD"; options->input[0].name = "KEYBOARD";
options->input.at(0).deviceType = INPUT_USE_KEYBOARD; options->input[0].deviceType = INPUT_USE_KEYBOARD;
options->input.at(1).id = 0; options->input[1].id = 0;
options->input.at(1).name = "GAME CONTROLLER"; options->input[1].name = "GAME CONTROLLER";
options->input.at(1).deviceType = INPUT_USE_GAMECONTROLLER; options->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
return true; return true;
} }
else else
{ // Si hay mas de un dispositivo, se recorre el vector { // Si hay mas de un dispositivo, se recorre el vector
printf("numplayer:%i\n", numPlayer); if (options->console)
printf("deviceindex:%i\n", deviceIndex.at(numPlayer)); {
std::cout << "numplayer:" << numPlayer << std::endl;
std::cout << "deviceindex:" << deviceIndex[numPlayer] << std::endl;
}
// Incrementa el indice // Incrementa el indice
if (deviceIndex.at(numPlayer) < numDevices - 1) if (deviceIndex[numPlayer] < numDevices - 1)
{ {
deviceIndex.at(numPlayer)++; deviceIndex[numPlayer]++;
} }
else else
{ {
deviceIndex.at(numPlayer) = 0; deviceIndex[numPlayer] = 0;
}
if (options->console)
{
std::cout << "deviceindex:" << deviceIndex[numPlayer] << std::endl;
} }
printf("deviceindex:%i\n", deviceIndex.at(numPlayer));
// Si coincide con el del otro jugador, se lo intercambian // Si coincide con el del otro jugador, se lo intercambian
if (deviceIndex.at(0) == deviceIndex.at(1)) if (deviceIndex[0] == deviceIndex[1])
{ {
const int theOtherPlayer = (numPlayer + 1) % 2; const int theOtherPlayer = (numPlayer + 1) % 2;
deviceIndex.at(theOtherPlayer)--; deviceIndex[theOtherPlayer]--;
if (deviceIndex.at(theOtherPlayer) < 0) if (deviceIndex[theOtherPlayer] < 0)
{ {
deviceIndex.at(theOtherPlayer) = numDevices - 1; deviceIndex[theOtherPlayer] = numDevices - 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
options->input[0] = availableInputDevices.at(deviceIndex.at(0)); options->input[0] = availableInputDevices[deviceIndex[0]];
options->input[1] = availableInputDevices.at(deviceIndex.at(1)); options->input[1] = availableInputDevices[deviceIndex[1]];
return true; return true;
} }
@@ -1031,10 +1068,13 @@ bool Title::updatePlayerInputs(int numPlayer)
void Title::createTiledBackground() void Title::createTiledBackground()
{ {
// Crea la textura para el mosaico de fondo // Crea la textura para el mosaico de fondo
background = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH * 2, GAME_HEIGHT * 2); background = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH * 2, GAMECANVAS_HEIGHT * 2);
if (background == nullptr) if (background == nullptr)
{ {
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError()); if (options->console)
{
std::cout << "TitleSurface could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
} }
// Crea los objetos para pintar en la textura de fondo // Crea los objetos para pintar en la textura de fondo
@@ -1070,7 +1110,11 @@ void Title::createTiledBackground()
// Comprueba cuantos mandos hay conectados para gestionar el menu de opciones // Comprueba cuantos mandos hay conectados para gestionar el menu de opciones
void Title::checkInputDevices() void Title::checkInputDevices()
{ {
printf("Filling devices for options menu...\n"); if (options->console)
{
std::cout << "Filling devices for options menu..." << std::endl;
}
input->discoverGameController();
const int numControllers = input->getNumControllers(); const int numControllers = input->getNumControllers();
availableInputDevices.clear(); availableInputDevices.clear();
input_t temp; input_t temp;
@@ -1083,7 +1127,10 @@ void Title::checkInputDevices()
temp.name = input->getControllerName(i); temp.name = input->getControllerName(i);
temp.deviceType = INPUT_USE_GAMECONTROLLER; temp.deviceType = INPUT_USE_GAMECONTROLLER;
availableInputDevices.push_back(temp); availableInputDevices.push_back(temp);
printf("Device %i:\t%s\n", (int)availableInputDevices.size(), temp.name.c_str()); if (options->console)
{
std::cout << "Device " << (int)availableInputDevices.size() << " - " << temp.name.c_str() << std::endl;
}
} }
// Añade el teclado al final // Añade el teclado al final
@@ -1091,11 +1138,15 @@ void Title::checkInputDevices()
temp.name = "KEYBOARD"; temp.name = "KEYBOARD";
temp.deviceType = INPUT_USE_KEYBOARD; temp.deviceType = INPUT_USE_KEYBOARD;
availableInputDevices.push_back(temp); availableInputDevices.push_back(temp);
printf("Device %i:\t%s\n\n", (int)availableInputDevices.size(), temp.name.c_str()); if (options->console)
{
std::cout << "Device " << (int)availableInputDevices.size() << " - " << temp.name.c_str() << std::endl;
std::cout << std::endl;
}
} }
// Recarga las texturas // Recarga las texturas
void Title::reloadTextures() void Title::reLoadTextures()
{ {
dustTexture->reLoad(); dustTexture->reLoad();
coffeeTexture->reLoad(); coffeeTexture->reLoad();

View File

@@ -14,6 +14,7 @@
#include "const.h" #include "const.h"
#include "fade.h" #include "fade.h"
#include "game.h" #include "game.h"
#include "hiscore_table.h"
#include "instructions.h" #include "instructions.h"
#include "item.h" #include "item.h"
@@ -21,7 +22,7 @@
#define TITLE_H #define TITLE_H
// Textos // Textos
#define TEXT_COPYRIGHT "@2020,2022 JailDesigner (v2.1b)" #define TEXT_COPYRIGHT "@2020,2022 JailDesigner (v2.2a)"
// Contadores // Contadores
#define TITLE_COUNTER 800 #define TITLE_COUNTER 800
@@ -48,12 +49,13 @@ private:
Input *input; // Objeto para leer las entradas de teclado o mando Input *input; // Objeto para leer las entradas de teclado o mando
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Instructions *instructions; // Objeto para la sección de las instrucciones Instructions *instructions; // Objeto para la sección de las instrucciones
HiScoreTable *hiScoreTable; // Objeto para mostrar las mejores puntuaciones online
Game *demoGame; // Objeto para lanzar la demo del juego Game *demoGame; // Objeto para lanzar la demo del juego
SDL_Event *eventHandler; // Manejador de eventos SDL_Event *eventHandler; // Manejador de eventos
Texture *dustTexture; // Textura con los graficos del polvo Texture *dustTexture; // Textura con los graficos del polvo
Texture *coffeeTexture; // Textura con los graficos de la palabra coffee Texture *coffeeTexture; // Textura con los graficos de la palabra coffee
Texture *crisisTexture; // Textura con los graficos de la plabra crisis Texture *crisisTexture; // Textura con los graficos de la plabra crisis
Texture *gradientTexture; // Textura con los graficos para el degradado del fondo del titulo Texture *gradientTexture; // Textura con los graficos para el degradado del fondo del titulo
SDL_Rect backgroundWindow; // Ventana visible para la textura de fondo del titulo SDL_Rect backgroundWindow; // Ventana visible para la textura de fondo del titulo
@@ -72,8 +74,8 @@ private:
Fade *fade; // Objeto para realizar fundidos en pantalla Fade *fade; // Objeto para realizar fundidos en pantalla
// Variable // Variable
JA_Music titleMusic; // Musica para el titulo JA_Music_t* titleMusic; // Musica para el titulo
JA_Sound crashSound; // Sonido con el impacto del título JA_Sound_t* crashSound; // Sonido con el impacto del título
int backgroundCounter; // Temporizador para el fondo de tiles de la pantalla de titulo int backgroundCounter; // Temporizador para el fondo de tiles de la pantalla de titulo
int counter; // Temporizador para la pantalla de titulo int counter; // Temporizador para la pantalla de titulo
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
@@ -118,6 +120,9 @@ private:
// Ejecuta la parte donde se muestran las instrucciones // Ejecuta la parte donde se muestran las instrucciones
section_t runInstructions(mode_e mode); section_t runInstructions(mode_e mode);
// Ejecuta la parte donde se muestra la tabla de puntuaciones
section_t runHiScoreTable(mode_hiScoreTable_e mode);
// Ejecuta el juego en modo demo // Ejecuta el juego en modo demo
section_t runDemoGame(); section_t runDemoGame();
@@ -131,7 +136,7 @@ private:
void checkInputDevices(); void checkInputDevices();
// Recarga las texturas // Recarga las texturas
void reloadTextures(); void reLoadTextures();
public: public:
// Constructor // Constructor