#include "gamestates.h" #include "jgame.h" #include #include #include "aux_font.h" #include "proc_mapa.h" #include "proc_arounders.h" namespace gamestate { namespace play { namespace eixir { const int no = 0; const int postfase = 1; const int mort = 2; } draw::surface *faded = nullptr; draw::surface *fondo = nullptr; draw::surface *cursor = nullptr; draw::surface *aigua = nullptr; uint32_t *original_palette = nullptr; uint32_t arounderCount; uint32_t startTicks; uint32_t currentTicks; int aigua_frame1 = 0; int aigua_frame2 = 5; int exit = 0; bool loop(); bool loop_pause(); bool loop_menu(); void backToLoop(); void draw(); void draw_aigua(); void finalize(); void init() { // Ara comença tot, per tant no volem eixir play::exit = play::eixir::no; // Carregar el fondo que toque i la seua paleta (que nomes usa els colors del 128 al 255) char arxiuFondo[10] = "BKG00.GIF"; arxiuFondo[4] = (game::getConfig("fase") % 10) + 48; play::fondo = draw::loadSurface(arxiuFondo, true); // Carregar la paleta estandar (colors del 0 al 128) uint32_t *pal = draw::loadPalette("tiles.gif"); draw::setPalette(pal, 128); free(pal); // Carregar els gifs auxiliars i crear la superficie per al fondo de la pausa i el menu play::cursor = draw::loadSurface("cursor.gif"); play::aigua = draw::loadSurface("aigua.gif"); play::faded = draw::createSurface(320, 200); arounders::init(); // [TODO] Crear el primer Arounder // REALMENT NO. PREFEREIXC QUE PASEN UNS SEGONS ABANS QUE ARRIBE EL PRIMER // mapa::arounders::eixits++; // arounder_seleccionat = primerArounders // Enxufa el arradio audio::loadMusic((game::getConfig("fase")+1) % 5 == 0 ? "mus6.ogg" : "mus4.ogg"); audio::playMusic(); // Fiquem a contar el cronómetre de arounders play::arounderCount = play::startTicks = game::getTicks(); // Fade in i anem al bucle principal draw::fadein(); game::setState(gamestate::play::loop); } bool loop() { // Si ja s'ha demanat l'eixida... if (play::exit) { // I si ja s'ha acabat el fadeout... if (!draw::isfading()) { // Alliberem memòria play::finalize(); // I anem on toque if (play::exit==play::eixir::postfase) gamestate::postfase::init(); else if (play::exit==play::eixir::mort) gamestate::mort::init(); } // En qualsevol cas, renderitzem i eixim ja del bucle (fins que acabe el fadeout) draw::render(); return true; } // Pintar tot menys el cursor play::draw(); // Si se pulsa 'P', o el botó del mig del ratolí, o si la finestra perd el foco... if (input::keyPressed(SDL_SCANCODE_P) || input::mouseClk(input::mouse::button::middle) || !game::windowHasFocus) { // Parem el cronòmetre d'arounders play::arounderCount = game::getTicks() - play::arounderCount; // Pintem el que hi ha a la pantalla en la surface "faded", li afegim el text "PAUSA" i aixó es tot el que pintarem fins eixir de la pausa draw::setSource(nullptr); draw::setDestination(play::faded); draw::draw(); font::selectFont(font::type::fade); font::print(136, 80, "PAUSA"); draw::setDestination(nullptr); // Reduïm tots els colors de la paleta (menys els epecials) a la meitat del seu color play::original_palette = draw::getPalette(); for (int i=0; i<256; ++i) if ( i!=61 && i!= 62 && (i<68 || i >75) ) { uint32_t p = play::original_palette[i]; uint8_t r = (p >> 16) & 0xff; uint8_t g = (p >> 8) & 0xff; uint8_t b = p & 0xff; draw::setPaletteEntry(i, r >> 1, g >> 1, b >> 1); } // Canviem el bucle principal a "loop_pausa()" game::setState(gamestate::play::loop_pause); return true; } // Si se pulsa ESC... if (input::keyPressed(SDL_SCANCODE_ESCAPE)) { // Parem el cronòmetre d'arounders play::arounderCount = game::getTicks() - play::arounderCount; // Pintem el que hi ha a la pantalla en la surface "faded", li afegim el menú i aixó es tot el que pintarem fins eixir del menú draw::setSource(nullptr); draw::setDestination(play::faded); draw::draw(); draw::surface *menu = draw::loadSurface("menu.gif"); draw::setSource(menu); draw::draw(97, 52); draw::freeSurface(menu); font::selectFont(font::type::fade); font::print(129, 60, "CONTINUAR"); font::print(129, 71, "REINICIAR"); font::print(112, 82, "MENU PRINCIPAL"); font::print(143, 93, "EIXIR"); draw::setDestination(nullptr); // Reduïm tots els colors de la paleta (menys els epecials) a la meitat del seu color play::original_palette = draw::getPalette(); for (int i=0; i<256; ++i) if ( i!=61 && i!= 62 && (i<68 || i >75) ) { uint32_t p = play::original_palette[i]; uint8_t r = (p >> 16) & 0xff; uint8_t g = (p >> 8) & 0xff; uint8_t b = p & 0xff; draw::setPaletteEntry(i, r >> 1, g >> 1, b >> 1); } // Canviem el bucle principal a "loop_menu()" game::setState(gamestate::play::loop_menu); return true; } // Ara ja, pintem el cursor i enviem tot a pantalla // No ho havem fet abans perque en el fondo de la pausa o el menú no volem que aparega el cursor draw::setSource(cursor); draw::draw(input::mouseX(), input::mouseY()); draw::render(); // Si pulsem el botó de la dreta, el arounder seleccionat deixa de fer l'acció que està fent if (input::mouseClk(input::mouse::button::right)) { arounders::abortarAccio(); } if (input::mouseClk(input::mouse::button::left)) { if (!arounders::seleccionar()) { if (input::mouseY()<165 && arounders::seleccionat != nullptr && arounders::seleccionat->accio == arounders::accions::caminar) { arounders::seleccionat->orientacio = input::mouseX() > arounders::seleccionat->x ? arounders::orientacions::dreta : arounders::orientacions::esquerra; } } const int botoPulsat = mapa::procesar(); if (botoPulsat != -1 && arounders::seleccionat != nullptr) { if (botoPulsat == arounders::seleccionat->prevista) { arounders::seleccionat->prevista = arounders::seleccionat->accio; } else { arounders::seleccionat->prevista = botoPulsat; } } } currentTicks = game::getTicks() - startTicks; if( currentTicks >= mapa::velocitat ) { startTicks = game::getTicks(); aigua_frame1 = (aigua_frame1+1)%10; aigua_frame2 = (aigua_frame2+1)%10; arounders::procesar(); } if ( (game::getTicks() - arounderCount) >= mapa::velocitat*58) { if (mapa::arounders::eixits < mapa::arounders::totals) { arounders::afegir(); mapa::arounders::eixits++; arounderCount = game::getTicks(); } } if (mapa::arounders::arrivats + mapa::arounders::morts == mapa::arounders::totals) { if (mapa::arounders::arrivats >= mapa::arounders::necessaris) { game::setConfig("fase", game::getConfig("fase")+1); draw::fadeout(); audio::fadeoutMusic(); play::exit = 1; } else { draw::fadeout(); audio::fadeoutMusic(); play::exit = 2; } } return true; } bool loop_pause() { draw::draw(faded); draw::setSource(cursor); draw::draw(input::mouseX(), input::mouseY()); draw::render(); if (input::keyPressed(SDL_SCANCODE_P) || input::keyPressed(SDL_SCANCODE_ESCAPE)) { play::backToLoop(); } return true; } bool loop_menu() { if (play::exit) { if (!draw::isfading()) { play::finalize(); if (exit==1) { mapa::carregar(); gamestate::play::init(); } if (exit==2) gamestate::menu::init(); } draw::render(); return true; } draw::draw(faded); draw::setSource(cursor); draw::draw(input::mouseX(), input::mouseY()); draw::render(); if (input::keyPressed(SDL_SCANCODE_ESCAPE)) { play::backToLoop(); } if (input::mouseClk(input::mouse::button::left)) { if (input::mouseX() >= 97 && input::mouseX() <= 223) { if (input::mouseY() >= 60 && input::mouseY() <= 65) { play::backToLoop(); } if (input::mouseY() >= 71 && input::mouseY() <= 76) { free(play::original_palette); draw::fadeout(); audio::fadeoutMusic(); play::exit = 1; } if (input::mouseY() >= 82 && input::mouseY() <= 87) { free(play::original_palette); draw::fadeout(); audio::fadeoutMusic(); play::exit = 2; } if (input::mouseY() >= 93 && input::mouseY() <= 98) { return false; } } } return true; } void backToLoop() { draw::setPalette(play::original_palette, 256); free(play::original_palette); game::setState(gamestate::play::loop); arounderCount = game::getTicks() - arounderCount; } void draw() { draw::draw(play::fondo); int accio = 0; int prevista = 0; if (arounders::seleccionat) { accio = arounders::seleccionat->accio; prevista = arounders::seleccionat->prevista; } mapa::pintar(accio, prevista); draw_aigua(); arounders::pintar(); // [TODO] de fet, pintar la marca en el modul "arounders" /* if (arounders::seleccionat) { draw::setSource(marca); draw::draw(arounderSeleccionat->X-3, arounderSeleccionat->Y-3); } */ } void draw_aigua() { static int frames1[10] = {0,1,2,1,0,3,4,5,4,3}; static int frames2[10] = {6,7,8,7,6,9,10,11,10,9}; int *frames; frames = (game::getConfig("fase")+1) % 5 == 0 ? frames2 : frames1; draw::setSource(aigua); for (int i=0;i<10;i++) { draw::draw(i*32, 150, 16, 15, frames[aigua_frame1]*16, 0); draw::draw(16+i*32, 150, 16, 15, frames[aigua_frame2]*16, 0); } } void finalize() { draw::freeSurface(faded); draw::freeSurface(fondo); draw::freeSurface(cursor); draw::freeSurface(aigua); } } }