Trabajando en prog.cpp

This commit is contained in:
2022-08-11 13:58:51 +02:00
parent 57ddf60c1b
commit 09ad78b02e
8 changed files with 1674 additions and 4 deletions

1144
data/gamecontrollerdb.txt Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

206
source/input.cpp Normal file
View File

@@ -0,0 +1,206 @@
#include "input.h"
#include <iostream>
// Constructor
Input::Input(std::string file)
{
// Fichero gamecontrollerdb.txt
mDBpath = file;
// Inicializa las variables
for (int i = 0; i < 17; i++)
{
mKeyBindings[i].scancode = 0;
mKeyBindings[i].active = false;
mGameControllerBindings[i].button = SDL_CONTROLLER_BUTTON_INVALID;
mGameControllerBindings[i].active = false;
}
discoverGameController();
}
// Destructor
Input::~Input()
{
for (int i = 0; i < mNumGamepads; i++)
mConnectedControllers[i] = nullptr;
}
// Asigna uno de los posibles inputs a una tecla del teclado
void Input::bindKey(Uint8 input, SDL_Scancode code)
{
mKeyBindings[input].scancode = code;
}
// Asigna uno de los posibles inputs a un botón del mando
void Input::bindGameControllerButton(Uint8 input, SDL_GameControllerButton button)
{
mGameControllerBindings[input].button = button;
}
// Comprueba si un input esta activo
bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
{
bool successKeyboard = false;
bool successGameController = false;
if (device == INPUT_USE_ANY)
index = 0;
if ((device == INPUT_USE_KEYBOARD) || (device == INPUT_USE_ANY))
{
const Uint8 *mKeystates = SDL_GetKeyboardState(NULL);
if (repeat)
{
if (mKeystates[mKeyBindings[input].scancode] != 0)
successKeyboard = true;
else
successKeyboard = false;
}
else
{
if (!mKeyBindings[input].active)
{
if (mKeystates[mKeyBindings[input].scancode] != 0)
{
mKeyBindings[input].active = true;
successKeyboard = true;
}
else
{
successKeyboard = false;
}
}
else
{
if (mKeystates[mKeyBindings[input].scancode] == 0)
{
mKeyBindings[input].active = false;
successKeyboard = false;
}
else
{
successKeyboard = false;
}
}
}
}
if (gameControllerFound())
if ((device == INPUT_USE_GAMECONTROLLER) || (device == INPUT_USE_ANY))
{
if (repeat)
{
if (SDL_GameControllerGetButton(mConnectedControllers[index], mGameControllerBindings[input].button) != 0)
successGameController = true;
else
successGameController = false;
}
else
{
if (!mGameControllerBindings[input].active)
{
if (SDL_GameControllerGetButton(mConnectedControllers[index], mGameControllerBindings[input].button) != 0)
{
mGameControllerBindings[input].active = true;
successGameController = true;
}
else
{
successGameController = false;
}
}
else
{
if (SDL_GameControllerGetButton(mConnectedControllers[index], mGameControllerBindings[input].button) == 0)
{
mGameControllerBindings[input].active = false;
successGameController = false;
}
else
{
successGameController = false;
}
}
}
}
return (successKeyboard || successGameController);
}
// Comprueba si hay un mando conectado
bool Input::discoverGameController()
{
bool found = false;
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1)
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
if (SDL_GameControllerAddMappingsFromFile(mDBpath.c_str()) < 0)
printf("Error, could not load %s file: %s\n", mDBpath.c_str(), SDL_GetError());
int nJoysticks = SDL_NumJoysticks();
mNumGamepads = 0;
// Cuenta el numero de mandos
for (int i = 0; i < nJoysticks; i++)
if (SDL_IsGameController(i))
mNumGamepads++;
printf("\nChecking for game controllers...\n");
printf("%i joysticks found, %i are gamepads\n", nJoysticks, mNumGamepads);
if (mNumGamepads > 0)
{
found = true;
for (int i = 0; i < mNumGamepads; i++)
{
// Abre el mando y lo añade a la lista
SDL_GameController *pad = SDL_GameControllerOpen(i);
if (SDL_GameControllerGetAttached(pad) == 1)
{
mConnectedControllers.push_back(pad);
std::string separator(" #");
std::string name = SDL_GameControllerNameForIndex(i);
name.resize(25);
name = name + separator + std::to_string(i);
std::cout << name << std::endl;
mControllerNames.push_back(name);
}
else
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
}
//mGameController = mConnectedControllers[0];
SDL_GameControllerEventState(SDL_ENABLE);
}
return found;
}
// Comprueba si hay algun mando conectado
bool Input::gameControllerFound()
{
if (mNumGamepads > 0)
return true;
else
return false;
}
// Obten el nombre de un mando de juego
std::string Input::getControllerName(int index)
{
if (mNumGamepads > 0)
return mControllerNames[index];
else
return "";
}
// Obten el numero de mandos conectados
int Input::getNumControllers()
{
return mNumGamepads;
}

86
source/input.h Normal file
View File

@@ -0,0 +1,86 @@
#pragma once
#include <SDL2/SDL.h>
#include <string>
#include <vector>
#ifndef INPUT_H
#define INPUT_H
#define INPUT_NULL 0
#define INPUT_UP 1
#define INPUT_DOWN 2
#define INPUT_LEFT 3
#define INPUT_RIGHT 4
#define INPUT_ACCEPT 5
#define INPUT_CANCEL 6
#define INPUT_BUTTON_1 7
#define INPUT_BUTTON_2 8
#define INPUT_BUTTON_3 9
#define INPUT_BUTTON_4 10
#define INPUT_BUTTON_5 11
#define INPUT_BUTTON_6 12
#define INPUT_BUTTON_7 13
#define INPUT_BUTTON_8 14
#define INPUT_BUTTON_PAUSE 15
#define INPUT_BUTTON_ESCAPE 16
#define REPEAT_TRUE true
#define REPEAT_FALSE false
#define INPUT_USE_KEYBOARD 0
#define INPUT_USE_GAMECONTROLLER 1
#define INPUT_USE_ANY 2
// Clase Input
class Input
{
private:
struct keyBindings_t
{
Uint8 scancode; // Scancode asociado
bool active; // Indica si está activo
};
keyBindings_t mKeyBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
struct GameControllerBindings_t
{
SDL_GameControllerButton button; // GameControllerButton asociado
bool active; // Indica si está activo
};
GameControllerBindings_t mGameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<SDL_GameController *> mConnectedControllers; // Vector con todos los mandos conectados
std::vector<std::string> mControllerNames; // Vector con los nombres de los mandos
int mNumGamepads; // Numero de mandos conectados
std::string mDBpath; // Ruta al archivo gamecontrollerdb.txt
// Comprueba si hay un mando conectado
bool discoverGameController();
public:
// Constructor
Input(std::string file);
// Destructor
~Input();
// Asigna uno de los posibles inputs a una tecla del teclado
void bindKey(Uint8 input, SDL_Scancode code);
// Asigna uno de los posibles inputs a un botón del mando
void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button);
// Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat, int device = INPUT_USE_ANY, int index = 0);
// Comprueba si hay algun mando conectado
bool gameControllerFound();
// Obten el numero de mandos conectados
int getNumControllers();
// Obten el nombre de un mando de juego
std::string getControllerName(int index);
};
#endif

View File

@@ -3,10 +3,183 @@
// Constructor
Prog::Prog(std::string executablePath)
{
// Establece las opciones por defecto
options = new options_t;
options->fullScreenMode = 0;
options->windowSize = 1;
options->filter = FILTER_NEAREST;
options->vSync = true;
options->screenWidth = 320;
options->screenHeight = 240;
options->integerScale = true;
options->keepAspect = true;
// Crea los objetos
asset = new Asset(executablePath);
input = new Input(asset->get("gamecontrollerdb.txt"));
screen = new Screen(renderer,320,240,320,240);
// Inicializa las variables
section.name = PROG_SECTION_GAME;
initSDL();
initJailAudio();
}
Prog::~Prog()
{
delete asset;
delete input;
delete options;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
// Inicializa JailAudio
void Prog::initJailAudio()
{
JA_Init(48000, AUDIO_S16, 2);
}
// Arranca SDL y crea la ventana
bool Prog::initSDL()
{
// Indicador de éxito
bool success = true;
// Inicializa SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0)
{
printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Inicia el generador de numeros aleatorios
std::srand(static_cast<unsigned int>(SDL_GetTicks()));
// Establece el filtro de la textura
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options->filter).c_str()))
{
printf("Warning: Nearest texture filtering not enabled!\n");
}
// Crea la ventana
window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, options->screenWidth * options->windowSize, options->screenHeight * options->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (window == NULL)
{
printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones
if (options->vSync)
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
else
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL)
{
printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Inicializa el color de renderizado
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado
SDL_RenderSetLogicalSize(renderer, options->screenWidth, options->screenHeight);
// Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
}
}
}
printf("\n");
return success;
}
// Crea el indice de ficheros de recursos
bool Prog::setFileList()
{
// Ficheros binarios
asset->add("/data/volcano.map", data);
asset->add("/data/config.bin", data, false);
asset->add("/data/gamecontrollerdb.txt", data);
// Texturas
asset->add("/media/gfx/actors.png", bitmap);
asset->add("/media/gfx/bg_surface.png", bitmap);
asset->add("/media/gfx/filter.png", bitmap);
asset->add("/media/gfx/hud.png", bitmap);
asset->add("/media/gfx/menu_animation.png", bitmap);
asset->add("/media/gfx/menu.png", bitmap);
asset->add("/media/gfx/player.png", bitmap);
asset->add("/media/gfx/tiles_surface.png", bitmap);
asset->add("/media/gfx/tiles_volcano.png", bitmap);
// Sonidos
asset->add("/media/sound/sound_player_coin.wav", sound);
asset->add("/media/sound/sound_player_death.wav", sound);
asset->add("/media/sound/sound_drop_enemy.wav", sound);
asset->add("/media/sound/sound_drop_splat.wav", sound);
asset->add("/media/sound/sound_player_jump.wav", sound);
asset->add("/media/sound/sound_menu_logo.wav", sound);
asset->add("/media/sound/sound_menu_start.wav", sound);
// Musicas
asset->add("/media/music/music_menu.ogg", music);
asset->add("/media/music/music_surface.ogg", music);
asset->add("/media/music/music_volcano.ogg", music);
return asset->check();
}
// Obtiene el valor de la variable
Uint8 Prog::getSection()
{
return section.name;
}
// Establece el valor de la variable
void Prog::setSection(section_t section)
{
this->section = section;
}
void Prog::runGame()
{
game = new Game();
//setSection(game->run());
section.name = PROG_SECTION_QUIT;
setSection(section);
delete game;
}
void Prog::run()
{
// Bucle principal
while (!(getSection() == PROG_SECTION_QUIT))
{
switch (getSection())
{
case PROG_SECTION_LOGO:
//runLogo();
break;
case PROG_SECTION_INTRO:
//runIntro();
break;
case PROG_SECTION_TITLE:
//runTitle();
break;
case PROG_SECTION_GAME:
runGame();
break;
}
}
}

View File

@@ -2,14 +2,63 @@
#include <SDL2/SDL.h>
#include <string>
#include "asset.h"
#include "jail_audio.h"
#include "game.h"
#include "input.h"
#include "utils.h"
#include "screen.h"
#ifndef PROG_H
#define PROG_H
#define WINDOW_CAPTION "Volcano"
#define WINDOW_WIDTH 320
#define WINDOW_HEIGHT 240
#define GAME_WIDTH 320
#define GAME_HEIGHT 240
class Prog
{
private:
Asset *asset;
SDL_Window *window; // La ventana donde dibujamos
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto encargado de gestionar los ficheros de recursos
Screen *screen; // Objeto encargado de dibujar en pantalla
Game *game; // Objeto para la sección del juego
Input *input; // Objeto Input para gestionar las entradas
section_t section; // Sección y subsección actual del programa;
struct options_t *options; // Contiene las opciones del programa
// Inicializa jail_audio
void initJailAudio();
// Arranca SDL y crea la ventana
bool initSDL();
// 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();
// Ejecuta la seccion de juego de la introducción
void runIntro();
// Ejecuta la seccion de juego con el titulo y los menus
void runTitle();
// Ejecuta la seccion de juego donde se juega
void runGame();
public:
// Constructor

View File

@@ -6,6 +6,16 @@
#ifndef UTILS_H
#define UTILS_H
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
// Secciones del programa
#define PROG_SECTION_LOGO 0
#define PROG_SECTION_INTRO 1
#define PROG_SECTION_TITLE 2
#define PROG_SECTION_GAME 3
#define PROG_SECTION_QUIT 4
// Estructura para definir un circulo
struct circle_t
{
@@ -32,12 +42,14 @@ struct section_t
// Estructura con todas las opciones de configuración del programa
struct options_t
{
Uint8 difficulty; // Dificultad del juego
Uint8 language; // Idioma usado en el juego
Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa
Uint8 windowSize; // Contiene el valor del 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
bool vSync; // Indica si se quiere usar vsync o no
int screenWidth; // Ancho de la pantalla/ventana
int screenHeight; // Alto de la pantalla/ventana
bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
};
// Calcula el cuadrado de la distancia entre dos puntos