diff --git a/source/const.h b/source/const.h index 292994b..4768f47 100644 --- a/source/const.h +++ b/source/const.h @@ -9,7 +9,7 @@ // Textos #define WINDOW_CAPTION "Coffee Crisis" -#define TEXT_COPYRIGHT "@2020,2021 JAILDESIGNER (V1.5)" +#define TEXT_COPYRIGHT "@2020,2021 JailDesigner (v2.0)" // Recursos #define BINFILE_SCORE 0 @@ -143,7 +143,7 @@ const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3; // Variables del jugador #define PLAYER_INVULNERABLE_COUNTER 200 -#define PLAYER_POWERUP_COUNTER 2500 +#define PLAYER_POWERUP_COUNTER 1500 // Secciones del programa #define PROG_SECTION_LOGO 0 @@ -345,5 +345,9 @@ const color_t shdwTxtColor = {0x43, 0x43, 0x4F}; #define NUMBER_OF_ENEMY_FORMATIONS 100 #define MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION 50 +// Dificultad del juego +#define DIFFICULTY_EASY 0 +#define DIFFICULTY_NORMAL 1 +#define DIFFICULTY_HARD 2 #endif \ No newline at end of file diff --git a/source/director.cpp b/source/director.cpp index 3c42670..8ea2fae 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -10,15 +10,40 @@ // Constructor Director::Director(std::string path) { - // Crea los objetos - mInput1 = new Input(USE_KEYBOARD); - mInput2 = new Input(USE_GAMECONTROLLER); - mOptions = new options_t; - - // Inicializa variables + // Inicializa la ruta setExecutablePath(path); + + // Establece la lista de ficheros setFileList(); - checkFileList(); + + // Si falta algún fichero no inicies el programa + Uint8 section = PROG_SECTION_LOGO; + if (!checkFileList()) + section = PROG_SECTION_QUIT; + + // Crea el objeto y carga el fichero de configuración + mOptions = new options_t; + if (!loadConfigFile()) + { + mOptions->fullScreenMode = 0; + mOptions->windowSize = 3; + mOptions->language = en_UK; + mOptions->fullScreenMode = 0; + mOptions->fullScreenModePrevious = 0; + mOptions->windowSize = 3; + mOptions->windowSizePrevious = 3; + mOptions->language = en_UK; + mOptions->languagePrevious = en_UK; + mOptions->difficulty = 0; + mOptions->player1Input = INPUT_USE_KEYBOARD; + mOptions->player2Input = INPUT_USE_GAMECONTROLLER; + mOptions->filter = 0; + mOptions->vSync = true; + } + + // Crea los objetos + mInput1 = new Input(mOptions->player1Input); + mInput2 = new Input(mOptions->player2Input); // Inicializa SDL initSDL(); @@ -39,7 +64,7 @@ Director::Director(std::string path) #endif // Inicializa el resto de variables - init(); + init(section); } Director::~Director() @@ -63,18 +88,10 @@ Director::~Director() } // Inicia las variables necesarias para arrancar el programa -void Director::init() +void Director::init(Uint8 name) { - // Carga el fichero de configuración - if (!loadConfigFile()) - { - mOptions->fullScreenMode = 0; - mOptions->windowSize = 3; - mOptions->language = en_UK; - } - // Sección - mSection.name = PROG_SECTION_LOGO; + mSection.name = name; mSection.subsection = 0; // Textos @@ -96,7 +113,7 @@ void Director::init() mInput1->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W); mInput1->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E); #endif - mInput1->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); // PAUSE + mInput1->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); // PAUSE mInput1->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); // ESCAPE mInput2->bindGameController(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP); @@ -108,7 +125,7 @@ void Director::init() mInput2->bindGameController(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_X); mInput2->bindGameController(INPUT_BUTTON_2, SDL_CONTROLLER_BUTTON_Y); mInput2->bindGameController(INPUT_BUTTON_3, SDL_CONTROLLER_BUTTON_B); - mInput2->bindGameController(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE); // PAUSE + mInput2->bindGameController(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE); // PAUSE mInput2->bindGameController(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE); // ESCAPE } @@ -149,7 +166,8 @@ bool Director::initSDL() else { // Crea un renderizador para la ventana con vsync - mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + //mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED); if (mRenderer == NULL) { printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError()); @@ -176,7 +194,11 @@ bool Director::initSDL() // Crea el indice de ficheros void Director::setFileList() { - // Ficheros binarios + // Inicializa el vector + for (int i = 0; i < 100; i++) + mFileList[i] = ""; + + // Ficheros binarios #ifdef __MIPSEL__ mFileList[0] = "/media/data/local/home/.coffee_crisis/score.bin"; mFileList[1] = "/media/data/local/home/.coffee_crisis/demo.bin"; @@ -220,7 +242,6 @@ void Director::setFileList() mFileList[33] = mExecutablePath + "/" + "../media/gfx/intro.png"; mFileList[34] = mExecutablePath + "/" + "../media/gfx/items.png"; mFileList[35] = mExecutablePath + "/" + "../media/gfx/logo.png"; - mFileList[36] = mExecutablePath + "/" + "../media/gfx/menu.png"; mFileList[37] = mExecutablePath + "/" + "../media/gfx/player1_body.png"; mFileList[38] = mExecutablePath + "/" + "../media/gfx/player1_death.png"; mFileList[39] = mExecutablePath + "/" + "../media/gfx/player1_legs.png"; @@ -237,79 +258,114 @@ void Director::setFileList() mFileList[28] = mExecutablePath + "/" + "../media/font/nokia.png"; mFileList[29] = mExecutablePath + "/" + "../media/font/smb2_big.png"; mFileList[47] = mExecutablePath + "/" + "../media/font/smb2_big.txt"; - mFileList[30] = mExecutablePath + "/" + "../media/font/smb2.png"; - mFileList[48] = mExecutablePath + "/" + "../media/font/smb2.txt"; + mFileList[30] = mExecutablePath + "/" + "../media/font/smb2.png"; + mFileList[48] = mExecutablePath + "/" + "../media/font/smb2.txt"; } // Comprueba que todos los ficheros existen bool Director::checkFileList() { bool success = true; - /*std::string p; + std::string p; std::string filename; SDL_RWops *file; + printf("Checking files...\n\n"); + // Comprueba los ficheros de musica - printf("\n>> MUSIC FILES\n"); + printf(">> MUSIC FILES\n"); if (success) - for (int i = 0; i < TOTAL_MUSIC; i++) + for (int i = 3; i < 100; i++) { - p = mMusic[i].file.c_str(); - filename = p.substr(p.find_last_of("\\/") + 1); - file = SDL_RWFromFile(p.c_str(), "r+b"); - if (file != NULL) + if (mFileList[i].find("/media/music/") != std::string::npos) { - printf("Checking file %-20s [OK]\n", filename.c_str()); + p = mFileList[i].c_str(); + filename = p.substr(p.find_last_of("\\/") + 1); + file = SDL_RWFromFile(p.c_str(), "r+b"); + if (file != NULL) + { + printf("Checking file %-20s [OK]\n", filename.c_str()); + } + else + { + printf("Checking file %-20s [ERROR]\n", filename.c_str()); + success = false; + break; + } + SDL_RWclose(file); } - else - { - printf("Checking file %-20s [ERROR]\n", filename.c_str()); - success = false; - break; - } - SDL_RWclose(file); } // Comprueba los ficheros de sonidos printf("\n>> SOUND FILES\n"); if (success) - for (int i = 0; i < TOTAL_SOUND; i++) + for (int i = 3; i < 100; i++) { - p = mSound[i].file.c_str(); - filename = p.substr(p.find_last_of("\\/") + 1); - file = SDL_RWFromFile(p.c_str(), "r+b"); - if (file != NULL) + if (mFileList[i].find("/media/sound/") != std::string::npos) { - printf("Checking file %-20s [OK]\n", filename.c_str()); + p = mFileList[i].c_str(); + filename = p.substr(p.find_last_of("\\/") + 1); + file = SDL_RWFromFile(p.c_str(), "r+b"); + if (file != NULL) + { + printf("Checking file %-20s [OK]\n", filename.c_str()); + } + else + { + printf("Checking file %-20s [ERROR]\n", filename.c_str()); + success = false; + break; + } + SDL_RWclose(file); } - else - { - printf("Checking file %-20s [ERROR]\n", filename.c_str()); - success = false; - break; - } - SDL_RWclose(file); } - // Comprueba los ficheros con texturas - printf("\n>> TEXTURE FILES\n"); + // Comprueba los ficheros con graficos + printf("\n>> BITMAP FILES\n"); if (success) - for (int i = 0; i < TOTAL_TEXTURE; i++) + for (int i = 3; i < 100; i++) { - p = mTexture[i].file.c_str(); - filename = p.substr(p.find_last_of("\\/") + 1); - file = SDL_RWFromFile(p.c_str(), "r+b"); - if (file != NULL) + if (mFileList[i].find("/media/gfx/") != std::string::npos) { - printf("Checking file %-20s [OK]\n", filename.c_str()); + p = mFileList[i].c_str(); + filename = p.substr(p.find_last_of("\\/") + 1); + file = SDL_RWFromFile(p.c_str(), "r+b"); + if (file != NULL) + { + printf("Checking file %-20s [OK]\n", filename.c_str()); + } + else + { + printf("Checking file %-20s [ERROR]\n", filename.c_str()); + success = false; + break; + } + SDL_RWclose(file); } - else + } + + // Comprueba los ficheros con fuentes de texto + printf("\n>> FONT FILES\n"); + if (success) + for (int i = 3; i < 100; i++) + { + if (mFileList[i].find("/media/font/") != std::string::npos) { - printf("Checking file %-20s [ERROR]\n", filename.c_str()); - success = false; - break; + p = mFileList[i].c_str(); + filename = p.substr(p.find_last_of("\\/") + 1); + file = SDL_RWFromFile(p.c_str(), "r+b"); + if (file != NULL) + { + printf("Checking file %-20s [OK]\n", filename.c_str()); + } + else + { + printf("Checking file %-20s [ERROR]\n", filename.c_str()); + success = false; + break; + } + SDL_RWclose(file); } - SDL_RWclose(file); } // Resultado @@ -318,7 +374,6 @@ bool Director::checkFileList() else printf("\n** A file is missing. Exiting.\n\n"); -*/ return success; } @@ -329,6 +384,11 @@ bool Director::loadConfigFile() mOptions->fullScreenMode = 0; mOptions->windowSize = 3; mOptions->language = en_UK; + mOptions->difficulty = DIFFICULTY_NORMAL; + mOptions->player1Input = INPUT_USE_KEYBOARD; + mOptions->player2Input = INPUT_USE_GAMECONTROLLER; + mOptions->filter = 0; + mOptions->vSync = true; // Indicador de éxito en la carga bool success = true; @@ -352,6 +412,11 @@ bool Director::loadConfigFile() SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1); SDL_RWwrite(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1); SDL_RWwrite(file, &mOptions->language, sizeof(mOptions->language), 1); + SDL_RWwrite(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1); + SDL_RWwrite(file, &mOptions->player1Input, sizeof(mOptions->player1Input), 1); + SDL_RWwrite(file, &mOptions->player2Input, sizeof(mOptions->player2Input), 1); + SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1); + SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); // Cierra el fichero SDL_RWclose(file); @@ -370,6 +435,11 @@ bool Director::loadConfigFile() SDL_RWread(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1); SDL_RWread(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1); SDL_RWread(file, &mOptions->language, sizeof(mOptions->language), 1); + SDL_RWread(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1); + SDL_RWread(file, &mOptions->player1Input, sizeof(mOptions->player1Input), 1); + SDL_RWread(file, &mOptions->player2Input, sizeof(mOptions->player2Input), 1); + SDL_RWread(file, &mOptions->filter, sizeof(mOptions->filter), 1); + SDL_RWread(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); // Normaliza los valores if (!((mOptions->fullScreenMode == 0) || @@ -403,9 +473,14 @@ bool Director::saveConfigFile() if (file != NULL) { // Guarda los datos - SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(Uint32), 1); - SDL_RWwrite(file, &mOptions->windowSize, sizeof(Uint8), 1); - SDL_RWwrite(file, &mOptions->language, sizeof(Uint8), 1); + SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1); + SDL_RWwrite(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1); + SDL_RWwrite(file, &mOptions->language, sizeof(mOptions->language), 1); + SDL_RWwrite(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1); + SDL_RWwrite(file, &mOptions->player1Input, sizeof(mOptions->player1Input), 1); + SDL_RWwrite(file, &mOptions->player2Input, sizeof(mOptions->player2Input), 1); + SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1); + SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); printf("Writing file %s\n", filename.c_str()); diff --git a/source/director.h b/source/director.h index 69954ec..b3e2cc3 100644 --- a/source/director.h +++ b/source/director.h @@ -50,9 +50,6 @@ private: // Inicializa jail_audio void initJailAudio(); - // Inicializa los textos del juego en el idioma seleccionado - //void initTextStrings(Uint8 lang); - // Arranca SDL y crea la ventana bool initSDL(); @@ -80,12 +77,16 @@ private: // 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: @@ -96,7 +97,7 @@ public: ~Director(); // Inicia las variables necesarias para arrancar el programa - void init(); + void init(Uint8 name); // Bucle principal void run(); diff --git a/source/fade.cpp b/source/fade.cpp index 6818139..17a96de 100644 --- a/source/fade.cpp +++ b/source/fade.cpp @@ -9,8 +9,6 @@ Fade::Fade(SDL_Renderer *renderer) mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT); if (mBackbuffer == NULL) printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError()); - - init(); } // Destructor @@ -21,15 +19,18 @@ Fade::~Fade() } // Inicializa las variables -void Fade::init() +void Fade::init(Uint8 r, Uint8 g, Uint8 b) { mFadeType = FADE_CENTER; mEnabled = false; mFinished = false; mCounter = 0; - mR = 0x27; - mG = 0x27; - mB = 0x36; + //mR = 0x27; + //mG = 0x27; + //mB = 0x36; + mR = r; + mG = g; + mB = b; } // Pinta una transición en pantalla diff --git a/source/fade.h b/source/fade.h index 4a6e63c..b5612ad 100644 --- a/source/fade.h +++ b/source/fade.h @@ -31,7 +31,7 @@ public: ~Fade(); // Inicializa las variables - void init(); + void init(Uint8 r, Uint8 g, Uint8 b); // Pinta una transición en pantalla void render(); diff --git a/source/game.cpp b/source/game.cpp index 5db84c3..bfb5f81 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -84,6 +84,9 @@ Game::Game(int numPlayers, SDL_Renderer *renderer, std::string *filelist, std::s Game::~Game() { + saveScoreFile(); + saveDemoFile(); + mRenderer = nullptr; mFileList = nullptr; mInput[0] = nullptr; @@ -286,8 +289,7 @@ void Game::init() mSection.subsection = GAME_SECTION_PLAY_1P; mMenaceCurrent = 0; mMenaceThreshold = 0; - //mScore = 0; - mHiScore = 0; + //mHiScore = 0; mHiScoreAchieved = false; mCurrentStage = 0; mStageBitmapCounter = STAGE_COUNTER; @@ -350,7 +352,7 @@ void Game::init() mDemo.counter = 0; // Iniciualiza el objeto para el fundido - mFade->init(); + mFade->init(0x27, 0x27, 0x36); // Inicializa los objetos de texto mText->init(); @@ -2131,25 +2133,19 @@ void Game::checkPlayerItemCollision(int index) JA_PlaySound(mSoundItemPickup); break; case ITEM_COFFEE: - mPlayer[index]->giveExtraHit(); - JA_PlaySound(mSoundItemPickup); if (mPlayer[index]->getCoffees() == 2) { mPlayer[index]->addScore(5000); updateHiScore(); createItemScoreSprite(mItem[i]->getPosX() + (mItem[i]->getWidth() / 2) - (m5000Bitmap->getWidth() / 2), mPlayer[index]->getPosY(), m5000Bitmap); } + mPlayer[index]->giveExtraHit(); + JA_PlaySound(mSoundItemPickup); break; case ITEM_COFFEE_MACHINE: mPlayer[index]->setPowerUp(true); JA_PlaySound(mSoundItemPickup); mCoffeeMachineEnabled = false; - { - printf("-collision-\n"); - printf("x\t%f\n", mItem[i]->getPosX()); - printf("y\t%f\n", mItem[i]->getPosY()); - printf("---\n"); - } break; default: @@ -2419,10 +2415,6 @@ void Game::throwPlayer(int x, int y, int index) const int sentit = ((rand() % 2) ? 1 : -1); mDeathIndex = getSmartSpriteFreeIndex(); - /*if (index == 1) - mSmartSprite[mDeathIndex]->init(mTexturePlayer1Death, mRenderer); - if (index == 2) - mSmartSprite[mDeathIndex]->init(mTexturePlayer2Death, mRenderer);*/ mSmartSprite[mDeathIndex]->init(mPlayer[index]->getDeadTexture(), mRenderer); mSmartSprite[mDeathIndex]->setPosX(x); mSmartSprite[mDeathIndex]->setPosY(y); @@ -3300,12 +3292,14 @@ void Game::runGameOverScreen() // Dibuja la informacion de debug en pantalla void Game::renderDebugInfo() { + const color_t color = {0xFF, 0x20, 0x20}; + //mText->writeShadowed(2, 2 + 0 * BLOCK, "POW: " + std::to_string(mPlayer[0]->mPowerUpCounter), color); + //if (mHelper.needCoffeeMachine) + // mText->writeShadowed(2, 2 + 1 * BLOCK, "NEED COFFEMACHINE", color); + if (mDebug.enabled) { - const color_t color = {0xFF, 0x20, 0x20}; - - SDL_RenderSetLogicalSize(mRenderer, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2); - + //SDL_RenderSetLogicalSize(mRenderer, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2); mText->writeShadowed(2, 2 + 0 * BLOCK, "menace(umb): " + std::to_string(mMenaceCurrent) + "(" + std::to_string(mMenaceThreshold) + ")", color); mText->writeShadowed(2, 2 + 1 * BLOCK, "currentPower: " + std::to_string(mStage[mCurrentStage].currentPower), color); mText->writeShadowed(2, 2 + 2 * BLOCK, "mCurrentStage:" + std::to_string(mCurrentStage), color); diff --git a/source/input.cpp b/source/input.cpp index 1550d51..40cb5a3 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -17,41 +17,19 @@ Input::Input(int source) mSource = source; - if (mSource == USE_GAMECONTROLLER) - { - /* - if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1) - SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); - - int nJoysticks = SDL_NumJoysticks(); - int numGamepads = 0; - - // Count how many controllers there are - for (int i = 0; i < nJoysticks; i++) - if (SDL_IsGameController(i)) - numGamepads++; - - printf("%i joysticks found, %i are gamepads\n", nJoysticks, numGamepads); - //SDL_JoystickEventState(SDL_ENABLE); - */ - if (!discoverGameController()) - mSource = USE_KEYBOARD; - } - - // Comprueba si hay algún mando conectado - //discoverGameController(); - - // En caso de haber un mando, el objeto se puede utilizar con entradas de mando - //if (mGameControllerFound) - // mSource = source; - // Si no hay un mando, el objeto se configura como teclado - //else - // mSource = USE_KEYBOARD; - - if (mSource == USE_KEYBOARD) - printf("Input using KEYBOARD\n"); + if (mSource == INPUT_USE_KEYBOARD) + printf("\nInput requested KEYBOARD\n"); else - printf("Input using GAMECONTROLLER\n"); + printf("\nInput requested GAMECONTROLLER"); + + if (mSource == INPUT_USE_GAMECONTROLLER) + if (!discoverGameController()) + mSource = INPUT_USE_KEYBOARD; + + if (mSource == INPUT_USE_KEYBOARD) + printf("Input asigned was KEYBOARD\n"); + else + printf("Input asigned was GAMECONTROLLER (%s)\n", SDL_GameControllerNameForIndex(0)); } // Destructor @@ -74,7 +52,7 @@ void Input::bindGameController(Uint8 input, SDL_GameControllerButton button) // Comprueba si un input esta activo bool Input::checkInput(Uint8 input, bool repeat) { - if (mSource == USE_KEYBOARD) + if (mSource == INPUT_USE_KEYBOARD) { const Uint8 *mKeystates = SDL_GetKeyboardState(NULL); @@ -152,173 +130,41 @@ bool Input::checkInput(Uint8 input, bool repeat) } } -// Gestiona las entradas desde el mando de juego -/*bool Input::checkGameController(Uint8 state) -{ - bool success = false; - - // No hay mando. Siempre devuelve falso salvo NO_INPUT que siempre es cierto - if (!mGameControllerFound) - { - if (state == NO_INPUT) - return true; - else - return false; - } - - - switch (state) - { - case INPUT_NULL: - success = !checkGameController(INPUT_UP) && !checkGameController(INPUT_DOWN) && !checkGameController(INPUT_LEFT) && !checkGameController(INPUT_RIGHT) && - !checkGameController(INPUT_ACCEPT) && !checkGameController(INPUT_CANCEL) && !checkGameController(INPUT_PAUSE) && - !checkGameController(INPUT_FIRE_UP) && !checkGameController(INPUT_FIRE_LEFT) && !checkGameController(INPUT_FIRE_RIGHT); - break; - case INPUT_UP: - success = (SDL_JoystickGetAxis(mGameController, 1) < -JOYSTICK_DEAD_ZONE) || (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_DPAD_UP)); - break; - case INPUT_DOWN: - success = (SDL_JoystickGetAxis(mGameController, 1) > JOYSTICK_DEAD_ZONE) || (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_DPAD_DOWN)); - break; - case INPUT_LEFT: - success = (SDL_JoystickGetAxis(mGameController, 0) < -JOYSTICK_DEAD_ZONE) || (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_DPAD_LEFT)); - break; - case INPUT_RIGHT: - success = (SDL_JoystickGetAxis(mGameController, 0) > JOYSTICK_DEAD_ZONE) || (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)); - break; - case INPUT_ACCEPT: - success = (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_B)); - break; - case INPUT_CANCEL: - success = (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_A)); - break; - case INPUT_PAUSE: - success = (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_START)); - break; - case INPUT_FIRE_UP: - success = (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_Y)); - break; - case INPUT_FIRE_LEFT: - success = (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_X)); - break; - case INPUT_FIRE_RIGHT: - success = (SDL_JoystickGetButton(mGameController, SDL_CONTROLLER_BUTTON_B)); - break; - - default: - break; - } - return success; -}*/ - // Comprueba si hay un mando conectado bool Input::discoverGameController() { bool found = false; - /* - printf("%i joystics found\n", SDL_NumJoysticks()); - for (int i = 0; i < SDL_NumJoysticks(); ++i) - { - if (SDL_IsGameController(i)) - { - char *mapping; - printf("Index %i is a compatible controller, named %s\n", i, SDL_GameControllerNameForIndex(i)); - mGameController = SDL_GameControllerOpen(i); - mapping = SDL_GameControllerMapping(mGameController); - printf("Controller %i is mapped as %s\n", i, mapping); - SDL_free(mapping); - found = true; - } - else - { - printf("Index %i is not a compatible controller.\n", i); - found = false; - } - } - */ if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1) SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); int nJoysticks = SDL_NumJoysticks(); - int numGamepads = 0; + mNumGamepads = 0; // Count how many controllers there are for (int i = 0; i < nJoysticks; i++) if (SDL_IsGameController(i)) - numGamepads++; + mNumGamepads++; - printf("%i joysticks found, %i are gamepads\n", nJoysticks, numGamepads); + printf(" (%i joysticks found, %i are gamepads)\n", nJoysticks, mNumGamepads); - //if (numGamepads > 0) - // found = true; - //SDL_JoystickEventState(SDL_ENABLE); - - if (numGamepads > 0) + if (mNumGamepads > 0) { - for (int i = 0; i < numGamepads; i++) + found = true; + + for (int i = 0; i < mNumGamepads; i++) { // Open the controller and add it to our list - mGameController = SDL_GameControllerOpen(i); - if (SDL_GameControllerGetAttached(mGameController) == 1) - //connectedControllers.push_back(pad); - { - found = true; - printf("%s\n", SDL_GameControllerNameForIndex(i)); - } + SDL_GameController *pad = SDL_GameControllerOpen(i); + if (SDL_GameControllerGetAttached(pad) == 1) + mConnectedControllers.push_back(pad); else std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl; } + + mGameController = mConnectedControllers[0]; SDL_GameControllerEventState(SDL_ENABLE); } - //SDL_GameControllerGetButton(mGameController, SDL_CONTROLLER_BUTTON_A); - //printf("hola"); return found; -} -/*if (SDL_NumJoysticks() < 1) - { - printf("Warning: No joysticks connected!\n"); - mGameControllerFound = false; - std::cout << "Warning: No joysticks connected!\n"; - } - else - {*/ -// Carga el mando - -/*mGameController = SDL_GameControllerOpen(0); - - if (mGameController == NULL) - { - printf("Warning: Unable to open game controller!\nSDL Error: %s\n", SDL_GetError()); - mGameControllerFound = false; - } - else - { - printf("%i joysticks were found.\n", SDL_NumJoysticks()); - std::cout << "joysticks were found!\n"; - mGameControllerFound = true; - - //printf("%i buttons\n", SDL_JoystickNumButtons(mGameController)); - - // Obtiene el dispositivo de control háptico - mControllerHaptic = SDL_HapticOpenFromJoystick(mGameController); - if (mControllerHaptic == NULL) - { - printf("Warning: Controller does not support haptics!\nSDL Error: %s\n", SDL_GetError()); - } - else - { - printf("Haptics detected\n"); - - // Inicializa la vibración - if (SDL_HapticRumbleInit(mControllerHaptic) < 0) - { - printf("Warning: Unable to initialize rumble!\nSDL Error: %s\n", SDL_GetError()); - } - } - } -} - -return mGameControllerFound; -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/source/input.h b/source/input.h index 8609313..666ed3d 100644 --- a/source/input.h +++ b/source/input.h @@ -1,5 +1,6 @@ #pragma once #include "ifdefs.h" +#include #ifndef INPUT_H #define INPUT_H @@ -25,8 +26,8 @@ #define REPEAT_TRUE true #define REPEAT_FALSE false -#define USE_KEYBOARD 0 -#define USE_GAMECONTROLLER 1 +#define INPUT_USE_KEYBOARD 0 +#define INPUT_USE_GAMECONTROLLER 1 // Clase Input class Input @@ -47,8 +48,9 @@ private: GameControllerBindings_t mGameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos SDL_GameController *mGameController; // Manejador para el mando - //SDL_Haptic *mControllerHaptic; // Manejador para el mando con vibración - //bool mGameControllerFound; // Variable para saber si hay un mando conectado + + std::vector mConnectedControllers; + int mNumGamepads; int mSource; // Indica si el objeto usará un mando o un teclado diff --git a/source/lang.h b/source/lang.h index 4d29415..cbdb8f7 100644 --- a/source/lang.h +++ b/source/lang.h @@ -61,14 +61,14 @@ const std::string gTextStrings[MAX_TEXT_STRINGS][3] = "LANGUAGE"}, // 9 - {"[ACEPTAR]", - "[ACEPTAR]", - "[ACCEPT]"}, + {"[ ACEPTAR ]", + "[ ACEPTAR ]", + "[ ACCEPT ]"}, // 10 - {"[CANCELAR]", - "[CANCELAR]", - "[CANCEL]"}, + {"[ CANCELAR ]", + "[ CANCELAR ]", + "[ CANCEL ]"}, // 11 {"OBJETIVO", diff --git a/source/main.cpp b/source/main.cpp index f9a6dee..2855002 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -41,20 +41,20 @@ un tipo asociado diferente a NO_KIND int main(int argc, char *args[]) { // Inicia el generador de numeros aleatorios - //srand(time(nullptr)); std::srand(static_cast(SDL_GetTicks())); - // Crea el objeto mDirector - Director *mDirector = new Director(args[0]); printf("Starting the game...\n\n"); + + // Crea el objeto Director + Director *mDirector = new Director(args[0]); // Bucle principal mDirector->run(); - // Libera todos los recursos y cierra SDL + // Destruye el objeto Director delete mDirector; mDirector = nullptr; - printf("Shutting down the game...\n"); + printf("\nShutting down the game...\n"); return 0; } diff --git a/source/player.cpp b/source/player.cpp index 3f03426..aefc5a2 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -672,9 +672,9 @@ void Player::setPowerUpCounter(Uint16 value) // Actualiza el valor de la variable void Player::updatePowerUpCounter() { - if (mPowerUpCounter > 0) + if ((mPowerUpCounter > 0) && (mPowerUp)) { - --mPowerUpCounter; + mPowerUpCounter--; } else { diff --git a/source/player.h b/source/player.h index 803d8f2..34aa050 100644 --- a/source/player.h +++ b/source/player.h @@ -34,7 +34,6 @@ private: bool mExtraHit; // Indica si el jugador tiene un toque extra Uint8 mCoffees; // Indica cuantos cafes lleva acumulados bool mPowerUp; // Indica si el jugador tiene activo el modo PowerUp - Uint16 mPowerUpCounter; // Temporizador para el modo PowerUp bool mInput; // Indica si puede recibir ordenes de entrada AnimatedSprite *mSpriteLegs; // Sprite para dibujar las piernas @@ -46,6 +45,7 @@ private: void shiftColliders(); // Actualiza el circulo de colisión a la posición del jugador public: + Uint16 mPowerUpCounter; // Temporizador para el modo PowerUp // Constructor Player(); diff --git a/source/title.cpp b/source/title.cpp index eed7b9c..468fcad 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -21,6 +21,7 @@ Title::Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::stri mTitleTexture = new LTexture(); mItemsTexture = new LTexture(); mTextTexture = new LTexture(); + mTextTexture2 = new LTexture(); mCoffeeBitmap = new SmartSprite(); mCrisisBitmap = new SmartSprite(); mDustBitmapL = new AnimatedSprite(); @@ -28,6 +29,7 @@ Title::Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::stri mTile = new Sprite(); mGradient = new Sprite(); mText = new Text(mFileList[48], mTextTexture, mRenderer); + mText2 = new Text(mFileList[46], mTextTexture2, mRenderer); mMenu.title = new Menu(mRenderer, mText, mInput, mFileList); mMenu.options = new Menu(mRenderer, mText, mInput, mFileList); @@ -45,6 +47,9 @@ Title::~Title() delete mText; mText = nullptr; + delete mText2; + mText2 = nullptr; + delete mFade; mFade = nullptr; @@ -60,6 +65,10 @@ Title::~Title() delete mTextTexture; mTextTexture = nullptr; + mTextTexture2->unload(); + delete mTextTexture2; + mTextTexture2 = nullptr; + delete mCoffeeBitmap; mCoffeeBitmap = nullptr; @@ -118,7 +127,8 @@ void Title::init(bool demo, Uint8 subsection) mTicks = 0; mTicksSpeed = 15; mText->init(); - mFade->init(); + mText2->init(); + mFade->init(0x00, 0x00, 0x00); mDemo = demo; // Inicializa el bitmap de Coffee @@ -232,16 +242,18 @@ void Title::init(bool demo, Uint8 subsection) } // Inicializa los objetos de menu - mMenu.title->init("TITLE", 0, 14 * BLOCK, MENU_BACKGROUND_SOLID); - mMenu.title->addItem(mTextStrings[51]); // 1 PLAYER - mMenu.title->addItem(mTextStrings[52]); // 2 PLAYERS - mMenu.title->addItem(mTextStrings[1]); // OPTIONS - mMenu.title->addItem(mTextStrings[2], 0, 5); // HOW TO PLAY - mMenu.title->addItem(mTextStrings[3]); // QUIT - mMenu.title->setDefaultActionWhenCancel(4); + mMenu.title->init("TITLE", 0, 14 * BLOCK, MENU_BACKGROUND_TRANSPARENT); + mMenu.title->addItem(mTextStrings[51]); // 1 PLAYER + mMenu.title->addItem(mTextStrings[52], 0, 5); // 2 PLAYERS + mMenu.title->addItem(mTextStrings[1], 0, 5); // OPTIONS + //mMenu.title->addItem(mTextStrings[2], 0, 5); // HOW TO PLAY + mMenu.title->addItem(mTextStrings[3]); // QUIT + mMenu.title->setDefaultActionWhenCancel(3); mMenu.title->setBackgroundColor(0x30, 0x30, 0x40, 192); - mMenu.title->setSelectorColor(0xe5, 0x1c, 0x23, 255); - mMenu.title->setSelectorTextColor(0xFF, 0xF1, 0x76); + //mMenu.title->setSelectorColor(0xe5, 0x1c, 0x23, 255); + mMenu.title->setSelectorColor(0xe5, 0x1c, 0x23, 0); + //mMenu.title->setSelectorTextColor(0xFF, 0xF1, 0x76); + mMenu.title->setSelectorTextColor(0xFF, 0xB4, 0x00); mMenu.title->centerMenu(SCREEN_CENTER_X); mMenu.title->centerMenuElements(); @@ -272,6 +284,7 @@ bool Title::loadMedia() success &= loadTextureFromFile(mTitleTexture, mFileList[40], mRenderer); success &= loadTextureFromFile(mItemsTexture, mFileList[34], mRenderer); success &= loadTextureFromFile(mTextTexture, mFileList[30], mRenderer); + success &= loadTextureFromFile(mTextTexture2, mFileList[27], mRenderer); // Sonidos mSound = JA_LoadSound(mFileList[21].c_str()); @@ -344,11 +357,11 @@ void Title::updateMenuLabels() mMenu.options->centerMenu(SCREEN_CENTER_X); mMenu.options->centerMenuElements(); - mMenu.title->setItemCaption(0, mTextStrings[51]); - mMenu.title->setItemCaption(1, mTextStrings[52]); - mMenu.title->setItemCaption(2, mTextStrings[1]); - mMenu.title->setItemCaption(3, mTextStrings[2]); - mMenu.title->setItemCaption(4, mTextStrings[3]); + mMenu.title->setItemCaption(0, mTextStrings[51]); // 1 PLAYER + mMenu.title->setItemCaption(1, mTextStrings[52]); // 2 PLAYERS + mMenu.title->setItemCaption(2, mTextStrings[1]); // OPTIONS + //mMenu.title->setItemCaption(3, mTextStrings[2]); // HOW TO PLAY + mMenu.title->setItemCaption(3, mTextStrings[3]); // QUIT mMenu.title->centerMenu(SCREEN_CENTER_X); mMenu.title->centerMenuElements(); @@ -594,10 +607,10 @@ section_t Title::run(Uint8 subsection) mOptions->windowSizePrevious = mOptions->windowSize; mOptions->languagePrevious = mOptions->language; break; - case 3: // HOW TO PLAY - runInstructions(INSTRUCTIONS_MODE_MANUAL); - break; - case 4: // QUIT + //case 3: // HOW TO PLAY + // runInstructions(INSTRUCTIONS_MODE_MANUAL); + // break; + case 3: // QUIT mPostFade = 2; mFade->activateFade(); break; @@ -678,7 +691,7 @@ section_t Title::run(Uint8 subsection) mText->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, mTextStrings[23], 1, noColor, 1, shdwTxtColor); // Texto con el copyright y versión - mText->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, SCREEN_HEIGHT - (BLOCK * 2), TEXT_COPYRIGHT, 1, noColor, 1, shdwTxtColor); + mText2->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, SCREEN_HEIGHT - (BLOCK * 2), TEXT_COPYRIGHT, 1, noColor, 1, shdwTxtColor); // Fade mFade->render(); diff --git a/source/title.h b/source/title.h index 0b39720..c8b2811 100644 --- a/source/title.h +++ b/source/title.h @@ -33,6 +33,7 @@ private: LTexture *mItemsTexture; // Textura con los gráficos de los items para las instrucciones LTexture *mTitleTexture; // Textura con los graficos para el titulo LTexture *mTextTexture; // Textura con los gráficos para el texto + LTexture *mTextTexture2; // Textura con los gráficos para el texto SDL_Event *mEventHandler; // Manejador de eventos SDL_Rect mBackgroundWindow; // Ventana visible para la textura de fondo del titulo SDL_Renderer *mRenderer; // El renderizador de la ventana @@ -53,6 +54,7 @@ private: section_t mNextSection; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo Uint8 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa Text *mText; // Objeto de texto para poder escribir textos en pantalla + Text *mText2; // Objeto de texto para poder escribir textos en pantalla Fade *mFade; // Objeto para realizar fundidos en pantalla Uint8 mPostFade; // Opción a realizar cuando termina el fundido Input *mInput; // Objeto para leer las entradas de teclado o mando diff --git a/source/utils.h b/source/utils.h index f23a4a9..ed667de 100644 --- a/source/utils.h +++ b/source/utils.h @@ -48,6 +48,11 @@ struct options_t Uint8 windowSizePrevious; // Usado por si se cancelan los cambios en el menu de opciones Uint8 language; // Idioma usado en el juego Uint8 languagePrevious; // Usado por si se cancelan los cambios en el menu de opciones + Uint8 difficulty; // Dificultad del juego + Uint8 player1Input; // Modo de control para el jugador 1 (teclado o mando) + Uint8 player2Input; // Modo de control para el jugador 2 (teclado o mando) + Uint32 filter; // Filtro usado para el escalado de la imagen + bool vSync; // Indica si se quiere usar vsync o no }; // Calcula el cuadrado de la distancia entre dos puntos