From 42c0f19c6805fee105d57a2d70e67785154160db Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 31 Aug 2021 21:05:04 +0200 Subject: [PATCH] Working on support for various controllers --- source/director.cpp | 12 +++---- source/input.cpp | 8 +++-- source/input.h | 3 ++ source/logo.cpp | 21 +++++------- source/title.cpp | 82 +++++++++++++++++++++++++++++++++++++++------ source/title.h | 7 +++- 6 files changed, 101 insertions(+), 32 deletions(-) diff --git a/source/director.cpp b/source/director.cpp index e7624dd..acc2938 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -371,8 +371,8 @@ bool Director::loadConfigFile() 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->input[0], sizeof(mOptions->input[0]), 1); - SDL_RWwrite(file, &mOptions->input[1], sizeof(mOptions->input[1]), 1); + SDL_RWwrite(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1); + SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1); SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); @@ -394,8 +394,8 @@ bool Director::loadConfigFile() 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->input[0], sizeof(mOptions->input[0]), 1); - SDL_RWread(file, &mOptions->input[1], sizeof(mOptions->input[1]), 1); + SDL_RWread(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1); + SDL_RWread(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); SDL_RWread(file, &mOptions->filter, sizeof(mOptions->filter), 1); SDL_RWread(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); @@ -435,8 +435,8 @@ bool Director::saveConfigFile() 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->input[0], sizeof(mOptions->input[0]), 1); - SDL_RWwrite(file, &mOptions->input[1], sizeof(mOptions->input[1]), 1); + SDL_RWwrite(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1); + SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1); SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); diff --git a/source/input.cpp b/source/input.cpp index 649991d..dc8b705 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -4,8 +4,6 @@ // Contestar cuantos joystics ha detectado // Preguntarlepor los joystics que ha encontrado para ir poniendolos en la variable de opciones - - // Constructor Input::Input(std::string file) { @@ -202,4 +200,10 @@ std::string Input::getControllerName(int index) return mControllerNames[index]; else return ""; +} + +// Obten el numero de mandos conectados +int Input::getNumControllers() +{ + return mNumGamepads; } \ No newline at end of file diff --git a/source/input.h b/source/input.h index 1531512..bea512b 100644 --- a/source/input.h +++ b/source/input.h @@ -77,6 +77,9 @@ public: // Comprueba si hay algun mando conectado bool gameControllerFound(); + // Obten el numero de mandos conectados + int getNumControllers(); + // Obten el nombre de un mando de juego std::string getControllerName(int index); }; diff --git a/source/logo.cpp b/source/logo.cpp index 7c2e5e0..3ae6cbd 100644 --- a/source/logo.cpp +++ b/source/logo.cpp @@ -4,6 +4,9 @@ #include #endif +# define INIT_FADE 100 +# define END_LOGO 200 + // Constructor Logo::Logo(SDL_Renderer *renderer, std::string *fileList) { @@ -71,6 +74,7 @@ section_t Logo::run() { init(); const SDL_Rect rect = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; + const int fadeLenght = END_LOGO - INIT_FADE; while (mSection.name == PROG_SECTION_LOGO) { @@ -92,9 +96,6 @@ section_t Logo::run() } } - // Cambia el destino donde se pinta todo - //SDL_SetRenderTarget(mRenderer, mBackbuffer); - // Limpia el destino SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_RenderClear(mRenderer); @@ -103,22 +104,16 @@ section_t Logo::run() mSprite->render(); // Dibuja el fade - if (mCounter >= 200) + if (mCounter >= INIT_FADE) { - Uint16 alpha = mCounter - 200; + Uint16 alpha = (255 * (mCounter - INIT_FADE)) / fadeLenght; if (alpha < 256) SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, alpha); else - SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); // alpha - 0 trans, 255 opaco + SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_RenderFillRect(mRenderer, &rect); } - // Vuelve a usar el renderizador como destino - //SDL_SetRenderTarget(mRenderer, NULL); - - // Copia el backbufer al renderizador - //SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL); - // Actualiza la pantalla SDL_RenderPresent(mRenderer); @@ -134,7 +129,7 @@ section_t Logo::run() JA_StopMusic(); } - if (mCounter == 500) // minimo 200 + 255 + if (mCounter == END_LOGO + 20) { mCounter = 0; mSection.name = PROG_SECTION_INTRO; diff --git a/source/title.cpp b/source/title.cpp index 27d3e85..637f0fe 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -141,6 +141,11 @@ void Title::init(bool demo, Uint8 subsection) mOptions->input[0].deviceType = INPUT_USE_KEYBOARD; mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER; } + + checkInputDevices(); + + mDeviceIndex[0] = 0; + mDeviceIndex[1] = 0; // Inicializa el bitmap de Coffee mCoffeeBitmap->init(mTitleTexture, mRenderer); @@ -363,7 +368,8 @@ void Title::updateMenuLabels() else { mMenu.options->setGreyed(i, false); - mMenu.options->setItemCaption(i, mInput->getControllerName(0)); + //mMenu.options->setItemCaption(i, mInput->getControllerName(0)); + mMenu.options->setItemCaption(i, mOptions->input[0].name); } break; @@ -392,7 +398,8 @@ void Title::updateMenuLabels() else { mMenu.options->setGreyed(i, false); - mMenu.options->setItemCaption(i, mInput->getControllerName(0)); + //mMenu.options->setItemCaption(i, mInput->getControllerName(0)); + mMenu.options->setItemCaption(i, mOptions->input[1].name); } break; @@ -755,11 +762,11 @@ section_t Title::run(Uint8 subsection) updateMenuLabels(); break; case 1: // PLAYER 1 CONTROLS - switchInputs(1); + updatePlayerInputs(1); updateMenuLabels(); break; case 3: // PLAYER 2 CONTROLS - switchInputs(2); + updatePlayerInputs(2); updateMenuLabels(); break; case 5: // Language @@ -908,17 +915,45 @@ void Title::runDemoGame() } // Modifica las opciones para los controles de los jugadores -void Title::switchInputs(int value) +bool Title::updatePlayerInputs(int numPlayer) { - Uint8 temp; - temp = mOptions->input[0].deviceType; - mOptions->input[0].deviceType = mOptions->input[1].deviceType; - mOptions->input[1].deviceType = temp; + const int numDevices = mInput->getNumControllers(); - if (!mInput->gameControllerFound()) + // Si no hay mandos se deja todo de manera prefijada + if (numDevices == 0) { + mDeviceIndex[0] = 0; + mDeviceIndex[1] = 0; + mOptions->input[0].id = -1; + mOptions->input[0].name = "KEYBOARD"; mOptions->input[0].deviceType = INPUT_USE_KEYBOARD; + mOptions->input[1].id = 0; + mOptions->input[0].name = "GAME CONTROLLER"; mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER; + + return true; + } + else // Si hay mas de un dispositivo, se recorre el vector + { + // Incrementa el indice + if (mDeviceIndex[numPlayer] < numDevices - 1) + mDeviceIndex[numPlayer]++; + else + mDeviceIndex[numPlayer] = 0; + + // Si coincide con el del otro jugador, se lo intercambian + if (mDeviceIndex[0] == mDeviceIndex[1]) + { + const int temp = mDeviceIndex[0]; + mDeviceIndex[0] = mDeviceIndex[1]; + mDeviceIndex[1] = temp; + } + + // Copia el dispositivo marcado por el indice a la variable de opciones de cada jugador + mOptions->input[0] = mAvailableInputDevices[mDeviceIndex[0]]; + mOptions->input[1] = mAvailableInputDevices[mDeviceIndex[1]]; + + return true; } } @@ -940,4 +975,31 @@ void Title::createTiledBackground() } SDL_SetRenderTarget(mRenderer, nullptr); +} + +// Comprueba cuantos mandos hay conectados para gestionar el menu de opciones +void Title::checkInputDevices() +{ + printf("Filling devices for options menu...\n"); + int numControllers = mInput->getNumControllers(); + mAvailableInputDevices.clear(); + input_t temp; + + // Añade todos los mandos + if (numControllers > 0) + for (int i = 0; i < numControllers; i++) + { + temp.id = i; + temp.name = mInput->getControllerName(i); + temp.deviceType = INPUT_USE_GAMECONTROLLER; + mAvailableInputDevices.push_back(temp); + printf("Device %i:\t%s\n", mAvailableInputDevices.size(), temp.name.c_str()); + } + + // Añade el teclado al final + temp.id = -1; + temp.name = "KEYBOARD"; + temp.deviceType = INPUT_USE_KEYBOARD; + mAvailableInputDevices.push_back(temp); + printf("Device %i:\t%s\n\n", mAvailableInputDevices.size(), temp.name.c_str()); } \ No newline at end of file diff --git a/source/title.h b/source/title.h index 3429f4e..7fa6d2f 100644 --- a/source/title.h +++ b/source/title.h @@ -72,6 +72,8 @@ private: struct options_t *mOptions; // Variable con todas las variables de las opciones del programa options_t mOptionsPrevious; // Variable de respaldo para las opciones + std::vector mAvailableInputDevices; // Vector con todos los metodos de control disponibles + int mDeviceIndex[2]; // Indice para el jugador [i] del vector de dispositivos de entrada disponibles // Carga los recursos necesarios para la sección 'Title' bool loadMedia(); @@ -92,11 +94,14 @@ private: void runDemoGame(); // Modifica las opciones para los controles de los jugadores - void switchInputs(int value); + bool updatePlayerInputs(int numPlayer); // Crea el mosaico de fondo del titulo void createTiledBackground(); + // Comprueba cuantos mandos hay conectados para gestionar el menu de opciones + void checkInputDevices(); + public: // Constructor Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::string *fileList, options_t *options, Lang *lang);