Compare commits

..

73 Commits

Author SHA1 Message Date
d33d2e4a09 Cambiado el nombre de algunos enemigos 2022-11-29 21:26:28 +01:00
d9174dcdb9 Cambiado el nombre de algunos enemigos 2022-11-29 21:08:33 +01:00
22f7204e08 Añadidas mas dll para el release de windows 2022-11-29 19:41:14 +01:00
06fab0d457 Actualizado Makefile 2022-11-29 19:16:14 +01:00
f180f88068 Corregido error en el texto de las teclas nuevas para moverse 2022-11-29 19:12:04 +01:00
4109d6c938 Actualizado Readme.md. Cambiado LICENSE a LICENSE.txt 2022-11-29 19:11:02 +01:00
9c2264ca75 Actualizado Makefile 2022-11-29 19:07:59 +01:00
c59739c7ba Cambiado el tamaño del borde de porcentaje a valor absoluto en pixeles 2022-11-29 18:45:25 +01:00
4a430c0d5b Actualizadas las instrucciones con el método de control escogido 2022-11-29 18:22:40 +01:00
5a7f637f4b Cambiada la tecla de pausa a la tecla H (HOLD) 2022-11-29 18:07:31 +01:00
c63298b555 Posibilidad de escoger diferentes configuraciónes prefijadas de teclas de control desde el fichero de configuración 2022-11-29 18:05:38 +01:00
82aa91bead Corregida la funcion para verificar si existen los ficheros de recursos 2022-11-29 17:29:18 +01:00
f4129e109a Actualizado Makefile 2022-11-29 17:25:08 +01:00
5e8714697d Añadido un tile para poder bajar en la fase ULA HOP! 2022-11-29 17:23:12 +01:00
dd4355051f Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/jaildoctors_dilemma 2022-11-28 09:01:22 +01:00
160b212a43 Actualizado info.plist 2022-11-28 09:01:21 +01:00
69d3b076d7 Modificadas algunas fases para prevenir glitches 2022-11-28 07:53:07 +01:00
3817a01712 Guardado de las opciones de las notificaciones 2022-11-24 12:55:34 +01:00
ba19dcb904 Actualizar 'README.md' 2022-11-23 22:37:02 +01:00
b035b92ff4 Retocada ROAD TO THE JAIL 2022-11-23 22:32:57 +01:00
8c425f5698 Fix: De enter_id iba siempre a intro 2022-11-23 22:22:32 +01:00
d382bb6403 Optimizado el calculo del tamaño de las notificaciones 2022-11-23 20:53:01 +01:00
da64a5e082 Oculta el ratón en el modo a pantalla completa 2022-11-23 20:38:21 +01:00
7070dac482 Arreglado tamaño de las notificaciones en pantalla completa 2022-11-23 20:33:54 +01:00
ea5360ea74 Trabajando en las notificaciones 2022-11-23 20:14:53 +01:00
3aa4440390 Trabajando en las notificaciones 2022-11-23 20:05:07 +01:00
ce105e252e Trabajando en el tamaño de las notificaciones 2022-11-23 19:52:10 +01:00
1aac5b7719 Trabajando en las notificaciones 2022-11-23 18:20:29 +01:00
a8b467290f Completado el ciclo para pedir el ID online. Añadido sonido a las notificaciones. Agregado control de versión del fichero de configuración 2022-11-23 16:59:40 +01:00
706ad6f9c0 Trabajando en el escalado de las notificaciones 2022-11-23 14:11:47 +01:00
54d428ed96 Ya permite establecer el online ID desde el propio juego 2022-11-23 13:29:35 +01:00
c71adfbac4 Trabajando en la sección EnterID 2022-11-23 09:54:08 +01:00
c955543d31 Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/jaildoctors_dilemma 2022-11-22 16:44:27 +01:00
fae8e2d82c Actualizado Makefile 2022-11-22 16:44:23 +01:00
ff7b825cbb Actualizar 'README.md' 2022-11-22 16:39:39 +01:00
09ed0105e9 Cambiada la ubicación del fichero config.txt a la carpeta de sistema 2022-11-22 16:26:58 +01:00
07ae93fd3a Actualizado Makefile 2022-11-22 14:11:17 +01:00
72fb30b927 Actualizado Makefile 2022-11-22 13:59:41 +01:00
8d37f31a08 Cambiada una frase de castellano a ingles en el fichero de estadisticas 2022-11-22 13:35:15 +01:00
e6fb412c4d Fix: La pantalla de Game Over no mostraba Tu peor pesadilla 2022-11-22 13:34:33 +01:00
10c29eb547 Actualizado Makefile 2022-11-22 13:20:13 +01:00
1f9e36dc93 Actualizado info.plist 2022-11-22 13:07:12 +01:00
c114884de1 FIx: El logo se formaba mal despues de haber toqueteado cosas de la clase Sprite 2022-11-22 13:05:34 +01:00
d6a366555d Actualizado Makefile 2022-11-22 12:53:56 +01:00
fd0d8a05fe Actualizado Makefile 2022-11-22 12:45:47 +01:00
79d610a7d9 Actualizado Makefile 2022-11-22 12:42:25 +01:00
9060e1c92a Añadida carpeta de sistema para el modo debug 2022-11-22 12:38:09 +01:00
0d586c0827 Ya funcionan las estadísticas online 2022-11-22 10:42:30 +01:00
fd0bebf533 Trabajando en las estadisticas online 2022-11-18 20:06:07 +01:00
2665b93b70 Añadida Tu peor pesadilla a la pantalla de Game Over 2022-11-18 16:07:33 +01:00
c35be7d21c Empezado a escribir datos de estadisticas en el servidor 2022-11-19 12:07:36 +01:00
bc84968b23 Ya funcionan las notificaciones 2022-11-19 10:28:15 +01:00
1b49097f80 Cambiado el tamaño por defecto del borde 2022-11-19 09:27:55 +01:00
859e3f3b44 Actualizado Makefile 2022-11-19 09:27:24 +01:00
3fa7657c79 Cuendo el jugador entra a la Jail, recupera todas sus vidas 2022-11-19 09:22:10 +01:00
e90c61a416 FIx: El jugador no se moria al caer de alto si se mantenia la tecla de slto pulsada 2022-11-19 09:02:35 +01:00
d003b51de4 Reparada la clase Screen 2022-11-19 07:49:01 +01:00
8d381010c8 Trabajando en la clase Screen 2022-11-19 07:37:03 +01:00
2216c9632e Trabajando en las notificaciones 2022-11-18 23:15:38 +01:00
fdc8797d2b Arreglada la clase Screen. Había un lio de conceptos con varias variables 2022-11-18 20:09:03 +01:00
90bdad7d51 Modificado Makefile 2022-11-18 10:43:54 +01:00
d50b193d9f Cambiado el fichero de estadisticas a stats.csv 2022-11-18 10:43:01 +01:00
ee885d5ca7 Ya crea correctamente la carpeta de sistema en las tres plataformas 2022-11-18 10:40:51 +01:00
bb3a0f263b Ya crea la carpeta de sistema en MacOS y Windows 2022-11-18 10:35:15 +01:00
85d6c48f42 Ya crea la carpeta de sistema en Linux 2022-11-18 09:48:46 +01:00
896dd9daef Trabajando en el guardado de las estadisticas en las carpetas del sistema 2022-11-18 07:32:15 +01:00
dc8c0c9e4f Fix: Algunas texturas desaparecen al bloquearse la pantalla 2022-11-17 17:54:05 +01:00
7af0dda1a0 En la pantalla de Game Over se muestran las habitaciones y los items conseguidos 2022-11-17 16:33:37 +01:00
0adf8c63f4 Las habitaciones solo cuentan como visitadas una vez por partida 2022-11-17 16:06:31 +01:00
d33f691743 Fix: Algunas texturas desaparecen al bloquearse la pantalla 2022-11-17 16:04:03 +01:00
a304f50e93 Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/jaildoctors_dilemma 2022-11-17 11:53:07 +01:00
496bf5c05c Actualizado Makefile 2022-11-17 11:53:00 +01:00
26a6bd6b1f Cambiada la posición y dirección inicial del tuno magenta en KILLING SPREE 2022-11-17 11:31:54 +01:00
78 changed files with 2258 additions and 473 deletions

4
.gitignore vendored
View File

@@ -1,5 +1,5 @@
.vscode .vscode
*config.txt *data/config/config.txt
*stats.txt *stats.txt
*.DS_Store *.DS_Store
thumbs.db thumbs.db
@@ -10,4 +10,4 @@ thumbs.db
*.tar.gz *.tar.gz
*.zip *.zip
*.app *.app
*_debug *_debug*

View File

@@ -2,7 +2,7 @@ executable = jaildoctors_dilemma
source = source/*.cpp source/common/*.cpp source = source/*.cpp source/common/*.cpp
appName = JailDoctor's Dilemma appName = JailDoctor's Dilemma
releaseFolder = jdd_release releaseFolder = jdd_release
version = v1.03 version = v1.06.2
# Release names # Release names
windowsRelease = $(executable)-$(version)-win32-x64.zip windowsRelease = $(executable)-$(version)-win32-x64.zip
@@ -12,34 +12,33 @@ linuxRelease = $(executable)-$(version)-linux.tar.gz
windows: windows:
@echo off @echo off
powershell if (Test-Path data\config) {Remove-Item data\config -Recurse -Force} 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"
powershell if (-not (Test-Path data\config)) {New-Item data\config -ItemType Directory} strip -s -R .comment -R .gnu.version "$(executable).exe" --strip-unneeded
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lmingw32 -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 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 data\config) {Remove-Item data\config -Recurse -Force} 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 data\config)) {New-Item data\config -ItemType Directory}
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 "LICENSE" -Destination "$(releaseFolder)"
powershell Copy-Item "README.md" -Destination "$(releaseFolder)"
powershell Copy-Item "release/SDL2.dll" -Destination "$(releaseFolder)"
# Remove data
powershell if (Test-Path "$(releaseFolder)\data\room\map.world") {Remove-Item "$(releaseFolder)\data\room\map.world" -Recurse -Force} powershell if (Test-Path "$(releaseFolder)\data\room\map.world") {Remove-Item "$(releaseFolder)\data\room\map.world" -Recurse -Force}
powershell if (Test-Path "$(releaseFolder)\data\room\standard.tsx") {Remove-Item "$(releaseFolder)\data\room\standard.tsx" -Recurse -Force} powershell if (Test-Path "$(releaseFolder)\data\room\standard.tsx") {Remove-Item "$(releaseFolder)\data\room\standard.tsx" -Recurse -Force}
# Copy root files
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 -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"
strip -s -R .comment -R .gnu.version "$(releaseFolder)/$(executable).exe" --strip-unneeded strip -s -R .comment -R .gnu.version "$(releaseFolder)/$(executable).exe" --strip-unneeded
# Create ZIP # Create ZIP
@@ -47,16 +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:
rm -rdf data/config clang++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o "$(executable)"
mkdir -p data/config
clang++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -o $(executable)_macos 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 data/config
rm -rdf "$(releaseFolder)" rm -rdf "$(releaseFolder)"
rm -rdf Frameworks rm -rdf Frameworks
rm -f tmp.dmg rm -f tmp.dmg
@@ -64,7 +63,6 @@ macos_release:
rm -f "$(macosAppleSiliconRelease)" rm -f "$(macosAppleSiliconRelease)"
# Create folders # Create folders
mkdir -p data/config
mkdir -p "$(releaseFolder)/$(appName).app/Contents/Frameworks" mkdir -p "$(releaseFolder)/$(appName).app/Contents/Frameworks"
mkdir -p "$(releaseFolder)/$(appName).app/Contents/MacOS" mkdir -p "$(releaseFolder)/$(appName).app/Contents/MacOS"
mkdir -p "$(releaseFolder)/$(appName).app/Contents/Resources" mkdir -p "$(releaseFolder)/$(appName).app/Contents/Resources"
@@ -82,6 +80,11 @@ 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 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
@@ -104,36 +107,36 @@ macos_release:
rm -rdf "$(releaseFolder)" rm -rdf "$(releaseFolder)"
linux: linux:
rm -rdf data/config g++ $(source) -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o "$(executable)"
mkdir -p data/config strip -s -R .comment -R .gnu.version "$(executable)" --strip-unneeded
g++ $(source) -D DEBUG -std=c++11 -Wall -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o $(executable)_linux
strip -s -R .comment -R .gnu.version $(executable)_linux --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 data/config rm -rdf "$(releaseFolder)"
rm -rdf $(releaseFolder)
# Create folders # Create folders
mkdir -p data/config mkdir -p "$(releaseFolder)"
mkdir -p $(releaseFolder)
# Copy data # Copy data
cp -R data $(releaseFolder) cp -R data "$(releaseFolder)"
cp LICENSE $(releaseFolder) cp LICENSE.txt "$(releaseFolder)"
cp README.md $(releaseFolder) cp README.md "$(releaseFolder)"
# Delete data # Delete data
rm -f "$(releaseFolder)/data/room/map.world" rm -f "$(releaseFolder)/data/room/map.world"
rm -f "$(releaseFolder)/data/room/standard.tsx" rm -f "$(releaseFolder)/data/room/standard.tsx"
# 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

@@ -1,37 +1,87 @@
# JailDoctor's Dilemma # JailDoctor's Dilemma (v1.06.2)
JailDoc es un Jailer. A los Jailers les gusta empezar proyectos. A nadie le gusta terminarlos. Los Jailers viven en la Jail. A la Jail va uno a empezar proyectos. A la Jail va uno a enseñar sus proyectos. A la Jail va uno a aprender como empezar nuevos proyectos. A la Jail va uno a ayudar a sus compañeros a que empiecen nuevos proyectos. JailDoc es un Jailer. A los Jailers les gusta empezar proyectos. A nadie le gusta terminarlos. Los Jailers viven en la Jail. A la Jail va uno a empezar proyectos. A la Jail va uno a enseñar sus proyectos. A la Jail va uno a aprender como empezar nuevos proyectos. A la Jail va uno a ayudar a sus compañeros a que empiecen nuevos proyectos.
![JailDoctor's Dilemma - Title screen](https://php.sustancia.synology.me/images/jdd_title.png) ![JailDoctor's Dilemma - Title screen](https://php.sustancia.synology.me/images/jdd_title.png)
JailDoc es un Jailer destacado entre los Jailers. Tiene más proyectos empezados que nadie y es el que más ayuda a que los demas empiecen los suyos. JailDoc es un Jailer destacado entre los Jailers. Tiene más proyectos empezados que nadie y es el que más ayuda a que los demas empiecen los suyos.
Un día, ocurrió algo. Alguien terminó un proyecto. Alguien liberó el *Puzzle Jail Facker*. Algún desaprensivo. Un día, ocurrió algo. Alguien terminó un proyecto. Alguien liberó el *Puzzle Jail Facker*. Algún desaprensivo.
Esto hizo que JailDoc decidiera terminar y entregar uno de sus proyectos, pero, ¿cual? ¿JailBattle? ¿Sigmasuá? ¿Calculín Doom? Menudo dilema. JailDoc se arremangó y decidió finalizar y entregar todos sus proyectos inacabados. ¿Lo logrará? Esto hizo que JailDoc decidiera terminar y entregar uno de sus proyectos, pero, ¿cual? ¿JailBattle? ¿Sigmasuá? ¿Calculín Doom? Menudo dilema. JailDoc se arremangó y decidió finalizar y entregar todos sus proyectos inacabados. ¿Lo logrará?
## Jugabilidad ## Jugabilidad
Ayuda a JailDoc a recuperar las partes de su proyecto que estan desperdigadas por cualquier lugar del Universo Jailer. Hay mas de **150 piezas** desperdigadas por **60 pantallas**. Algunas son un paseo, pero en otras tendras que calcular muy bien tus movimientos si no quieres acabar como un arounder del montón. Ayuda a JailDoc a recuperar las partes de su proyecto que estan desperdigadas por cualquier lugar del Universo Jailer. Hay mas de **150 piezas** desperdigadas por **60 pantallas**. Algunas son un paseo, pero en otras tendras que calcular muy bien tus movimientos si no quieres acabar como un arounder del montón.
![JailDoctor's Dilemma - Gameplay](https://php.sustancia.synology.me/images/jdd_game1.png) ![JailDoctor's Dilemma - Gameplay](https://php.sustancia.synology.me/images/jdd_game1.png)
Cuando consigas recuperar gran parte de las piezas desperdigadas, dirigete a la Jail a mostrar a los Jailers como se termina un proyecto. Ten en cuenta que Bry no te dejará entrar. Solo aquellos que han realizado un *Fire Effect* o un *Facedor de Tornejos* son dignos de tal privilegio. Cuando consigas recuperar gran parte de las piezas desperdigadas, dirigete a la Jail a mostrar a los Jailers como se termina un proyecto. Ten en cuenta que Bry no te dejará entrar. Solo aquellos que han realizado un *Fire Effect* o un *Facedor de Tornejos* son dignos de tal privilegio.
## Controles ## Controles
El juego permite tanto el uso del teclado como de un mando de control. Las teclas para manejar el juego son las siguientes: El juego permite tanto el uso del teclado como de un mando de control. Las teclas para manejar el juego son las siguientes:
- **Cursores**: Para mover a izquierda o derecha a JailDoc y para saltar
- **Tecla M**: Activa o desactiva la música
- **Tecla P**: Pone en pausa el juego - **Cursores**: Para mover a izquierda o derecha a JailDoc y para saltar. En el fichero de configuración se pueden cambiar las teclas por otras opciones prefijadas: O, P para moverse y Q para saltar o A, D para moverse y W para saltar.
- **Tecla ESC**: Sale del juego si estas jugando. Sale del programa en cualquier otra circunstancia
- **Tecla F**: Cambia a modo de pantalla completa o de ventana - **Tecla M**: Activa o desactiva la música
- **Teclas F1 a F4**: Cambian el tamaño de la ventana
- **Tecla B**: Activa o desactiva el borde de colores de la pantalla cuando el programa se ejecuta en modo de ventana - **Tecla P**: Pone en pausa el juego
- **Tecla ESC**: Sale del juego si estas jugando. Sale del programa en cualquier otra circunstancia
- **Tecla F**: Cambia a modo de pantalla completa o de ventana
- **Teclas F1 a F4**: Cambian el tamaño de la ventana
- **Tecla B**: Activa o desactiva el borde de colores de la pantalla cuando el programa se ejecuta en modo de ventana
![JailDoctor's Dilemma - Gameplay](https://php.sustancia.synology.me/images/jdd_game2.png) ![JailDoctor's Dilemma - Gameplay](https://php.sustancia.synology.me/images/jdd_game2.png)
## Datos del programa
El programa guarda automáticamente la configuración del modo de video y las estadísticas de juego en tu carpeta personal del sistema. Esta carpeta tiene una ubicación distinta en función del sistema operativo que utilices.
En **Windows** se encuentra en:
`C:\Users\<nombre_de_usuario>\AppData\Roaming\jaildoctors_dilemma`
En **MacOS** se encuentra en:
`~/Library/Application Support/jaildoctors_dilemma`
En **Linux** se encuentra en:
`~/.jaildoctors_dilemma`
La primera vez, el juego te pregunta por tu identificador online. Esta información se guarda para futuras partidas.
En la carpeta está el fichero de configuración `config.txt` donde se puede modificar la configuración para conectarse al servicio online y los ficheros `stats.csv` y `stats_buffer.csv` con información de las estadisticas de juego.
## Agradecimientos ## Agradecimientos
Agradecimientos como siempre a todos los Jailers por motivarme a hacer el juego y ayudarme en los momentos de duda a la hora de escribir el código. Y, como siempre, en especial a JailDoc por su unidad de Jail_Audio y cualquier otro código/ayuda/enseñanzas que haya necesitado para terminar el programa. Agradecimientos como siempre a todos los Jailers por motivarme a hacer el juego y ayudarme en los momentos de duda a la hora de escribir el código. Y, como siempre, en especial a JailDoc por su unidad de Jail_Audio y cualquier otro código/ayuda/enseñanzas que haya necesitado para terminar el programa.
Si no me he descontado, este es el cuarto juego que consigo crear. Si no me he descontado, este es el cuarto juego que consigo crear.
*13 de noviembre de 2022, JailDesigner* *13 de noviembre de 2022, JailDesigner*

View File

Before

Width:  |  Height:  |  Size: 310 B

After

Width:  |  Height:  |  Size: 310 B

View File

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 122 B

View File

Before

Width:  |  Height:  |  Size: 205 B

After

Width:  |  Height:  |  Size: 205 B

View File

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 189 B

View File

Before

Width:  |  Height:  |  Size: 351 B

After

Width:  |  Height:  |  Size: 351 B

View File

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 323 B

View File

Before

Width:  |  Height:  |  Size: 378 B

After

Width:  |  Height:  |  Size: 378 B

View File

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 139 B

View File

Before

Width:  |  Height:  |  Size: 129 B

After

Width:  |  Height:  |  Size: 129 B

View File

@@ -9,8 +9,8 @@ roomLeft=0
roomRight=02.room roomRight=02.room
[enemy] [enemy]
tileSetFile=jailer.png tileSetFile=jailer_#1.png
animation=jailer.ani animation=jailer_#1.ani
width=16 width=16
height=16 height=16
x=1 x=1
@@ -25,8 +25,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jailer3.png tileSetFile=jailer_#3.png
animation=jailer3.ani animation=jailer_#3.ani
width=16 width=16
height=16 height=16
x=4 x=4
@@ -41,8 +41,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jailer.png tileSetFile=jailer_#1.png
animation=jailer.ani animation=jailer_#1.ani
width=16 width=16
height=16 height=16
x=7 x=7
@@ -57,8 +57,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jailer2.png tileSetFile=jailer_#2.png
animation=jailer2.ani animation=jailer_#2.ani
width=16 width=16
height=16 height=16
x=10 x=10
@@ -73,8 +73,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jailer.png tileSetFile=jailer_#1.png
animation=jailer.ani animation=jailer_#1.ani
width=16 width=16
height=16 height=16
x=13 x=13
@@ -89,8 +89,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=printer.png tileSetFile=elsa.png
animation=printer.ani animation=elsa.ani
width=16 width=16
height=16 height=16
x=3 x=3
@@ -105,8 +105,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=printer.png tileSetFile=elsa.png
animation=printer.ani animation=elsa.ani
width=16 width=16
height=16 height=16
x=6 x=6

View File

@@ -17,7 +17,7 @@
34,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25, 34,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25,
34,34,389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,387,25,25, 34,34,389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,387,25,25,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,513,190,189,190,537,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,513,189,190,537,0,0,0,0,
34,34,189,190,189,190,189,190,189,190,189,190,189,190,189,190,189,190,189,191,0,0,189,190,189,190,189,190,189,190,25,25 34,34,189,190,189,190,189,190,189,190,189,190,189,190,189,190,189,190,189,191,0,0,189,190,189,190,189,190,189,190,25,25
</data> </data>
</layer> </layer>

View File

@@ -18,7 +18,7 @@
0,0,0,0,0,0,0,0,531,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17, 0,0,0,0,0,0,0,0,531,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,
0,0,0,0,0,0,0,0,0,531,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17, 0,0,0,0,0,0,0,0,0,531,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,
0,0,0,0,0,0,0,0,0,0,349,349,349,349,349,349,349,349,349,349,349,538,0,0,0,0,0,0,0,0,0,17, 0,0,0,0,0,0,0,0,0,0,349,349,349,349,349,349,349,349,349,349,349,538,0,0,0,0,0,0,0,0,0,17,
0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,349,349,349,349,349,349,349,349,349,349,0,0,349,349,349 563,563,563,563,563,563,563,563,563,563,0,0,0,41,41,41,41,349,349,349,349,349,349,349,349,349,349,0,0,349,349,349
</data> </data>
</layer> </layer>
</map> </map>

View File

@@ -9,13 +9,13 @@
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
25,0,0,0,527,25,25,25,25,25,25,25,25,25,25,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 25,0,0,0,527,25,25,25,25,25,25,25,25,25,25,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,25,25,25,0,0,0,0,0,0,0,0,0,0,0,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,25,25,25,0,0,0,0,0,0,0,0,0,0,0,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,527, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,527,25,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25,551,0,0,0,0,0,0,0,0,0,527,25,25, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25,551,0,0,0,0,0,0,0,0,0,527,25,25,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25,25,25,0,0,0,0,0,25,25,25,25,25, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25,25,25,0,0,0,0,0,25,25,25,25,25,
25,25,25,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 25,25,25,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25,25,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,251,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,251,0,0,0,0,0,25,25,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
0,0,0,0,395,395,395,395,395,371,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,0,0,0,0,0,0,0, 0,0,0,0,395,395,395,395,395,371,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,0,0,0,0,0,0,25,
0,0,0,0,0,0,0,0,0,323,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,323,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
25,25,551,0,0,0,0,0,0,347,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 25,25,551,0,0,0,0,0,0,347,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25

View File

@@ -48,9 +48,9 @@ animation=tuno.ani
width=16 width=16
height=16 height=16
x=28 x=28
y=8 y=6
vx=0 vx=0
vy=0.4 vy=-0.4
x1=28 x1=28
y1=2 y1=2
x2=28 x2=28

View File

@@ -30,7 +30,7 @@ flip=true
[enemy] [enemy]
tileSetFile=bat.png tileSetFile=bat.png
animation=bat.ani animation=bat.ani
width=9 width=8
height=7 height=7
x=14 x=14
y=2 y=2
@@ -46,7 +46,7 @@ color=bright_blue
[enemy] [enemy]
tileSetFile=bat.png tileSetFile=bat.png
animation=bat.ani animation=bat.ani
width=9 width=8
height=7 height=7
x=10 x=10
y=10 y=10
@@ -62,7 +62,7 @@ color=cyan
[enemy] [enemy]
tileSetFile=bat.png tileSetFile=bat.png
animation=bat.ani animation=bat.ani
width=9 width=8
height=7 height=7
x=15 x=15
y=1 y=1

View File

@@ -15,7 +15,7 @@
116,0,0,0,377,377,377,0,0,0,0,0,0,115,114,115,114,0,0,0,0,0,377,377,377,377,0,0,0,0,140,116, 116,0,0,0,377,377,377,0,0,0,0,0,0,115,114,115,114,0,0,0,0,0,377,377,377,377,0,0,0,0,140,116,
140,0,0,0,0,0,0,0,0,0,0,377,0,114,115,114,115,0,0,377,0,0,0,0,0,0,0,0,0,0,116,140, 140,0,0,0,0,0,0,0,0,0,0,377,0,114,115,114,115,0,0,377,0,0,0,0,0,0,0,0,0,0,116,140,
116,0,0,0,0,0,0,0,0,0,0,0,0,115,114,115,114,0,0,0,0,0,0,0,0,0,431,432,114,115,140,116, 116,0,0,0,0,0,0,0,0,0,0,0,0,115,114,115,114,0,0,0,0,0,0,0,0,0,431,432,114,115,140,116,
140,0,0,0,0,0,0,0,377,0,0,0,0,114,115,114,115,0,0,0,0,0,0,431,432,431,432,431,432,0,116,140, 140,0,0,0,0,0,0,377,377,0,0,0,0,114,115,114,115,0,0,0,0,0,0,431,432,431,432,431,432,0,116,140,
0,0,0,0,0,0,0,0,0,0,0,0,377,115,114,115,114,0,0,377,0,0,0,0,0,0,0,0,0,0,140,116, 0,0,0,0,0,0,0,0,0,0,0,0,377,115,114,115,114,0,0,377,0,0,0,0,0,0,0,0,0,0,140,116,
0,0,0,0,0,0,0,0,0,0,0,0,0,114,115,114,115,0,0,0,0,0,0,0,0,0,0,0,0,0,116,140, 0,0,0,0,0,0,0,0,0,0,0,0,0,114,115,114,115,0,0,0,0,0,0,0,0,0,0,0,0,0,116,140,
114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,0,0,114,115,114,115,114,115 114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,0,0,114,115,114,115,114,115

View File

@@ -9,8 +9,8 @@ roomLeft=39.room
roomRight=37.room roomRight=37.room
[enemy] [enemy]
tileSetFile=arounder_stop.png tileSetFile=stopped_arounder.png
animation=arounder_stop.ani animation=stopped_arounder.ani
width=7 width=7
height=8 height=8
x=9 x=9
@@ -25,8 +25,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_stop.png tileSetFile=stopped_arounder.png
animation=arounder_stop.ani animation=stopped_arounder.ani
width=7 width=7
height=8 height=8
x=18 x=18
@@ -41,8 +41,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_walk.png tileSetFile=walking_arounder.png
animation=arounder_walk.ani animation=walking_arounder.ani
width=5 width=5
height=8 height=8
x=12 x=12
@@ -75,8 +75,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_fly.png tileSetFile=flying_arounder.png
animation=arounder_fly.ani animation=flying_arounder.ani
width=7 width=7
height=7 height=7
x=3 x=3

View File

@@ -27,8 +27,8 @@ color=white
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_fly.png tileSetFile=flying_arounder.png
animation=arounder_fly.ani animation=flying_arounder.ani
width=7 width=7
height=7 height=7
x=9 x=9
@@ -44,8 +44,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_fly.png tileSetFile=flying_arounder.png
animation=arounder_fly.ani animation=flying_arounder.ani
width=7 width=7
height=7 height=7
x=15 x=15
@@ -61,8 +61,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_fly.png tileSetFile=flying_arounder.png
animation=arounder_fly.ani animation=flying_arounder.ani
width=7 width=7
height=7 height=7
x=22 x=22
@@ -78,8 +78,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_fly.png tileSetFile=flying_arounder.png
animation=arounder_fly.ani animation=flying_arounder.ani
width=7 width=7
height=7 height=7
x=16 x=16

View File

@@ -25,8 +25,8 @@ color=red
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_walk.png tileSetFile=walking_arounder.png
animation=arounder_walk.ani animation=walking_arounder.ani
width=5 width=5
height=8 height=8
x=10 x=10
@@ -42,8 +42,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_walk.png tileSetFile=walking_arounder.png
animation=arounder_walk.ani animation=walking_arounder.ani
width=5 width=5
height=8 height=8
x=15 x=15
@@ -59,8 +59,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_walk.png tileSetFile=walking_arounder.png
animation=arounder_walk.ani animation=walking_arounder.ani
width=5 width=5
height=8 height=8
x=20 x=20
@@ -76,8 +76,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_walk.png tileSetFile=walking_arounder.png
animation=arounder_walk.ani animation=walking_arounder.ani
width=5 width=5
height=8 height=8
x=14 x=14

View File

@@ -25,8 +25,8 @@ color=bright_cyan
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_stop.png tileSetFile=stopped_arounder.png
animation=arounder_stop.ani animation=stopped_arounder.ani
width=7 width=7
height=8 height=8
x=8 x=8
@@ -41,8 +41,8 @@ color=bright_cyan
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_stop.png tileSetFile=stopped_arounder.png
animation=arounder_stop.ani animation=stopped_arounder.ani
width=7 width=7
height=8 height=8
x=11 x=11
@@ -57,8 +57,8 @@ color=bright_cyan
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_stop.png tileSetFile=stopped_arounder.png
animation=arounder_stop.ani animation=stopped_arounder.ani
width=7 width=7
height=8 height=8
x=24 x=24
@@ -73,8 +73,8 @@ color=bright_cyan
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_walk.png tileSetFile=walking_arounder.png
animation=arounder_walk.ani animation=walking_arounder.ani
width=5 width=5
height=8 height=8
x=12 x=12
@@ -90,8 +90,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_walk.png tileSetFile=walking_arounder.png
animation=arounder_walk.ani animation=walking_arounder.ani
width=5 width=5
height=8 height=8
x=14 x=14
@@ -107,8 +107,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=arounder_walk.png tileSetFile=walking_arounder.png
animation=arounder_walk.ani animation=walking_arounder.ani
width=5 width=5
height=8 height=8
x=14 x=14

View File

@@ -11,8 +11,8 @@ itemColor1=red
itemColor2=yellow itemColor2=yellow
[enemy] [enemy]
tileSetFile=jb_alien.png tileSetFile=jailbattle_alien.png
animation=jb_alien.ani animation=jailbattle_alien.ani
width=13 width=13
height=15 height=15
x=10 x=10
@@ -28,8 +28,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jb_alien.png tileSetFile=jailbattle_alien.png
animation=jb_alien.ani animation=jailbattle_alien.ani
width=13 width=13
height=15 height=15
x=25 x=25
@@ -45,8 +45,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jb_human.png tileSetFile=jailbattle_human.png
animation=jb_human.ani animation=jailbattle_human.ani
width=11 width=11
height=13 height=13
x=7 x=7
@@ -62,8 +62,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jb_human.png tileSetFile=jailbattle_human.png
animation=jb_human.ani animation=jailbattle_human.ani
width=11 width=11
height=13 height=13
x=18 x=18

View File

@@ -11,8 +11,8 @@ itemColor1=white
itemColor2=green itemColor2=green
[enemy] [enemy]
tileSetFile=jb_human.png tileSetFile=jailbattle_human.png
animation=jb_human.ani animation=jailbattle_human.ani
width=11 width=11
height=13 height=13
x=17 x=17
@@ -28,8 +28,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jb_human.png tileSetFile=jailbattle_human.png
animation=jb_human.ani animation=jailbattle_human.ani
width=11 width=11
height=13 height=13
x=2 x=2
@@ -45,8 +45,8 @@ flip=true
[/enemy] [/enemy]
[enemy] [enemy]
tileSetFile=jb_alien.png tileSetFile=jailbattle_alien.png
animation=jb_alien.ani animation=jailbattle_alien.ani
width=11 width=11
height=13 height=13
x=24 x=24

BIN
data/sound/notify.wav Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -23,11 +23,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.4.3</string> <string>1.0.6.2</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0.0</string> <string>1.0.6.2</string>
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

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.

13
source/cheevos.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include "cheevos.h"
// Constructor
Cheevos::Cheevos(options_t *options)
{
this->options = options;
}
// Destructor
Cheevos::~Cheevos()
{
}

27
source/cheevos.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
#include <SDL2/SDL.h>
#include "common/utils.h"
#include <string>
#include <vector>
#ifndef CHEEVOS_H
#define CHEEVOS_H
class Cheevos
{
private:
// Punteros y objetos
options_t *options;
// Variables
public:
// Constructor
Cheevos(options_t *options);
// Destructor
~Cheevos();
};
#endif

View File

@@ -10,10 +10,10 @@ Asset::Asset(std::string executablePath)
} }
// 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);
@@ -114,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)
{ {

View File

@@ -31,6 +31,7 @@ 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
}; };
// Variables // Variables
@@ -50,7 +51,7 @@ public:
Asset(std::string path); Asset(std::string path);
// 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);

154
source/common/jscore.cpp Normal file
View File

@@ -0,0 +1,154 @@
#include "jscore.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#endif
#include <unistd.h>
#include <string>
#include <vector>
namespace jscore {
using namespace std;
struct user {
string name;
int points;
};
vector<user> score;
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
int sock;
struct sockaddr_in client;
int PORT = 9911;
string HOST = "jaildoctor.duckdns.org";
#ifdef WIN32
WSADATA WsaData;
#endif
bool jscore_error = false;
string error_message;
void init(std::string host, const int port) {
PORT = port;
HOST = host;
}
void setErrorMessage(string message) {
jscore_error = true;
error_message = message;
}
string sendRequest(const string request) {
#ifdef WIN32
int ret = WSAStartup(0x101,&WsaData);
if (ret != 0) return 0;
#endif
struct hostent * host = gethostbyname(HOST.c_str());
if ( (host == NULL) || (host->h_addr == NULL) ) {
setErrorMessage("Error retrieving DNS information.\n");
return "";
}
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons( PORT );
memcpy(&client.sin_addr, host->h_addr, host->h_length);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
setErrorMessage("Error creating socket.\n");
return "";
}
if ( connect(sock, (struct sockaddr *)&client, sizeof(client)) < 0 ) {
close(sock);
setErrorMessage("Could not connect\n");
return "";
}
string r = request + " HTTP/1.1\r\nHost: "+HOST+"\r\nConnection: close\r\n\r\n\r\n";
if (send(sock, r.c_str(), r.length(), 0) != (int)r.length()) {
setErrorMessage("Error sending request.\n");
return "";
}
char cur;
char start[5]="\r\n\r\n";
int pos = 0;
while ( recv(sock, &cur, 1,0) > 0 ) {
if (cur==start[pos]) { pos++; if (pos == 4) break; } else { pos = 0; }
}
char buffer[1024]; buffer[0]=0; pos=0;
while ( recv(sock, &cur, 1,0) > 0 ) {
buffer[pos] = cur;
pos++;
}
#ifdef WIN32
WSACleanup();
#endif
buffer[pos]=0;
return buffer;
}
const bool initOnlineScore(string game) {
string strbuff = sendRequest("GET /score-list.php?game=" + game);
if (jscore_error) return not jscore_error;
user u;
char buffer[1024];
strcpy(buffer, strbuff.c_str());
char *str = buffer;
char *p = str;
score.clear();
while (*p!=0) {
while (*p!=',') {p++;}
*p=0; u.name = str; p++; str=p;
while (*p!='\n') {p++;}
*p=0; u.points = atoi(str); p++; str=p;
score.push_back(u);
}
return not jscore_error;
}
const int getNumUsers() {
return score.size();
}
string getUserName(const int index) {
return score[index].name;
}
const int getPoints(const int index) {
return score[index].points;
}
const bool updateUserPoints(string game, string user, const int points) {
string strbuff = sendRequest("GET /score-update.php?game=" + game + "&user=" + user + "&points=" + to_string(points));
initOnlineScore(game);
return not jscore_error;
}
const int getUserPoints(string game, std::string user) {
return atoi(sendRequest("GET /getuserpoints.php?game=" + game + "&user=" + user).c_str());
}
string getUserData(string game, string user) {
return sendRequest("GET /getuserdata.php?game=" + game + "&user=" + user);
}
void setUserData(string game, string user, string data) {
sendRequest("GET /setuserdata.php?game=" + game + "&user=" + user + "&data=" + data);
}
};

16
source/common/jscore.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#include <string>
namespace jscore {
void init(std::string host, const int port);
const bool initOnlineScore(std::string game);
const int getNumUsers();
std::string getUserName(const int index);
const int getPoints(const int index);
const int getUserPoints(std::string game, std::string user);
const bool updateUserPoints(std::string game, std::string user, const int points);
std::string getUserData(std::string game, std::string user);
void setUserData(std::string game, std::string user, std::string data);
};

223
source/common/notify.cpp Normal file
View File

@@ -0,0 +1,223 @@
#include "notify.h"
#include <string>
#include <stdio.h>
#include <iostream>
// Constructor
Notify::Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile, std::string soundFile, options_t *options)
{
// Inicializa variables
this->renderer = renderer;
this->options = options;
bgColor = options->notifications.color;
waitTime = 300;
// Crea objetos
texture = new Texture(renderer, bitmapFile);
text = new Text(textFile, texture, renderer);
sound = JA_LoadSound(soundFile.c_str());
}
// Destructor
Notify::~Notify()
{
// Libera la memoria de los objetos
delete texture;
delete text;
JA_DeleteSound(sound);
for (auto notification : notifications)
{
delete notification.sprite;
delete notification.texture;
}
}
// Dibuja las notificaciones por pantalla
void Notify::render()
{
for (int i = (int)notifications.size() - 1; i >= 0; --i)
{
notifications.at(i).sprite->render();
}
}
// Actualiza el estado de las notificaiones
void Notify::update()
{
for (int i = 0; i < (int)notifications.size(); ++i)
{
notifications.at(i).counter++;
// Comprueba los estados
if (notifications.at(i).state == ns_rising)
{
const float step = ((float)notifications.at(i).counter / notifications.at(i).travelDist);
const int alpha = 255 * step;
if (options->notifications.posV == pos_top)
{
notifications.at(i).rect.y++;
}
else
{
notifications.at(i).rect.y--;
}
notifications.at(i).texture->setAlpha(alpha);
if (notifications.at(i).rect.y == notifications.at(i).y)
{
notifications.at(i).state = ns_stay;
notifications.at(i).texture->setAlpha(255);
notifications.at(i).counter = 0;
}
}
else if (notifications.at(i).state == ns_stay)
{
if (notifications.at(i).counter == waitTime)
{
notifications.at(i).state = ns_vanishing;
notifications.at(i).counter = 0;
}
}
else if (notifications.at(i).state == ns_vanishing)
{
const float step = (notifications.at(i).counter / (float)notifications.at(i).travelDist);
const int alpha = 255 * (1 - step);
if (options->notifications.posV == pos_top)
{
notifications.at(i).rect.y--;
}
else
{
notifications.at(i).rect.y++;
}
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.at(i).sprite->setRect(notifications.at(i).rect);
}
clearFinishedNotifications();
}
// Elimina las notificaciones finalizadas
void Notify::clearFinishedNotifications()
{
for (int i = (int)notifications.size() - 1; i >= 0; --i)
{
if (notifications.at(i).state == ns_finished)
{
delete notifications.at(i).sprite;
delete notifications.at(i).texture;
notifications.erase(notifications.begin() + i);
}
}
}
// Muestra una notificación de texto por pantalla;
void Notify::showText(std::string text)
{
// Inicializa variables
const int width = this->text->lenght(text) + (this->text->getCharacterSize() * 2);
const int height = this->text->getCharacterSize() * 2;
const int padding = (this->text->getCharacterSize() / 2);
// Posición horizontal
int despH = 0;
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
notification_t n;
// Inicializa variables
n.y = offset;
n.travelDist = travelDist;
n.counter = 0;
n.state = ns_rising;
n.text = text;
if (options->notifications.posV == pos_top)
{
n.rect = {despH, offset - travelDist, width, height};
}
else
{
n.rect = {despH, offset + travelDist, width, height};
}
// Crea la textura
n.texture = new Texture(renderer);
n.texture->createBlank(renderer, width, height, SDL_TEXTUREACCESS_TARGET);
n.texture->setAsRenderTarget(renderer);
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(renderer);
n.texture->setBlendMode(SDL_BLENDMODE_BLEND);
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
n.sprite = new Sprite(n.rect, n.texture, renderer);
// Añade la notificación a la lista
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;
}

85
source/common/notify.h Normal file
View File

@@ -0,0 +1,85 @@
#pragma once
#include <SDL2/SDL.h>
#include "jail_audio.h"
#include "sprite.h"
#include "text.h"
#include "texture.h"
#include "utils.h"
#include <vector>
#ifndef NOTIFY_H
#define NOTIFY_H
class Notify
{
private:
enum notification_state_e
{
ns_rising,
ns_stay,
ns_vanishing,
ns_finished
};
enum notification_position_e
{
upperLeft,
upperCenter,
upperRight,
middleLeft,
middleRight,
bottomLeft,
bottomCenter,
bottomRight
};
struct notification_t
{
std::string text;
int counter;
notification_state_e state;
notification_position_e position;
Texture *texture;
Sprite *sprite;
SDL_Rect rect;
int y;
int travelDist;
};
// Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana
Texture *texture; // Textura para la fuente de las notificaciones
Text *text; // Objeto para dibujar texto
options_t *options; // Variable con todas las opciones del programa
// Variables
color_t bgColor; // Color de fondo de las notificaciones
int waitTime; // Tiempo que se ve la notificación
std::vector<notification_t> notifications; // La lista de notificaciones activas
JA_Sound sound; // Sonido a reproducir cuando suena la notificación
// Elimina las notificaciones finalizadas
void clearFinishedNotifications();
public:
// Dibuja las notificaciones por pantalla
void render();
// Actualiza el estado de las notificaiones
void update();
// Constructor
Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile, std::string soundFile, options_t *options);
// Destructor
~Notify();
// Muestra una notificación de texto por pantalla;
void showText(std::string text);
// Indica si hay notificaciones activas
bool active();
};
#endif

View File

@@ -3,15 +3,23 @@
#include <iostream> #include <iostream>
// Constructor // Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, 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;
this->renderer = renderer; this->renderer = renderer;
this->options = options; this->options = options;
this->asset = asset;
gameCanvasWidth = gameInternalResX; // Crea los objetos
gameCanvasHeight = gameInternalResY; notify = new Notify(renderer, asset->get("smb2.png"), asset->get("smb2.txt"), asset->get("notify.wav"), options);
gameCanvasWidth = options->gameWidth;
gameCanvasHeight = options->gameHeight;
borderWidth = options->borderWidth * 2;
borderHeight = options->borderHeight * 2;
notificationLogicalWidth = gameCanvasWidth;
notificationLogicalHeight = gameCanvasHeight;
iniFade(); iniFade();
iniSpectrumFade(); iniSpectrumFade();
@@ -22,20 +30,24 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, i
// Crea la textura donde se dibujan los graficos del juego // Crea la textura donde se dibujan los graficos del juego
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)
{
if (options->console)
{ {
std::cout << "TitleSurface could not be created!\nSDL Error: " << SDL_GetError() << std::endl; 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; // Destructor
anchor.bottom = gameCanvasHeight; Screen::~Screen()
anchor.middle = gameCanvasHeight / 2; {
delete notify;
} }
// Limpia la pantalla // Limpia la pantalla
@@ -64,107 +76,111 @@ void Screen::blit()
// Copia la textura de juego en el renderizador en la posición adecuada // Copia la textura de juego en el renderizador en la posición adecuada
SDL_RenderCopy(renderer, gameCanvas, nullptr, &dest); SDL_RenderCopy(renderer, gameCanvas, nullptr, &dest);
// Dibuja las notificaciones
renderNotifications();
// Muestra por pantalla el renderizador // Muestra por pantalla el renderizador
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }
// 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; windowWidth = gameCanvasWidth;
screenHeight = gameCanvasHeight; 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);
} }
// 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
@@ -187,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
@@ -339,3 +361,53 @@ void Screen::renderFX()
renderFade(); renderFade();
renderSpectrumFade(); renderSpectrumFade();
} }
// Actualiza el notificador
void Screen::updateNotifier()
{
notify->update();
notifyActive = notify->active();
}
// Muestra una notificación de texto por pantalla;
void Screen::showNotification(std::string text)
{
notify->showText(text);
}
// Dibuja las notificaciones
void Screen::renderNotifications()
{
if (!notifyActive)
{
return;
}
SDL_RenderSetLogicalSize(renderer, notificationLogicalWidth, notificationLogicalHeight);
notify->render();
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

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "asset.h"
#include "notify.h"
#include "utils.h" #include "utils.h"
#include <vector> #include <vector>
@@ -10,34 +12,29 @@
#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 punteros // 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
SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
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
// Variables // Variables
int screenWidth; // Ancho de la pantalla o ventana int windowWidth; // Ancho de la pantalla o ventana
int screenHeight; // Alto de la pantalla o ventana int windowHeight; // Alto de la pantalla o ventana
int gameCanvasWidth; // Resolución interna del juego. Es el ancho 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
int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego
anchor_t anchor; // Variable con los anclajes de la pantalla int borderWidth; // Anchura del borde
int borderHeight; // Anltura del borde
SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana 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 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
// Variables - Efectos // Variables - Efectos
bool fade; // Indica si esta activo el efecto de fade bool fade; // Indica si esta activo el efecto de fade
@@ -66,9 +63,18 @@ private:
// Dibuja el spectrum fade // Dibuja el spectrum fade
void renderSpectrumFade(); void renderSpectrumFade();
// Dibuja las notificaciones
void renderNotifications();
// Establece el tamaño de las notificaciones
void setNotificationSize();
public: public:
// Constructor // Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, int gameInternalResX, int gameInternalResY); Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options);
// Destructor
~Screen();
// Limpia la pantalla // Limpia la pantalla
void clean(color_t color = {0x00, 0x00, 0x00}); void clean(color_t color = {0x00, 0x00, 0x00});
@@ -80,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();
@@ -95,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);
@@ -120,6 +127,12 @@ public:
// Dibuja los efectos // Dibuja los efectos
void renderFX(); void renderFX();
// Actualiza el notificador
void updateNotifier();
// Muestra una notificación de texto por pantalla;
void showNotification(std::string text);
}; };
#endif #endif

View File

@@ -18,7 +18,7 @@ Sprite::Sprite(int x, int y, int w, int h, Texture *texture, SDL_Renderer *rende
this->texture = texture; this->texture = texture;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
spriteClip = {x, y, w, h}; spriteClip = {0, 0, w, h};
// Inicializa variables // Inicializa variables
enabled = true; enabled = true;
@@ -41,7 +41,7 @@ Sprite::Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer)
this->texture = texture; this->texture = texture;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
spriteClip = {x, y, w, h}; spriteClip = {0, 0, w, h};
// Inicializa variables // Inicializa variables
enabled = true; enabled = true;
@@ -83,8 +83,8 @@ int Sprite::getHeight()
// Establece la posición del objeto // Establece la posición del objeto
void Sprite::setPos(SDL_Rect rect) void Sprite::setPos(SDL_Rect rect)
{ {
x = rect.x; this->x = rect.x;
y = rect.y; this->y = rect.y;
} }
// Establece el valor de la variable // Establece el valor de la variable
@@ -166,6 +166,12 @@ void Sprite::setRenderer(SDL_Renderer *renderer)
this->renderer = renderer; this->renderer = renderer;
} }
// Obten el valor de la variable
SDL_Renderer *Sprite::getRenderer()
{
return renderer;
}
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setEnabled(bool value) void Sprite::setEnabled(bool value)
{ {

View File

@@ -81,6 +81,9 @@ public:
// Establece el valor de la variable // Establece el valor de la variable
void setRenderer(SDL_Renderer *renderer); void setRenderer(SDL_Renderer *renderer);
// Obten el valor de la variable
SDL_Renderer *getRenderer();
// Establece el valor de la variable // Establece el valor de la variable
void setEnabled(bool value); void setEnabled(bool value);

View File

@@ -94,6 +94,9 @@ Text::Text(std::string textFile, Texture *texture, SDL_Renderer *renderer)
// Crea los objetos // Crea los objetos
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
// Inicializa variables
fixedWidth = false;
} }
// Constructor // Constructor
@@ -111,6 +114,9 @@ Text::Text(textFile_t *textFile, Texture *texture, SDL_Renderer *renderer)
// Crea los objetos // Crea los objetos
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
// Inicializa variables
fixedWidth = false;
} }
// Destructor // Destructor
@@ -133,7 +139,8 @@ void Text::write(int x, int y, std::string text, int kerning, int lenght)
sprite->setPosX(x + shift); sprite->setPosX(x + shift);
sprite->setPosY(y); sprite->setPosY(y);
sprite->render(); sprite->render();
shift += (offset[int(text[i])].w + kerning); // shift += (offset[int(text[i])].w + kerning);
shift += fixedWidth ? boxWidth : (offset[int(text[i])].w + kerning);
} }
} }
@@ -226,3 +233,9 @@ void Text::reLoadTexture()
{ {
sprite->getTexture()->reLoad(); sprite->getTexture()->reLoad();
} }
// Establece si se usa un tamaño fijo de letra
void Text::setFixedWidth(bool value)
{
fixedWidth = value;
}

View File

@@ -38,6 +38,7 @@ private:
// 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
public: public:
@@ -71,6 +72,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

@@ -294,28 +294,6 @@ SDL_Point checkCollision(d_line_t &l1, v_line_t &l2)
return {-1, -1}; return {-1, -1};
} }
// Detector de colisiones entre una linea diagonal y una vertical
/*bool checkCollision(d_line_t &l1, v_line_t &l2)
{
// Normaliza la linea diagonal
normalizeLine(l1);
// Comprueba si la linea vertical esta a la izquierda de la linea diagonal
if (l2.x < l1.x1)
{
return false;
}
// Comprueba si la linea vertical esta a la derecha de la linea diagonal
if (l2.x > l1.x2)
{
return false;
}
// Inacabada
return true;
}*/
// Normaliza una linea diagonal // Normaliza una linea diagonal
void normalizeLine(d_line_t &l) void normalizeLine(d_line_t &l)
{ {
@@ -367,16 +345,6 @@ bool checkCollision(SDL_Point &p, d_line_t &l)
// En caso contrario, el punto está en la linea // En caso contrario, el punto está en la linea
return true; return true;
/*const int m = (l.y2 - l.y1) / (l.x2 - l.x1);
const int c = 0;
// Comprueba si p cumple la ecuación de la linea
if (p.y == ((m * p.x) + c))
return true;
return false;*/
} }
// Devuelve un color_t a partir de un string // Devuelve un color_t a partir de un string

View File

@@ -54,6 +54,33 @@ enum palette_e
p_zxarne p_zxarne
}; };
// Posiciones de las notificaciones
enum not_pos_e
{
pos_top,
pos_bottom,
pos_left,
pos_middle,
pos_right
};
// Tipos de control de teclado
enum ctrl_schem_e
{
ctrl_cursor,
ctrl_opqa,
ctrl_wasd
};
// 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 para saber la seccion y subseccion del programa // Estructura para saber la seccion y subseccion del programa
struct section_t struct section_t
{ {
@@ -70,22 +97,55 @@ struct cheat_t
bool altSkin; // Indicxa si se usa una skin diferente para el jugador bool altSkin; // Indicxa si se usa una skin diferente para el jugador
}; };
// Estructura para el servicio online
struct online_t
{
bool enabled; // Indica si se quiere usar el modo online o no
std::string server; // Servidor para los servicios online
int port; // Puerto del servidor
std::string gameID; // Identificador del juego para los servicios online
std::string jailerID; // Identificador del jugador para los servicios online
int score; // Puntuación almacenada online
};
// Estructura para almacenar estadísticas
struct op_stats_t
{
int rooms; // Cantidad de habitaciones visitadas
int items; // Cantidad de items obtenidos
std::string worstNightmare; // Habitación con más muertes acumuladas
};
// Estructura con opciones de la pantalla
struct op_screen_t
{
int windowWidth; // Ancho de la ventana
int windowHeight; // Alto de la ventana
};
// 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
{ {
Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa std::string configVersion; // Versión del programa. Sirve para saber si las opciones son compatibles
Uint32 videoMode; // Contiene el valor del modo de pantalla completa
int windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana int windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana
Uint32 filter; // Filtro usado para el escalado de la imagen Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no bool vSync; // Indica si se quiere usar vsync o no
int screenWidth; // Ancho de la pantalla o ventana int gameWidth; // Ancho de la resolucion nativa del juego
int screenHeight; // Alto de la pantalla o ventana int gameHeight; // Alto 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 bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana
float borderSize; // Porcentaje de borde que se añade a lo ventana 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 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 bool console; // Indica si ha de mostrar información por la consola de texto
cheat_t cheat; // Contiene trucos y ventajas para el juego cheat_t cheat; // Contiene trucos y ventajas para el juego
op_stats_t stats; // Datos con las estadisticas de juego
online_t online; // Datos del servicio online
op_notification_t notifications; // Opciones relativas a las notificaciones;
op_screen_t screen; // Opciones relativas a la clase screen
ctrl_schem_e keys; // Teclas usadas para jugar
}; };
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos

View File

@@ -57,7 +57,8 @@ const int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3;
#define SECTION_PROG_GAME_OVER 6 #define SECTION_PROG_GAME_OVER 6
#define SECTION_PROG_ENDING 7 #define SECTION_PROG_ENDING 7
#define SECTION_PROG_ENDING2 8 #define SECTION_PROG_ENDING2 8
#define SECTION_PROG_QUIT 9 #define SECTION_PROG_ENTER_ID 9
#define SECTION_PROG_QUIT 10
// Subsecciones // Subsecciones
#define SUBSECTION_LOGO_TO_INTRO 0 #define SUBSECTION_LOGO_TO_INTRO 0

View File

@@ -133,6 +133,20 @@ void Credits::checkEventHandler()
// Inicializa los textos // Inicializa los textos
void Credits::iniTexts() void Credits::iniTexts()
{ {
std::string keys = "";
if (options->keys == ctrl_cursor)
{
keys = "CURSORS";
}
else if (options->keys == ctrl_opqa)
{
keys = "O,P AND Q";
}
else
{
keys = "A,D AND W";
}
texts.clear(); texts.clear();
texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"INSTRUCTIONS:", stringToColor(options->palette, "yellow")}); texts.push_back({"INSTRUCTIONS:", stringToColor(options->palette, "yellow")});
@@ -145,9 +159,9 @@ void Credits::iniTexts()
texts.push_back({"KEYS:", stringToColor(options->palette, "yellow")}); texts.push_back({"KEYS:", stringToColor(options->palette, "yellow")});
texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"CURSORS TO MOVE AND JUMP", stringToColor(options->palette, "white")}); texts.push_back({keys + " TO MOVE AND JUMP", stringToColor(options->palette, "white")});
texts.push_back({"M TO TURN ON/OFF THE MUSIC", stringToColor(options->palette, "white")}); texts.push_back({"M TO TURN ON/OFF THE MUSIC", stringToColor(options->palette, "white")});
texts.push_back({"P TO PAUSE THE GAME", stringToColor(options->palette, "white")}); texts.push_back({"H TO HOLD/PAUSE THE GAME", stringToColor(options->palette, "white")});
texts.push_back({"F1-F4 TO CHANGE WINDOWS SIZE", stringToColor(options->palette, "white")}); texts.push_back({"F1-F4 TO CHANGE WINDOWS SIZE", stringToColor(options->palette, "white")});
texts.push_back({"F TO SWITCH TO FULLSCREEN", stringToColor(options->palette, "white")}); texts.push_back({"F TO SWITCH TO FULLSCREEN", stringToColor(options->palette, "white")});
texts.push_back({"B TO SWITCH THE BORDER SCREEN", stringToColor(options->palette, "white")}); texts.push_back({"B TO SWITCH THE BORDER SCREEN", stringToColor(options->palette, "white")});
@@ -264,6 +278,9 @@ void Credits::update()
// Actualiza el contador // Actualiza el contador
updateCounter(); updateCounter();
// Actualiza las notificaciones
screen->updateNotifier();
// Actualiza el sprite con el brillo // Actualiza el sprite con el brillo
if (counter > 770) if (counter > 770)
{ {
@@ -315,14 +332,6 @@ section_t Credits::run()
// Cambia la paleta // Cambia la paleta
void Credits::switchPalette() void Credits::switchPalette()
{ {
if (options->palette == p_zxspectrum) options->palette = options->palette == p_zxspectrum ? p_zxarne : p_zxspectrum;
{
options->palette = p_zxarne;
}
else
{
options->palette = p_zxspectrum;
}
fillTexture(); fillTexture();
} }

View File

@@ -153,6 +153,9 @@ void Demo::update()
scoreboard->update(); scoreboard->update();
screen->updateFX(); screen->updateFX();
checkRoomChange(); checkRoomChange();
// Actualiza las notificaciones
screen->updateNotifier();
} }
} }

View File

@@ -1,7 +1,15 @@
#include "director.h" #include "common/jscore.h"
#include "common/utils.h" #include "common/utils.h"
#include "director.h"
#include <errno.h>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <sys/stat.h>
#include <unistd.h>
#ifndef _WIN32
#include <pwd.h>
#endif
// Constructor // Constructor
Director::Director(int argc, char *argv[]) Director::Director(int argc, char *argv[])
@@ -14,11 +22,14 @@ Director::Director(int argc, char *argv[])
#endif #endif
// Crea e inicializa las opciones del programa // Crea e inicializa las opciones del programa
iniOptions(); initOptions();
// Comprueba los parametros del programa // Comprueba los parametros del programa
checkProgramArguments(argc, argv); checkProgramArguments(argc, argv);
// Crea la carpeta del sistema donde guardar datos
createSystemFolder();
// Crea el objeto que controla los ficheros de recursos // Crea el objeto que controla los ficheros de recursos
asset = new Asset(executablePath); asset = new Asset(executablePath);
asset->setVerbose(options->console); asset->setVerbose(options->console);
@@ -26,7 +37,7 @@ Director::Director(int argc, char *argv[])
// Si falta algún fichero no inicia el programa // Si falta algún fichero no inicia el programa
if (!setFileList()) if (!setFileList())
{ {
section.name = SECTION_PROG_QUIT; exit(EXIT_FAILURE);
} }
// Inicializa variables desde el fichero de configuración // Inicializa variables desde el fichero de configuración
@@ -42,9 +53,8 @@ Director::Director(int argc, char *argv[])
resource = new Resource(renderer, asset, options); resource = new Resource(renderer, asset, options);
input = new Input(asset->get("gamecontrollerdb.txt")); input = new Input(asset->get("gamecontrollerdb.txt"));
initInput(); initInput();
screen = new Screen(window, renderer, options, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); screen = new Screen(window, renderer, asset, options);
screen->setBorderColor(borderColor); screen->setBorderColor(borderColor);
screen->setVideoMode(options->fullScreenMode);
debug = new Debug(renderer, screen, asset); debug = new Debug(renderer, screen, asset);
music = JA_LoadMusic(asset->get("title.ogg").c_str()); music = JA_LoadMusic(asset->get("title.ogg").c_str());
} }
@@ -68,21 +78,55 @@ Director::~Director()
SDL_Quit(); SDL_Quit();
} }
// Inicializa los servicios online
void Director::initOnline()
{
if (options->online.jailerID == "")
{ // Jailer ID no definido
options->online.enabled = false;
}
else
{ // Jailer ID iniciado
if (options->online.enabled)
{ // Establece el servidor y el puerto
jscore::init(options->online.server, options->online.port);
const std::string caption = options->online.jailerID + " IS LOGGED IN";
screen->showNotification(caption);
if (options->console)
{
std::cout << caption << std::endl;
}
}
}
}
// Crea e inicializa las opciones del programa // Crea e inicializa las opciones del programa
void Director::iniOptions() void Director::initOptions()
{ {
// Crea el puntero a la estructura de opciones // Crea el puntero a la estructura de opciones
options = new options_t; options = new options_t;
// Inicializa valores // Version del archivo de configuración
options->fullScreenMode = 0; options->configVersion = "v1.06.1";
// Opciones de control
options->keys = ctrl_cursor;
// Opciones de video
options->gameWidth = GAMECANVAS_WIDTH;
options->gameHeight = GAMECANVAS_HEIGHT;
options->videoMode = 0;
options->windowSize = 3; options->windowSize = 3;
options->filter = FILTER_NEAREST; options->filter = FILTER_NEAREST;
options->vSync = true; options->vSync = true;
options->integerScale = true; options->integerScale = true;
options->keepAspect = true; options->keepAspect = true;
options->borderEnabled = true; options->borderEnabled = true;
options->borderSize = 0.1f; options->borderWidth = 32;
options->borderHeight = 24;
options->palette = p_zxspectrum; options->palette = p_zxspectrum;
// Estos valores no se guardan en el fichero de configuraci´ón // Estos valores no se guardan en el fichero de configuraci´ón
@@ -91,6 +135,25 @@ void Director::iniOptions()
options->cheat.invincible = false; options->cheat.invincible = false;
options->cheat.jailEnabled = false; options->cheat.jailEnabled = false;
options->cheat.altSkin = false; options->cheat.altSkin = false;
options->stats.rooms = 0;
options->stats.items = 0;
// Opciones online
options->online.enabled = true;
options->online.server = "jaildoctor.duckdns.org";
options->online.port = 9911;
#ifdef DEBUG
options->online.gameID = "jaildoctors_dilemma_test";
#else
options->online.gameID = "jaildoctors_dilemma";
#endif
options->online.jailerID = "";
// Opciones de las notificaciones
options->notifications.posV = pos_top;
options->notifications.posH = pos_left;
options->notifications.sound = true;
options->notifications.color = {64, 64, 64};
} }
// Comprueba los parametros del programa // Comprueba los parametros del programa
@@ -135,6 +198,10 @@ bool Director::loadConfig()
// Indicador de éxito en la carga // Indicador de éxito en la carga
bool success = true; bool success = true;
// Versión actual del fichero
const std::string configVersion = options->configVersion;
options->configVersion = "";
// Variables para manejar el fichero // Variables para manejar el fichero
std::string line; std::string line;
std::ifstream file(asset->get("config.txt")); std::ifstream file(asset->get("config.txt"));
@@ -181,19 +248,40 @@ bool Director::loadConfig()
saveConfig(); saveConfig();
} }
// Si la versión de fichero no coincide, crea un fichero nuevo con los valores por defecto
if (configVersion != options->configVersion)
{
initOptions();
saveConfig();
}
// Normaliza los valores
const bool a = options->videoMode == 0;
const bool b = options->videoMode == SDL_WINDOW_FULLSCREEN;
const bool c = options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP;
if (!(a || b || c))
{
options->videoMode = 0;
}
if (options->windowSize < 1 || options->windowSize > 4)
{
options->windowSize = 3;
}
// Aplica opciones // Aplica opciones
if (options->borderEnabled) // if (options->borderEnabled)
{ //{
const int incWidth = GAMECANVAS_WIDTH * options->borderSize; // const int incWidth = GAMECANVAS_WIDTH * options->borderSize;
const int incHeight = GAMECANVAS_HEIGHT * options->borderSize; // const int incHeight = GAMECANVAS_HEIGHT * options->borderSize;
options->screenWidth = (GAMECANVAS_WIDTH + incWidth) * options->windowSize; // options->gameWidth = GAMECANVAS_WIDTH + incWidth;
options->screenHeight = (GAMECANVAS_HEIGHT + incHeight) * options->windowSize; // options->gameHeight = GAMECANVAS_HEIGHT + incHeight;
} //}
else // else
{ //{
options->screenWidth = GAMECANVAS_WIDTH * options->windowSize; // options->gameWidth = GAMECANVAS_WIDTH;
options->screenHeight = GAMECANVAS_HEIGHT * options->windowSize; // options->gameHeight = GAMECANVAS_HEIGHT;
} //}
return success; return success;
} }
@@ -206,20 +294,54 @@ bool Director::saveConfig()
// Crea y abre el fichero de texto // Crea y abre el fichero de texto
std::ofstream file(asset->get("config.txt")); std::ofstream file(asset->get("config.txt"));
if (file.good())
{
if (options->console)
{
std::cout << asset->get("config.txt") << " open for writing" << std::endl;
}
}
else
{
if (options->console)
{
std::cout << asset->get("config.txt") << " can't be opened" << std::endl;
}
}
// Escribe en el fichero // Escribe en el fichero
if (options->fullScreenMode == 0) file << "## VERSION\n";
file << "configVersion=" + options->configVersion + "\n";
file << "\n## CONTROL OPTIONS\n";
file << "## keys = CURSOR | OPQA | WASD\n";
if (options->keys == ctrl_cursor)
{ {
file << "fullScreenMode=0\n"; file << "keys=CURSOR\n";
}
else if (options->keys == ctrl_opqa)
{
file << "keys=OPQA\n";
}
else if (options->keys == ctrl_wasd)
{
file << "keys=WASD\n";
} }
else if (options->fullScreenMode == SDL_WINDOW_FULLSCREEN) file << "\n## VISUAL OPTIONS\n";
if (options->videoMode == 0)
{ {
file << "fullScreenMode=SDL_WINDOW_FULLSCREEN\n"; file << "videoMode=0\n";
} }
else if (options->fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP) else if (options->videoMode == SDL_WINDOW_FULLSCREEN)
{ {
file << "fullScreenMode=SDL_WINDOW_FULLSCREEN_DESKTOP\n"; file << "videoMode=SDL_WINDOW_FULLSCREEN\n";
}
else if (options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
file << "videoMode=SDL_WINDOW_FULLSCREEN_DESKTOP\n";
} }
file << "windowSize=" + std::to_string(options->windowSize) + "\n"; file << "windowSize=" + std::to_string(options->windowSize) + "\n";
@@ -237,15 +359,104 @@ bool Director::saveConfig()
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 << "borderHeight=" + std::to_string(options->borderHeight) + "\n";
file << "palette=" + std::to_string(options->palette) + "\n"; file << "palette=" + std::to_string(options->palette) + "\n";
file << "\n## ONLINE OPTIONS\n";
file << "enabled=" + boolToString(options->online.enabled) + "\n";
file << "server=" + options->online.server + "\n";
file << "port=" + std::to_string(options->online.port) + "\n";
file << "jailerID=" + options->online.jailerID + "\n";
file << "\n## NOTIFICATION OPTIONS\n";
file << "## notifications.posV = pos_top | pos_bottom\n";
if (options->notifications.posV == pos_top)
{
file << "notifications.posV=pos_top\n";
}
else
{
file << "notifications.posV=pos_bottom\n";
}
file << "## notifications.posH = pos_left | pos_middle | pos_right\n";
if (options->notifications.posH == pos_left)
{
file << "notifications.posH=pos_left\n";
}
else if (options->notifications.posH == pos_middle)
{
file << "notifications.posH=pos_middle\n";
}
else
{
file << "notifications.posH=pos_right\n";
}
file << "notifications.sound=" + boolToString(options->notifications.sound) + "\n";
// Cierra el fichero // Cierra el fichero
file.close(); file.close();
return success; return success;
} }
// Crea la carpeta del sistema donde guardar datos
void Director::createSystemFolder()
{
#ifdef DEBUG
const std::string folderName = "jaildoctors_dilemma_debug";
#else
const std::string folderName = "jaildoctors_dilemma";
#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 los recursos // Carga los recursos
void Director::loadResources(section_t section) void Director::loadResources(section_t section)
{ {
@@ -349,9 +560,9 @@ void Director::loadResources(section_t section)
textureList.push_back("abad.png"); textureList.push_back("abad.png");
textureList.push_back("abad_bell.png"); textureList.push_back("abad_bell.png");
textureList.push_back("amstrad_cs.png"); textureList.push_back("amstrad_cs.png");
textureList.push_back("arounder_fly.png"); textureList.push_back("flying_arounder.png");
textureList.push_back("arounder_stop.png"); textureList.push_back("stopped_arounder.png");
textureList.push_back("arounder_walk.png"); textureList.push_back("walking_arounder.png");
textureList.push_back("arounders_door.png"); textureList.push_back("arounders_door.png");
textureList.push_back("arounders_machine.png"); textureList.push_back("arounders_machine.png");
textureList.push_back("bat.png"); textureList.push_back("bat.png");
@@ -373,11 +584,11 @@ void Director::loadResources(section_t section)
textureList.push_back("diskette.png"); textureList.push_back("diskette.png");
textureList.push_back("dong.png"); textureList.push_back("dong.png");
textureList.push_back("guitar.png"); textureList.push_back("guitar.png");
textureList.push_back("jb_alien.png"); textureList.push_back("jailbattle_alien.png");
textureList.push_back("jb_human.png"); textureList.push_back("jailbattle_human.png");
textureList.push_back("jailer.png"); textureList.push_back("jailer_#1.png");
textureList.push_back("jailer2.png"); textureList.push_back("jailer_#2.png");
textureList.push_back("jailer3.png"); textureList.push_back("jailer_#3.png");
textureList.push_back("jeannine.png"); textureList.push_back("jeannine.png");
textureList.push_back("lamp.png"); textureList.push_back("lamp.png");
textureList.push_back("lord_abad.png"); textureList.push_back("lord_abad.png");
@@ -385,7 +596,7 @@ void Director::loadResources(section_t section)
textureList.push_back("matatunos.png"); textureList.push_back("matatunos.png");
textureList.push_back("mummy.png"); textureList.push_back("mummy.png");
textureList.push_back("paco.png"); textureList.push_back("paco.png");
textureList.push_back("printer.png"); textureList.push_back("elsa.png");
textureList.push_back("qvoid.png"); textureList.push_back("qvoid.png");
textureList.push_back("sam.png"); textureList.push_back("sam.png");
textureList.push_back("sigmasua.png"); textureList.push_back("sigmasua.png");
@@ -412,9 +623,9 @@ void Director::loadResources(section_t section)
animationList.push_back("abad.ani"); animationList.push_back("abad.ani");
animationList.push_back("abad_bell.ani"); animationList.push_back("abad_bell.ani");
animationList.push_back("amstrad_cs.ani"); animationList.push_back("amstrad_cs.ani");
animationList.push_back("arounder_fly.ani"); animationList.push_back("flying_arounder.ani");
animationList.push_back("arounder_stop.ani"); animationList.push_back("stopped_arounder.ani");
animationList.push_back("arounder_walk.ani"); animationList.push_back("walking_arounder.ani");
animationList.push_back("arounders_door.ani"); animationList.push_back("arounders_door.ani");
animationList.push_back("arounders_machine.ani"); animationList.push_back("arounders_machine.ani");
animationList.push_back("bat.ani"); animationList.push_back("bat.ani");
@@ -436,11 +647,11 @@ void Director::loadResources(section_t section)
animationList.push_back("diskette.ani"); animationList.push_back("diskette.ani");
animationList.push_back("dong.ani"); animationList.push_back("dong.ani");
animationList.push_back("guitar.ani"); animationList.push_back("guitar.ani");
animationList.push_back("jb_alien.ani"); animationList.push_back("jailbattle_alien.ani");
animationList.push_back("jb_human.ani"); animationList.push_back("jailbattle_human.ani");
animationList.push_back("jailer.ani"); animationList.push_back("jailer_#1.ani");
animationList.push_back("jailer2.ani"); animationList.push_back("jailer_#2.ani");
animationList.push_back("jailer3.ani"); animationList.push_back("jailer_#3.ani");
animationList.push_back("jeannine.ani"); animationList.push_back("jeannine.ani");
animationList.push_back("lamp.ani"); animationList.push_back("lamp.ani");
animationList.push_back("lord_abad.ani"); animationList.push_back("lord_abad.ani");
@@ -448,7 +659,7 @@ void Director::loadResources(section_t section)
animationList.push_back("matatunos.ani"); animationList.push_back("matatunos.ani");
animationList.push_back("mummy.ani"); animationList.push_back("mummy.ani");
animationList.push_back("paco.ani"); animationList.push_back("paco.ani");
animationList.push_back("printer.ani"); animationList.push_back("elsa.ani");
animationList.push_back("qvoid.ani"); animationList.push_back("qvoid.ani");
animationList.push_back("sam.ani"); animationList.push_back("sam.ani");
animationList.push_back("sigmasua.ani"); animationList.push_back("sigmasua.ani");
@@ -523,9 +734,9 @@ void Director::loadResources(section_t section)
textureList.push_back("abad.png"); textureList.push_back("abad.png");
textureList.push_back("aerojailer.png"); textureList.push_back("aerojailer.png");
textureList.push_back("amstrad_cs.png"); textureList.push_back("amstrad_cs.png");
textureList.push_back("arounder_fly.png"); textureList.push_back("flying_arounder.png");
textureList.push_back("arounder_stop.png"); textureList.push_back("stopped_arounder.png");
textureList.push_back("arounder_walk.png"); textureList.push_back("walking_arounder.png");
textureList.push_back("arounder.png"); textureList.push_back("arounder.png");
textureList.push_back("arounders_door.png"); textureList.push_back("arounders_door.png");
textureList.push_back("arounders_machine.png"); textureList.push_back("arounders_machine.png");
@@ -548,11 +759,11 @@ void Director::loadResources(section_t section)
textureList.push_back("dong.png"); textureList.push_back("dong.png");
textureList.push_back("guitar.png"); textureList.push_back("guitar.png");
textureList.push_back("heavy.png"); textureList.push_back("heavy.png");
textureList.push_back("jailer.png"); textureList.push_back("jailer_#1.png");
textureList.push_back("jailer2.png"); textureList.push_back("jailer_#2.png");
textureList.push_back("jailer3.png"); textureList.push_back("jailer_#3.png");
textureList.push_back("jb_alien.png"); textureList.push_back("jailbattle_alien.png");
textureList.push_back("jb_human.png"); textureList.push_back("jailbattle_human.png");
textureList.push_back("jeannine.png"); textureList.push_back("jeannine.png");
textureList.push_back("lamp.png"); textureList.push_back("lamp.png");
textureList.push_back("lord_abad.png"); textureList.push_back("lord_abad.png");
@@ -560,7 +771,7 @@ void Director::loadResources(section_t section)
textureList.push_back("mummy.png"); textureList.push_back("mummy.png");
textureList.push_back("paco.png"); textureList.push_back("paco.png");
textureList.push_back("pepe_rosita_job.png"); textureList.push_back("pepe_rosita_job.png");
textureList.push_back("printer.png"); textureList.push_back("elsa.png");
textureList.push_back("qvoid.png"); textureList.push_back("qvoid.png");
textureList.push_back("robot.png"); textureList.push_back("robot.png");
textureList.push_back("sam.png"); textureList.push_back("sam.png");
@@ -604,9 +815,9 @@ void Director::loadResources(section_t section)
animationList.push_back("abad.ani"); animationList.push_back("abad.ani");
animationList.push_back("aerojailer.ani"); animationList.push_back("aerojailer.ani");
animationList.push_back("amstrad_cs.ani"); animationList.push_back("amstrad_cs.ani");
animationList.push_back("arounder_fly.ani"); animationList.push_back("flying_arounder.ani");
animationList.push_back("arounder_stop.ani"); animationList.push_back("stopped_arounder.ani");
animationList.push_back("arounder_walk.ani"); animationList.push_back("walking_arounder.ani");
animationList.push_back("arounder.ani"); animationList.push_back("arounder.ani");
animationList.push_back("arounders_door.ani"); animationList.push_back("arounders_door.ani");
animationList.push_back("arounders_machine.ani"); animationList.push_back("arounders_machine.ani");
@@ -629,11 +840,11 @@ void Director::loadResources(section_t section)
animationList.push_back("dong.ani"); animationList.push_back("dong.ani");
animationList.push_back("guitar.ani"); animationList.push_back("guitar.ani");
animationList.push_back("heavy.ani"); animationList.push_back("heavy.ani");
animationList.push_back("jailer.ani"); animationList.push_back("jailer_#1.ani");
animationList.push_back("jailer2.ani"); animationList.push_back("jailer_#2.ani");
animationList.push_back("jailer3.ani"); animationList.push_back("jailer_#3.ani");
animationList.push_back("jb_alien.ani"); animationList.push_back("jailbattle_alien.ani");
animationList.push_back("jb_human.ani"); animationList.push_back("jailbattle_human.ani");
animationList.push_back("jeannine.ani"); animationList.push_back("jeannine.ani");
animationList.push_back("lamp.ani"); animationList.push_back("lamp.ani");
animationList.push_back("lord_abad.ani"); animationList.push_back("lord_abad.ani");
@@ -641,7 +852,7 @@ void Director::loadResources(section_t section)
animationList.push_back("mummy.ani"); animationList.push_back("mummy.ani");
animationList.push_back("paco.ani"); animationList.push_back("paco.ani");
animationList.push_back("pepe_rosita_job.ani"); animationList.push_back("pepe_rosita_job.ani");
animationList.push_back("printer.ani"); animationList.push_back("elsa.ani");
animationList.push_back("qvoid.ani"); animationList.push_back("qvoid.ani");
animationList.push_back("robot.ani"); animationList.push_back("robot.ani");
animationList.push_back("sam.ani"); animationList.push_back("sam.ani");
@@ -810,19 +1021,40 @@ 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 == "configVersion")
{ {
if (value == "SDL_WINDOW_FULLSCREEN_DESKTOP") options->configVersion = value;
{
options->fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
} }
else if (value == "SDL_WINDOW_FULLSCREEN")
else if (var == "keys")
{ {
options->fullScreenMode = SDL_WINDOW_FULLSCREEN; if (value == "OPQA")
{
options->keys = ctrl_opqa;
}
else if (value == "WASD")
{
options->keys = ctrl_wasd;
} }
else else
{ {
options->fullScreenMode = 0; options->keys = ctrl_cursor;
}
}
else if (var == "videoMode")
{
if (value == "SDL_WINDOW_FULLSCREEN_DESKTOP")
{
options->videoMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
}
else if (value == "SDL_WINDOW_FULLSCREEN")
{
options->videoMode = SDL_WINDOW_FULLSCREEN;
}
else
{
options->videoMode = 0;
} }
} }
@@ -867,13 +1099,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 == "borderHeight")
{
options->borderHeight = std::stoi(value);
} }
else if (var == "palette") else if (var == "palette")
@@ -891,7 +1124,64 @@ bool Director::setOptions(options_t *options, std::string var, std::string value
} }
} }
else if (var == "") else if (var == "enabled")
{
options->online.enabled = stringToBool(value);
}
else if (var == "server")
{
options->online.server = value;
}
else if (var == "port")
{
if (value == "")
{
value = "0";
}
options->online.port = std::stoi(value);
}
else if (var == "jailerID")
{
options->online.jailerID = value;
}
else if (var == "notifications.posH")
{
if (value == "pos_left")
{
options->notifications.posH = pos_left;
}
else if (value == "pos_middle")
{
options->notifications.posH = pos_middle;
}
else
{
options->notifications.posH = pos_right;
}
}
else if (var == "notifications.posV")
{
if (value == "pos_top")
{
options->notifications.posV = pos_top;
}
else
{
options->notifications.posV = pos_bottom;
}
}
else if (var == "notifications.sound")
{
options->notifications.sound = stringToBool(value);
}
else if (var == "" || var.substr(0, 1) == "#")
{ {
} }
@@ -913,10 +1203,26 @@ void Director::initInput()
input->discoverGameController(); input->discoverGameController();
// Asigna inputs a teclas // Asigna inputs a teclas
if (options->keys == ctrl_cursor)
{
input->bindKey(INPUT_UP, SDL_SCANCODE_UP); input->bindKey(INPUT_UP, SDL_SCANCODE_UP);
input->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN);
input->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT); input->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT);
input->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT); input->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT);
}
else if (options->keys == ctrl_opqa)
{
input->bindKey(INPUT_UP, SDL_SCANCODE_Q);
input->bindKey(INPUT_LEFT, SDL_SCANCODE_O);
input->bindKey(INPUT_RIGHT, SDL_SCANCODE_P);
}
else if (options->keys == ctrl_wasd)
{
input->bindKey(INPUT_UP, SDL_SCANCODE_W);
input->bindKey(INPUT_LEFT, SDL_SCANCODE_A);
input->bindKey(INPUT_RIGHT, SDL_SCANCODE_D);
}
input->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN);
input->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN); input->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN);
input->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE); input->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE);
input->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_SPACE); input->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_SPACE);
@@ -971,7 +1277,15 @@ bool Director::initSDL()
} }
// Crea la ventana // Crea la ventana
window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, options->screenWidth, options->screenHeight, 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)
{ {
if (options->console) if (options->console)
@@ -1006,7 +1320,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);
@@ -1036,10 +1350,13 @@ bool Director::setFileList()
asset->add(prefix + "/data/font/debug.png", t_font); asset->add(prefix + "/data/font/debug.png", t_font);
asset->add(prefix + "/data/font/debug.txt", t_font); asset->add(prefix + "/data/font/debug.txt", t_font);
// Configuración // Datos
asset->add(prefix + "/data/input/gamecontrollerdb.txt", t_data); asset->add(prefix + "/data/input/gamecontrollerdb.txt", t_data);
asset->add(prefix + "/data/config/config.txt", t_data, false);
asset->add(prefix + "/data/config/stats.txt", t_data, false); // Ficheros de sistema
asset->add(systemFolder + "/config.txt", t_data, false, true);
asset->add(systemFolder + "/stats_buffer.csv", t_data, false, true);
asset->add(systemFolder + "/stats.csv", t_data, false, true);
// Habitaciones // Habitaciones
asset->add(prefix + "/data/room/01.room", t_room); asset->add(prefix + "/data/room/01.room", t_room);
@@ -1176,12 +1493,12 @@ bool Director::setFileList()
asset->add(prefix + "/data/enemies/abad.png", t_bitmap); asset->add(prefix + "/data/enemies/abad.png", t_bitmap);
asset->add(prefix + "/data/enemies/amstrad_cs.ani", t_data); asset->add(prefix + "/data/enemies/amstrad_cs.ani", t_data);
asset->add(prefix + "/data/enemies/amstrad_cs.png", t_bitmap); asset->add(prefix + "/data/enemies/amstrad_cs.png", t_bitmap);
asset->add(prefix + "/data/enemies/arounder_fly.ani", t_data); asset->add(prefix + "/data/enemies/flying_arounder.ani", t_data);
asset->add(prefix + "/data/enemies/arounder_fly.png", t_bitmap); asset->add(prefix + "/data/enemies/flying_arounder.png", t_bitmap);
asset->add(prefix + "/data/enemies/arounder_stop.ani", t_data); asset->add(prefix + "/data/enemies/stopped_arounder.ani", t_data);
asset->add(prefix + "/data/enemies/arounder_stop.png", t_bitmap); asset->add(prefix + "/data/enemies/stopped_arounder.png", t_bitmap);
asset->add(prefix + "/data/enemies/arounder_walk.ani", t_data); asset->add(prefix + "/data/enemies/walking_arounder.ani", t_data);
asset->add(prefix + "/data/enemies/arounder_walk.png", t_bitmap); asset->add(prefix + "/data/enemies/walking_arounder.png", t_bitmap);
asset->add(prefix + "/data/enemies/arounders_door.ani", t_data); asset->add(prefix + "/data/enemies/arounders_door.ani", t_data);
asset->add(prefix + "/data/enemies/arounders_door.png", t_bitmap); asset->add(prefix + "/data/enemies/arounders_door.png", t_bitmap);
asset->add(prefix + "/data/enemies/arounders_machine.ani", t_data); asset->add(prefix + "/data/enemies/arounders_machine.ani", t_data);
@@ -1224,16 +1541,16 @@ bool Director::setFileList()
asset->add(prefix + "/data/enemies/guitar.png", t_bitmap); asset->add(prefix + "/data/enemies/guitar.png", t_bitmap);
asset->add(prefix + "/data/enemies/heavy.ani", t_data); asset->add(prefix + "/data/enemies/heavy.ani", t_data);
asset->add(prefix + "/data/enemies/heavy.png", t_bitmap); asset->add(prefix + "/data/enemies/heavy.png", t_bitmap);
asset->add(prefix + "/data/enemies/jailer.ani", t_data); asset->add(prefix + "/data/enemies/jailer_#1.ani", t_data);
asset->add(prefix + "/data/enemies/jailer.png", t_bitmap); asset->add(prefix + "/data/enemies/jailer_#1.png", t_bitmap);
asset->add(prefix + "/data/enemies/jailer2.ani", t_data); asset->add(prefix + "/data/enemies/jailer_#2.ani", t_data);
asset->add(prefix + "/data/enemies/jailer2.png", t_bitmap); asset->add(prefix + "/data/enemies/jailer_#2.png", t_bitmap);
asset->add(prefix + "/data/enemies/jailer3.ani", t_data); asset->add(prefix + "/data/enemies/jailer_#3.ani", t_data);
asset->add(prefix + "/data/enemies/jailer3.png", t_bitmap); asset->add(prefix + "/data/enemies/jailer_#3.png", t_bitmap);
asset->add(prefix + "/data/enemies/jb_alien.ani", t_data); asset->add(prefix + "/data/enemies/jailbattle_alien.ani", t_data);
asset->add(prefix + "/data/enemies/jb_alien.png", t_bitmap); asset->add(prefix + "/data/enemies/jailbattle_alien.png", t_bitmap);
asset->add(prefix + "/data/enemies/jb_human.ani", t_data); asset->add(prefix + "/data/enemies/jailbattle_human.ani", t_data);
asset->add(prefix + "/data/enemies/jb_human.png", t_bitmap); asset->add(prefix + "/data/enemies/jailbattle_human.png", t_bitmap);
asset->add(prefix + "/data/enemies/jeannine.ani", t_data); asset->add(prefix + "/data/enemies/jeannine.ani", t_data);
asset->add(prefix + "/data/enemies/jeannine.png", t_bitmap); asset->add(prefix + "/data/enemies/jeannine.png", t_bitmap);
asset->add(prefix + "/data/enemies/lamp.ani", t_data); asset->add(prefix + "/data/enemies/lamp.ani", t_data);
@@ -1246,8 +1563,8 @@ bool Director::setFileList()
asset->add(prefix + "/data/enemies/mummy.png", t_bitmap); asset->add(prefix + "/data/enemies/mummy.png", t_bitmap);
asset->add(prefix + "/data/enemies/paco.ani", t_data); asset->add(prefix + "/data/enemies/paco.ani", t_data);
asset->add(prefix + "/data/enemies/paco.png", t_bitmap); asset->add(prefix + "/data/enemies/paco.png", t_bitmap);
asset->add(prefix + "/data/enemies/printer.ani", t_data); asset->add(prefix + "/data/enemies/elsa.ani", t_data);
asset->add(prefix + "/data/enemies/printer.png", t_bitmap); asset->add(prefix + "/data/enemies/elsa.png", t_bitmap);
asset->add(prefix + "/data/enemies/qvoid.ani", t_data); asset->add(prefix + "/data/enemies/qvoid.ani", t_data);
asset->add(prefix + "/data/enemies/qvoid.png", t_bitmap); asset->add(prefix + "/data/enemies/qvoid.png", t_bitmap);
asset->add(prefix + "/data/enemies/robot.ani", t_data); asset->add(prefix + "/data/enemies/robot.ani", t_data);
@@ -1333,6 +1650,7 @@ bool Director::setFileList()
asset->add(prefix + "/data/sound/jump22.wav", t_sound); asset->add(prefix + "/data/sound/jump22.wav", t_sound);
asset->add(prefix + "/data/sound/jump23.wav", t_sound); asset->add(prefix + "/data/sound/jump23.wav", t_sound);
asset->add(prefix + "/data/sound/jump24.wav", t_sound); asset->add(prefix + "/data/sound/jump24.wav", t_sound);
asset->add(prefix + "/data/sound/notify.wav", t_sound);
// Logo // Logo
asset->add(prefix + "/data/logo/jailgames.png", t_bitmap); asset->add(prefix + "/data/logo/jailgames.png", t_bitmap);
@@ -1455,6 +1773,20 @@ void Director::runDemo()
resource->free(); resource->free();
} }
// Ejecuta la seccion en la que se solicita al usuario su ID online
void Director::runEnterID()
{
if (options->console)
{
std::cout << "\n* SECTION: ENTER_ID" << std::endl;
}
// loadResources(section);
enterID = new EnterID(renderer, screen, asset, options, section);
setSection(enterID->run());
delete enterID;
resource->free();
}
// Ejecuta la seccion del final del juego // Ejecuta la seccion del final del juego
void Director::runEnding() void Director::runEnding()
{ {
@@ -1539,6 +1871,10 @@ void Director::run()
runDemo(); runDemo();
break; break;
case SECTION_PROG_ENTER_ID:
runEnterID();
break;
case SECTION_PROG_GAME: case SECTION_PROG_GAME:
runGame(); runGame();
break; break;

View File

@@ -12,13 +12,14 @@
#include "const.h" #include "const.h"
#include "credits.h" #include "credits.h"
#include "demo.h" #include "demo.h"
#include "ending.h"
#include "ending2.h"
#include "enter_id.h"
#include "game_over.h"
#include "game.h" #include "game.h"
#include "intro.h" #include "intro.h"
#include "logo.h" #include "logo.h"
#include "title.h" #include "title.h"
#include "game_over.h"
#include "ending.h"
#include "ending2.h"
#ifndef DIRECTOR_H #ifndef DIRECTOR_H
#define DIRECTOR_H #define DIRECTOR_H
@@ -39,6 +40,7 @@ private:
Intro *intro; // Objeto para gestionar la introducción del juego Intro *intro; // Objeto para gestionar la introducción del juego
Credits *credits; // Objeto para gestionar los creditos del juego Credits *credits; // Objeto para gestionar los creditos del juego
Demo *demo; // Objeto para gestionar el modo demo, en el que se ven pantallas del juego Demo *demo; // Objeto para gestionar el modo demo, en el que se ven pantallas del juego
EnterID *enterID; // Objeto para gestionar la sección donde se solicita el ID online al usuario
Ending *ending; // Objeto para gestionar el final del juego Ending *ending; // Objeto para gestionar el final del juego
Ending2 *ending2; // Objeto para gestionar el final del juego Ending2 *ending2; // Objeto para gestionar el final del juego
GameOver *gameOver; // Objeto para gestionar el final de la partida GameOver *gameOver; // Objeto para gestionar el final de la partida
@@ -46,12 +48,16 @@ private:
struct options_t *options; // Variable con todas las opciones del programa struct options_t *options; // Variable con todas las opciones del programa
// Variables // Variables
section_t section; // Sección y subsección actual del programa;
JA_Music music; // Musica del titulo JA_Music music; // Musica del titulo
std::string executablePath; // Path del ejecutable std::string executablePath; // Path del ejecutable
section_t section; // Sección y subsección actual del programa; std::string systemFolder; // Carpeta del sistema donde guardar datos
// Crea e inicializa las opciones del programa // Crea e inicializa las opciones del programa
void iniOptions(); void initOptions();
// Inicializa los servicios online
void initOnline();
// Comprueba los parametros del programa // Comprueba los parametros del programa
void checkProgramArguments(int argc, char *argv[]); void checkProgramArguments(int argc, char *argv[]);
@@ -62,6 +68,9 @@ private:
// Guarda el fichero de configuración // Guarda el fichero de configuración
bool saveConfig(); bool saveConfig();
// Crea la carpeta del sistema donde guardar datos
void createSystemFolder();
// Carga los recursos // Carga los recursos
void loadResources(section_t section); void loadResources(section_t section);
@@ -104,6 +113,9 @@ private:
// Ejecuta la seccion de la demo, donde se ven pantallas del juego // Ejecuta la seccion de la demo, donde se ven pantallas del juego
void runDemo(); void runDemo();
// Ejecuta la seccion en la que se solicita al usuario su ID online
void runEnterID();
// Ejecuta la seccion del final del juego // Ejecuta la seccion del final del juego
void runEnding(); void runEnding();

View File

@@ -103,6 +103,9 @@ void Ending::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
// Actualiza las notificaciones
screen->updateNotifier();
} }
} }

View File

@@ -102,6 +102,9 @@ void Ending2::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
// Actualiza las notificaciones
screen->updateNotifier();
} }
} }
@@ -292,7 +295,7 @@ void Ending2::iniSpriteList()
spriteList.push_back("spark"); spriteList.push_back("spark");
spriteList.push_back("code"); spriteList.push_back("code");
spriteList.push_back("paco"); spriteList.push_back("paco");
spriteList.push_back("printer"); spriteList.push_back("elsa");
spriteList.push_back("z80"); spriteList.push_back("z80");
spriteList.push_back("bell"); spriteList.push_back("bell");
@@ -301,9 +304,9 @@ void Ending2::iniSpriteList()
spriteList.push_back("amstrad_cs"); spriteList.push_back("amstrad_cs");
spriteList.push_back("breakout"); spriteList.push_back("breakout");
spriteList.push_back("arounder_fly"); spriteList.push_back("flying_arounder");
spriteList.push_back("arounder_stop"); spriteList.push_back("stopped_arounder");
spriteList.push_back("arounder_walk"); spriteList.push_back("walking_arounder");
spriteList.push_back("arounders_door"); spriteList.push_back("arounders_door");
spriteList.push_back("arounders_machine"); spriteList.push_back("arounders_machine");
@@ -321,12 +324,12 @@ void Ending2::iniSpriteList()
spriteList.push_back("dimallas"); spriteList.push_back("dimallas");
spriteList.push_back("guitar"); spriteList.push_back("guitar");
spriteList.push_back("jb_alien"); spriteList.push_back("jailbattle_alien");
spriteList.push_back("jb_human"); spriteList.push_back("jailbattle_human");
spriteList.push_back("jailer"); spriteList.push_back("jailer_#1");
spriteList.push_back("jailer2"); spriteList.push_back("jailer_#2");
spriteList.push_back("jailer3"); spriteList.push_back("jailer_#3");
spriteList.push_back("bry"); spriteList.push_back("bry");
spriteList.push_back("upv_student"); spriteList.push_back("upv_student");

310
source/enter_id.cpp Normal file
View File

@@ -0,0 +1,310 @@
#include "common/jail_audio.h"
#include "common/jscore.h"
#include "const.h"
#include "enter_id.h"
#include <iostream>
// Constructor
EnterID::EnterID(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, section_t section)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
this->options = options;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
texture = new Texture(renderer, asset->get("smb2.png"));
text = new Text(asset->get("smb2.txt"), texture, renderer);
// Crea la textura para el texto que se escribe en pantalla
textTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (textTexture == nullptr)
{
if (options->console)
{
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
SDL_SetTextureBlendMode(textTexture, SDL_BLENDMODE_BLEND);
// Inicializa variables
counter = 0;
ticks = 0;
ticksSpeed = 15;
pos = 0;
name[pos] = 0;
maxLenght = 15;
this->section.subsection = section.subsection;
if (options->online.enabled && options->online.jailerID == "")
{
this->section.name = SECTION_PROG_ENTER_ID;
}
else
{
endSection();
}
// Escribe el texto en la textura
fillTexture();
}
// Destructor
EnterID::~EnterID()
{
delete eventHandler;
delete text;
delete texture;
}
// Bucle para el logo del juego
section_t EnterID::run()
{
// Detiene la música
JA_StopMusic();
while (section.name == SECTION_PROG_ENTER_ID)
{
update();
render();
}
return section;
}
// Comprueba el manejador de eventos
void EnterID::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 = SECTION_PROG_QUIT;
break;
}
// El ENTER solo se comprueba cuando se suelta, para no saltarse la siguiente sección
if ((eventHandler->type == SDL_KEYUP && eventHandler->key.repeat == 0) || (eventHandler->type == SDL_JOYBUTTONUP))
{
if (eventHandler->key.keysym.scancode == SDL_SCANCODE_RETURN)
{
options->online.jailerID = (std::string)name;
endSection();
break;
}
}
// Comprueba las teclas que se han pulsado
if ((eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0) || (eventHandler->type == SDL_JOYBUTTONDOWN))
{
if (eventHandler->key.keysym.scancode >= SDL_SCANCODE_A && eventHandler->key.keysym.scancode <= SDL_SCANCODE_Z)
{ // Si pulsa una letra
if (pos < maxLenght)
{
name[pos++] = eventHandler->key.keysym.scancode + 61;
name[pos] = 0;
}
}
else if (eventHandler->key.keysym.scancode >= SDL_SCANCODE_1 && eventHandler->key.keysym.scancode <= SDL_SCANCODE_9)
{ // Si pulsa un número
if (pos < maxLenght)
{ // En ascii el '0' va antes del '1', pero en scancode el '0' va despues de '9'
name[pos++] = eventHandler->key.keysym.scancode + 19;
name[pos] = 0;
}
}
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_0)
{
if (pos < maxLenght)
{
name[pos++] = 48;
name[pos] = 0;
}
}
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_BACKSPACE)
{
if (pos > 0)
{
name[--pos] = 0;
}
}
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_ESCAPE)
{
section.name = SECTION_PROG_QUIT;
break;
}
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_F1)
{
screen->setWindowSize(1);
break;
}
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_F2)
{
screen->setWindowSize(2);
break;
}
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_F3)
{
screen->setWindowSize(3);
break;
}
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_F4)
{
screen->setWindowSize(4);
break;
}
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_F5)
{
switchPalette();
break;
}
}
}
}
// Actualiza las variables
void EnterID::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba el manejador de eventos
checkEventHandler();
// Actualiza el contador
counter++;
// Actualiza el cursor
cursor = (counter % 20 >= 10) ? " " : "_";
}
}
// Dibuja en pantalla
void EnterID::render()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean();
// Dibuja la textura con el texto en pantalla
SDL_RenderCopy(renderer, textTexture, nullptr, nullptr);
// Escribe el jailerID
const std::string jailerID = (std::string)name + cursor;
const color_t color = stringToColor(options->palette, "white");
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, (16 * 8 + 1), jailerID, 1, color);
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
// Inicializa los textos
void EnterID::iniTexts()
{
texts.clear();
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"ONLINE CONFIGURATION:", stringToColor(options->palette, "red")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"YOU HAVE NOT SPECIFIED ANY ID", stringToColor(options->palette, "white")});
texts.push_back({"FOR THE ONLINE SERVICE", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"PLEASE ENTER AN ID OR", stringToColor(options->palette, "white")});
texts.push_back({"LEAVE BLANK FOR OFFLINE MODE", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"JAILER_ID:", stringToColor(options->palette, "red")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
texts.push_back({"", stringToColor(options->palette, "white")});
}
// Escribe el texto en la textura
void EnterID::fillTexture()
{
// Inicializa los textos
iniTexts();
// Rellena la textura de texto
SDL_SetRenderTarget(renderer, textTexture);
color_t c = stringToColor(options->palette, "black");
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF);
SDL_RenderClear(renderer);
// Escribe el texto en la textura
const int size = text->getCharacterSize();
int i = 0;
for (auto t : texts)
{
text->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, i * size, t.label, 1, t.color);
i++;
}
SDL_SetRenderTarget(renderer, nullptr);
}
// Cambia la paleta
void EnterID::switchPalette()
{
options->palette = options->palette == p_zxspectrum ? p_zxarne : p_zxspectrum;
fillTexture();
}
// Inicializa los servicios online
void EnterID::initOnline()
{
if (options->online.jailerID == "")
{ // Jailer ID no definido
options->online.enabled = false;
}
else
{ // Jailer ID iniciado
options->online.enabled = true;
jscore::init(options->online.server, options->online.port);
const std::string caption = options->online.jailerID + " IS LOGGED IN";
screen->showNotification(caption);
if (options->console)
{
std::cout << caption << std::endl;
}
}
}
// Termina la sección
void EnterID::endSection()
{
initOnline();
section.name = (section.subsection == SUBSECTION_LOGO_TO_INTRO) ? SECTION_PROG_INTRO : SECTION_PROG_TITLE;
section.subsection = 0;
}

80
source/enter_id.h Normal file
View File

@@ -0,0 +1,80 @@
#pragma once
#include <SDL2/SDL.h>
#include "common/asset.h"
#include "common/screen.h"
#include "common/utils.h"
#include "common/text.h"
#include "common/texture.h"
#include <string>
#include <vector>
#ifndef ENTER_ID_H
#define ASK_ME_H
class EnterID
{
private:
struct captions_t
{
std::string label; // Texto a escribir
color_t color; // Color del texto
};
// Punteros y objetos
Asset *asset; // Objeto con los ficheros de recursos
options_t *options; // Puntero a las opciones del juego
Screen *screen; // Objeto encargado de dibujar en pantalla
SDL_Event *eventHandler; // Manejador de eventos
SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Texture *textTexture; // Textura para dibujar el texto
Text *text; // Objeto para escribir texto en pantalla
Texture *texture; // Textura para la fuente para el texto
// Variables
int counter; // 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
std::vector<captions_t> texts; // Vector con los textos
std::string cursor; // Contiene el caracter que se muestra como cursor
char name[15];
int pos;
int maxLenght; // Tamaño máximo del jailerID
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
// Comprueba el manejador de eventos
void checkEventHandler();
// Inicializa los textos
void iniTexts();
// Escribe el texto en la textura
void fillTexture();
// Cambia la paleta
void switchPalette();
// Inicializa los servicios online
void initOnline();
// Termina la sección
void endSection();
public:
// Constructor
EnterID(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, section_t section);
// Destructor
~EnterID();
// Bucle principal
section_t run();
};
#endif

View File

@@ -21,8 +21,8 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
this->options = options; this->options = options;
#ifdef DEBUG #ifdef DEBUG
currentRoom = "48.room"; currentRoom = "01.room";
const int x1 = 18; const int x1 = 25;
const int y1 = 13; const int y1 = 13;
spawnPoint = {x1 * 8, y1 * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL}; spawnPoint = {x1 * 8, y1 * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
#endif #endif
@@ -40,13 +40,15 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer);
music = JA_LoadMusic(asset->get("game.ogg").c_str()); music = JA_LoadMusic(asset->get("game.ogg").c_str());
deathSound = JA_LoadSound(asset->get("death.wav").c_str()); deathSound = JA_LoadSound(asset->get("death.wav").c_str());
stats = new Stats(asset->get("stats.txt")); stats = new Stats(asset->get("stats.csv"), asset->get("stats_buffer.csv"), options);
stats->addVisit(room->getName());
// Inicializa el resto de variables // Inicializa el resto de variables
ticks = 0; ticks = 0;
ticksSpeed = 15; ticksSpeed = 15;
board.lives = 9; board.lives = 9;
#ifdef DEBUG
board.lives = 9;
#endif
board.items = 0; board.items = 0;
board.rooms = 1; board.rooms = 1;
board.music = true; board.music = true;
@@ -57,6 +59,8 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
blackScreen = false; blackScreen = false;
blackScreenCounter = 0; blackScreenCounter = 0;
totalItems = getTotalItems(); totalItems = getTotalItems();
initStats();
stats->addVisit(room->getName());
section.name = SECTION_PROG_GAME; section.name = SECTION_PROG_GAME;
section.subsection = 0; section.subsection = 0;
@@ -92,6 +96,11 @@ void Game::checkEventHandler()
break; break;
} }
if (eventHandler->type == SDL_RENDER_DEVICE_RESET || eventHandler->type == SDL_RENDER_TARGETS_RESET)
{
reLoadTextures();
}
if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0)) if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
{ {
switch (eventHandler->key.keysym.scancode) switch (eventHandler->key.keysym.scancode)
@@ -126,6 +135,10 @@ void Game::checkEventHandler()
case SDL_SCANCODE_D: case SDL_SCANCODE_D:
goToRoom(BORDER_RIGHT); goToRoom(BORDER_RIGHT);
break; break;
case SDL_SCANCODE_F6:
screen->showNotification("MAMA MIRA! SIN MANOS!");
break;
#endif #endif
case SDL_SCANCODE_M: case SDL_SCANCODE_M:
@@ -133,7 +146,7 @@ void Game::checkEventHandler()
board.music ? JA_ResumeMusic() : JA_PauseMusic(); board.music ? JA_ResumeMusic() : JA_PauseMusic();
break; break;
case SDL_SCANCODE_P: case SDL_SCANCODE_H:
switchPause(); switchPause();
break; break;
@@ -223,11 +236,15 @@ void Game::update()
checkIfPlayerIsAlive(); checkIfPlayerIsAlive();
checkGameOver(); checkGameOver();
checkEndGame(); checkEndGame();
checkRestoringJail();
scoreboard->update(); scoreboard->update();
input->update(); input->update();
updateBlackScreen(); updateBlackScreen();
// Actualiza las notificaciones
screen->updateNotifier();
#ifdef DEBUG #ifdef DEBUG
updateDebugInfo(); updateDebugInfo();
#endif #endif
@@ -332,16 +349,18 @@ bool Game::changeRoom(std::string file)
setScoreBoardColor(); setScoreBoardColor();
if (roomTracker->addRoom(file)) if (roomTracker->addRoom(file))
{ // Incrementa el contador de habitaciones visitadas {
// Incrementa el contador de habitaciones visitadas
board.rooms++; board.rooms++;
options->stats.rooms = board.rooms;
// Actualiza las estadisticas
stats->addVisit(room->getName());
} }
// Pasa la nueva habitación al jugador // Pasa la nueva habitación al jugador
player->setRoom(room); player->setRoom(room);
// Actualiza las estadisticas
stats->addVisit(room->getName());
return true; return true;
} }
@@ -587,3 +606,35 @@ void Game::switchPause()
paused = true; paused = true;
} }
} }
// Da vidas al jugador cuando está en la Jail
void Game::checkRestoringJail()
{
if (room->getName() != "THE JAIL" || board.lives == 9)
{
return;
}
static int counter = 0;
counter++;
if (counter == 100)
{
counter = 0;
board.lives++;
JA_PlaySound(deathSound);
}
}
// Inicializa el diccionario de las estadísticas
void Game::initStats()
{
std::vector<res_room_t> *rooms = new std::vector<res_room_t>;
rooms = resource->getAllRooms();
for (auto room : *rooms)
{
stats->addDictionary(room.room->number, room.room->name);
}
stats->init();
}

View File

@@ -127,6 +127,12 @@ private:
// Pone el juego en pausa // Pone el juego en pausa
void switchPause(); void switchPause();
// Da vidas al jugador cuando está en la Jail
void checkRestoringJail();
// Inicializa el diccionario de las estadísticas
void initStats();
public: public:
// Constructor // Constructor
Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Input *input, Debug *debug); Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Input *input, Debug *debug);

View File

@@ -28,9 +28,9 @@ GameOver::GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, A
iniFade = 310; iniFade = 310;
fadeLenght = 20; fadeLenght = 20;
playerSprite->setPosX(GAMECANVAS_CENTER_X + 10); playerSprite->setPosX(GAMECANVAS_CENTER_X + 10);
playerSprite->setPosY(GAMECANVAS_CENTER_Y + 10); playerSprite->setPosY(30);
tvSprite->setPosX(GAMECANVAS_CENTER_X - tvSprite->getAnimationClip(0, 0).w - 10); tvSprite->setPosX(GAMECANVAS_CENTER_X - tvSprite->getAnimationClip(0, 0).w - 10);
tvSprite->setPosY(GAMECANVAS_CENTER_Y + 10); tvSprite->setPosY(30);
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
@@ -73,12 +73,17 @@ void GameOver::update()
// Actualiza los dos sprites // Actualiza los dos sprites
playerSprite->update(); playerSprite->update();
tvSprite->update(); tvSprite->update();
// Actualiza las notificaciones
screen->updateNotifier();
} }
} }
// Dibuja el final en pantalla // Dibuja el final en pantalla
void GameOver::render() void GameOver::render()
{ {
const int y = 32;
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen->start(); screen->start();
@@ -86,12 +91,22 @@ void GameOver::render()
screen->clean(); screen->clean();
// Escribe el texto de GAME OVER // Escribe el texto de GAME OVER
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y - 20, "G A M E O V E R", 1, color); text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y, "G A M E O V E R", 1, color);
// Dibuja los sprites // Dibuja los sprites
playerSprite->setPosY(y + 30);
tvSprite->setPosY(y + 30);
renderSprites(); renderSprites();
// text->write(0, 0, std::to_string(counter)); // Escribe el texto con las habitaciones y los items
const std::string itemsTxt = std::to_string(options->stats.items / 100) + std::to_string((options->stats.items % 100) / 10) + std::to_string(options->stats.items % 10);
const std::string roomsTxt = std::to_string(options->stats.rooms / 100) + std::to_string((options->stats.rooms % 100) / 10) + std::to_string(options->stats.rooms % 10);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 80, "ITEMS: " + itemsTxt, 1, color);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 90, "ROOMS: " + roomsTxt, 1, color);
// Escribe el texto con "Tu peor pesadilla"
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 110, "YOUR WORST NIGHTMARE IS", 1, color);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 120, options->stats.worstNightmare, 1, color);
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->blit(); screen->blit();
@@ -180,7 +195,7 @@ void GameOver::updateColor()
if (counter < half) if (counter < half)
{ {
//const float step = std::min(std::max(counter, iniFade) - iniFade, fadeLenght) / (float)fadeLenght; // const float step = std::min(std::max(counter, iniFade) - iniFade, fadeLenght) / (float)fadeLenght;
const float step = std::min(counter, fadeLenght) / (float)fadeLenght; const float step = std::min(counter, fadeLenght) / (float)fadeLenght;
const int index = (colors.size() - 1) - int((colors.size() - 1) * step); const int index = (colors.size() - 1) - int((colors.size() - 1) * step);
color = colors.at(index); color = colors.at(index);

View File

@@ -251,6 +251,9 @@ void Intro::update()
// Gestiona el contador de carga // Gestiona el contador de carga
updateLoad(); updateLoad();
// Actualiza las notificaciones
screen->updateNotifier();
// Comprueba si ha terminado la intro // Comprueba si ha terminado la intro
if (loadCounter >= 768) if (loadCounter >= 768)
{ {

View File

@@ -19,9 +19,11 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
sprite2->setSpriteClip(0, 0, texture2->getWidth(), texture2->getHeight()); sprite2->setSpriteClip(0, 0, texture2->getWidth(), texture2->getHeight());
texture2->setColor(0, 0, 0); texture2->setColor(0, 0, 0);
// Crea los sprites de cada linea
for (int i = 0; i < texture->getHeight(); ++i) for (int i = 0; i < texture->getHeight(); ++i)
{ {
sprite.push_back(new Sprite(0, i, texture->getWidth(), 1, texture, renderer)); sprite.push_back(new Sprite(0, i, texture->getWidth(), 1, texture, renderer));
sprite.back()->setSpriteClip(0, i, texture->getWidth(), 1);
if (i % 2 == 0) if (i % 2 == 0)
{ {
sprite.at(i)->setPosX(256 + (i * 3)); sprite.at(i)->setPosX(256 + (i * 3));
@@ -80,12 +82,11 @@ void Logo::checkEventHandler()
} }
// Comprueba las teclas que se han pulsado // Comprueba las teclas que se han pulsado
if ((eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0) || (eventHandler->type == SDL_JOYBUTTONDOWN)) if ((eventHandler->type == SDL_KEYUP && eventHandler->key.repeat == 0) || (eventHandler->type == SDL_JOYBUTTONUP))
{ {
switch (eventHandler->key.keysym.scancode) switch (eventHandler->key.keysym.scancode)
{ {
case SDL_SCANCODE_ESCAPE: case SDL_SCANCODE_ESCAPE:
//std::cout << "PULSADO ESCAPE" << std::endl;
section.name = SECTION_PROG_QUIT; section.name = SECTION_PROG_QUIT;
break; break;
@@ -124,8 +125,8 @@ void Logo::checkEventHandler()
break; break;
default: default:
section.name = SECTION_PROG_TITLE; section.subsection = SUBSECTION_LOGO_TO_TITLE;
section.subsection = 0; endSection();
break; break;
} }
} }
@@ -262,19 +263,13 @@ void Logo::update()
// Gestiona el color de las texturas // Gestiona el color de las texturas
updateTextureColors(); updateTextureColors();
// Actualiza las notificaciones
screen->updateNotifier();
// Comprueba si ha terminado el logo // Comprueba si ha terminado el logo
if (counter == endLogo + postLogo) if (counter == endLogo + postLogo)
{ {
if (section.subsection == SUBSECTION_LOGO_TO_INTRO) endSection();
{
section.name = SECTION_PROG_INTRO;
section.subsection = 0;
}
else
{
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
}
} }
} }
} }
@@ -317,12 +312,11 @@ section_t Logo::run()
// Cambia la paleta // Cambia la paleta
void Logo::switchPalette() void Logo::switchPalette()
{ {
if (options->palette == p_zxspectrum) options->palette = options->palette == p_zxspectrum ? p_zxarne : p_zxspectrum;
{ }
options->palette = p_zxarne;
} // Termina la sección
else void Logo::endSection()
{ {
options->palette = p_zxspectrum; section.name = SECTION_PROG_ENTER_ID;
}
} }

View File

@@ -56,6 +56,9 @@ private:
// Cambia la paleta // Cambia la paleta
void switchPalette(); void switchPalette();
// Termina la sección
void endSection();
public: public:
// Constructor // Constructor
Logo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, int subsection); Logo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, int subsection);

View File

@@ -823,6 +823,8 @@ void Player::setState(state_e value)
{ {
prevState = state; prevState = state;
state = value; state = value;
checkState();
} }
// Comprueba si el jugador esta vivo // Comprueba si el jugador esta vivo

View File

@@ -63,7 +63,9 @@ room_t loadRoomFile(std::string file_path, bool verbose)
room.itemColor2 = "magenta"; room.itemColor2 = "magenta";
room.autoSurfaceDirection = 1; room.autoSurfaceDirection = 1;
const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1); const std::string fileName = file_path.substr(file_path.find_last_of("\\/") + 1);
room.number = fileName.substr(0, fileName.find_last_of("."));
std::string line; std::string line;
std::ifstream file(file_path); std::ifstream file(file_path);
@@ -94,7 +96,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
{ {
if (verbose) if (verbose)
{ {
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; std::cout << "Warning: file " << fileName.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
} }
} }
} while (line != "[/enemy]"); } while (line != "[/enemy]");
@@ -123,7 +125,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
{ {
if (verbose) if (verbose)
{ {
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; std::cout << "Warning: file " << fileName.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
} }
} }
@@ -143,7 +145,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
{ {
if (verbose) if (verbose)
{ {
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; std::cout << "Warning: file " << fileName.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
} }
} }
} }
@@ -152,7 +154,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
// Cierra el fichero // Cierra el fichero
if (verbose) if (verbose)
{ {
std::cout << "Room loaded: " << filename.c_str() << std::endl; std::cout << "Room loaded: " << fileName.c_str() << std::endl;
} }
file.close(); file.close();
} }
@@ -160,7 +162,7 @@ room_t loadRoomFile(std::string file_path, bool verbose)
else else
{ {
{ {
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl; std::cout << "Warning: Unable to open " << fileName.c_str() << " file" << std::endl;
} }
} }
@@ -400,6 +402,7 @@ Room::Room(room_t *room, SDL_Renderer *renderer, Screen *screen, Asset *asset, o
this->debug = debug; this->debug = debug;
this->options = options; this->options = options;
number = room->number;
name = room->name; name = room->name;
bgColor = room->bgColor; bgColor = room->bgColor;
borderColor = room->borderColor; borderColor = room->borderColor;
@@ -824,6 +827,7 @@ bool Room::itemCollision(SDL_Rect &rect)
items.erase(items.begin() + i); items.erase(items.begin() + i);
JA_PlaySound(itemSound); JA_PlaySound(itemSound);
*itemsPicked = *itemsPicked + 1; *itemsPicked = *itemsPicked + 1;
options->stats.items = *itemsPicked;
return true; return true;
} }
} }

View File

@@ -36,6 +36,7 @@ struct aTile_t
struct room_t struct room_t
{ {
std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
std::string bgColor; // Color de fondo de la habitación std::string bgColor; // Color de fondo de la habitación
std::string borderColor; // Color del borde de la pantalla std::string borderColor; // Color del borde de la pantalla
@@ -89,6 +90,7 @@ private:
options_t *options; // Puntero a las opciones del juego options_t *options; // Puntero a las opciones del juego
// Variables // Variables
std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
std::string bgColor; // Color de fondo de la habitación std::string bgColor; // Color de fondo de la habitación
std::string borderColor; // Color del borde de la pantalla std::string borderColor; // Color del borde de la pantalla

View File

@@ -1,31 +1,66 @@
#include "common/jscore.h"
#include "stats.h" #include "stats.h"
#include <iostream> #include <algorithm>
#include <fstream> #include <fstream>
#include <iostream>
#include <sstream> #include <sstream>
// Constructor // Constructor
Stats::Stats(std::string file) Stats::Stats(std::string file, std::string buffer, options_t *options)
{ {
this->options = options;
bufferPath = buffer;
filePath = file; filePath = file;
bufferList.clear();
list.clear(); list.clear();
loadFromFile(); dictionary.clear();
} }
// Destructor // Destructor
Stats::~Stats() Stats::~Stats()
{ {
saveToFile(); // Vuelca los datos del buffer en la lista de estadisticas
updateListFromBuffer();
// Calcula cual es la habitación con más muertes
checkWorstNightmare();
// Guarda las estadísticas
saveToServer();
saveToFile(bufferPath, bufferList);
saveToFile(filePath, list);
bufferList.clear();
list.clear(); list.clear();
dictionary.clear();
}
// Inicializador
// Se debe llamar a este procediiento una vez se haya creado el diccionario numero-nombre
void Stats::init()
{
loadFromFile(bufferPath, bufferList);
loadFromFile(filePath, list);
if (options->online.enabled)
{
loadFromServer();
}
// Vuelca los datos del buffer en la lista de estadisticas
updateListFromBuffer();
} }
// Añade una muerte a las estadisticas // Añade una muerte a las estadisticas
void Stats::addDeath(std::string name) void Stats::addDeath(std::string name)
{ {
// Normaliza el nombre
// std::replace(name.begin(), name.end(), ' ', '_');
// Primero busca si ya hay una entrada con ese nombre // Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name); const int index = findByName(name, bufferList);
if (index != -1) if (index != -1)
{ {
list.at(index).died++; bufferList.at(index).died++;
} }
// En caso contrario crea la entrada // En caso contrario crea la entrada
@@ -35,18 +70,21 @@ void Stats::addDeath(std::string name)
item.name = name; item.name = name;
item.visited = 0; item.visited = 0;
item.died = 1; item.died = 1;
list.push_back(item); bufferList.push_back(item);
} }
} }
// Añade una visita a las estadisticas // Añade una visita a las estadisticas
void Stats::addVisit(std::string name) void Stats::addVisit(std::string name)
{ {
// Normaliza el nombre
// std::replace(name.begin(), name.end(), ' ', '_');
// Primero busca si ya hay una entrada con ese nombre // Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name); const int index = findByName(name, bufferList);
if (index != -1) if (index != -1)
{ {
list.at(index).visited++; bufferList.at(index).visited++;
} }
// En caso contrario crea la entrada // En caso contrario crea la entrada
@@ -56,12 +94,12 @@ void Stats::addVisit(std::string name)
item.name = name; item.name = name;
item.visited = 1; item.visited = 1;
item.died = 0; item.died = 0;
list.push_back(item); bufferList.push_back(item);
} }
} }
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int Stats::findByName(std::string name) int Stats::findByName(std::string name, std::vector<stats_t> &list)
{ {
int i = 0; int i = 0;
@@ -78,8 +116,10 @@ int Stats::findByName(std::string name)
} }
// Carga las estadisticas desde un fichero // Carga las estadisticas desde un fichero
bool Stats::loadFromFile() bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list)
{ {
list.clear();
// Indicador de éxito en la carga // Indicador de éxito en la carga
bool success = true; bool success = true;
@@ -123,20 +163,68 @@ bool Stats::loadFromFile()
// El fichero no existe // El fichero no existe
else else
{ // Crea el fichero con los valores por defecto { // Crea el fichero con los valores por defecto
saveToFile(); saveToFile(filePath, list);
} }
return success; return success;
} }
// Carga las estadisticas desde un servidor
void Stats::loadFromServer()
{
// Limpia los datos del servidor
// eraseServerData();
list.clear();
std::string data;
if (options->online.enabled)
{
data = jscore::getUserData(options->online.gameID, options->online.jailerID);
}
std::stringstream ss(data);
std::string tmp;
int count = 0;
for (int i = 0; i < (int)data.size(); ++i)
{
if (data[i] == ';')
{
count++;
}
}
while (count > 0)
{
stats_t stat;
// Obtiene el nombre
getline(ss, tmp, ';');
stat.name = numberToName(tmp);
// Obtiene las visitas
getline(ss, tmp, ';');
stat.visited = std::stoi(tmp);
// Obtiene las muertes
getline(ss, tmp, ';');
stat.died = std::stoi(tmp);
list.push_back(stat);
count = count - 3;
}
}
// Guarda las estadisticas en un fichero // Guarda las estadisticas en un fichero
void Stats::saveToFile() void Stats::saveToFile(std::string filePath, std::vector<stats_t> &list)
{ {
// Crea y abre el fichero de texto // Crea y abre el fichero de texto
std::ofstream file(filePath); std::ofstream file(filePath);
// Escribe en el fichero // Escribe en el fichero
file << "# NOMBRE DE LA HABITACION;VISITAS;MUERTES" << std::endl; file << "# ROOM NAME;VISITS;DEATHS" << std::endl;
for (auto item : list) for (auto item : list)
{ {
file << item.name << ";" << item.visited << ";" << item.died << std::endl; file << item.name << ";" << item.visited << ";" << item.died << std::endl;
@@ -145,3 +233,103 @@ void Stats::saveToFile()
// Cierra el fichero // Cierra el fichero
file.close(); file.close();
} }
// Guarda las estadisticas en un servidor
void Stats::saveToServer()
{
std::string data = "";
if (options->online.enabled)
{
for (auto item : list)
{
data = data + nameToNumber(item.name) + ";" + std::to_string(item.visited) + ";" + std::to_string(item.died) + ";";
}
jscore::setUserData(options->online.gameID, options->online.jailerID, data);
}
}
// Calcula cual es la habitación con más muertes
void Stats::checkWorstNightmare()
{
int deaths = 0;
for (auto item : list)
{
if (item.died > deaths)
{
deaths = item.died;
options->stats.worstNightmare = item.name;
}
}
}
// Añade una entrada al diccionario
void Stats::addDictionary(std::string number, std::string name)
{
dictionary.push_back({number, name});
}
// Obtiene el nombre de una habitación a partir del número
std::string Stats::numberToName(std::string number)
{
for (auto l : dictionary)
{
if (l.number == number)
{
return l.name;
}
}
return "";
}
// Obtiene el número de una habitación a partir del nombre
std::string Stats::nameToNumber(std::string name)
{
for (auto l : dictionary)
{
if (l.name == name)
{
return l.number;
}
}
return "";
}
// Vuelca los datos del buffer en la lista de estadisticas
void Stats::updateListFromBuffer()
{
// Actualiza list desde bufferList
for (auto buffer : bufferList)
{
int index = findByName(buffer.name, list);
if (index != -1)
{ // Encontrado. Aumenta sus estadisticas
list.at(index).visited += buffer.visited;
list.at(index).died += buffer.died;
}
else
{ // En caso contrario crea la entrada
stats_t item;
item.name = buffer.name;
item.visited = buffer.visited;
item.died = buffer.died;
list.push_back(item);
}
}
// Sube los datos al servidor
if (options->online.enabled)
{
saveToServer();
bufferList.clear();
}
saveToFile(bufferPath, bufferList);
saveToFile(filePath, list);
}
// Limpia los datos del servidor
void Stats::eraseServerData()
{
jscore::setUserData(options->online.gameID, options->online.jailerID, "");
}

View File

@@ -7,41 +7,81 @@
#ifndef STATS_H #ifndef STATS_H
#define STATS_H #define STATS_H
struct stats_t
{
std::string name; // Nombre de la habitación donde se encuentra el objeto
int visited; // Cuenta las veces que se ha visitado una habitación
int died; // Cuenta las veces que se ha muerto en una habitación
};
class Stats class Stats
{ {
private: private:
struct stats_t
{
std::string name; // Nombre de la habitación
int visited; // Cuenta las veces que se ha visitado una habitación
int died; // Cuenta las veces que se ha muerto en una habitación
};
struct stats_dictionary_t
{
std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación
};
// Punteros y objetos
options_t *options;
// Variables // Variables
std::vector<stats_t> list; // Lista con las estadisticas por habitación std::vector<stats_dictionary_t> dictionary; // Lista con la equivalencia nombre-numero de habitacion
std::string filePath; // Fichero con las estadísticas std::vector<stats_t> bufferList; // Lista con las estadisticas temporales por habitación
std::vector<stats_t> list; // Lista con las estadisticas completas por habitación
std::string bufferPath; // Fichero con las estadísticas temporales
std::string filePath; // Fichero con las estadísticas completas
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int findByName(std::string name); int findByName(std::string name, std::vector<stats_t> &list);
// Carga las estadisticas desde un fichero // Carga las estadisticas desde un fichero
bool loadFromFile(); bool loadFromFile(std::string filePath, std::vector<stats_t> &list);
// Carga las estadisticas desde un servidor
void loadFromServer();
// Guarda las estadisticas en un fichero // Guarda las estadisticas en un fichero
void saveToFile(); void saveToFile(std::string filePath, std::vector<stats_t> &list);
// Guarda las estadisticas en un servidor
void saveToServer();
// Calcula cual es la habitación con más muertes
void checkWorstNightmare();
// Obtiene el nombre de una habitación a partir del número
std::string numberToName(std::string number);
// Obtiene el número de una habitación a partir del nombre
std::string nameToNumber(std::string name);
// Vuelca los datos del buffer en la lista de estadisticas
void updateListFromBuffer();
// Limpia los datos del servidor
void eraseServerData();
public: public:
// Constructor // Constructor
Stats(std::string file); Stats(std::string file, std::string buffer, options_t *options);
// Destructor // Destructor
~Stats(); ~Stats();
// Inicializador
// Se debe llamar a este procediiento una vez se haya creado el diccionario numero-nombre
void init();
// Añade una muerte a las estadisticas // Añade una muerte a las estadisticas
void addDeath(std::string name); void addDeath(std::string name);
// Añade una visita a las estadisticas // Añade una visita a las estadisticas
void addVisit(std::string name); void addVisit(std::string name);
// Añade una entrada al diccionario
void addDictionary(std::string number, std::string name);
}; };
#endif #endif

View File

@@ -115,6 +115,12 @@ void Title::checkEventHandler()
switchPalette(); switchPalette();
break; break;
#ifdef DEBUG
case SDL_SCANCODE_F6:
screen->showNotification("MAMA MIRA! SIN MANOS!");
break;
#endif
default: default:
break; break;
} }
@@ -176,6 +182,9 @@ void Title::update()
// Actualiza la marquesina // Actualiza la marquesina
updateMarquee(); updateMarquee();
// Actualiza las notificaciones
screen->updateNotifier();
// Comprueba si ha terminado la marquesina y acaba con el titulo // Comprueba si ha terminado la marquesina y acaba con el titulo
if (letters.at(letters.size() - 1).x < -10) if (letters.at(letters.size() - 1).x < -10)
{ {