Improving menu class. Selector flickers when selecting

This commit is contained in:
2021-08-30 17:16:53 +02:00
parent 005eab5694
commit 74c08884ae
6 changed files with 58 additions and 43 deletions

View File

@@ -117,17 +117,17 @@ void Director::init(Uint8 name)
mInput->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); // PAUSE mInput->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); // PAUSE
mInput->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); // ESCAPE mInput->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); // ESCAPE
mInput->bindGameController(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP); mInput->bindGameControllerButton(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP);
mInput->bindGameController(INPUT_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN); mInput->bindGameControllerButton(INPUT_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
mInput->bindGameController(INPUT_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT); mInput->bindGameControllerButton(INPUT_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
mInput->bindGameController(INPUT_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); mInput->bindGameControllerButton(INPUT_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
mInput->bindGameController(INPUT_ACCEPT, SDL_CONTROLLER_BUTTON_B); mInput->bindGameControllerButton(INPUT_ACCEPT, SDL_CONTROLLER_BUTTON_B);
mInput->bindGameController(INPUT_CANCEL, SDL_CONTROLLER_BUTTON_A); mInput->bindGameControllerButton(INPUT_CANCEL, SDL_CONTROLLER_BUTTON_A);
mInput->bindGameController(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_X); mInput->bindGameControllerButton(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_X);
mInput->bindGameController(INPUT_BUTTON_2, SDL_CONTROLLER_BUTTON_Y); mInput->bindGameControllerButton(INPUT_BUTTON_2, SDL_CONTROLLER_BUTTON_Y);
mInput->bindGameController(INPUT_BUTTON_3, SDL_CONTROLLER_BUTTON_B); mInput->bindGameControllerButton(INPUT_BUTTON_3, SDL_CONTROLLER_BUTTON_B);
mInput->bindGameController(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE); // PAUSE mInput->bindGameControllerButton(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE); // PAUSE
mInput->bindGameController(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE); // ESCAPE mInput->bindGameControllerButton(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE); // ESCAPE
} }
// Inicializa JailAudio // Inicializa JailAudio
@@ -317,7 +317,7 @@ bool Director::checkFileList()
success &= checkFolder("SOUND", "/media/sound/"); success &= checkFolder("SOUND", "/media/sound/");
if (success) if (success)
success &= checkFolder("GFX", "/media/gfx/"); success &= checkFolder("BITMAP", "/media/gfx/");
if (success) if (success)
success &= checkFolder("FONT", "/media/font/"); success &= checkFolder("FONT", "/media/font/");

View File

@@ -1,5 +1,5 @@
#include "input.h" #include "input.h"
#include <stdio.h> //#include <stdio.h>
#include <iostream> #include <iostream>
// Constructor // Constructor
@@ -21,6 +21,8 @@ Input::Input()
// Destructor // Destructor
Input::~Input() Input::~Input()
{ {
SDL_GameControllerClose(mGameController);
mGameController = nullptr;
} }
// Asigna uno de los posibles inputs a una tecla del teclado // Asigna uno de los posibles inputs a una tecla del teclado
@@ -30,7 +32,7 @@ void Input::bindKey(Uint8 input, SDL_Scancode code)
} }
// Asigna uno de los posibles inputs a un botón del mando // Asigna uno de los posibles inputs a un botón del mando
void Input::bindGameController(Uint8 input, SDL_GameControllerButton button) void Input::bindGameControllerButton(Uint8 input, SDL_GameControllerButton button)
{ {
mGameControllerBindings[input].button = button; mGameControllerBindings[input].button = button;
} }
@@ -139,7 +141,8 @@ bool Input::discoverGameController()
if (SDL_IsGameController(i)) if (SDL_IsGameController(i))
mNumGamepads++; mNumGamepads++;
printf(" (%i joysticks found, %i are gamepads)\n", nJoysticks, mNumGamepads); printf("\nChecking for game controllers...\n");
printf("%i joysticks found, %i are gamepads\n", nJoysticks, mNumGamepads);
if (mNumGamepads > 0) if (mNumGamepads > 0)
{ {
@@ -150,7 +153,13 @@ bool Input::discoverGameController()
// Abre el mando y lo añade a la lista // Abre el mando y lo añade a la lista
SDL_GameController *pad = SDL_GameControllerOpen(i); SDL_GameController *pad = SDL_GameControllerOpen(i);
if (SDL_GameControllerGetAttached(pad) == 1) if (SDL_GameControllerGetAttached(pad) == 1)
{
mConnectedControllers.push_back(pad); mConnectedControllers.push_back(pad);
std::string name = SDL_GameControllerNameForIndex(i);
std::cout << SDL_GameControllerNameForIndex(i) << std::endl;
name.resize(25);
mControllerNames.push_back(name);
}
else else
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl; std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
} }
@@ -170,3 +179,9 @@ bool Input::gameControllerFound()
else else
return false; return false;
} }
// Obten el nombre de un mando de juego
std::string Input::getControllerName(int index)
{
return mControllerNames[index];
}

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ifdefs.h" #include "ifdefs.h"
#include <string>
#include <vector> #include <vector>
#ifndef INPUT_H #ifndef INPUT_H
@@ -49,8 +50,8 @@ private:
GameControllerBindings_t mGameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos GameControllerBindings_t mGameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
SDL_GameController *mGameController; // Manejador para el mando SDL_GameController *mGameController; // Manejador para el mando
std::vector<SDL_GameController*> mConnectedControllers; std::vector<SDL_GameController*> mConnectedControllers;
std::vector<std::string> mControllerNames;
int mNumGamepads; int mNumGamepads;
// Comprueba si hay un mando conectado // Comprueba si hay un mando conectado
@@ -67,13 +68,16 @@ public:
void bindKey(Uint8 input, SDL_Scancode code); void bindKey(Uint8 input, SDL_Scancode code);
// Asigna uno de los posibles inputs a un botón del mando // Asigna uno de los posibles inputs a un botón del mando
void bindGameController(Uint8 input, SDL_GameControllerButton button); void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button);
// Comprueba si un input esta activo // Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat, int device=INPUT_USE_ANY); bool checkInput(Uint8 input, bool repeat, int device=INPUT_USE_ANY);
// Comprueba si hay algun mando conectado // Comprueba si hay algun mando conectado
bool gameControllerFound(); bool gameControllerFound();
// Obten el nombre de un mando de juego
std::string getControllerName(int index);
}; };
#endif #endif

View File

@@ -216,7 +216,6 @@ void Menu::reset()
mSelector.originH = mSelector.targetH = mItem[0].h; mSelector.originH = mSelector.targetH = mItem[0].h;
mSelector.moving = false; mSelector.moving = false;
mSelector.resizing = false; mSelector.resizing = false;
} }
// Deja el menu sin elemento seleccionado // Deja el menu sin elemento seleccionado
@@ -311,7 +310,7 @@ void Menu::render()
SDL_RenderDrawRect(mRenderer, &mRectBG.rect); SDL_RenderDrawRect(mRenderer, &mRectBG.rect);
} }
// Renderitza el text // Renderitza el texto
for (int i = 0; i < mTotalItems; i++) for (int i = 0; i < mTotalItems; i++)
{ {
if (i == mSelector.index) if (i == mSelector.index)
@@ -345,10 +344,8 @@ void Menu::render()
// Establece el rectangulo de fondo del menu y el selector // Establece el rectangulo de fondo del menu y el selector
void Menu::setRectSize() void Menu::setRectSize()
{ {
findHeight(); mRectBG.rect.w = findWidth();
findWidth(); mRectBG.rect.h = findHeight();
mRectBG.rect.w = mWidth;
mRectBG.rect.h = mHeight;
// La posición X es la del menú menos medio caracter // La posición X es la del menú menos medio caracter
mRectBG.rect.x = mPosX - (mText->getCharacterWidth() / 2); mRectBG.rect.x = mPosX - (mText->getCharacterWidth() / 2);
@@ -357,7 +354,6 @@ void Menu::setRectSize()
mRectBG.rect.y = mPosY - (mText->getCharacterWidth() / 2) - mVerticalPadding; mRectBG.rect.y = mPosY - (mText->getCharacterWidth() / 2) - mVerticalPadding;
// Establecemos los valores del rectangulo del selector a partir de los valores del rectangulo de fondo // Establecemos los valores del rectangulo del selector a partir de los valores del rectangulo de fondo
//mSelector.rect.h = (mText->getCharacterWidth() * 1) + 1;
mSelector.rect.h = getSelectorHeight(mSelector.index); mSelector.rect.h = getSelectorHeight(mSelector.index);
mSelector.rect.w = mRectBG.rect.w; mSelector.rect.w = mRectBG.rect.w;
mSelector.rect.x = mRectBG.rect.x; mSelector.rect.x = mRectBG.rect.x;
@@ -438,7 +434,7 @@ void Menu::centerMenuOnY(int value)
setRectSize(); setRectSize();
// Obten el alto del menu // Obten el alto del menu
findHeight(); mHeight = findHeight();
// Establece la nueva posición centrada en funcion del elemento más ancho // Establece la nueva posición centrada en funcion del elemento más ancho
mPosY = (value) - (mHeight / 2); mPosY = (value) - (mHeight / 2);
@@ -534,30 +530,34 @@ void Menu::checkInput()
} }
// Calcula el ancho del menu // Calcula el ancho del menu
void Menu::findWidth() Uint16 Menu::findWidth()
{ {
mWidth = 0; Uint16 width = 0;
// Obtenemos la anchura del item mas ancho // Obtenemos la anchura del item mas ancho
for (int i = 0; i < mTotalItems; i++) for (int i = 0; i < mTotalItems; i++)
if (mItem[i].w > mWidth) if (mItem[i].w > width)
mWidth = mItem[i].w; width = mItem[i].w;
// La anchura de la cadena más larga, mas un caracter // La anchura de la cadena más larga, mas un caracter
mWidth += (mText->getCharacterWidth() * 1); width += (mText->getCharacterWidth() * 1);
return width;
} }
// Calcula el alto del menu // Calcula el alto del menu
void Menu::findHeight() Uint16 Menu::findHeight()
{ {
mHeight = 0; Uint16 height = 0;
// Obtenemos la altura de la suma de alturas de los items // Obtenemos la altura de la suma de alturas de los items
for (int i = 0; i < mTotalItems; i++) for (int i = 0; i < mTotalItems; i++)
mHeight += mItem[i].h + mItem[i].hPaddingDown; height += mItem[i].h + mItem[i].hPaddingDown;
// La altura de la suma de los items mas un caracter y menos un pixel (porque el texto en realidad es de 7 pixeles) // La altura de la suma de los items mas un caracter y menos un pixel (porque el texto en realidad es de 7 pixeles)
mHeight += (mText->getCharacterWidth() * 1) - 1; height += (mText->getCharacterWidth() * 1) - 1;
return height;
} }
// Recoloca los elementos del menu en el eje Y // Recoloca los elementos del menu en el eje Y
@@ -566,10 +566,8 @@ void Menu::replaceElementsOnY()
mItem[0].y = mPosY; mItem[0].y = mPosY;
for (int i = 1; i < mTotalItems; i++) for (int i = 1; i < mTotalItems; i++)
{
mItem[i].y = mItem[i - 1].y + mItem[i - 1].h + mItem[i - 1].hPaddingDown; mItem[i].y = mItem[i - 1].y + mItem[i - 1].h + mItem[i - 1].hPaddingDown;
} }
}
// Establece el estado seleccionable de un item // Establece el estado seleccionable de un item
void Menu::setSelectable(Uint8 index, bool value) void Menu::setSelectable(Uint8 index, bool value)
@@ -593,11 +591,7 @@ void Menu::setLinkedDown(Uint8 index, bool value)
int Menu::getSelectorHeight(int value) int Menu::getSelectorHeight(int value)
{ {
if (mItem[value].linkedDown) if (mItem[value].linkedDown)
{
return mItem[value + 1].y + mItem[value + 1].h - mItem[value].y - 1; return mItem[value + 1].y + mItem[value + 1].h - mItem[value].y - 1;
}
else else
{
return mItem[value].h - 1; return mItem[value].h - 1;
} }
}

View File

@@ -123,10 +123,10 @@ private:
void checkMenuInput(Menu *menu); void checkMenuInput(Menu *menu);
// Calcula el ancho del menu // Calcula el ancho del menu
void findWidth(); Uint16 findWidth();
// Calcula el alto del menu // Calcula el alto del menu
void findHeight(); Uint16 findHeight();
// Recoloca los elementos del menu en el eje Y // Recoloca los elementos del menu en el eje Y
void replaceElementsOnY(); void replaceElementsOnY();

View File

@@ -356,6 +356,7 @@ void Title::updateMenuLabels()
mMenu.options->setGreyed(i, true); mMenu.options->setGreyed(i, true);
else else
mMenu.options->setGreyed(i, false); mMenu.options->setGreyed(i, false);
mMenu.options->setItemCaption(i, mInput->getControllerName(0));
break; break;
default: default:
@@ -382,6 +383,7 @@ void Title::updateMenuLabels()
mMenu.options->setGreyed(i, true); mMenu.options->setGreyed(i, true);
else else
mMenu.options->setGreyed(i, false); mMenu.options->setGreyed(i, false);
mMenu.options->setItemCaption(i, mInput->getControllerName(0));
break; break;
default: default: