#include "demo.h" #include // Para SDL_Rect #include // Para SDL_GetTicks #include // Para basic_ostream, basic_ios, operator<<, cout #include "asset.h" // Para Asset #include "const.h" // Para BLOCK, PLAY_AREA_WIDTH, SECTION_DEMO #include "input.h" // Para Input, REPEAT_FALSE, inputs_e #include "item_tracker.h" // Para ItemTracker #include "resource.h" // Para Resource #include "room.h" // Para Room #include "screen.h" // Para Screen #include "text.h" // Para Text, TXT_CENTER, TXT_COLOR #include "utils.h" // Para color_t, stringToColor, options_t, secti... #include "options.h" #include "debug.h" // Constructor Demo::Demo() : screen(Screen::get()), renderer(Screen::get()->getRenderer()), resource(Resource::get()), asset(Asset::get()), input(Input::get()), debug(Debug::get()) { // Inicia algunas variables board.iniClock = SDL_GetTicks(); rooms.push_back("04.room"); rooms.push_back("54.room"); rooms.push_back("20.room"); rooms.push_back("09.room"); rooms.push_back("05.room"); rooms.push_back("11.room"); rooms.push_back("31.room"); rooms.push_back("44.room"); roomIndex = 0; currentRoom = rooms[roomIndex]; // Crea los objetos itemTracker = new ItemTracker(); scoreboard = new Scoreboard(&board); room = new Room(resource->getRoom(currentRoom), itemTracker, &board.items, false); eventHandler = new SDL_Event(); text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); // Inicializa el resto de variables counter = 0; roomTime = 400; ticks = 0; ticksSpeed = 15; board.lives = 9; board.items = 0; board.rooms = 1; board.jailEnabled = false; board.music = true; setScoreBoardColor(); options.section.name = SECTION_DEMO; options.section.subsection = 0; } Demo::~Demo() { // Libera la memoria de los objetos delete itemTracker; delete scoreboard; delete room; delete eventHandler; delete text; } // Comprueba los eventos de la cola void Demo::checkEvents() { // Comprueba los eventos que hay en la cola while (SDL_PollEvent(eventHandler) != 0) { // Evento de salida de la aplicación if (eventHandler->type == SDL_QUIT) { options.section.name = SECTION_QUIT; screen->setBorderColor(stringToColor(options.palette, "black")); break; } } } // Comprueba las entradas void Demo::checkInput() { if (input->checkInput(input_exit, REPEAT_FALSE)) { options.section.name = SECTION_QUIT; } else if (input->checkInput(input_toggle_border, REPEAT_FALSE)) { screen->toggleBorder(); reLoadTextures(); } else if (input->checkInput(input_toggle_videomode, REPEAT_FALSE)) { screen->toggleVideoMode(); reLoadTextures(); } else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) { screen->decWindowSize(); reLoadTextures(); } else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) { screen->incWindowSize(); reLoadTextures(); } else if (input->checkInput(input_toggle_palette, REPEAT_FALSE)) { switchPalette(); } else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_jump, REPEAT_FALSE)) { options.section.name = SECTION_TITLE; options.section.subsection = 0; } } // Bucle para el juego void Demo::run() { while (options.section.name == SECTION_DEMO) { update(); checkEvents(); render(); } } // Actualiza el juego, las variables, comprueba la entrada, etc. void Demo::update() { // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego if (SDL_GetTicks() - ticks > ticksSpeed) { // Actualiza el contador de ticks ticks = SDL_GetTicks(); // Comprueba las entradas checkInput(); // Actualiza los objetos room->update(); scoreboard->update(); screen->updateFX(); checkRoomChange(); screen->update(); } } // Pinta los objetos en pantalla void Demo::render() { // Prepara para dibujar el frame screen->start(); // Dibuja los elementos del juego en orden room->renderMap(); room->renderEnemies(); room->renderItems(); renderRoomName(); scoreboard->render(); screen->renderFX(); // Actualiza la pantalla screen->render(); } // Escribe el nombre de la pantalla void Demo::renderRoomName() { // Texto en el centro de la pantalla SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2}; color_t color = stringToColor(options.palette, "white"); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_RenderFillRect(renderer, &rect); text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room->getName(), 1, room->getBGColor()); } // Recarga todas las texturas void Demo::reLoadTextures() { if (options.console) { std::cout << "** RELOAD REQUESTED" << std::endl; } room->reLoadTexture(); scoreboard->reLoadTexture(); text->reLoadTexture(); } // Cambia la paleta void Demo::switchPalette() { // Modifica la variable if (options.palette == p_zxspectrum) { options.palette = p_zxarne; } else { options.palette = p_zxspectrum; } room->reLoadPalette(); scoreboard->reLoadPalette(); // Pone el color del marcador en función del color del borde de la habitación setScoreBoardColor(); } // Cambia de habitación bool Demo::changeRoom(std::string file) { // En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada if (file != "0") // Verifica que exista el fichero que se va a cargar if (asset->get(file) != "") { // Elimina la habitación actual delete room; room = nullptr; // Crea un objeto habitación nuevo a partir del fichero room = new Room(resource->getRoom(file), itemTracker, &board.items, false); // Pone el color del marcador en función del color del borde de la habitación setScoreBoardColor(); return true; } return false; } // Comprueba si se ha de cambiar de habitación void Demo::checkRoomChange() { counter++; if (counter == roomTime) { counter = 0; roomIndex++; if (roomIndex == (int)rooms.size()) { options.section.name = SECTION_LOGO; options.section.subsection = SUBSECTION_LOGO_TO_TITLE; } else { changeRoom(rooms[roomIndex]); } } } // Pone el color del marcador en función del color del borde de la habitación void Demo::setScoreBoardColor() { // Obtiene el color del borde const color_t c = room->getBorderColor(); // Si el color es negro lo cambia a blanco const color_t cBlack = stringToColor(options.palette, "black"); board.color = colorAreEqual(c, cBlack) ? stringToColor(options.palette, "white") : c; // Si el color es negro brillante lo cambia a blanco const color_t cBrightBlack = stringToColor(options.palette, "bright_black"); board.color = colorAreEqual(c, cBrightBlack) ? stringToColor(options.palette, "white") : c; }