From bbe82d329b70be9d48a73c4f8d7e0b8d4621803c Mon Sep 17 00:00:00 2001 From: Sergio Valor Martinez Date: Wed, 7 Dec 2022 11:23:19 +0100 Subject: [PATCH] Los datos se guardan en la carpeta de sistema --- source/director.cpp | 184 ++++++++++++++++++++++++++++++++------- source/director.h | 14 ++- source/game.cpp | 79 +++++++++++++---- source/hiscore_table.cpp | 5 +- source/instructions.cpp | 2 +- source/main.cpp | 8 +- source/title.cpp | 34 ++++++-- 7 files changed, 262 insertions(+), 64 deletions(-) diff --git a/source/director.cpp b/source/director.cpp index 77db82e..6ebe934 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -5,25 +5,38 @@ #include #include #include +#include +#include + +#ifndef _WIN32 +#include +#endif // Constructor -Director::Director(std::string path) +Director::Director(int argc, char *argv[]) { // Inicializa variables section.name = PROG_SECTION_LOGO; - // Crea el objeto que controla los ficheros de recursos - asset = new Asset(path); - - // Establece la lista de ficheros - if (!setFileList()) - { // Si falta algún fichero no inicia el programa - section.name = PROG_SECTION_QUIT; - } - // Inicializa las opciones del programa initOptions(); + // Comprueba los parametros del programa + checkProgramArguments(argc, argv); + + // Crea la carpeta del sistema donde guardar datos + createSystemFolder(); + + // Crea el objeto que controla los ficheros de recursos + asset = new Asset(executablePath); + asset->setVerbose(options->console); + + // Si falta algún fichero no inicia el programa + if (!setFileList()) + { + exit(EXIT_FAILURE); + } + // Carga el fichero de configuración loadConfigFile(); @@ -108,7 +121,10 @@ bool Director::initSDL() if (SDL_Init(SDL_INIT_EVERYTHING) < 0) // if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0) { - std::cout << "SDL could not initialize!\nSDL Error: " << SDL_GetError() << std::endl; + if (options->console) + { + std::cout << "SDL could not initialize!\nSDL Error: " << SDL_GetError() << std::endl; + } success = false; } else @@ -119,7 +135,10 @@ bool Director::initSDL() // Establece el filtro de la textura if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options->filter).c_str())) { - std::cout << "Warning: Nearest texture filtering not enabled!\n"; + if (options->console) + { + std::cout << "Warning: Nearest texture filtering not enabled!\n"; + } } // Crea la ventana @@ -133,7 +152,10 @@ bool Director::initSDL() window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (options->gameWidth + incW) * options->windowSize, (options->gameHeight + incH) * options->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); if (window == nullptr) { - std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + if (options->console) + { + std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + } success = false; } else @@ -150,7 +172,10 @@ bool Director::initSDL() if (renderer == nullptr) { - std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + if (options->console) + { + std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + } success = false; } else @@ -167,7 +192,10 @@ bool Director::initSDL() } } - std::cout << std::endl; + if (options->console) + { + std::cout << std::endl; + } return success; } @@ -181,10 +209,9 @@ bool Director::setFileList() #endif // Ficheros de configuración - asset->add(prefix + "/data/config/score.bin", t_data, false); + asset->add(systemFolder + "/config.txt", t_data, false, true); + asset->add(systemFolder + "/score.bin", t_data, false, true); asset->add(prefix + "/data/config/demo.bin", t_data); - asset->add(prefix + "/data/config/config.txt", t_data, false); - asset->add(prefix + "/data/config/jailer_id.txt", t_data, false); asset->add(prefix + "/data/config/gamecontrollerdb.txt", t_data); // Musicas @@ -321,13 +348,11 @@ void Director::initOptions() inp.deviceType = INPUT_USE_GAMECONTROLLER; options->input.push_back(inp); + // Video options->gameWidth = GAMECANVAS_WIDTH; options->gameHeight = GAMECANVAS_HEIGHT; options->videoMode = 0; options->windowSize = 3; - options->language = ba_BA; - options->difficulty = DIFFICULTY_NORMAL; - options->playerSelected = 0; options->filter = FILTER_NEAREST; options->vSync = true; options->integerScale = true; @@ -336,6 +361,12 @@ void Director::initOptions() options->borderHeight = 0; options->borderEnabled = false; + // Varios + options->playerSelected = 0; + options->difficulty = DIFFICULTY_NORMAL; + options->language = ba_BA; + options->console = false; + // Online options->online.enabled = false; options->online.server = ""; @@ -345,6 +376,77 @@ void Director::initOptions() options->online.score = 0; } +// Comprueba los parametros del programa +void Director::checkProgramArguments(int argc, char *argv[]) +{ + // Establece la ruta del programa + executablePath = argv[0]; + + // Comprueba el resto de parametros + for (int i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "--console") == 0) + { + options->console = true; + } + } +} + +// Crea la carpeta del sistema donde guardar datos +void Director::createSystemFolder() +{ +#ifdef DEBUG + const std::string folderName = "coffee_crisis_debug"; +#else + const std::string folderName = "coffee_crisis"; +#endif + +#ifdef _WIN32 + systemFolder = std::string(getenv("APPDATA")) + "/" + folderName; +#elif __APPLE__ + struct passwd *pw = getpwuid(getuid()); + const char *homedir = pw->pw_dir; + systemFolder = std::string(homedir) + "/Library/Application Support/" + folderName; +#elif __linux__ + struct passwd *pw = getpwuid(getuid()); + const char *homedir = pw->pw_dir; + systemFolder = std::string(homedir) + "/." + folderName; +#endif + + struct stat st = {0}; + if (stat(systemFolder.c_str(), &st) == -1) + { + errno = 0; +#ifdef _WIN32 + int ret = mkdir(systemFolder.c_str()); +#else + int ret = mkdir(systemFolder.c_str(), S_IRWXU); +#endif + + if (ret == -1) + { + switch (errno) + { + case EACCES: + printf("the parent directory does not allow write"); + exit(EXIT_FAILURE); + + case EEXIST: + printf("pathname already exists"); + exit(EXIT_FAILURE); + + case ENAMETOOLONG: + printf("pathname is too long"); + exit(EXIT_FAILURE); + + default: + perror("mkdir"); + exit(EXIT_FAILURE); + } + } + } +} + // Carga el fichero de configuración bool Director::loadConfigFile() { @@ -352,14 +454,18 @@ bool Director::loadConfigFile() bool success = true; // Variables para manejar el fichero + const std::string filePath = "config.txt"; std::string line; - std::ifstream file(asset->get("config.txt")); + std::ifstream file(asset->get(filePath)); // Si el fichero se puede abrir if (file.good()) { // Procesa el fichero linea a linea - std::cout << "Reading file config.txt\n"; + if (options->console) + { + std::cout << "Reading file " << filePath << std::endl; + } while (std::getline(file, line)) { // Comprueba que la linea no sea un comentario @@ -370,15 +476,21 @@ bool Director::loadConfigFile() // Procesa las dos subcadenas if (!setOptions(options, line.substr(0, pos), line.substr(pos + 1, line.length()))) { - std::cout << "Warning: file config.txt\n"; - std::cout << "unknown parameter " << line.substr(0, pos).c_str() << std::endl; + if (options->console) + { + std::cout << "Warning: file " << filePath << std::endl; + std::cout << "Unknown parameter " << line.substr(0, pos).c_str() << std::endl; + } success = false; } } } // Cierra el fichero - std::cout << "Closing file config.txt\n\n"; + if (options->console) + { + std::cout << "Closing file " << filePath << std::endl; + } file.close(); } @@ -544,7 +656,10 @@ void Director::initOnline() if (options->online.jailerID == "") { // Jailer ID no definido screen->showNotification("No ha especificado ningun Jailer ID"); - std::cout << "No ha especificado ningun Jailer ID" << std::endl; + if (options->console) + { + std::cout << "No ha especificado ningun Jailer ID" << std::endl; + } } else { // Jailer ID iniciado @@ -556,12 +671,18 @@ void Director::initOnline() if (jscore::initOnlineScore(options->online.gameID)) { screen->showNotification(options->online.jailerID + " ha iniciado sesion"); - std::cout << options->online.jailerID << " ha iniciado sesion" << std::endl; + if (options->console) + { + std::cout << options->online.jailerID << " ha iniciado sesion" << std::endl; + } } else { screen->showNotification("Fallo al conectar a " + options->online.server); - std::cout << "Fallo al conectar a " << options->online.server << std::endl; + if (options->console) + { + std::cout << "Fallo al conectar a " << options->online.server << std::endl; + } options->online.enabled = false; @@ -573,7 +694,10 @@ void Director::initOnline() if (points == 0) { // Fallo de conexión o no hay registros screen->showNotification("No se ha podido obtener la puntuacion online"); - std::cout << "No se ha podido obtener la puntuacion online" << std::endl; + if (options->console) + { + std::cout << "No se ha podido obtener la puntuacion online" << std::endl; + } } else { diff --git a/source/director.h b/source/director.h index 36dc7bb..5094bd1 100644 --- a/source/director.h +++ b/source/director.h @@ -45,8 +45,10 @@ private: Asset *asset; // Objeto que gestiona todos los ficheros de recursos // Variables - struct options_t *options; // Variable con todas las opciones del programa - section_t section; // Sección y subsección actual del programa; + struct options_t *options; // Variable con todas las opciones del programa + section_t section; // Sección y subsección actual del programa; + std::string executablePath; // Path del ejecutable + std::string systemFolder; // Carpeta del sistema donde guardar datos // Inicializa jail_audio void initJailAudio(); @@ -75,6 +77,12 @@ private: // Guarda el fichero de configuración bool saveConfigFile(); + // Comprueba los parametros del programa + void checkProgramArguments(int argc, char *argv[]); + + // Crea la carpeta del sistema donde guardar datos + void createSystemFolder(); + // Establece el valor de la variable void setSection(section_t section); @@ -92,7 +100,7 @@ private: public: // Constructor - Director(std::string path); + Director(int argc, char *argv[]); // Destructor ~Director(); diff --git a/source/game.cpp b/source/game.cpp index 3d8088b..560bbb5 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -385,8 +385,11 @@ void Game::init() // Carga los recursos necesarios para la sección 'Game' void Game::loadMedia() { - std::cout << std::endl - << "** LOADING RESOURCES FOR GAME SECTION" << std::endl; + if (options->console) + { + std::cout << std::endl + << "** LOADING RESOURCES FOR GAME SECTION" << std::endl; + } // Carga ficheros loadScoreFile(); @@ -573,8 +576,11 @@ void Game::loadMedia() // Musicas gameMusic = JA_LoadMusic(asset->get("playing.ogg").c_str()); - std::cout << "** RESOURCES FOR GAME SECTION LOADED" << std::endl - << std::endl; + if (options->console) + { + std::cout << "** RESOURCES FOR GAME SECTION LOADED" << std::endl + << std::endl; + } } // Carga el fichero de puntos @@ -589,13 +595,19 @@ bool Game::loadScoreFile() // El fichero no existe if (file == nullptr) { - std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl; + if (options->console) + { + std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl; + } // Creamos el fichero para escritura file = SDL_RWFromFile(p.c_str(), "w+b"); if (file != nullptr) { - std::cout << "New file (" << filename.c_str() << ") created!" << std::endl; + if (options->console) + { + std::cout << "New file (" << filename.c_str() << ") created!" << std::endl; + } // Inicializamos los datos for (int i = 0; i < TOTAL_SCORE_DATA; ++i) @@ -609,7 +621,10 @@ bool Game::loadScoreFile() } else { - std::cout << "Error: Unable to create file " << filename.c_str() << std::endl; + if (options->console) + { + std::cout << "Error: Unable to create file " << filename.c_str() << std::endl; + } success = false; } } @@ -617,7 +632,10 @@ bool Game::loadScoreFile() else { // Cargamos los datos - std::cout << "Reading file " << filename.c_str() << std::endl; + if (options->console) + { + std::cout << "Reading file " << filename.c_str() << std::endl; + } for (int i = 0; i < TOTAL_SCORE_DATA; ++i) SDL_RWread(file, &scoreDataFile[i], sizeof(Uint32), 1); @@ -655,13 +673,19 @@ bool Game::loadDemoFile() // El fichero no existe if (file == nullptr) { - std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl; + if (options->console) + { + std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl; + } // Creamos el fichero para escritura file = SDL_RWFromFile(p.c_str(), "w+b"); if (file != nullptr) { - std::cout << "New file (" << filename.c_str() << ") created!" << std::endl; + if (options->console) + { + std::cout << "New file (" << filename.c_str() << ") created!" << std::endl; + } // Inicializamos los datos for (int i = 0; i < TOTAL_DEMO_DATA; ++i) @@ -681,7 +705,10 @@ bool Game::loadDemoFile() } else { - std::cout << "Error: Unable to create file " << filename.c_str() << std::endl; + if (options->console) + { + std::cout << "Error: Unable to create file " << filename.c_str() << std::endl; + } success = false; } } @@ -689,7 +716,10 @@ bool Game::loadDemoFile() else { // Cargamos los datos - std::cout << "Reading file " << filename.c_str() << std::endl; + if (options->console) + { + std::cout << "Reading file " << filename.c_str() << std::endl; + } for (int i = 0; i < TOTAL_DEMO_DATA; ++i) SDL_RWread(file, &demo.dataFile[i], sizeof(demoKeys_t), 1); @@ -715,14 +745,20 @@ bool Game::saveScoreFile() SDL_RWwrite(file, &scoreDataFile[i], sizeof(Uint32), 1); } - std::cout << "Writing file " << filename.c_str() << std::endl; + if (options->console) + { + std::cout << "Writing file " << filename.c_str() << std::endl; + } // Cerramos el fichero SDL_RWclose(file); } else { - std::cout << "Error: Unable to save " << filename.c_str() << " file! " << SDL_GetError() << std::endl; + if (options->console) + { + std::cout << "Error: Unable to save " << filename.c_str() << " file! " << SDL_GetError() << std::endl; + } } return success; } @@ -771,14 +807,20 @@ bool Game::saveDemoFile() SDL_RWwrite(file, &demo.dataFile[i], sizeof(demoKeys_t), 1); } - std::cout << "Writing file " << filename.c_str() << std::endl; + if (options->console) + { + std::cout << "Writing file " << filename.c_str() << std::endl; + } // Cerramos el fichero SDL_RWclose(file); } else { - std::cout << "Error: Unable to save " << filename.c_str() << " file! " << SDL_GetError() << std::endl; + if (options->console) + { + std::cout << "Error: Unable to save " << filename.c_str() << " file! " << SDL_GetError() << std::endl; + } } } return success; @@ -3851,7 +3893,10 @@ void Game::loadAnimations(std::string filePath, std::vector *buffer if (file) { - std::cout << "Animation loaded: " << filePath.substr(filePath.find_last_of("\\/") + 1).c_str() << std::endl; + if (options->console) + { + std::cout << "Animation loaded: " << filePath.substr(filePath.find_last_of("\\/") + 1).c_str() << std::endl; + } while (std::getline(file, line)) { buffer->push_back(line); diff --git a/source/hiscore_table.cpp b/source/hiscore_table.cpp index 5d0c091..3eedae6 100644 --- a/source/hiscore_table.cpp +++ b/source/hiscore_table.cpp @@ -22,7 +22,10 @@ HiScoreTable::HiScoreTable(SDL_Renderer *renderer, Screen *screen, Asset *asset, backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); if (backbuffer == nullptr) { - std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + if (options->console) + { + std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + } } // Inicializa variables diff --git a/source/instructions.cpp b/source/instructions.cpp index 14a4bed..2bd43cc 100644 --- a/source/instructions.cpp +++ b/source/instructions.cpp @@ -40,7 +40,7 @@ Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset, backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); if (backbuffer == nullptr) { - std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } // Inicializa variables diff --git a/source/main.cpp b/source/main.cpp index babfef2..5538a1e 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -42,12 +42,12 @@ Reescribiendo el código el 27/09/2022 #include "director.h" #include -int main(int argc, char *args[]) +int main(int argc, char *argv[]) { - std::cout << "Starting the game...\n\n"; - + std::cout << "Starting the game..." << std::endl; + // Crea el objeto Director - Director *director = new Director(args[0]); + Director *director = new Director(argc, argv); // Bucle principal director->run(); diff --git a/source/title.cpp b/source/title.cpp index f81aa85..9a401a4 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -1025,8 +1025,11 @@ bool Title::updatePlayerInputs(int numPlayer) } else { // Si hay mas de un dispositivo, se recorre el vector - std::cout << "numplayer:" << numPlayer << std::endl; - std::cout << "deviceindex:" << deviceIndex[numPlayer] << std::endl; + if (options->console) + { + std::cout << "numplayer:" << numPlayer << std::endl; + std::cout << "deviceindex:" << deviceIndex[numPlayer] << std::endl; + } // Incrementa el indice if (deviceIndex[numPlayer] < numDevices - 1) @@ -1037,7 +1040,10 @@ bool Title::updatePlayerInputs(int numPlayer) { deviceIndex[numPlayer] = 0; } - std::cout << "deviceindex:" << deviceIndex[numPlayer] << std::endl; + if (options->console) + { + std::cout << "deviceindex:" << deviceIndex[numPlayer] << std::endl; + } // Si coincide con el del otro jugador, se lo intercambian if (deviceIndex[0] == deviceIndex[1]) @@ -1065,7 +1071,10 @@ void Title::createTiledBackground() background = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH * 2, GAMECANVAS_HEIGHT * 2); if (background == nullptr) { - std::cout << "TitleSurface could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + if (options->console) + { + std::cout << "TitleSurface could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + } } // Crea los objetos para pintar en la textura de fondo @@ -1101,7 +1110,10 @@ void Title::createTiledBackground() // Comprueba cuantos mandos hay conectados para gestionar el menu de opciones void Title::checkInputDevices() { - std::cout << "Filling devices for options menu..." << std::endl; + if (options->console) + { + std::cout << "Filling devices for options menu..." << std::endl; + } input->discoverGameController(); const int numControllers = input->getNumControllers(); availableInputDevices.clear(); @@ -1115,7 +1127,10 @@ void Title::checkInputDevices() temp.name = input->getControllerName(i); temp.deviceType = INPUT_USE_GAMECONTROLLER; availableInputDevices.push_back(temp); - std::cout << "Device " << (int)availableInputDevices.size() << " - " << temp.name.c_str() << std::endl; + if (options->console) + { + std::cout << "Device " << (int)availableInputDevices.size() << " - " << temp.name.c_str() << std::endl; + } } // Añade el teclado al final @@ -1123,8 +1138,11 @@ void Title::checkInputDevices() temp.name = "KEYBOARD"; temp.deviceType = INPUT_USE_KEYBOARD; availableInputDevices.push_back(temp); - std::cout << "Device " << (int)availableInputDevices.size() << " - " << temp.name.c_str() << std::endl; - std::cout << std::endl; + if (options->console) + { + std::cout << "Device " << (int)availableInputDevices.size() << " - " << temp.name.c_str() << std::endl; + std::cout << std::endl; + } } // Recarga las texturas