Arreglada la clase Screen. Había un lio de conceptos con varias variables

This commit is contained in:
2022-11-18 20:09:03 +01:00
parent 90bdad7d51
commit fdc8797d2b
20 changed files with 708 additions and 128 deletions

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);
};

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

@@ -0,0 +1,156 @@
#include "notify.h"
#include <string>
#include <stdio.h>
// Constructor
Notify::Notify(SDL_Renderer *renderer, std::string bitmapFile, std::string textFile)
{
// Inicializa variables
this->renderer = renderer;
bgColor = {64, 64, 64};
waitTime = 300;
// Crea objetos
texture = new Texture(renderer, bitmapFile);
text = new Text(textFile, texture, renderer);
}
// Destructor
Notify::~Notify()
{
// Libera la memoria de los objetos
delete texture;
delete text;
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;
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);
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)
{
// Crea constantes
const int width = this->text->lenght(text) + (this->text->getCharacterSize() * 2);
const int height = this->text->getCharacterSize() * 2;
const int despH = this->text->getCharacterSize() / 2;
const int despV = despH;
const int travelDist = height + despV;
// const int offset = (int)notifications.size() * (travelDist) + despV;
const int 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;
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, despV, text, 1, {255, 255, 255}, 1, {0, 0, 0});
// Crea el sprite
n.sprite = new Sprite(n.rect, n.texture, renderer);
// Añade la notificación a la lista
notifications.push_back(n);
}
// Indica si hay notificaciones activas
bool Notify::active()
{
if ((int)notifications.size() > 0)
{
return true;
}
return false;
}

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

@@ -0,0 +1,82 @@
#pragma once
#include <SDL2/SDL.h>
#include "text.h"
#include "texture.h"
#include "sprite.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
// 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
// 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);
// 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,19 @@
#include <iostream>
// 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
this->window = window;
this->renderer = renderer;
this->options = options;
this->asset = asset;
gameCanvasWidth = gameInternalResX;
gameCanvasHeight = gameInternalResY;
// Crea los objetos
notify = new Notify(renderer, asset->get("smb2.png"), asset->get("smb2.txt"));
gameCanvasWidth = options->gameWidth;
gameCanvasHeight = options->gameHeight;
iniFade();
iniSpectrumFade();
@@ -27,15 +31,16 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, i
}
// Establece el modo de video
setVideoMode(options->fullScreenMode);
setVideoMode(options->videoMode);
// Calcula los anclajes
anchor.left = 0;
anchor.right = gameCanvasWidth;
anchor.center = gameCanvasWidth / 2;
anchor.top = 0;
anchor.bottom = gameCanvasHeight;
anchor.middle = gameCanvasHeight / 2;
// Inicializa variables
notifyActive = false;
}
// Destructor
Screen::~Screen()
{
delete notify;
}
// Limpia la pantalla
@@ -64,42 +69,49 @@ void Screen::blit()
// Copia la textura de juego en el renderizador en la posición adecuada
SDL_RenderCopy(renderer, gameCanvas, nullptr, &dest);
// Dibuja las notificaciones
// renderNotifications();
// Muestra por pantalla el renderizador
SDL_RenderPresent(renderer);
}
// Establece el modo de video
void Screen::setVideoMode(int fullScreenMode)
void Screen::setVideoMode(int videoMode)
{
// Aplica el modo de video
SDL_SetWindowFullscreen(window, fullScreenMode);
SDL_SetWindowFullscreen(window, videoMode);
// Si está activo el modo ventana quita el borde
if (fullScreenMode == 0)
if (videoMode == 0)
{
if (options->borderEnabled)
{
const int incWidth = gameCanvasWidth * options->borderSize;
const int incHeight = gameCanvasHeight * options->borderSize;
screenWidth = gameCanvasWidth + incWidth;
screenHeight = gameCanvasHeight + incHeight;
dest = {0 + (incWidth / 2), 0 + (incHeight / 2), gameCanvasWidth, gameCanvasHeight};
const int incWidth = options->gameWidth * options->borderSize;
const int incHeight = options->gameHeight * options->borderSize;
gameCanvasWidth = options->gameWidth + incWidth;
gameCanvasHeight = options->gameHeight + incHeight;
screenWidth = gameCanvasWidth * options->windowSize;
screenHeight = gameCanvasHeight * options->windowSize;
dest = {0 + (incWidth / 2), 0 + (incHeight / 2), options->gameWidth, options->gameHeight};
}
else
{
screenWidth = gameCanvasWidth;
screenHeight = gameCanvasHeight;
gameCanvasWidth = options->gameWidth;
gameCanvasHeight = options->gameHeight;
screenWidth = gameCanvasWidth * options->windowSize;
screenHeight = gameCanvasHeight * options->windowSize;
dest = {0, 0, gameCanvasWidth, gameCanvasHeight};
}
// Modifica el tamaño del renderizador y de la ventana
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight);
SDL_SetWindowSize(window, screenWidth * options->windowSize, screenHeight * options->windowSize);
SDL_RenderSetLogicalSize(renderer, gameCanvasWidth, gameCanvasHeight);
SDL_SetWindowSize(window, screenWidth, screenHeight);
}
// 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)
{
// Obten el alto y el ancho de la ventana
SDL_GetWindowSize(window, &screenWidth, &screenHeight);
@@ -149,22 +161,14 @@ void Screen::setVideoMode(int fullScreenMode)
}
// Actualiza el valor de la variable
options->fullScreenMode = fullScreenMode;
options->videoMode = videoMode;
}
// Camibia entre pantalla completa y ventana
void Screen::switchVideoMode()
{
if (options->fullScreenMode == 0)
{
options->fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
}
else
{
options->fullScreenMode = 0;
}
setVideoMode(options->fullScreenMode);
options->videoMode = (options->videoMode == 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
setVideoMode(options->videoMode);
}
// Cambia el tamaño de la ventana
@@ -338,4 +342,30 @@ void Screen::renderFX()
{
renderFade();
renderSpectrumFade();
}
// Actualiza el notificador
void Screen::updateNotifier()
{
notify->update();
notifyActive = notify->active();
}
// Muestra una notificación de texto por pantalla;
void Screen::showText(std::string text)
{
notify->showText(text);
}
// Dibuja las notificaciones
void Screen::renderNotifications()
{
if (!notifyActive)
{
return;
}
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight);
notify->render();
SDL_RenderSetLogicalSize(renderer, gameCanvasWidth, gameCanvasHeight);
}

View File

@@ -1,6 +1,8 @@
#pragma once
#include <SDL2/SDL.h>
#include "asset.h"
#include "notify.h"
#include "utils.h"
#include <vector>
@@ -10,42 +12,33 @@
#define FILTER_NEAREST 0
#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
{
private:
// Objetos y punteros
SDL_Window *window; // Ventana de la aplicación
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
options_t *options; // Variable con todas las opciones del programa
Notify *notify; // Dibuja notificaciones por pantalla
// Variables
int screenWidth; // Ancho de la pantalla o ventana
int screenHeight; // 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 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
SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
bool notifyActive; // Indica si hay notificaciones activas
// Variables - Efectos
bool fade; // Indica si esta activo el efecto de fade
int fadeCounter; // Temporizador para el efecto de fade
int fadeLenght; // Duración del fade
bool spectrumFade; // Indica si esta activo el efecto de fade spectrum
int spectrumFadeCounter; // Temporizador para el efecto de fade spectrum
int spectrumFadeLenght; // Duración del fade spectrum
bool fade; // Indica si esta activo el efecto de fade
int fadeCounter; // Temporizador para el efecto de fade
int fadeLenght; // Duración del fade
bool spectrumFade; // Indica si esta activo el efecto de fade spectrum
int spectrumFadeCounter; // Temporizador para el efecto de fade spectrum
int spectrumFadeLenght; // Duración del fade spectrum
std::vector<color_t> spectrumColor; // Colores para el fade spectrum
// Inicializa las variables para el fade
@@ -66,9 +59,15 @@ private:
// Dibuja el spectrum fade
void renderSpectrumFade();
// Dibuja las notificaciones
void renderNotifications();
public:
// 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
void clean(color_t color = {0x00, 0x00, 0x00});
@@ -80,7 +79,7 @@ public:
void blit();
// Establece el modo de video
void setVideoMode(int fullScreenMode);
void setVideoMode(int videoMode);
// Camibia entre pantalla completa y ventana
void switchVideoMode();
@@ -120,6 +119,12 @@ public:
// Dibuja los efectos
void renderFX();
// Actualiza el notificador
void updateNotifier();
// Muestra una notificación de texto por pantalla;
void showText(std::string text);
};
#endif

View File

@@ -70,24 +70,36 @@ struct cheat_t
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 con todas las opciones de configuración del programa
struct options_t
{
Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa
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
bool vSync; // Indica si se quiere usar vsync o no
int screenWidth; // Ancho de la pantalla o ventana
int screenHeight; // Alto de la pantalla o ventana
bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
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
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
cheat_t cheat; // Contiene trucos y ventajas para el juego
int rooms; // Cantidad de habitaciones visitadas
int items; // Cantidad de items obtenidos
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
Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no
int gameWidth; // Ancho de la resolucion nativa del juego
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 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
float borderSize; // Porcentaje de borde que se añade a lo ventana
palette_e palette; // Paleta de colores a usar en el juego
bool console; // Indica si ha de mostrar información por la consola de texto
cheat_t cheat; // Contiene trucos y ventajas para el juego
int rooms; // Cantidad de habitaciones visitadas
int items; // Cantidad de items obtenidos
online_t online; // Datos del servicio online
};
// Calcula el cuadrado de la distancia entre dos puntos