12 Commits

Author SHA1 Message Date
4c3c844ccf Fix: En la secuencia del final, al pulsar ESC se cerraba el juego. Ahora vuelve al logo 2022-12-29 15:26:02 +01:00
48b8ae049a Testeados todos los logros. Los logros no funcionan con los trucos activados 2022-12-29 14:59:48 +01:00
c0d4eddde7 Colocados los disparadores de los logros en su sitio 2022-12-29 14:08:42 +01:00
f590101047 Definidos los logros 2022-12-29 13:03:10 +01:00
c7fcbd0258 Añadidos nuevos iconos para las notificaciones. Rediseñada la notificación de login. Arreglado bug: No se podia elegir un icono para las notificaciones que no fuera de la primera fila 2022-12-29 11:58:32 +01:00
b2061c86d2 Cambiado el tamaño de las notificaciones. Posibilidad de añadir un icono 2022-12-29 11:36:44 +01:00
510a6ca718 Añadido bisel a las notificaciones 2022-12-29 11:00:26 +01:00
ec8209265a Añadidos iconos a las notificaciones 2022-12-29 10:19:11 +01:00
e963251fd9 Modificadas las notificaciones a dos lineas de texto 2022-12-29 09:42:57 +01:00
a2f1efd2a6 Empezando a trabajar con los logros 2022-12-29 09:09:36 +01:00
8959b7bcce Arreglado el cambio de paleta durante la pantalla de carga optimizada 2022-12-16 11:15:13 +01:00
4d8bb46a52 Cambiada la variable section por un puntero 2022-12-16 09:32:33 +01:00
35 changed files with 621 additions and 268 deletions

View File

@@ -2,7 +2,7 @@ executable = jaildoctors_dilemma
source = source/*.cpp source/common/*.cpp
appName = JailDoctor's Dilemma
releaseFolder = jdd_release
version = v1.07
version = v1.08
# Release names
windowsRelease = $(executable)-$(version)-win32-x64.zip

View File

@@ -1,4 +1,4 @@
# JailDoctor's Dilemma (v1.07)
# JailDoctor's Dilemma (v1.08)
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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

View File

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

View File

@@ -1,13 +1,150 @@
#include "cheevos.h"
// Constructor
Cheevos::Cheevos(options_t *options)
Cheevos::Cheevos(Screen *screen, options_t *options)
{
// Copia la dirección de los objetos
this->options = options;
this->screen = screen;
// Inicializa los logros
init();
// inicializa variables
enabled = true;
}
// Destructor
Cheevos::~Cheevos()
{
cheevos.clear();
}
// Inicializa los logros
void Cheevos::init()
{
cheevos_t c;
c.completed = false;
c.valid = true;
c.icon = 2;
c.id = 1;
c.caption = "SHINY THINGS";
c.description = "Get 25\% of the items";
cheevos.push_back(c);
c.id = 2;
c.caption = "HALF THE WORK";
c.description = "Get 50\% of the items";
cheevos.push_back(c);
c.id = 3;
c.caption = "GETTING THERE";
c.description = "Get 75\% of the items";
cheevos.push_back(c);
c.id = 4;
c.caption = "THE COLLECTOR";
c.description = "Get 100\% of the items";
cheevos.push_back(c);
c.id = 5;
c.caption = "WANDERING AROUND";
c.description = "Visit 20 rooms";
cheevos.push_back(c);
c.id = 6;
c.caption = "I GOT LOST";
c.description = "Visit 40 rooms";
cheevos.push_back(c);
c.id = 7;
c.caption = "I LIKE TO EXPLORE";
c.description = "Visit all rooms";
cheevos.push_back(c);
c.id = 8;
c.caption = "FINISH THE GAME";
c.description = "Complete the game";
cheevos.push_back(c);
c.id = 9;
c.caption = "I WAS SUCKED BY A HOLE";
c.description = "Complete the game without entering the jail";
cheevos.push_back(c);
c.id = 10;
c.caption = "MY LITTLE PROJECTS";
c.description = "Complete the game with all items";
cheevos.push_back(c);
c.id = 11;
c.caption = "I LIKE MY MULTICOLOURED FRIENDS";
c.description = "Complete the game without dying";
cheevos.push_back(c);
c.id = 12;
c.caption = "SHIT PROJECTS DONE FAST";
c.description = "Complete the game in under 30 minutes";
cheevos.push_back(c);
}
// Busca un logro por id y devuelve el indice
int Cheevos::find(int id)
{
for (int i = 0; i < (int)cheevos.size(); ++i)
{
if (cheevos[i].id == id)
{
return i;
}
}
return -1;
}
// Desbloquea un logro
void Cheevos::unlock(int id)
{
const int index = find(id);
if (index == -1)
{
return;
}
if (!cheevos[index].valid)
{
return;
}
if (cheevos[index].completed)
{
return;
}
if (!enabled)
{
return;
}
cheevos[index].completed = true;
screen->showNotification("ACHIEVEMENT UNLOCKED!", cheevos[index].caption, cheevos[index].icon);
}
// Invalida un logro
void Cheevos::invalidate(int id)
{
const int index = find(id);
if (index == -1)
{
return;
}
cheevos[index].valid = false;
}
// Habilita o deshabilita los logros
void Cheevos::enable(bool value)
{
enabled = value;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include <SDL2/SDL.h>
#include "common/screen.h"
#include "common/utils.h"
#include <string>
#include <vector>
@@ -7,21 +8,48 @@
#ifndef CHEEVOS_H
#define CHEEVOS_H
struct cheevos_t
{
int id; // Identificador del logro
std::string caption; // Texto con el nombre del logro
std::string description; // Texto que describe el logro
int icon; // Indice del icono a utilizar en la notificación
bool completed; // Indica si se ha obtenido el logro
bool valid; // Indica si se puede obtener el logro
};
class Cheevos
{
private:
// Punteros y objetos
options_t *options;
Screen *screen; // Objeto encargado de dibujar en pantalla
options_t *options; // Puntero a las opciones del juego
// Variables
std::vector<cheevos_t> cheevos; // Listado de logros
bool enabled; // Indica si los logros se pueden obtener
// Inicializa los logros
void init();
// Busca un logro por id y devuelve el indice
int find(int id);
public:
// Constructor
Cheevos(options_t *options);
Cheevos(Screen *screen, options_t *options);
// Destructor
~Cheevos();
// Desbloquea un logro
void unlock(int id);
// Invalida un logro
void invalidate(int id);
// Habilita o deshabilita los logros
void enable(bool value);
};
#endif

View File

@@ -4,7 +4,7 @@
#include <iostream>
// Constructor
Notify::Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile, std::string soundFile, options_t *options)
Notify::Notify(SDL_Renderer *renderer, std::string iconFile, std::string bitmapFile, std::string textFile, std::string soundFile, options_t *options)
{
// Inicializa variables
this->renderer = renderer;
@@ -13,8 +13,9 @@ Notify::Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textF
waitTime = 300;
// Crea objetos
texture = new Texture(renderer, bitmapFile);
text = new Text(textFile, texture, renderer);
iconTexture = new Texture(renderer, iconFile);
textTexture = new Texture(renderer, bitmapFile);
text = new Text(textFile, textTexture, renderer);
sound = JA_LoadSound(soundFile.c_str());
}
@@ -22,7 +23,8 @@ Notify::Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textF
Notify::~Notify()
{
// Libera la memoria de los objetos
delete texture;
delete textTexture;
delete iconTexture;
delete text;
JA_DeleteSound(sound);
@@ -124,12 +126,15 @@ void Notify::clearFinishedNotifications()
}
// Muestra una notificación de texto por pantalla;
void Notify::showText(std::string text)
void Notify::showText(std::string text1, std::string text2, int icon)
{
// 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);
const int iconSize = 16;
const int padding = text->getCharacterSize();
const int iconSpace = icon >= 0 ? iconSize + padding : 0;
const std::string txt = text1.length() > text2.length() ? text1 : text2;
const int width = text->lenght(txt) + (padding * 2) + iconSpace;
const int height = (text->getCharacterSize() * 2) + (padding * 2);
// Posición horizontal
int despH = 0;
@@ -178,7 +183,8 @@ void Notify::showText(std::string text)
n.travelDist = travelDist;
n.counter = 0;
n.state = ns_rising;
n.text = text;
n.text1 = text1;
n.text2 = text2;
if (options->notifications.posV == pos_top)
{
n.rect = {despH, offset - travelDist, width, height};
@@ -191,14 +197,52 @@ void Notify::showText(std::string text)
// 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});
// Prepara para dibujar en la textura
n.texture->setAsRenderTarget(renderer);
// Dibuja el fondo de la notificación
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_Rect rect;
rect = {4, 0, width - (4 * 2), height};
SDL_RenderFillRect(renderer, &rect);
rect = {4 / 2, 1, width - 4, height - 2};
SDL_RenderFillRect(renderer, &rect);
rect = {1, 4 / 2, width - 2, height - 4};
SDL_RenderFillRect(renderer, &rect);
rect = {0, 4, width, height - (4 * 2)};
SDL_RenderFillRect(renderer, &rect);
// Dibuja el icono de la notificación
if (icon >= 0)
{
Sprite *sp = new Sprite({0, 0, iconSize, iconSize}, iconTexture, renderer);
sp->setPos({padding, padding, iconSize, iconSize});
sp->setSpriteClip({iconSize * (icon % 10), iconSize * (icon / 10), iconSize, iconSize});
sp->render();
delete sp;
}
// Escribe el texto de la notificación
color_t color = {255, 255, 255};
if (text2 != "")
{ // Dos lineas de texto
text->writeColored(padding + iconSpace, padding, text1, color);
text->writeColored(padding + iconSpace, padding + text->getCharacterSize() + 1, text2, color);
}
else
{ // Una linea de texto
text->writeColored(padding + iconSpace, (height / 2) - (text->getCharacterSize() / 2), text1, color);
}
// Deja de dibujar en la textura
SDL_SetRenderTarget(renderer, nullptr);
// Crea el sprite
// Crea el sprite de la notificación
n.sprite = new Sprite(n.rect, n.texture, renderer);
// Añade la notificación a la lista

View File

@@ -36,7 +36,8 @@ private:
struct notification_t
{
std::string text;
std::string text1;
std::string text2;
int counter;
notification_state_e state;
notification_position_e position;
@@ -49,7 +50,8 @@ private:
// Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana
Texture *texture; // Textura para la fuente de las notificaciones
Texture *textTexture; // Textura para la fuente de las notificaciones
Texture *iconTexture; // Textura para los iconos de las notificaciones
Text *text; // Objeto para dibujar texto
options_t *options; // Variable con todas las opciones del programa
@@ -57,7 +59,7 @@ private:
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_t* sound; // Sonido a reproducir cuando suena la notificación
JA_Sound_t *sound; // Sonido a reproducir cuando suena la notificación
// Elimina las notificaciones finalizadas
void clearFinishedNotifications();
@@ -70,13 +72,13 @@ public:
void update();
// Constructor
Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile, std::string soundFile, options_t *options);
Notify(SDL_Renderer *renderer, std::string iconFile, 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);
void showText(std::string text1 = "", std::string text2 = "", int icon = -1);
// Indica si hay notificaciones activas
bool active();

View File

@@ -12,7 +12,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options
this->asset = asset;
// Crea los objetos
notify = new Notify(renderer, asset->get("smb2.png"), asset->get("smb2.txt"), asset->get("notify.wav"), options);
notify = new Notify(renderer, asset->get("notify.png"), asset->get("smb2.png"), asset->get("smb2.txt"), asset->get("notify.wav"), options);
gameCanvasWidth = options->gameWidth;
gameCanvasHeight = options->gameHeight;
@@ -370,9 +370,9 @@ void Screen::updateNotifier()
}
// Muestra una notificación de texto por pantalla;
void Screen::showNotification(std::string text)
void Screen::showNotification(std::string text1, std::string text2, int icon)
{
notify->showText(text);
notify->showText(text1, text2, icon);
}
// Dibuja las notificaciones
@@ -383,9 +383,9 @@ void Screen::renderNotifications()
return;
}
//SDL_RenderSetLogicalSize(renderer, notificationLogicalWidth, notificationLogicalHeight);
SDL_RenderSetLogicalSize(renderer, notificationLogicalWidth, notificationLogicalHeight);
notify->render();
//SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
SDL_RenderSetLogicalSize(renderer, windowWidth, windowHeight);
}
// Establece el tamaño de las notificaciones

View File

@@ -132,7 +132,7 @@ public:
void updateNotifier();
// Muestra una notificación de texto por pantalla;
void showNotification(std::string text);
void showNotification(std::string text1 = "", std::string text2 = "", int icon = -1);
};
#endif

View File

@@ -2,7 +2,7 @@
#include <iostream>
// Constructor
Credits::Credits(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options)
Credits::Credits(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section)
{
// Copia la dirección de los objetos
this->resource = resource;
@@ -10,6 +10,7 @@ Credits::Credits(SDL_Renderer *renderer, Screen *screen, Resource *resource, Ass
this->screen = screen;
this->asset = asset;
this->options = options;
this->section = section;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
@@ -20,8 +21,8 @@ Credits::Credits(SDL_Renderer *renderer, Screen *screen, Resource *resource, Ass
counter = 0;
counterEnabled = true;
subCounter = 0;
section.name = SECTION_PROG_CREDITS;
section.subsection = 0;
section->name = SECTION_PROG_CREDITS;
section->subsection = 0;
ticks = 0;
ticksSpeed = 15;
sprite->setRect({194, 174, 8, 8});
@@ -74,7 +75,7 @@ void Credits::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
}
@@ -84,7 +85,7 @@ void Credits::checkEventHandler()
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
case SDL_SCANCODE_B:
@@ -122,8 +123,8 @@ void Credits::checkEventHandler()
break;
default:
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
section->name = SECTION_PROG_TITLE;
section->subsection = 0;
break;
}
}
@@ -259,7 +260,7 @@ void Credits::updateCounter()
// Comprueba si ha terminado la sección
if (counter > 1200)
{
section.name = SECTION_PROG_DEMO;
section->name = SECTION_PROG_DEMO;
}
}
@@ -318,15 +319,13 @@ void Credits::render()
}
// Bucle para el logo del juego
section_t Credits::run()
void Credits::run()
{
while (section.name == SECTION_PROG_CREDITS)
while (section->name == SECTION_PROG_CREDITS)
{
update();
render();
}
return section;
}
// Cambia la paleta

View File

@@ -36,12 +36,12 @@ private:
SDL_Texture *coverTexture; // Textura para cubrir el texto
AnimatedSprite *sprite; // Sprite para el brillo del corazón
options_t *options; // Puntero a las opciones del juego
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables
int counter; // Contador
bool counterEnabled; // Indica si esta activo el contador
int subCounter; // Contador secundario
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
@@ -69,13 +69,13 @@ private:
public:
// Constructor
Credits(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options);
Credits(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section);
// Destructor
~Credits();
// Bucle principal
section_t run();
void run();
};
#endif

View File

@@ -1,7 +1,7 @@
#include "demo.h"
// Constructor
Demo::Demo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Debug *debug)
Demo::Demo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section, Debug *debug)
{
// Inicia algunas variables
board.iniClock = SDL_GetTicks();
@@ -24,6 +24,7 @@ Demo::Demo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
this->screen = screen;
this->debug = debug;
this->options = options;
this->section = section;
// Crea los objetos
itemTracker = new ItemTracker();
@@ -44,8 +45,8 @@ Demo::Demo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
board.music = true;
setScoreBoardColor();
section.name = SECTION_PROG_DEMO;
section.subsection = 0;
section->name = SECTION_PROG_DEMO;
section->subsection = 0;
}
Demo::~Demo()
@@ -67,7 +68,7 @@ void Demo::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
screen->setBorderColor(stringToColor(options->palette, "black"));
break;
}
@@ -78,7 +79,7 @@ void Demo::checkEventHandler()
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
case SDL_SCANCODE_B:
@@ -116,8 +117,8 @@ void Demo::checkEventHandler()
break;
default:
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
section->name = SECTION_PROG_TITLE;
section->subsection = 0;
break;
}
}
@@ -125,15 +126,13 @@ void Demo::checkEventHandler()
}
// Bucle para el juego
section_t Demo::run()
void Demo::run()
{
while (section.name == SECTION_PROG_DEMO)
while (section->name == SECTION_PROG_DEMO)
{
update();
render();
}
return section;
}
// Actualiza el juego, las variables, comprueba la entrada, etc.
@@ -255,8 +254,8 @@ void Demo::checkRoomChange()
roomIndex++;
if (roomIndex == (int)rooms.size())
{
section.name = SECTION_PROG_LOGO;
section.subsection = SUBSECTION_LOGO_TO_TITLE;
section->name = SECTION_PROG_LOGO;
section->subsection = SUBSECTION_LOGO_TO_TITLE;
}
else
{

View File

@@ -34,11 +34,11 @@ private:
ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
Debug *debug; // Objeto para gestionar la información de debug
options_t *options; // Puntero a las opciones del juego
section_t *section; // Seccion actual dentro del juego
// Variables
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
section_t section; // Seccion actual dentro del juego
std::string currentRoom; // Fichero de la habitación actual
board_t board; // Estructura con los datos del marcador
int counter; // Contador para el modo demo
@@ -75,13 +75,13 @@ private:
public:
// Constructor
Demo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Debug *debug);
Demo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section, Debug *debug);
// Destructor
~Demo();
// Bucle para el juego
section_t run();
void run();
};
#endif

View File

@@ -14,11 +14,12 @@
// Constructor
Director::Director(int argc, char *argv[])
{
section.name = SECTION_PROG_LOGO;
section.subsection = SUBSECTION_LOGO_TO_INTRO;
section = new section_t();
section->name = SECTION_PROG_LOGO;
section->subsection = SUBSECTION_LOGO_TO_INTRO;
#ifdef DEBUG
section.name = SECTION_PROG_LOGO;
section->name = SECTION_PROG_GAME;
#endif
// Crea e inicializa las opciones del programa
@@ -65,6 +66,7 @@ Director::~Director()
saveConfig();
// Libera la memoria
delete section;
delete options;
delete asset;
delete input;
@@ -158,7 +160,7 @@ void Director::initOptions()
options->notifications.posV = pos_top;
options->notifications.posH = pos_left;
options->notifications.sound = true;
options->notifications.color = {64, 64, 64};
options->notifications.color = {48, 48, 48};
}
// Comprueba los parametros del programa
@@ -463,14 +465,14 @@ void Director::createSystemFolder()
}
// Carga los recursos
void Director::loadResources(section_t section)
void Director::loadResources(section_t *section)
{
if (options->console)
{
std::cout << "** LOAD RESOURCES" << std::endl;
}
if (section.name == SECTION_PROG_LOGO)
if (section->name == SECTION_PROG_LOGO)
{
std::vector<std::string> textureList;
textureList.push_back("jailgames.png");
@@ -479,7 +481,7 @@ void Director::loadResources(section_t section)
resource->loadTextures(textureList);
}
else if (section.name == SECTION_PROG_INTRO)
else if (section->name == SECTION_PROG_INTRO)
{
std::vector<std::string> textureList;
textureList.push_back("loading_screen_bn.png");
@@ -490,7 +492,7 @@ void Director::loadResources(section_t section)
resource->loadTextures(textureList);
}
else if (section.name == SECTION_PROG_TITLE)
else if (section->name == SECTION_PROG_TITLE)
{
std::vector<std::string> textureList;
textureList.push_back("loading_screen_color.png");
@@ -506,7 +508,7 @@ void Director::loadResources(section_t section)
resource->loadOffsets(offsetsList);
}
else if (section.name == SECTION_PROG_CREDITS)
else if (section->name == SECTION_PROG_CREDITS)
{
// Texturas
std::vector<std::string> textureList;
@@ -528,7 +530,7 @@ void Director::loadResources(section_t section)
resource->loadOffsets(offsetsList);
}
else if (section.name == SECTION_PROG_ENDING)
else if (section->name == SECTION_PROG_ENDING)
{
// Texturas
std::vector<std::string> textureList;
@@ -553,7 +555,7 @@ void Director::loadResources(section_t section)
resource->loadOffsets(offsetsList);
}
else if (section.name == SECTION_PROG_ENDING2)
else if (section->name == SECTION_PROG_ENDING2)
{
// Texturas
std::vector<std::string> textureList;
@@ -691,7 +693,7 @@ void Director::loadResources(section_t section)
resource->loadOffsets(offsetsList);
}
else if (section.name == SECTION_PROG_GAME_OVER)
else if (section->name == SECTION_PROG_GAME_OVER)
{
// Texturas
std::vector<std::string> textureList;
@@ -715,7 +717,7 @@ void Director::loadResources(section_t section)
resource->loadOffsets(offsetsList);
}
else if (section.name == SECTION_PROG_GAME || section.name == SECTION_PROG_DEMO)
else if (section->name == SECTION_PROG_GAME || section->name == SECTION_PROG_DEMO)
{
// Texturas
std::vector<std::string> textureList;
@@ -1363,6 +1365,9 @@ bool Director::setFileList()
asset->add(systemFolder + "/stats_buffer.csv", t_data, false, true);
asset->add(systemFolder + "/stats.csv", t_data, false, true);
// Notificaciones
asset->add(prefix + "/data/notifications/notify.png", t_bitmap);
// Habitaciones
asset->add(prefix + "/data/room/01.room", t_room);
asset->add(prefix + "/data/room/02.room", t_room);
@@ -1686,24 +1691,6 @@ bool Director::setFileList()
return asset->check();
}
// Obtiene el valor de la variable
Uint8 Director::getSubsection()
{
return section.subsection;
}
// Obtiene el valor de la variable
Uint8 Director::getSection()
{
return section.name;
}
// Establece el valor de la variable
void Director::setSection(section_t section)
{
this->section = section;
}
// Ejecuta la seccion de juego con el logo
void Director::runLogo()
{
@@ -1712,8 +1699,8 @@ void Director::runLogo()
std::cout << "\n* SECTION: LOGO" << std::endl;
}
loadResources(section);
logo = new Logo(renderer, screen, resource, asset, options, section.subsection);
setSection(logo->run());
logo = new Logo(renderer, screen, resource, asset, options, section);
logo->run();
delete logo;
resource->free();
}
@@ -1726,8 +1713,8 @@ void Director::runIntro()
std::cout << "\n* SECTION: INTRO" << std::endl;
}
loadResources(section);
intro = new Intro(renderer, screen, resource, asset, options);
setSection(intro->run());
intro = new Intro(renderer, screen, resource, asset, options, section);
intro->run();
delete intro;
resource->free();
}
@@ -1744,8 +1731,8 @@ void Director::runTitle()
JA_PlayMusic(music);
}
loadResources(section);
title = new Title(renderer, screen, resource, asset, options);
setSection(title->run());
title = new Title(renderer, screen, resource, asset, options, section);
title->run();
delete title;
resource->free();
}
@@ -1758,8 +1745,8 @@ void Director::runCredits()
std::cout << "\n* SECTION: CREDITS" << std::endl;
}
loadResources(section);
credits = new Credits(renderer, screen, resource, asset, options);
setSection(credits->run());
credits = new Credits(renderer, screen, resource, asset, options, section);
credits->run();
delete credits;
resource->free();
}
@@ -1772,8 +1759,8 @@ void Director::runDemo()
std::cout << "\n* SECTION: DEMO" << std::endl;
}
loadResources(section);
demo = new Demo(renderer, screen, resource, asset, options, debug);
setSection(demo->run());
demo = new Demo(renderer, screen, resource, asset, options, section, debug);
demo->run();
delete demo;
resource->free();
}
@@ -1787,7 +1774,7 @@ void Director::runEnterID()
}
// loadResources(section);
enterID = new EnterID(renderer, screen, asset, options, section);
setSection(enterID->run());
enterID->run();
delete enterID;
resource->free();
}
@@ -1800,8 +1787,8 @@ void Director::runEnding()
std::cout << "\n* SECTION: ENDING" << std::endl;
}
loadResources(section);
ending = new Ending(renderer, screen, resource, asset, options);
setSection(ending->run());
ending = new Ending(renderer, screen, resource, asset, options, section);
ending->run();
delete ending;
resource->free();
}
@@ -1814,8 +1801,8 @@ void Director::runEnding2()
std::cout << "\n* SECTION: ENDING2" << std::endl;
}
loadResources(section);
ending2 = new Ending2(renderer, screen, resource, asset, options);
setSection(ending2->run());
ending2 = new Ending2(renderer, screen, resource, asset, options, section);
ending2->run();
delete ending2;
resource->free();
}
@@ -1828,8 +1815,8 @@ void Director::runGameOver()
std::cout << "\n* SECTION: GAME OVER" << std::endl;
}
loadResources(section);
gameOver = new GameOver(renderer, screen, resource, asset, options);
setSection(gameOver->run());
gameOver = new GameOver(renderer, screen, resource, asset, options, section);
gameOver->run();
delete gameOver;
resource->free();
}
@@ -1843,8 +1830,8 @@ void Director::runGame()
}
JA_StopMusic();
loadResources(section);
game = new Game(renderer, screen, resource, asset, options, input, debug);
setSection(game->run());
game = new Game(renderer, screen, resource, asset, options, input, section, debug);
game->run();
delete game;
resource->free();
}
@@ -1852,9 +1839,9 @@ void Director::runGame()
void Director::run()
{
// Bucle principal
while (getSection() != SECTION_PROG_QUIT)
while (section->name != SECTION_PROG_QUIT)
{
switch (getSection())
switch (section->name)
{
case SECTION_PROG_LOGO:
runLogo();

View File

@@ -46,10 +46,10 @@ private:
GameOver *gameOver; // Objeto para gestionar el final de la partida
Debug *debug; // Objeto para getsionar la información de debug
struct options_t *options; // Variable con todas las opciones del programa
section_t *section; // Sección y subsección actual del programa;
// Variables
section_t section; // Sección y subsección actual del programa;
JA_Music_t* music; // Musica del titulo
JA_Music_t *music; // Musica del titulo
std::string executablePath; // Path del ejecutable
std::string systemFolder; // Carpeta del sistema donde guardar datos
@@ -72,7 +72,7 @@ private:
void createSystemFolder();
// Carga los recursos
void loadResources(section_t section);
void loadResources(section_t *section);
// Asigna variables a partir de dos cadenas
bool setOptions(options_t *options, std::string var, std::string value);
@@ -89,15 +89,6 @@ private:
// Crea el indice de ficheros
bool setFileList();
// Obtiene el valor de la variable
Uint8 getSubsection();
// Obtiene el valor de la variable
Uint8 getSection();
// Establece el valor de la variable
void setSection(section_t section);
// Ejecuta la seccion de juego con el logo
void runLogo();

View File

@@ -1,7 +1,7 @@
#include "ending.h"
// Constructor
Ending::Ending(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options)
Ending::Ending(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section)
{
// Copia los punteros
this->renderer = renderer;
@@ -9,6 +9,7 @@ Ending::Ending(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset
this->resource = resource;
this->asset = asset;
this->options = options;
this->section = section;
// Reserva memoria para los punteros a objetos
eventHandler = new SDL_Event();
@@ -19,8 +20,8 @@ Ending::Ending(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset
counter = -1;
preCounter = 0;
coverCounter = 0;
section.name = SECTION_PROG_ENDING;
section.subsection = 0;
section->name = SECTION_PROG_ENDING;
section->subsection = 0;
ticks = 0;
ticksSpeed = 15;
scene = 0;
@@ -150,7 +151,7 @@ void Ending::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
}
@@ -160,7 +161,8 @@ void Ending::checkEventHandler()
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_LOGO;
section->subsection = SUBSECTION_LOGO_TO_INTRO;
break;
case SDL_SCANCODE_B:
@@ -482,11 +484,11 @@ void Ending::iniScenes()
}
// Bucle principal
section_t Ending::run()
void Ending::run()
{
JA_PlayMusic(music);
while (section.name == SECTION_PROG_ENDING)
while (section->name == SECTION_PROG_ENDING)
{
update();
render();
@@ -494,8 +496,6 @@ section_t Ending::run()
JA_StopMusic();
JA_SetVolume(128);
return section;
}
// Actualiza los contadores
@@ -571,7 +571,7 @@ void Ending::checkChangeScene()
if (scene == 5)
{
// Termina el bucle
section.name = SECTION_PROG_ENDING2;
section->name = SECTION_PROG_ENDING2;
// Mantiene los valores anteriores
scene = 4;

View File

@@ -58,19 +58,19 @@ private:
SDL_Event *eventHandler; // Manejador de eventos
Text *text; // Objeto para escribir texto en pantalla
SDL_Texture *coverTexture; // Textura para cubrir el texto
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables
int counter; // Contador
int preCounter; // Contador previo
int coverCounter; // Contador para la cortinilla
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<endingTexture_t> spriteTexts; // Vector con los sprites de texto con su cortinilla
std::vector<endingTexture_t> spritePics; // Vector con los sprites de texto con su cortinilla
int scene; // Escena actual
std::vector<scene_t> scenes; // Vector con los textos e imagenes de cada escena
JA_Music_t* music; // Musica que suena durante el final
JA_Music_t *music; // Musica que suena durante el final
// Actualiza el objeto
void update();
@@ -113,13 +113,13 @@ private:
public:
// Constructor
Ending(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options);
Ending(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section);
// Destructor
~Ending();
// Bucle principal
section_t run();
void run();
};
#endif

View File

@@ -2,7 +2,7 @@
#include <algorithm>
// Constructor
Ending2::Ending2(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options)
Ending2::Ending2(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section)
{
// Copia los punteros
this->renderer = renderer;
@@ -10,6 +10,7 @@ Ending2::Ending2(SDL_Renderer *renderer, Screen *screen, Resource *resource, Ass
this->resource = resource;
this->asset = asset;
this->options = options;
this->section = section;
// Reserva memoria para los punteros a objetos
eventHandler = new SDL_Event();
@@ -21,8 +22,8 @@ Ending2::Ending2(SDL_Renderer *renderer, Screen *screen, Resource *resource, Ass
preCounter = 0;
postCounter = 0;
postCounterEnabled = false;
section.name = SECTION_PROG_ENDING2;
section.subsection = 0;
section->name = SECTION_PROG_ENDING2;
section->subsection = 0;
ticks = 0;
ticksSpeed = 15;
distSpriteText = 8;
@@ -184,7 +185,7 @@ void Ending2::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
}
@@ -194,7 +195,8 @@ void Ending2::checkEventHandler()
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_LOGO;
section->subsection = SUBSECTION_LOGO_TO_INTRO;
break;
case SDL_SCANCODE_B:
@@ -239,11 +241,11 @@ void Ending2::checkEventHandler()
}
// Bucle principal
section_t Ending2::run()
void Ending2::run()
{
JA_PlayMusic(music);
while (section.name == SECTION_PROG_ENDING2)
while (section->name == SECTION_PROG_ENDING2)
{
update();
render();
@@ -251,8 +253,6 @@ section_t Ending2::run()
JA_StopMusic();
JA_SetVolume(128);
return section;
}
// Actualiza los contadores
@@ -275,8 +275,8 @@ void Ending2::updateCounters()
if (postCounter > 600)
{
section.name = SECTION_PROG_LOGO;
section.subsection = SUBSECTION_LOGO_TO_INTRO;
section->name = SECTION_PROG_LOGO;
section->subsection = SUBSECTION_LOGO_TO_INTRO;
}
}

View File

@@ -30,16 +30,16 @@ private:
std::vector<AnimatedSprite *> sprites; // Vector con todos los sprites a dibujar
std::vector<MovingSprite *> spriteTexts; // Vector con los sprites de texto de los sprites
std::vector<MovingSprite *> texts; // Vector con los sprites de texto
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables
bool counterEnabled; // Indica si está el contador habilitado
int preCounter; // Contador previo
int postCounter; // Contador posterior
bool postCounterEnabled; // Indica si está habilitado el contador
section_t section; // Estado del bucle principal para saber si continua o se sale
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
JA_Music_t* music; // Musica que suena durante el final
JA_Music_t *music; // Musica que suena durante el final
std::vector<std::string> spriteList; // Lista con todos los sprites a dibujar
std::vector<color_t> colors; // Vector con los colores para el fade
int maxSpriteWidth; // El valor de ancho del sprite mas ancho
@@ -115,13 +115,13 @@ private:
public:
// Constructor
Ending2(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options);
Ending2(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section);
// Destructor
~Ending2();
// Bucle principal
section_t run();
void run();
};
#endif

View File

@@ -5,13 +5,14 @@
#include <iostream>
// Constructor
EnterID::EnterID(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, section_t section)
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;
this->section = section;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
@@ -36,11 +37,10 @@ EnterID::EnterID(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t
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;
this->section->name = SECTION_PROG_ENTER_ID;
}
else
{
@@ -60,18 +60,16 @@ EnterID::~EnterID()
}
// Bucle para el logo del juego
section_t EnterID::run()
void EnterID::run()
{
// Detiene la música
JA_StopMusic();
while (section.name == SECTION_PROG_ENTER_ID)
while (section->name == SECTION_PROG_ENTER_ID)
{
update();
render();
}
return section;
}
// Comprueba el manejador de eventos
@@ -83,7 +81,7 @@ void EnterID::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
}
@@ -138,7 +136,7 @@ void EnterID::checkEventHandler()
else if (eventHandler->key.keysym.scancode == SDL_SCANCODE_ESCAPE)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
}
@@ -298,11 +296,11 @@ void EnterID::initOnline()
jscore::init(options->online.server, options->online.port);
#ifdef DEBUG
const std::string caption = options->online.jailerID + " IS LOGGED IN (DEBUG)";
const std::string caption = "IS LOGGED IN (DEBUG)";
#else
const std::string caption = options->online.jailerID + " IS LOGGED IN";
const std::string caption = "IS LOGGED IN";
#endif
screen->showNotification(caption);
screen->showNotification(options->online.jailerID, caption, 11);
if (options->console)
{
std::cout << caption << std::endl;
@@ -314,6 +312,6 @@ void EnterID::initOnline()
void EnterID::endSection()
{
initOnline();
section.name = (section.subsection == SUBSECTION_LOGO_TO_INTRO) ? SECTION_PROG_INTRO : SECTION_PROG_TITLE;
section.subsection = 0;
section->name = (section->subsection == SUBSECTION_LOGO_TO_INTRO) ? SECTION_PROG_INTRO : SECTION_PROG_TITLE;
section->subsection = 0;
}

View File

@@ -29,10 +29,10 @@ private:
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
section_t *section; // Estado del bucle principal para saber si continua o se sale
// 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
@@ -68,13 +68,13 @@ private:
public:
// Constructor
EnterID(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, section_t section);
EnterID(SDL_Renderer *renderer, Screen *screen, Asset *asset, options_t *options, section_t *section);
// Destructor
~EnterID();
// Bucle principal
section_t run();
void run();
};
#endif

View File

@@ -2,15 +2,8 @@
#include <iostream>
// Constructor
Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Input *input, Debug *debug)
Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, Input *input, section_t *section, Debug *debug)
{
// Inicia algunas variables
board.iniClock = SDL_GetTicks();
currentRoom = "03.room";
const int x = 25;
const int y = 13;
spawnPoint = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
// Copia los punteros
this->resource = resource;
this->renderer = renderer;
@@ -19,15 +12,24 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
this->input = input;
this->debug = debug;
this->options = options;
this->section = section;
// Inicia algunas variables
board.iniClock = SDL_GetTicks();
#ifdef DEBUG
currentRoom = "01.room";
const int x1 = 25;
const int y1 = 13;
spawnPoint = {x1 * 8, y1 * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
currentRoom = "03.room";
const int x = 25;
const int y = 13;
spawnPoint = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
#else
currentRoom = "03.room";
const int x = 25;
const int y = 13;
spawnPoint = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
#endif
// Crea los objetos
cheevos = new Cheevos(screen, options);
scoreboard = new ScoreBoard(renderer, resource, asset, options, &board);
itemTracker = new ItemTracker();
roomTracker = new RoomTracker();
@@ -80,14 +82,17 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
totalItems = getTotalItems();
initStats();
stats->addVisit(room->getName());
const bool cheats = options->cheat.infiniteLives || options->cheat.invincible || options->cheat.jailEnabled;
cheevos->enable(!cheats); // Deshabilita los logros si hay trucos activados
section.name = SECTION_PROG_GAME;
section.subsection = 0;
section->name = SECTION_PROG_GAME;
section->subsection = 0;
}
Game::~Game()
{
// Libera la memoria de los objetos
delete cheevos;
delete scoreboard;
delete itemTracker;
delete roomTracker;
@@ -112,7 +117,7 @@ void Game::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
screen->setBorderColor(stringToColor(options->palette, "black"));
break;
}
@@ -122,12 +127,12 @@ void Game::checkEventHandler()
reLoadTextures();
}
if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
if (eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0)
{
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_TITLE;
section->name = SECTION_PROG_TITLE;
break;
#ifdef DEBUG
case SDL_SCANCODE_G:
@@ -158,7 +163,19 @@ void Game::checkEventHandler()
break;
case SDL_SCANCODE_F6:
screen->showNotification("MAMA MIRA! SIN MANOS!");
screen->showNotification("ACHIEVEMENT UNLOCKED!", "FINISH THE GAME", 2);
break;
case SDL_SCANCODE_F7:
screen->showNotification("NO ICON");
break;
case SDL_SCANCODE_F8:
screen->showNotification("NO ICON", "NO TEXT");
break;
case SDL_SCANCODE_F9:
screen->showNotification("JAILDESIGNER", "LOGGED IN", 1);
break;
#endif
@@ -213,7 +230,7 @@ void Game::checkEventHandler()
}
// Bucle para el juego
section_t Game::run()
void Game::run()
{
JA_PlayMusic(music);
if (!board.music)
@@ -221,15 +238,13 @@ section_t Game::run()
JA_PauseMusic();
}
while (section.name == SECTION_PROG_GAME)
while (section->name == SECTION_PROG_GAME)
{
update();
render();
}
JA_StopMusic();
return section;
}
// Actualiza el juego, las variables, comprueba la entrada, etc.
@@ -258,6 +273,7 @@ void Game::update()
checkGameOver();
checkEndGame();
checkRestoringJail();
checkSomeCheevos();
scoreboard->update();
input->update();
@@ -432,7 +448,7 @@ void Game::checkGameOver()
{
if (board.lives < 0 && blackScreenCounter > 17)
{
section.name = SECTION_PROG_GAME_OVER;
section->name = SECTION_PROG_GAME_OVER;
}
}
@@ -453,6 +469,9 @@ void Game::killPlayer()
// Actualiza las estadisticas
stats->addDeath(room->getName());
// Invalida el logro de pasarse el juego sin morir
cheevos->invalidate(11);
// Destruye la habitacion y el jugador
delete room;
delete this->player;
@@ -569,7 +588,10 @@ bool Game::checkEndGame()
if (haveTheItems && isOnTheRoom && isOnTheDoor)
{
section.name = SECTION_PROG_ENDING;
// Comprueba los logros de completar el juego
checkEndGameCheevos();
section->name = SECTION_PROG_ENDING;
return true;
}
@@ -635,11 +657,19 @@ void Game::checkRestoringJail()
counter++;
}
// Incrementa el numero de vidas
if (counter == 100)
{
counter = 0;
board.lives++;
JA_PlaySound(deathSound);
// Invalida el logro de completar el juego sin entrar a la jail
const bool haveTheItems = board.items >= int(totalItems * 0.9f);
if (!haveTheItems)
{
cheevos->invalidate(9);
}
}
}
@@ -673,4 +703,74 @@ void Game::fillRoomNameTexture()
// Deja el renderizador por defecto
SDL_SetRenderTarget(renderer, nullptr);
}
// Comprueba algunos logros
void Game::checkSomeCheevos()
{
// Logros sobre la cantidad de items
if (board.items == totalItems)
{
cheevos->unlock(4);
cheevos->unlock(3);
cheevos->unlock(2);
cheevos->unlock(1);
}
else if (board.items >= totalItems * 0.75f)
{
cheevos->unlock(3);
cheevos->unlock(2);
cheevos->unlock(1);
}
else if (board.items >= totalItems * 0.5f)
{
cheevos->unlock(2);
cheevos->unlock(1);
}
else if (board.items >= totalItems * 0.25f)
{
cheevos->unlock(1);
}
// Logros sobre las habitaciones visitadas
if (board.rooms >= 60)
{
cheevos->unlock(7);
cheevos->unlock(6);
cheevos->unlock(5);
}
else if (board.rooms >= 40)
{
cheevos->unlock(6);
cheevos->unlock(5);
}
else if (board.rooms >= 20)
{
cheevos->unlock(5);
}
}
// Comprueba los logros de completar el juego
void Game::checkEndGameCheevos()
{
// "Complete the game"
cheevos->unlock(8);
// "Complete the game without entering the jail"
cheevos->unlock(9);
// "Complete the game with all items"
if (board.items == totalItems)
{
cheevos->unlock(10);
}
// "Complete the game without dying"
cheevos->unlock(11);
// "Complete the game in under 30 minutes"
if (scoreboard->getMinutes() < 30)
{
cheevos->unlock(12);
}
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <SDL2/SDL.h>
#include "cheevos.h"
#include "common/animatedsprite.h"
#include "common/asset.h"
#include "common/debug.h"
@@ -37,17 +38,18 @@ private:
Input *input; // Objeto pata gestionar la entrada
Text *text; // Objeto para los textos del juego
ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador
Cheevos *cheevos; // Objeto encargado de gestionar los logros del juego
Resource *resource; // Objeto con los recursos
Debug *debug; // Objeto para gestionar la información de debug
options_t *options; // Puntero a las opciones del juego
Stats *stats; // Objeto encargado de gestionar las estadísticas
SDL_Texture *roomNameTexture; // Textura para escribir el nombre de la habitación
section_t *section; // Seccion actual dentro del juego
// Variables
JA_Music_t *music; // Musica que suena durante el juego
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
section_t section; // Seccion actual dentro del juego
std::string currentRoom; // Fichero de la habitación actual
playerSpawn_t spawnPoint; // Lugar de la habitación donde aparece el jugador
JA_Sound_t *deathSound; // Sonido a reproducir cuando muere el jugador
@@ -138,15 +140,21 @@ private:
// Pone el nombre de la habitación en la textura
void fillRoomNameTexture();
// Comprueba algunos logros
void checkSomeCheevos();
// Comprueba los logros de completar el juego
void checkEndGameCheevos();
public:
// 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, section_t *section, Debug *debug);
// Destructor
~Game();
// Bucle para el juego
section_t run();
void run();
};
#endif

View File

@@ -1,7 +1,7 @@
#include "game_over.h"
// Constructor
GameOver::GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options)
GameOver::GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section)
{
// Copia los punteros
this->renderer = renderer;
@@ -9,6 +9,7 @@ GameOver::GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, A
this->resource = resource;
this->asset = asset;
this->options = options;
this->section = section;
// Reserva memoria para los punteros a objetos
eventHandler = new SDL_Event();
@@ -20,8 +21,8 @@ GameOver::GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, A
// Inicializa variables
preCounter = 0;
counter = 0;
section.name = SECTION_PROG_GAME_OVER;
section.subsection = 0;
section->name = SECTION_PROG_GAME_OVER;
section->subsection = 0;
ticks = 0;
ticksSpeed = 15;
endSection = 400;
@@ -83,7 +84,7 @@ void GameOver::update()
void GameOver::render()
{
const int y = 32;
// Prepara para empezar a dibujar en la textura de juego
screen->start();
@@ -121,8 +122,8 @@ void GameOver::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section.subsection = 0;
section->name = SECTION_PROG_QUIT;
section->subsection = 0;
break;
}
@@ -132,7 +133,7 @@ void GameOver::checkEventHandler()
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
case SDL_SCANCODE_B:
@@ -177,15 +178,13 @@ void GameOver::checkEventHandler()
}
// Bucle principal
section_t GameOver::run()
void GameOver::run()
{
while (section.name == SECTION_PROG_GAME_OVER)
while (section->name == SECTION_PROG_GAME_OVER)
{
update();
render();
}
return section;
}
// Actualiza el color usado para renderizar los textos e imagenes
@@ -195,7 +194,6 @@ void GameOver::updateColor()
if (counter < half)
{
// const float step = std::min(std::max(counter, iniFade) - iniFade, fadeLenght) / (float)fadeLenght;
const float step = std::min(counter, fadeLenght) / (float)fadeLenght;
const int index = (colors.size() - 1) - int((colors.size() - 1) * step);
color = colors[index];
@@ -240,8 +238,8 @@ void GameOver::updateCounters()
// Comprueba si ha terminado la sección
else if (counter == endSection)
{
section.name = SECTION_PROG_LOGO;
section.subsection = SUBSECTION_LOGO_TO_TITLE;
section->name = SECTION_PROG_LOGO;
section->subsection = SUBSECTION_LOGO_TO_TITLE;
}
}

View File

@@ -28,11 +28,11 @@ private:
Text *text; // Objeto para escribir texto en pantalla
AnimatedSprite *playerSprite; // Sprite con el jugador
AnimatedSprite *tvSprite; // Sprite con el televisor
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables
int preCounter; // Contador previo
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<color_t> colors; // Vector con los colores para el fade
@@ -40,7 +40,7 @@ private:
int endSection; // Contador: cuando acaba la sección
int iniFade; // Contador: cuando emiepza el fade
int fadeLenght; // Contador: duración del fade
JA_Music_t* music; // Musica que suena durante el juego
JA_Music_t *music; // Musica que suena durante el juego
// Actualiza el objeto
void update();
@@ -65,13 +65,13 @@ private:
public:
// Constructor
GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options);
GameOver(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section);
// Destructor
~GameOver();
// Bucle principal
section_t run();
void run();
};
#endif

View File

@@ -1,7 +1,7 @@
#include "intro.h"
// Constructor
Intro::Intro(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options)
Intro::Intro(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section)
{
// Copia la dirección de los objetos
this->resource = resource;
@@ -9,6 +9,7 @@ Intro::Intro(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *
this->screen = screen;
this->asset = asset;
this->options = options;
this->section = section;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
@@ -31,8 +32,8 @@ Intro::Intro(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *
// Inicializa variables
preCounter = 0;
counter = 0;
section.name = SECTION_PROG_INTRO;
section.subsection = 0;
section->name = SECTION_PROG_INTRO;
section->subsection = 0;
ticks = 0;
ticksSpeed = 15;
loadCounter = 0;
@@ -82,7 +83,7 @@ void Intro::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
}
@@ -92,7 +93,7 @@ void Intro::checkEventHandler()
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
case SDL_SCANCODE_B:
@@ -126,12 +127,12 @@ void Intro::checkEventHandler()
break;
case SDL_SCANCODE_F5:
//switchPalette();
switchPalette();
break;
default:
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
section->name = SECTION_PROG_TITLE;
section->subsection = 0;
break;
}
}
@@ -141,7 +142,7 @@ void Intro::checkEventHandler()
// Gestiona el contador de carga
void Intro::updateLoad()
{
// Primera parte de la carga, la parte en blanco ynegro
// Primera parte de la carga, la parte en blanco y negro
if (loadingFirstPart)
{
// Cada 5 pasos el loadCounter se incrementa en uno
@@ -179,8 +180,8 @@ void Intro::updateLoad()
// Comprueba si ha terminado la intro
if (loadCounter >= 768)
{
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
section->name = SECTION_PROG_TITLE;
section->subsection = 0;
JA_StopMusic();
}
}
@@ -240,20 +241,19 @@ void Intro::render()
}
// Bucle para el logo del juego
section_t Intro::run()
void Intro::run()
{
// Inicia el sonido de carga
JA_SetVolume(64);
JA_PlayMusic(loadingSound1);
while (section.name == SECTION_PROG_INTRO)
while (section->name == SECTION_PROG_INTRO)
{
update();
render();
}
JA_SetVolume(128);
return section;
}
// Cambia la paleta
@@ -271,4 +271,45 @@ void Intro::switchPalette()
sprite1->setTexture(resource->getTexture("loading_screen_bn.png"));
sprite2->setTexture(resource->getTexture("loading_screen_color.png"));
}
recreateLoadingScreen();
}
// Reconstruye la pantalla de carga
void Intro::recreateLoadingScreen()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Primera parte de la carga, la parte en blanco y negro
if (loadingFirstPart)
{
const int numSteps = 5;
const int step = 51;
for (int i = 0; i <= counter; i++)
{
loadCounter = i / numSteps;
loadRect.x = step * (i % numSteps);
loadRect.y = lineIndex[loadCounter];
sprite1->setSpriteClip(loadRect);
sprite1->setRect(loadRect);
sprite1->render();
}
}
// Segunda parte de la carga, la parte de los bloques en color
else
{
for (int i = 0; i <= loadCounter; i++)
{
loadRect.x = (i * 8) % 256;
loadRect.y = (i / 32) * 8;
sprite2->setSpriteClip(loadRect);
sprite2->setRect(loadRect);
sprite2->render();
}
}
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}

View File

@@ -30,11 +30,11 @@ private:
Sprite *sprite1; // Sprite para manejar la textura loadingScreenTexture1
Sprite *sprite2; // Sprite para manejar la textura loadingScreenTexture2
options_t *options; // Puntero a las opciones del juego
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables
int preCounter; // Contador previo para realizar una pausa inicial
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
int loadCounter; // Contador para controlar las cargas
@@ -66,15 +66,18 @@ private:
// Cambia la paleta
void switchPalette();
// Reconstruye la pantalla de carga
void recreateLoadingScreen();
public:
// Constructor
Intro(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options);
Intro(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section);
// Destructor
~Intro();
// Bucle principal
section_t run();
void run();
};
#endif

View File

@@ -2,7 +2,7 @@
#include <iostream>
// Constructor
Logo::Logo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, int subsection)
Logo::Logo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section)
{
// Copia la dirección de los objetos
this->resource = resource;
@@ -10,6 +10,7 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
this->screen = screen;
this->asset = asset;
this->options = options;
this->section = section;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
@@ -37,8 +38,7 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *as
// Inicializa variables
counter = 0;
section.name = SECTION_PROG_LOGO;
section.subsection = subsection;
section->name = SECTION_PROG_LOGO;
ticks = 0;
ticksSpeed = 15;
initFade = 300;
@@ -77,17 +77,17 @@ void Logo::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
}
// Comprueba las teclas que se han pulsado
if ((eventHandler->type == SDL_KEYUP && eventHandler->key.repeat == 0) || (eventHandler->type == SDL_JOYBUTTONUP))
if ((eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0) || (eventHandler->type == SDL_JOYBUTTONUP))
{
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
case SDL_SCANCODE_B:
@@ -125,7 +125,7 @@ void Logo::checkEventHandler()
break;
default:
section.subsection = SUBSECTION_LOGO_TO_TITLE;
section->subsection = SUBSECTION_LOGO_TO_TITLE;
endSection();
break;
}
@@ -175,26 +175,32 @@ void Logo::updateTextureColors()
{
texture2->setColor(color[0].r, color[0].g, color[0].b);
}
else if (counter == ini + inc * 1)
{
texture2->setColor(color[1].r, color[1].g, color[1].b);
}
else if (counter == ini + inc * 2)
{
texture2->setColor(color[2].r, color[2].g, color[2].b);
}
else if (counter == ini + inc * 3)
{
texture2->setColor(color[3].r, color[3].g, color[3].b);
}
else if (counter == ini + inc * 4)
{
texture2->setColor(color[4].r, color[4].g, color[4].b);
}
else if (counter == ini + inc * 5)
{
texture2->setColor(color[5].r, color[5].g, color[5].b);
}
else if (counter == ini + inc * 6)
{
texture2->setColor(color[6].r, color[6].g, color[6].b);
@@ -210,31 +216,37 @@ void Logo::updateTextureColors()
texture->setColor(color[6].r, color[6].g, color[6].b);
texture2->setColor(color[6].r, color[6].g, color[6].b);
}
else if (counter == initFade + inc * 1)
{
texture->setColor(color[5].r, color[5].g, color[5].b);
texture2->setColor(color[5].r, color[5].g, color[5].b);
}
else if (counter == initFade + inc * 2)
{
texture->setColor(color[4].r, color[4].g, color[4].b);
texture2->setColor(color[4].r, color[4].g, color[4].b);
}
else if (counter == initFade + inc * 3)
{
texture->setColor(color[3].r, color[3].g, color[3].b);
texture2->setColor(color[3].r, color[3].g, color[3].b);
}
else if (counter == initFade + inc * 4)
{
texture->setColor(color[2].r, color[2].g, color[2].b);
texture2->setColor(color[2].r, color[2].g, color[2].b);
}
else if (counter == initFade + inc * 5)
{
texture->setColor(color[1].r, color[1].g, color[1].b);
texture2->setColor(color[1].r, color[1].g, color[1].b);
}
else if (counter == initFade + inc * 6)
{
texture->setColor(color[0].r, color[0].g, color[0].b);
@@ -295,18 +307,16 @@ void Logo::render()
}
// Bucle para el logo del juego
section_t Logo::run()
void Logo::run()
{
// Detiene la música
JA_StopMusic();
while (section.name == SECTION_PROG_LOGO)
while (section->name == SECTION_PROG_LOGO)
{
update();
render();
}
return section;
}
// Cambia la paleta
@@ -318,5 +328,5 @@ void Logo::switchPalette()
// Termina la sección
void Logo::endSection()
{
section.name = SECTION_PROG_ENTER_ID;
section->name = SECTION_PROG_ENTER_ID;
}

View File

@@ -27,11 +27,11 @@ private:
std::vector<Sprite *> sprite; // Vector con los sprites de cada linea que forman el bitmap JAILGAMES
Sprite *sprite2; // Sprite para manejar la textura2
options_t *options; // Puntero a las opciones del juego
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables
std::vector<color_t> color; // Vector con los colores para el fade
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
int initFade; // Tiempo del contador cuando inicia el fade a negro
@@ -61,13 +61,13 @@ private:
public:
// 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, section_t *section);
// Destructor
~Logo();
// Bucle principal
section_t run();
void run();
};
#endif

View File

@@ -169,4 +169,10 @@ void ScoreBoard::updateItemsColor()
{
itemsColor = stringToColor(options->palette, "magenta");
}
}
// Devuelve la cantidad de minutos de juego transcurridos
int ScoreBoard::getMinutes()
{
return getTime().minutes;
}

View File

@@ -84,6 +84,9 @@ public:
// Quita el modo pausa del marcador
void resume();
// Devuelve la cantidad de minutos de juego transcurridos
int getMinutes();
};
#endif

View File

@@ -1,7 +1,7 @@
#include "title.h"
// Constructor
Title::Title(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options)
Title::Title(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section)
{
// Copia la dirección de los objetos
this->resource = resource;
@@ -9,6 +9,7 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *
this->screen = screen;
this->asset = asset;
this->options = options;
this->section = section;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
@@ -25,8 +26,8 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *
// Inicializa variables
counter = 0;
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
section->name = SECTION_PROG_TITLE;
section->subsection = 0;
ticks = 0;
ticksSpeed = 15;
longText = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO: P.A.C.O. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?";
@@ -79,7 +80,7 @@ void Title::checkEventHandler()
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
}
@@ -88,19 +89,19 @@ void Title::checkEventHandler()
{
if (eventHandler->type == SDL_JOYBUTTONDOWN)
{
section.name = SECTION_PROG_GAME;
section.subsection = 0;
section->name = SECTION_PROG_GAME;
section->subsection = 0;
}
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
section->name = SECTION_PROG_QUIT;
break;
case SDL_SCANCODE_RETURN:
section.name = SECTION_PROG_GAME;
section.subsection = 0;
section->name = SECTION_PROG_GAME;
section->subsection = 0;
break;
case SDL_SCANCODE_B:
@@ -210,8 +211,8 @@ void Title::update()
// Comprueba si ha terminado la marquesina y acaba con el titulo
if (letters[letters.size() - 1].x < -10)
{
section.name = SECTION_PROG_CREDITS;
section.subsection = 0;
section->name = SECTION_PROG_CREDITS;
section->subsection = 0;
}
}
}
@@ -239,15 +240,13 @@ void Title::render()
}
// Bucle para el logo del juego
section_t Title::run()
void Title::run()
{
while (section.name == SECTION_PROG_TITLE)
while (section->name == SECTION_PROG_TITLE)
{
update();
render();
}
return section;
}
// Recarga las texturas

View File

@@ -36,10 +36,10 @@ private:
options_t *options; // Puntero a las opciones del juego
Texture *pressEnterTexture; // Textura con los graficos de PRESS ENTER
Sprite *pressEnterSprite; // Sprite para manejar la textura de PRESS ENTER
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables
int counter; // Contador
section_t section; // Estado del bucle principal para saber si continua o se sale
std::string longText; // Texto que aparece en la parte inferior del titulo
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
@@ -69,13 +69,13 @@ private:
public:
// Constructor
Title(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options);
Title(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section);
// Destructor
~Title();
// Bucle principal
section_t run();
void run();
};
#endif