#include "common/utils.h" #include "const.h" #include "director.h" #include #include #include #include #include #ifndef _WIN32 #include #endif // Constructor Director::Director(int argc, char *argv[]) { // Inicializa variables section = new section_t(); #ifdef RECORDING section->name = SECTION_PROG_GAME; section->subsection = SUBSECTION_GAME_PLAY_1P; #else section->name = SECTION_PROG_LOGO; #endif // Comprueba los parametros del programa checkProgramArguments(argc, argv); // Crea la carpeta del sistema donde guardar datos createSystemFolder("jailgames"); createSystemFolder("jailgames/coffee_crisis_arcade_edition"); // Inicializa las opciones del programa initOptions(); // 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 los parametros para configurar el juego loadParams(); // Carga el fichero de configuración loadConfigFile(); // Inicializa SDL initSDL(); // Inicializa JailAudio initJailAudio(); // Crea los objetos lang = new Lang(asset); lang->setLang(options->game.language); input = new Input(asset->get("gamecontrollerdb.txt")); initInput(); screen = new Screen(window, renderer, asset, input, options); // Carga los sonidos del juego loadSounds(); // Carga las musicas del juego loadMusics(); } Director::~Director() { saveConfigFile(); delete asset; delete input; delete screen; delete lang; delete options; delete param; delete section; deleteSounds(); deleteMusics(); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); } // Inicializa el objeto input void Director::initInput() { // Establece si ha de mostrar mensajes #ifdef VERBOSE input->setVerbose(true); #else input->setVerbose(options->console); #endif // Busca si hay mandos conectados input->discoverGameControllers(); // Teclado - Movimiento del jugador input->bindKey(input_up, SDL_SCANCODE_UP); input->bindKey(input_down, SDL_SCANCODE_DOWN); input->bindKey(input_left, SDL_SCANCODE_LEFT); input->bindKey(input_right, SDL_SCANCODE_RIGHT); input->bindKey(input_fire_left, SDL_SCANCODE_Q); input->bindKey(input_fire_center, SDL_SCANCODE_W); input->bindKey(input_fire_right, SDL_SCANCODE_E); input->bindKey(input_start, SDL_SCANCODE_RETURN); // Teclado - Otros input->bindKey(input_accept, SDL_SCANCODE_RETURN); input->bindKey(input_cancel, SDL_SCANCODE_ESCAPE); input->bindKey(input_pause, SDL_SCANCODE_P); input->bindKey(input_exit, SDL_SCANCODE_ESCAPE); input->bindKey(input_window_dec_size, SDL_SCANCODE_F1); input->bindKey(input_window_inc_size, SDL_SCANCODE_F2); input->bindKey(input_window_fullscreen, SDL_SCANCODE_F3); input->bindKey(input_video_shaders, SDL_SCANCODE_F4); const int numGamePads = input->getNumControllers(); for (int i = 0; i < numGamePads; ++i) { // Mando - Movimiento del jugador input->bindGameControllerButton(i, input_up, SDL_CONTROLLER_BUTTON_DPAD_UP); input->bindGameControllerButton(i, input_down, SDL_CONTROLLER_BUTTON_DPAD_DOWN); input->bindGameControllerButton(i, input_left, SDL_CONTROLLER_BUTTON_DPAD_LEFT); input->bindGameControllerButton(i, input_right, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); input->bindGameControllerButton(i, input_fire_left, SDL_CONTROLLER_BUTTON_X); input->bindGameControllerButton(i, input_fire_center, SDL_CONTROLLER_BUTTON_Y); input->bindGameControllerButton(i, input_fire_right, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); input->bindGameControllerButton(i, input_start, SDL_CONTROLLER_BUTTON_START); // Mando - Otros input->bindGameControllerButton(i, input_accept, SDL_CONTROLLER_BUTTON_START); input->bindGameControllerButton(i, input_cancel, SDL_CONTROLLER_BUTTON_A); input->bindGameControllerButton(i, input_pause, SDL_CONTROLLER_BUTTON_B); input->bindGameControllerButton(i, input_exit, SDL_CONTROLLER_BUTTON_BACK); } // Comprueba si ha de modificar las asignaciones por las que hay en las opciones en caso de coincidir el nombre del mando for (int i = 0; i < numGamePads; ++i) for (int index = 0; index < (int)options->controller.size(); ++index) if (input->getControllerName(i) == options->controller[index].name) for (int j = 0; j < (int)options->controller[index].inputs.size(); ++j) { input->bindGameControllerButton(i, options->controller[index].inputs[j], options->controller[index].buttons[j]); } // Modifica las opciones para colocar los valores asignados for (int index = 0; index < numGamePads; ++index) { options->controller[index].name = input->getControllerName(index); for (int j = 0; j < (int)options->controller[index].inputs.size(); ++j) { options->controller[index].buttons[j] = input->getControllerBinding(index, options->controller[index].inputs[j]); } } } // Inicializa JailAudio void Director::initJailAudio() { JA_Init(48000, AUDIO_S16, 2); JA_EnableMusic(options->audio.music.enabled); JA_EnableSound(options->audio.sound.enabled); JA_SetMusicVolume(options->audio.music.volume); JA_SetSoundVolume(options->audio.sound.volume); } // Arranca SDL y crea la ventana bool Director::initSDL() { // Indicador de éxito bool success = true; // Inicializa SDL if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { if (options->console) { std::cout << "SDL could not initialize!\nSDL Error: " << SDL_GetError() << std::endl; } success = false; } else { // Inicia el generador de numeros aleatorios std::srand(static_cast(SDL_GetTicks())); // Establece el filtro de la textura if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options->video.filter).c_str())) { if (options->console) { std::cout << "Warning: texture filtering not enabled!\n"; } } #ifndef NO_SHADERS if (!SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl")) { if (options->console) { std::cout << "Warning: opengl not enabled!\n"; } } #endif // Crea la ventana int incW = 0; int incH = 0; if (options->video.border.enabled) { incW = options->video.border.width * 2; incH = options->video.border.height * 2; } window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (param->gameWidth + incW) * options->video.window.size, (param->gameHeight + incH) * options->video.window.size, SDL_WINDOW_HIDDEN); if (window == nullptr) { if (options->console) { std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } success = false; } else { // Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones Uint32 flags = 0; if (options->video.vSync) { flags = flags | SDL_RENDERER_PRESENTVSYNC; } #ifndef NO_SHADERS // La aceleración se activa según el define flags = flags | SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; #endif renderer = SDL_CreateRenderer(window, -1, flags); if (renderer == nullptr) { if (options->console) { std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } 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, param->gameWidth, param->gameHeight); // Establece el modo de mezcla SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); } } } if (options->console) { std::cout << std::endl; } return success; } // Crea el indice de ficheros bool Director::setFileList() { #ifdef MACOS_BUNDLE const std::string prefix = "/../Resources"; #else const std::string prefix = ""; #endif // Ficheros de configuración asset->add(systemFolder + "/config.txt", t_data, false, true); asset->add(systemFolder + "/score.bin", t_data, false, true); asset->add(prefix + "/data/config/param.txt", t_data); asset->add(prefix + "/data/config/demo1.bin", t_data); asset->add(prefix + "/data/config/demo2.bin", t_data); asset->add(prefix + "/data/config/gamecontrollerdb.txt", t_data); // Notificaciones asset->add(prefix + "/data/notifications/notify.png", t_bitmap); // Musicas asset->add(prefix + "/data/music/intro.ogg", t_music); asset->add(prefix + "/data/music/playing.ogg", t_music); asset->add(prefix + "/data/music/title.ogg", t_music); // Sonidos asset->add(prefix + "/data/sound/balloon.wav", t_sound); asset->add(prefix + "/data/sound/bubble1.wav", t_sound); asset->add(prefix + "/data/sound/bubble2.wav", t_sound); asset->add(prefix + "/data/sound/bubble3.wav", t_sound); asset->add(prefix + "/data/sound/bubble4.wav", t_sound); asset->add(prefix + "/data/sound/bullet.wav", t_sound); asset->add(prefix + "/data/sound/coffeeout.wav", t_sound); asset->add(prefix + "/data/sound/hiscore.wav", t_sound); asset->add(prefix + "/data/sound/itemdrop.wav", t_sound); asset->add(prefix + "/data/sound/itempickup.wav", t_sound); asset->add(prefix + "/data/sound/menu_move.wav", t_sound); asset->add(prefix + "/data/sound/menu_select.wav", t_sound); asset->add(prefix + "/data/sound/player_collision.wav", t_sound); asset->add(prefix + "/data/sound/stage_change.wav", t_sound); asset->add(prefix + "/data/sound/title.wav", t_sound); asset->add(prefix + "/data/sound/clock.wav", t_sound); asset->add(prefix + "/data/sound/powerball.wav", t_sound); asset->add(prefix + "/data/sound/notify.wav", t_sound); // Shaders asset->add(prefix + "/data/shaders/crtpi.glsl", t_data); // Texturas asset->add(prefix + "/data/gfx/balloon1.png", t_bitmap); asset->add(prefix + "/data/gfx/balloon1.ani", t_data); asset->add(prefix + "/data/gfx/balloon2.png", t_bitmap); asset->add(prefix + "/data/gfx/balloon2.ani", t_data); asset->add(prefix + "/data/gfx/balloon3.png", t_bitmap); asset->add(prefix + "/data/gfx/balloon3.ani", t_data); asset->add(prefix + "/data/gfx/balloon4.png", t_bitmap); asset->add(prefix + "/data/gfx/balloon4.ani", t_data); asset->add(prefix + "/data/gfx/bullet.png", t_bitmap); asset->add(prefix + "/data/gfx/game_buildings.png", t_bitmap); asset->add(prefix + "/data/gfx/game_clouds.png", t_bitmap); asset->add(prefix + "/data/gfx/game_grass.png", t_bitmap); asset->add(prefix + "/data/gfx/game_power_meter.png", t_bitmap); asset->add(prefix + "/data/gfx/game_sky_colors.png", t_bitmap); asset->add(prefix + "/data/gfx/game_text.png", t_bitmap); asset->add(prefix + "/data/gfx/intro.png", t_bitmap); asset->add(prefix + "/data/gfx/logo_jailgames.png", t_bitmap); asset->add(prefix + "/data/gfx/logo_jailgames_mini.png", t_bitmap); asset->add(prefix + "/data/gfx/logo_since_1998.png", t_bitmap); asset->add(prefix + "/data/gfx/menu_game_over.png", t_bitmap); asset->add(prefix + "/data/gfx/menu_game_over_end.png", t_bitmap); asset->add(prefix + "/data/gfx/item_points1_disk.png", t_bitmap); asset->add(prefix + "/data/gfx/item_points1_disk.ani", t_data); asset->add(prefix + "/data/gfx/item_points2_gavina.png", t_bitmap); asset->add(prefix + "/data/gfx/item_points2_gavina.ani", t_data); asset->add(prefix + "/data/gfx/item_points3_pacmar.png", t_bitmap); asset->add(prefix + "/data/gfx/item_points3_pacmar.ani", t_data); asset->add(prefix + "/data/gfx/item_clock.png", t_bitmap); asset->add(prefix + "/data/gfx/item_clock.ani", t_data); asset->add(prefix + "/data/gfx/item_coffee.png", t_bitmap); asset->add(prefix + "/data/gfx/item_coffee.ani", t_data); asset->add(prefix + "/data/gfx/item_coffee_machine.png", t_bitmap); asset->add(prefix + "/data/gfx/item_coffee_machine.ani", t_data); asset->add(prefix + "/data/gfx/title_bg_tile.png", t_bitmap); asset->add(prefix + "/data/gfx/title_coffee.png", t_bitmap); asset->add(prefix + "/data/gfx/title_crisis.png", t_bitmap); asset->add(prefix + "/data/gfx/title_dust.png", t_bitmap); asset->add(prefix + "/data/gfx/title_dust.ani", t_data); asset->add(prefix + "/data/gfx/player1.gif", t_bitmap); asset->add(prefix + "/data/gfx/player1_pal1.gif", t_bitmap); asset->add(prefix + "/data/gfx/player1_pal2.gif", t_bitmap); asset->add(prefix + "/data/gfx/player1_pal3.gif", t_bitmap); asset->add(prefix + "/data/gfx/player2.gif", t_bitmap); asset->add(prefix + "/data/gfx/player2_pal1.gif", t_bitmap); asset->add(prefix + "/data/gfx/player2_pal2.gif", t_bitmap); asset->add(prefix + "/data/gfx/player2_pal3.gif", t_bitmap); asset->add(prefix + "/data/gfx/player.ani", t_data); asset->add(prefix + "/data/gfx/player1_power.gif", t_bitmap); asset->add(prefix + "/data/gfx/player2_power.gif", t_bitmap); asset->add(prefix + "/data/gfx/player_power.ani", t_data); // Fuentes de texto asset->add(prefix + "/data/font/8bithud.png", t_font); asset->add(prefix + "/data/font/8bithud.txt", t_font); asset->add(prefix + "/data/font/nokia.png", t_font); asset->add(prefix + "/data/font/nokia_big2.png", t_font); asset->add(prefix + "/data/font/nokia.txt", t_font); asset->add(prefix + "/data/font/nokia2.png", t_font); asset->add(prefix + "/data/font/nokia2.txt", t_font); asset->add(prefix + "/data/font/nokia_big2.txt", t_font); asset->add(prefix + "/data/font/smb2_big.png", t_font); asset->add(prefix + "/data/font/smb2_big.txt", t_font); asset->add(prefix + "/data/font/smb2.png", t_font); asset->add(prefix + "/data/font/smb2.txt", t_font); // Textos asset->add(prefix + "/data/lang/es_ES.txt", t_lang); asset->add(prefix + "/data/lang/en_UK.txt", t_lang); asset->add(prefix + "/data/lang/ba_BA.txt", t_lang); return asset->check(); } // Carga los parametros para configurar el juego void Director::loadParams() { param = new param_t; loadParam(param, asset->get("param.txt")); options->video.window.width = options->video.window.size * param->gameWidth; options->video.window.height = options->video.window.size * param->gameHeight; options->video.gameWidth = param->gameWidth; options->video.gameHeight = param->gameHeight; } // Inicializa las opciones del programa void Director::initOptions() { // Crea el puntero a la estructura de opciones options = new options_t; // Pone unos valores por defecto para las opciones // Opciones varias #ifdef VERBOSE options->console = true; #else options->console = false; #endif // Opciones de video options->video.mode = 0; options->video.window.size = 3; options->video.filter = FILTER_NEAREST; options->video.vSync = true; options->video.integerScale = true; options->video.keepAspect = true; options->video.border.width = 0; options->video.border.height = 0; options->video.border.enabled = false; options->video.shaders = true; // Opciones de audio options->audio.music.enabled = true; options->audio.music.volume = 128; options->audio.sound.enabled = true; options->audio.sound.volume = 64; // Opciones de juego options->game.difficulty = DIFFICULTY_NORMAL; options->game.language = ba_BA; ManageHiScoreTable *m = new ManageHiScoreTable(&options->game.hiScoreTable); m->clear(); delete m; // Opciones de control options->controller.clear(); op_controller_t c; const int numPlayers = 2; for (int index = 0; index < numPlayers; ++index) { c.index = index; c.deviceType = INPUT_USE_GAMECONTROLLER; c.name = "NO NAME"; c.inputs.clear(); c.inputs.push_back(input_fire_left); c.inputs.push_back(input_fire_center); c.inputs.push_back(input_fire_right); c.inputs.push_back(input_start); c.inputs.push_back(input_exit); c.buttons.clear(); c.buttons.push_back(SDL_CONTROLLER_BUTTON_X); c.buttons.push_back(SDL_CONTROLLER_BUTTON_Y); c.buttons.push_back(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); c.buttons.push_back(SDL_CONTROLLER_BUTTON_START); c.buttons.push_back(SDL_CONTROLLER_BUTTON_BACK); options->controller.push_back(c); } options->controller[0].deviceType = INPUT_USE_ANY; // El primer jugador puede usar tanto el teclado como el primer mando } // 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(std::string folder) { #ifdef _WIN32 systemFolder = std::string(getenv("APPDATA")) + "/" + folder; #elif __APPLE__ struct passwd *pw = getpwuid(getuid()); const char *homedir = pw->pw_dir; systemFolder = std::string(homedir) + "/Library/Application Support" + "/" + folder; #elif __linux__ struct passwd *pw = getpwuid(getuid()); const char *homedir = pw->pw_dir; systemFolder = std::string(homedir) + "/." + folder; #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() { // Indicador de éxito en la carga bool success = true; // Variables para manejar el fichero const std::string filePath = "config.txt"; std::string line; std::ifstream file(asset->get(filePath)); // Si el fichero se puede abrir if (file.good()) { // Procesa el fichero linea a linea if (options->console) { std::cout << "Reading file " << filePath << std::endl; } while (std::getline(file, line)) { // Comprueba que la linea no sea un comentario if (line.substr(0, 1) != "#") { // Encuentra la posición del caracter '=' int pos = line.find("="); // Procesa las dos subcadenas if (!setOptions(options, line.substr(0, pos), line.substr(pos + 1, line.length()))) { 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 if (options->console) { std::cout << "Closing file " << filePath << std::endl; } file.close(); } // El fichero no existe else { // Crea el fichero con los valores por defecto saveConfigFile(); } // Normaliza los valores const bool a = options->video.mode == 0; const bool b = options->video.mode == SDL_WINDOW_FULLSCREEN; const bool c = options->video.mode == SDL_WINDOW_FULLSCREEN_DESKTOP; if (!(a || b || c)) { options->video.mode = 0; } if (options->video.window.size < 1 || options->video.window.size > 4) { options->video.window.size = 3; } if (options->game.language < 0 || options->game.language > MAX_LANGUAGES) { options->game.language = en_UK; } return success; } // Guarda el fichero de configuración bool Director::saveConfigFile() { bool success = true; // Crea y abre el fichero de texto std::ofstream file(asset->get("config.txt")); if (file.good()) { if (options->console) { std::cout << asset->get("config.txt") << " open for writing" << std::endl; } } else { if (options->console) { std::cout << asset->get("config.txt") << " can't be opened" << std::endl; } } // Opciones de video file << "## VIDEO\n"; file << "## video.mode [0: window, 1: full screen]\n"; file << "## video.filter [0: nearest, 1: lineal]\n"; file << "\n"; if (options->video.mode == VIDEO_MODE_WINDOW) { file << "video.mode=0\n"; } else if (options->video.mode == VIDEO_MODE_FULLSCREEN) { file << "video.mode=1\n"; } file << "video.window.size=" + std::to_string(options->video.window.size) + "\n"; options->video.filter == FILTER_NEAREST ? file << "video.filter=0\n" : file << "video.filter=1\n"; file << "video.shaders=" + boolToString(options->video.shaders) + "\n"; file << "video.vSync=" + boolToString(options->video.vSync) + "\n"; file << "video.integerScale=" + boolToString(options->video.integerScale) + "\n"; file << "video.keepAspect=" + boolToString(options->video.keepAspect) + "\n"; file << "video.border.enabled=" + boolToString(options->video.border.enabled) + "\n"; file << "video.border.width=" + std::to_string(options->video.border.width) + "\n"; file << "video.border.height=" + std::to_string(options->video.border.height) + "\n"; // Opciones de audio file << "\n\n## AUDIO\n"; file << "## volume [0 .. 128]\n"; file << "\n"; file << "audio.music.enabled=" + boolToString(options->audio.music.enabled) + "\n"; file << "audio.music.volume=" + std::to_string(options->audio.music.volume) + "\n"; file << "audio.sound.enabled=" + boolToString(options->audio.sound.enabled) + "\n"; file << "audio.sound.volume=" + std::to_string(options->audio.sound.volume) + "\n"; // Opciones del juego file << "\n\n## GAME\n"; file << "## game.language [0: spanish, 1: valencian, 2: english]\n"; file << "## game.difficulty [0: easy, 1: normal, 2: hard]\n"; file << "\n"; file << "game.language=" + std::to_string(options->game.language) + "\n"; file << "game.difficulty=" + std::to_string(options->game.difficulty) + "\n"; // Opciones de mandos file << "\n\n## CONTROLLERS\n"; file << "\n"; const int numPlayers = 2; for (int index = 0; index < numPlayers; ++index) { const std::string joyIndex = std::to_string(index + 1); file << "controller" + joyIndex + ".name=" + options->controller[index].name + "\n"; file << "controller" + joyIndex + ".inputs.fire_left=" + std::to_string((int)options->controller[index].buttons[0]) + "\n"; file << "controller" + joyIndex + ".inputs.fire_center=" + std::to_string((int)options->controller[index].buttons[1]) + "\n"; file << "controller" + joyIndex + ".inputs.fire_right=" + std::to_string((int)options->controller[index].buttons[2]) + "\n"; file << "controller" + joyIndex + ".inputs.fire_start=" + std::to_string((int)options->controller[index].buttons[3]) + "\n"; file << "controller" + joyIndex + ".inputs.fire_exit=" + std::to_string((int)options->controller[index].buttons[4]) + "\n"; if (index < numPlayers - 1) { file << "\n"; } } // Cierra el fichero file.close(); return success; } // Carga los sonidos del juego void Director::loadSounds() { // Obtiene la lista con las rutas a los ficheros de sonidos std::vector list = asset->getListByType(t_sound); sounds.clear(); for (auto l : list) { const size_t lastIndex = l.find_last_of("/") + 1; const std::string name = l.substr(lastIndex, std::string::npos); sound_file_t temp; temp.name = name; // Añade el nombre del fichero temp.file = JA_LoadSound(l.c_str()); // Carga el fichero de audio sounds.push_back(temp); } } // Carga las musicas del juego void Director::loadMusics() { // Obtiene la lista con las rutas a los ficheros musicales std::vector list = asset->getListByType(t_music); musics.clear(); for (auto l : list) { const size_t lastIndex = l.find_last_of("/") + 1; const std::string name = l.substr(lastIndex, std::string::npos); music_file_t temp; temp.name = name; // Añade el nombre del fichero temp.file = JA_LoadMusic(l.c_str()); // Carga el fichero de audio musics.push_back(temp); } } // Descarga los sonidos del juego void Director::deleteSounds() { for (auto s : sounds) { JA_DeleteSound(s.file); } sounds.clear(); } // Descarga las músicas del juego void Director::deleteMusics() { for (auto m : musics) { JA_DeleteMusic(m.file); } musics.clear(); } // Ejecuta la seccion de juego con el logo void Director::runLogo() { logo = new Logo(renderer, screen, asset, input, param, section); logo->run(); delete logo; } // Ejecuta la seccion de juego de la introducción void Director::runIntro() { intro = new Intro(renderer, screen, asset, input, lang, param, section, getMusic(musics, "intro.ogg")); intro->run(); delete intro; } // Ejecuta la seccion de juego con el titulo y los menus void Director::runTitle() { title = new Title(renderer, screen, input, asset, options, lang, param, section, getMusic(musics, "title.ogg")); title->run(); delete title; } // Ejecuta la seccion de juego donde se juega void Director::runGame() { const int playerID = section->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2; game = new Game(playerID, 0, renderer, screen, asset, lang, input, false, param, options, section, getMusic(musics, "playing.ogg")); game->run(); delete game; } // Ejecuta la parte donde se muestra la tabla de puntuaciones void Director::runHiScoreTable() { hiScoreTable = new HiScoreTable(renderer, screen, asset, input, lang, param, options, section); hiScoreTable->run(); delete hiScoreTable; } // Ejecuta la parte donde se muestran las instrucciones void Director::runInstructions() { instructions = new Instructions(renderer, screen, asset, input, lang, param, section); instructions->run(); delete instructions; } // Ejecuta el juego en modo demo void Director::runDemoGame() { const int playerID = (rand() % 2) + 1; demoGame = new Game(playerID, 0, renderer, screen, asset, lang, input, true, param, options, section, nullptr); demoGame->run(); delete demoGame; } void Director::run() { // Bucle principal while (section->name != SECTION_PROG_QUIT) { switch (section->name) { case SECTION_PROG_LOGO: runLogo(); break; case SECTION_PROG_INTRO: runIntro(); break; case SECTION_PROG_TITLE: runTitle(); break; case SECTION_PROG_GAME: runGame(); break; case SECTION_PROG_HI_SCORE_TABLE: runHiScoreTable(); break; case SECTION_PROG_GAME_DEMO: runDemoGame(); break; case SECTION_PROG_INSTRUCTIONS: runInstructions(); break; } } } // Asigna variables a partir de dos cadenas bool Director::setOptions(options_t *options, std::string var, std::string value) { // Indicador de éxito en la asignación bool success = true; // Opciones de video if (var == "video.mode") { if (value == "0") { options->video.mode = VIDEO_MODE_WINDOW; } else { options->video.mode = VIDEO_MODE_FULLSCREEN; } } else if (var == "video.window.size") { options->video.window.size = std::stoi(value); if ((options->video.window.size < 1) || (options->video.window.size > 4)) { options->video.window.size = 3; } } else if (var == "video.filter") { if (value == "0") { options->video.filter = FILTER_NEAREST; } else { options->video.filter = FILTER_LINEAL; } } else if (var == "video.shaders") { options->video.shaders = stringToBool(value); } else if (var == "video.vSync") { options->video.vSync = stringToBool(value); } else if (var == "video.integerScale") { options->video.integerScale = stringToBool(value); } else if (var == "video.keepAspect") { options->video.keepAspect = stringToBool(value); } else if (var == "video.border.enabled") { options->video.border.enabled = stringToBool(value); } else if (var == "video.border.width") { options->video.border.width = std::stoi(value); } else if (var == "video.border.height") { options->video.border.height = std::stoi(value); } // Opciones de audio else if (var == "audio.music.enabled") { options->audio.music.enabled = stringToBool(value); } else if (var == "audio.music.volume") { options->audio.music.volume = std::stoi(value); } else if (var == "audio.sound.enabled") { options->audio.sound.enabled = stringToBool(value); } else if (var == "audio.sound.volume") { options->audio.sound.volume = std::stoi(value); } // Opciones de juego else if (var == "game.language") { options->game.language = std::stoi(value); } else if (var == "game.difficulty") { options->game.difficulty = std::stoi(value); } // Opciones de mandos else if (var == "controller1.name") { options->controller[0].name = value; } else if (var == "controller1.inputs.fire_left") { options->controller[0].buttons[0] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller1.inputs.fire_center") { options->controller[0].buttons[1] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller1.inputs.fire_right") { options->controller[0].buttons[2] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller1.inputs.fire_start") { options->controller[0].buttons[3] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller1.inputs.fire_exit") { options->controller[0].buttons[4] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller2.name") { options->controller[1].name = value; } else if (var == "controller2.inputs.fire_left") { options->controller[1].buttons[0] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller2.inputs.fire_center") { options->controller[1].buttons[1] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller2.inputs.fire_right") { options->controller[1].buttons[2] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller2.inputs.fire_start") { options->controller[1].buttons[3] = (SDL_GameControllerButton)std::stoi(value); } else if (var == "controller2.inputs.fire_exit") { options->controller[1].buttons[4] = (SDL_GameControllerButton)std::stoi(value); } // Lineas vacias o que empiezan por comentario else if (var == "" || var.substr(0, 1) == "#") { } else { success = false; } return success; }