- Added support for monitor aspect ratio selection in the layout.xml:

e.g. layout 4x3.xml, layout 16x9.xml, etc.
- Added controls configuration at startup when controls.conf is missing.
This commit is contained in:
Pieter Hulshoff 2018-02-11 15:00:07 +01:00
parent 42835e689b
commit aedd7e67fa
12 changed files with 8539 additions and 3103 deletions

View File

@ -1,298 +0,0 @@
up = Keypad 8,Up
down = Keypad 2,Down
left = Keypad 4,Left,joyButton7
right = Keypad 6,Right,joyButton5
pageUp = A
pageDown = B
letterUp = N
letterDown = M
favPlaylist = F
nextPlaylist = F2
prevPlaylist = F1
addPlaylist = I
removePlaylist = O
random = R
select = 1,Return,joyButton3
back = 2,Escape,joyButton0
quit = Q
# See below for a list of key codes that can be used for configuring the controls:
###################### ######################################################
# Code # Description
###################### ######################################################
# "0"
# "1"
# "2"
# "3"
# "4"
# "5"
# "6"
# "7"
# "8"
# "9"
# "A"
# "AC Back" the Back key (application control keypad)
# "AC Bookmarks" the Bookmarks key (application control keypad)
# "AC Forward" the Forward key (application control keypad)
# "AC Home" the Home key (application control keypad)
# "AC Refresh" the Refresh key (application control keypad)
# "AC Search" the Search key (application control keypad)
# "AC Stop" the Stop key (application control keypad)
# "Again" the Again key (Redo)
# "AltErase" Erase-Eaze
# "'"
# "Application" the Application / Compose / Context Menu (Windows)
# key
# "AudioMute" the Mute volume key
# "AudioNext" the Next Track media key
# "AudioPlay" the Play media key
# "AudioPrev" the Previous Track media key
# "AudioStop" the Stop media key)
# "B"
# "\" Located at the lower left of the return key on ISO
# keyboards and at the right end of the QWERTY row
# on ANSI keyboards. Produces REVERSE SOLIDUS
# (backslash) and VERTICAL LINE in a US layout,
# REVERSE SOLIDUS and VERTICAL LINE in a UK Mac layout,
# NUMBER SIGN and TILDE in a UK Windows layout, DOLLAR
# SIGN and POUND SIGN in a Swiss German layout,
# NUMBER SIGN and APOSTROPHE in a German layout, GRAVE
# ACCENT and POUND SIGN in a French Mac layout, and
# ASTERISK and MICRO SIGN in a French Windows layout.
# "Backspace"
# "BrightnessDown" the Brightness Down key
# "BrightnessUp" the Brightness Up key
# "C"
# "Calculator" the Calculator key
# "Cancel"
# "CapsLock"
# "Clear"
# "Clear / Again"
# ","
# "Computer" the My Computer key
# "Copy"
# "CrSel"
# "CurrencySubUnit" the Currency Subunit key
# "CurrencyUnit" the Currency Unit key
# "Cut"
# "D"
# "DecimalSeparator" the Decimal Separator key
# "Delete"
# "DisplaySwitch" display mirroring/dual display switch, video mode
# switch
# "Down" the Down arrow key (navigation keypad)
# "E"
# "Eject" the Eject key)
# "End"
# "="
# "Escape" the Esc key)
# "Execute"
# "ExSel"
# "F"
# "F1"
# "F10"
# "F11"
# "F12"
# "F13"
# "F14"
# "F15"
# "F16"
# "F17"
# "F18"
# "F19"
# "F2"
# "F20"
# "F21"
# "F22"
# "F23"
# "F24"
# "F3"
# "F4"
# "F5"
# "F6"
# "F7"
# "F8"
# "F9"
# "Find"
# "G"
# "`" Located in the top left corner (on both ANSI and ISO
# keyboards). Produces GRAVE ACCENT and TILDE in a US
# Windows layout and in US and UK Mac layouts on ANSI
# keyboards, GRAVE ACCENT and NOT SIGN in a UK Windows
# layout, SECTION SIGN and PLUS-MINUS SIGN in US and
# UK Mac layouts on ISO keyboards, SECTION SIGN and
# DEGREE SIGN in a Swiss German layout (Mac: only on
# ISO keyboards), CIRCUMFLEX ACCENT and DEGREE SIGN
# in a German layout (Mac: only on ISO keyboards),
# SUPERSCRIPT TWO and TILDE in a French Windows layout,
# COMMERCIAL AT and NUMBER SIGN in a French Mac layout
# on ISO keyboards, and LESS-THAN SIGN and GREATER-THAN
# SIGN in a Swiss German, German, or French Mac layout
# on ANSI keyboards.
# "H"
# "Help"
# "Home"
# "I"
# "Insert" insert on PC, help on some Mac keyboards (but does
# send code 73, not 117)
# "J"
# "K"
# "KBDIllumDown" the Keyboard Illumination Down key
# "KBDIllumToggle" the Keyboard Illumination Toggle key
# "KBDIllumUp" the Keyboard Illumination Up key
# "Keypad 0" the 0 key (numeric keypad)
# "Keypad 00" the 00 key (numeric keypad)
# "Keypad 000" the 000 key (numeric keypad)
# "Keypad 1" the 1 key (numeric keypad)
# "Keypad 2" the 2 key (numeric keypad)
# "Keypad 3" the 3 key (numeric keypad)
# "Keypad 4" the 4 key (numeric keypad)
# "Keypad 5" the 5 key (numeric keypad)
# "Keypad 6" the 6 key (numeric keypad)
# "Keypad 7" the 7 key (numeric keypad)
# "Keypad 8" the 8 key (numeric keypad)
# "Keypad 9" the 9 key (numeric keypad)
# "Keypad A" the A key (numeric keypad)
# "Keypad &" the & key (numeric keypad)
# "Keypad @" the @ key (numeric keypad)
# "Keypad B" the B key (numeric keypad)
# "Keypad Backspace" the Backspace key (numeric keypad)
# "Keypad Binary" the Binary key (numeric keypad)
# "Keypad C" the C key (numeric keypad)
# "Keypad Clear" the Clear key (numeric keypad)
# "Keypad ClearEntry" the Clear Entry key (numeric keypad)
# "Keypad :" the : key (numeric keypad)
# "Keypad ," the Comma key (numeric keypad)
# "Keypad D" the D key (numeric keypad)
# "Keypad &&" the && key (numeric keypad)
# "Keypad ||" the || key (numeric keypad)
# "Keypad Decimal" the Decimal key (numeric keypad)
# "Keypad /" the / key (numeric keypad)
# "Keypad E" the E key (numeric keypad)
# "Keypad Enter" the Enter key (numeric keypad)
# "Keypad =" the = key (numeric keypad)
# "Keypad = (AS400)" the Equals AS400 key (numeric keypad)
# "Keypad !" the ! key (numeric keypad)
# "Keypad F" the F key (numeric keypad)
# "Keypad >" the Greater key (numeric keypad)
# "Keypad #" the # key (numeric keypad)
# "Keypad Hexadecimal" the Hexadecimal key (numeric keypad)
# "Keypad {" the Left Brace key (numeric keypad)
# "Keypad (" the Left Parenthesis key (numeric keypad)
# "Keypad <" the Less key (numeric keypad)
# "Keypad MemAdd" the Mem Add key (numeric keypad)
# "Keypad MemClear" the Mem Clear key (numeric keypad)
# "Keypad MemDivide" the Mem Divide key (numeric keypad)
# "Keypad MemMultiply" the Mem Multiply key (numeric keypad)
# "Keypad MemRecall" the Mem Recall key (numeric keypad)
# "Keypad MemStore" the Mem Store key (numeric keypad)
# "Keypad MemSubtract" the Mem Subtract key (numeric keypad)
# "Keypad -" the - key (numeric keypad)
# "Keypad \*" the \* key (numeric keypad)
# "Keypad Octal" the Octal key (numeric keypad)
# "Keypad %" the Percent key (numeric keypad)
# "Keypad ." the . key (numeric keypad)
# "Keypad +" the + key (numeric keypad)
# "Keypad +/-" the +/- key (numeric keypad)
# "Keypad ^" the Power key (numeric keypad)
# "Keypad }" the Right Brace key (numeric keypad)
# "Keypad )" the Right Parenthesis key (numeric keypad)
# "Keypad Space" the Space key (numeric keypad)
# "Keypad Tab" the Tab key (numeric keypad)
# "Keypad \|" the \| key (numeric keypad)
# "Keypad XOR" the XOR key (numeric keypad)
# "L"
# "Left Alt" alt, option
# "Left Ctrl"
# "Left" the Left arrow key (navigation keypad)
# "["
# "Left GUI" windows, command (apple), meta
# "Left Shift"
# "M"
# "Mail" the Mail/eMail key
# "MediaSelect" the Media Select key
# "Menu"
# "-"
# "ModeSwitch" I'm not sure if this is really not covered by any of
# the above, but since there's a special KMOD_MODE for
# it I'm adding it here
# "Mute"
# "N"
# "Numlock" the Num Lock key (PC) / the Clear key (Mac)
# "O"
# "Oper"
# "Out"
# "P"
# "PageDown"
# "PageUp"
# "Paste"
# "Pause" the Pause / Break key
# "."
# "Power" The USB document says this is a status flag, not a
# physical key - but some Mac keyboards do have a
# power key.
# "PrintScreen"
# "Prior"
# "Q"
# "R"
# "Right Alt" alt gr, option
# "Right Ctrl"
# "Return" the Enter key (main keyboard)
# "Return"
# "Right GUI" windows, command (apple), meta
# "Right" the Right arrow key (navigation keypad)
# "]"
# "Right Shift"
# "S"
# "ScrollLock"
# "Select"
# ";"
# "Separator"
# "/"
# "Sleep" the Sleep key
# "Space" the Space Bar key(s)
# "Stop"
# "SysReq" the SysReq key
# "T"
# "Tab" the Tab key
# "ThousandsSeparator" the Thousands Separator key
# "U"
# "Undo"
# "Up" the Up arrow key (navigation keypad)
# "V"
# "VolumeDown"
# "VolumeUp"
# "W"
# "WWW" the WWW/World Wide Web key
# "X"
# "Y"
# "Z"
# "#" ISO USB keyboards actually use this code instead of
# 49 for the same key, but all OSes I've seen treat
# the two codes identically. So, as an implementor,
# unless your keyboard generates both of those codes
# and your OS treats them differently, you should
# generate SDL_SCANCODE_BACKSLASH instead of this
# code. As a user, you should not rely on this code
# becauseSDL will never generate it with most (all?)
# keyboards.
# "&"
# "*"
# "@"
# "^"
# ":"
# "$"
# "!"
# ">"
# "#"
# "("
# "<"
# "%"
# "+"
# "?"
# ")"
# "_"
# These codes were taken from https://wiki.libsdl.org/SDL_Keycode

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1807,7 +1807,7 @@
<!-- Collection Size -->
<reloadableText type="collectionIndexSize" x="1500" y="-68" xOrigin="right" yOrigin="center" fontSize="42" loadFontSize="42" layer="10">
<reloadableText type="collectionIndexSize" menuScrollReload="true" x="1500" y="-68" xOrigin="right" yOrigin="center" fontSize="42" loadFontSize="42" layer="10">
<onExit>
<set duration=".15">
<animate type="alpha" to="0" algorithm="easeinquadratic"/>
@ -2656,7 +2656,7 @@
<!----------------------------------------------------------------------------------------------------------------------------------->
<reloadableImage type="playlist" mode="common" alpha="0" x="980" y="500" xOrigin="center" yOrigin="top"
<reloadableImage type="playlist" mode="common" alpha="0" x="940" y="500" xOrigin="center" yOrigin="top"
maxHeight="30" layer="19">
<onEnter>
<set duration=".8">

View File

@ -51,8 +51,22 @@ UserInput::~UserInput()
bool UserInput::initialize()
{
// Optional keys
MapKey("pageDown", KeyCodePageDown, false );
MapKey("pageUp", KeyCodePageUp, false );
MapKey("letterDown", KeyCodeLetterDown, false);
MapKey("letterUp", KeyCodeLetterUp, false);
MapKey("favPlaylist", KeyCodeFavPlaylist, false);
MapKey("nextPlaylist", KeyCodeNextPlaylist, false);
MapKey("prevPlaylist", KeyCodePrevPlaylist, false);
MapKey("addPlaylist", KeyCodeAddPlaylist, false);
MapKey("removePlaylist", KeyCodeRemovePlaylist, false);
MapKey("random", KeyCodeRandom, false);
bool retVal = true;
// At least have controls for either a vertical or horizontal menu
if(!MapKey("up", KeyCodeUp))
{
retVal = MapKey("left", KeyCodeUp) && retVal;
@ -63,30 +77,17 @@ bool UserInput::initialize()
}
if(!MapKey("down", KeyCodeDown))
{
retVal = MapKey("right", KeyCodeDown) && retVal;
retVal = MapKey("right", KeyCodeDown ) && retVal;
}
if(!MapKey("right", KeyCodeRight))
if(!MapKey("right", KeyCodeRight ))
{
retVal = MapKey("down", KeyCodeRight) && retVal;
retVal = MapKey("down", KeyCodeRight ) && retVal;
}
// These keys are mandatory
retVal = MapKey("select", KeyCodeSelect) && retVal;
retVal = MapKey("back", KeyCodeBack) && retVal;
retVal = MapKey("quit", KeyCodeQuit) && retVal;
retVal = MapKey("pageDown", KeyCodePageDown);
retVal = MapKey("pageUp", KeyCodePageUp);
MapKey("letterDown", KeyCodeLetterDown, false);
MapKey("letterUp", KeyCodeLetterUp, false);
MapKey("favPlaylist", KeyCodeFavPlaylist, false);
MapKey("nextPlaylist", KeyCodeNextPlaylist, false);
MapKey("prevPlaylist", KeyCodePrevPlaylist, false);
MapKey("addPlaylist", KeyCodeAddPlaylist, false);
MapKey("removePlaylist", KeyCodeRemovePlaylist, false);
MapKey("random", KeyCodeRandom, false);
// these features will need to be implemented at a later time
// retVal = MapKey("admin", KeyCodeAdminMode) && retVal;
// retVal = MapKey("remove", KeyCodeHideItem) && retVal;
return retVal;
}

View File

@ -77,6 +77,7 @@ Page *PageBuilder::buildPage( std::string collectionName )
Page *page = NULL;
std::string layoutFile;
std::string layoutFileAspect;
std::string layoutName = layoutKey;
if ( collectionName == "" )
@ -89,19 +90,44 @@ Page *PageBuilder::buildPage( std::string collectionName )
layoutPath = Utils::combinePath(layoutPath, "layout");
}
layoutFile = Utils::combinePath(layoutPath, layoutPage + ".xml");
if ( screenWidth_*3/4 == screenHeight_ )
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + " 4x3.xml");
else if ( screenWidth_*4/3 == screenHeight_ )
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + " 3x4.xml");
else if ( screenWidth_*4/5 == screenHeight_ )
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + " 5x4.xml");
else if ( screenWidth_*5/4 == screenHeight_ )
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + " 4x5.xml");
else if ( screenWidth_*9/16 == screenHeight_ )
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + " 16x9.xml");
else if ( screenWidth_*16/9 == screenHeight_ )
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + " 9x16.xml");
else if ( screenWidth_*10/16 == screenHeight_ )
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + " 16x10.xml");
else if ( screenWidth_*16/10 == screenHeight_ )
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + " 10x16.xml");
else
layoutFileAspect = Utils::combinePath(layoutPath, layoutPage + ".xml");
Logger::write(Logger::ZONE_INFO, "Layout", "Initializing " + layoutFile);
Logger::write(Logger::ZONE_INFO, "Layout", "Initializing " + layoutFileAspect);
rapidxml::xml_document<> doc;
std::ifstream file(layoutFile.c_str());
std::vector<char> buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
std::ifstream file(layoutFileAspect.c_str());
if(!file.good())
if ( !file.good( ) )
{
Logger::write(Logger::ZONE_INFO, "Layout", "could not find layout file: " + layoutFile);
return NULL;
Logger::write( Logger::ZONE_INFO, "Layout", "could not find layout file: " + layoutFileAspect );
Logger::write( Logger::ZONE_INFO, "Layout", "Initializing " + layoutFile );
file.open( layoutFile.c_str( ) );
if ( !file.good( ) )
{
Logger::write( Logger::ZONE_INFO, "Layout", "could not find layout file: " + layoutFile );
return NULL;
}
}
std::vector<char> buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
try
{
buffer.push_back('\0');

View File

@ -21,6 +21,7 @@
#include "Utility/Utils.h"
#include "RetroFE.h"
#include "Version.h"
#include "SDL.h"
#include <cstdlib>
#include <fstream>
#include <dirent.h>
@ -128,13 +129,6 @@ bool ImportConfiguration(Configuration *c)
return false;
}
std::string controlsConfPath = Utils::combinePath(configPath, "controls.conf");
if(!c->import("controls", controlsConfPath))
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + controlsConfPath + "\"");
return false;
}
dp = opendir(launchersPath.c_str());
if(dp == NULL)

View File

@ -31,10 +31,13 @@
#include "Graphics/Component/ScrollingList.h"
#include "Graphics/Component/Video.h"
#include "Video/VideoFactory.h"
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <dirent.h>
#include <fstream>
#include <sstream>
#include <tuple>
#include <vector>
#include <SDL2/SDL_ttf.h>
#if defined(__linux) || defined(__APPLE__)
#include <sys/stat.h>
@ -137,7 +140,7 @@ void RetroFE::launchEnter( )
{
// Disable window focus
SDL_SetWindowGrab(SDL::getWindow(), SDL_FALSE);
SDL_SetWindowGrab(SDL::getWindow( ), SDL_FALSE);
// Free the textures, and optionally take down SDL
freeGraphicsMemory( );
@ -267,6 +270,27 @@ void RetroFE::run( )
if(! SDL::initialize( config_ ) ) return;
fontcache_.initialize( );
// Define control configuration
std::string controlsConfPath = Utils::combinePath( Configuration::absolutePath, "controls.conf" );
if ( !config_.import( "controls", controlsConfPath ) )
{
// Let the user input new controls
get_controls_config( );
// Re-initialize SDL to reset the controller situation
SDL::deInitialize( );
if(! SDL::initialize( config_ ) ) return;
// Retry reading the control configuration
if ( !config_.import( "controls", controlsConfPath ) )
{
Logger::write( Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + controlsConfPath + "\"" );
return;
}
}
float preloadTime = 0;
// Initialize video
@ -1152,3 +1176,201 @@ CollectionInfo *RetroFE::getCollection(std::string collectionName)
return collection;
}
std::string RetroFE::get_key( )
{
SDL_Event event;
std::string return_value;
while ( SDL_PollEvent( &event ) )
{
switch (event.type)
{
case SDL_JOYDEVICEADDED:
if ( !SDL_JoystickOpen( event.jdevice.which ) )
Logger::write( Logger::ZONE_INFO, "RetroFE", "Unable to open SDL joystick." );
else
Logger::write( Logger::ZONE_INFO, "RetroFE", "SDL joystick opened." );
break;
case SDL_KEYDOWN:
if ( return_value.empty( ) )
return_value = SDL_GetKeyName( event.key.keysym.sym);
break;
case SDL_JOYBUTTONDOWN:
if ( return_value.empty( ) )
return_value = "joyButton" + std::to_string( int( event.jbutton.button ) );
break;
case SDL_JOYAXISMOTION:
if ((event.jaxis.value > 30000 || event.jaxis.value < -30000) && event.jaxis.axis <= 3)
{
if ( event.jaxis.value > 0 )
{
if ( return_value.empty( ) )
return_value = "joyAxis" + std::to_string( int( event.jaxis.axis ) ) + "+";
}
else
{
if ( return_value.empty( ) )
return_value = "joyAxis" + std::to_string( int( event.jaxis.axis ) ) + "-";
}
}
break;
case SDL_JOYHATMOTION:
switch( event.jhat.value )
{
case SDL_HAT_UP:
if ( return_value.empty( ) )
return_value = "joyHat" + std::to_string( int( event.jhat.hat ) ) + "Up";
break;
case SDL_HAT_DOWN:
if ( return_value.empty( ) )
return_value = "joyHat" + std::to_string( int( event.jhat.hat ) ) + "Down";
break;
case SDL_HAT_LEFT:
if ( return_value.empty( ) )
return_value = "joyHat" + std::to_string( int( event.jhat.hat ) ) + "Left";
break;
case SDL_HAT_RIGHT:
if ( return_value.empty( ) )
return_value = "joyHat" + std::to_string( int( event.jhat.hat ) ) + "Right";
break;
}
break;
default:
break;
}
}
return return_value;
}
void RetroFE::print_string( std::string message, TTF_Font *font )
{
SDL_Surface *surfaceMessage;
SDL_Texture *messageTexture;
SDL_Rect messageRect;
SDL_Color color = {255, 255, 255, 0};
surfaceMessage = TTF_RenderText_Solid( font, message.c_str( ), color );
if ( !surfaceMessage )
Logger::write( Logger::ZONE_INFO, "RetroFE", "Could not render print_string text." );
messageTexture = SDL_CreateTextureFromSurface( SDL::getRenderer( ), surfaceMessage );
if ( !messageTexture )
Logger::write( Logger::ZONE_INFO, "RetroFE", "Could not create print_string texture." );
messageRect.w = SDL::getWindowWidth( ) * 8 / 10;
messageRect.h = SDL::getWindowWidth( ) * 8 * surfaceMessage->h / (10 * surfaceMessage->w);
messageRect.x = SDL::getWindowWidth( )/2 - messageRect.w/2;
messageRect.y = SDL::getWindowHeight( )/2 - messageRect.h/2;
SDL_LockMutex( SDL::getMutex( ) );
SDL_SetRenderDrawColor( SDL::getRenderer( ), 0, 0, 0, 0xFF );
SDL_RenderClear( SDL::getRenderer( ) );
SDL_RenderCopy( SDL::getRenderer( ), messageTexture, NULL, &messageRect);
SDL_RenderPresent( SDL::getRenderer( ) );
SDL_UnlockMutex( SDL::getMutex( ) );
SDL_FreeSurface( surfaceMessage);
SDL_DestroyTexture( messageTexture );
}
void RetroFE::get_controls_config( )
{
Logger::write( Logger::ZONE_INFO, "RetroFE", std::to_string( SDL_NumJoysticks( ) ) + " joysticks were found." );
TTF_Font *font = TTF_OpenFont( Utils::combinePath( "core", "OpenSans.ttf" ).c_str( ), 48 );
if ( !font )
{
Logger::write( Logger::ZONE_INFO, "RetroFE", "SDL could not open font OpenSans.ttf" );
return;
}
std::ofstream controls_file;
controls_file.open( "controls.conf" );
std::vector<std::tuple<std::string, std::string, bool>> controls;
controls.push_back( std::make_tuple( "up", "go up in the games/collection menu", true ) );
controls.push_back( std::make_tuple( "down", "go down in the games/collection menu", true ) );
controls.push_back( std::make_tuple( "left", "go left in the games/collection menu", true ) );
controls.push_back( std::make_tuple( "right", "go right in the games/collection menu", true ) );
controls.push_back( std::make_tuple( "pageUp", "go to the next page in your games/collection menu", false ) );
controls.push_back( std::make_tuple( "pageDown", "go to the previous page in your games/collection menu", false ) );
controls.push_back( std::make_tuple( "letterUp", "go to the next letter in your games/collection menu", false ) );
controls.push_back( std::make_tuple( "letterDown", "go to the previous letter in your games/collection menu", false ) );
controls.push_back( std::make_tuple( "favPlaylist", "switch to your Favorites playlist", false ) );
controls.push_back( std::make_tuple( "nextPlaylist", "switch to the next playlist", false ) );
controls.push_back( std::make_tuple( "prevPlaylist", "switch to the previous playlist", false ) );
controls.push_back( std::make_tuple( "addPlaylist", "add the selected game/collection to your Favorites playlist", false ) );
controls.push_back( std::make_tuple( "removePlaylist", "remove the selected game/collection from your Favorites playlist", false ) );
controls.push_back( std::make_tuple( "random", "select a random game/collection from the menu", false ) );
controls.push_back( std::make_tuple( "select", "enter the collection/start the game", true ) );
controls.push_back( std::make_tuple( "back", "go back to the previous menu", true ) );
controls.push_back( std::make_tuple( "quit", "quit RetroFE", true ) );
std::string key;
std::vector<std::string> keys;
// Clear input queue before we start, but do attach joysticks
get_key( );
for ( uint c = 0; c < controls.size( ); c++ )
{
keys.clear( );
int time_out = 0;
while ( true )
{
key = "";
while ( key.empty( ) )
{
if ( !keys.size( ) )
{
if ( std::get<2>( controls[c] ) )
print_string( "Please enter your control to " + std::get<1>( controls[c] ) + ". This key is mandatory for proper RetroFE usage.", font );
else
print_string( "Please enter your control to " + std::get<1>( controls[c] ) + " or wait " + std::to_string( 10 - time_out / 10 ) + " second(s) to not make a selection for this control.", font );
}
else
{
print_string( "Please enter another control to " + std::get<1>( controls[c] ) + " or wait " + std::to_string( 10 - time_out / 10 ) + " second(s) to continue with the next control.", font );
}
SDL_Delay( 100 );
key = get_key( );
time_out++;
if ( (!std::get<2>( controls[c] ) || keys.size( )) && time_out > 100 )
break;
}
if ( key.empty( ) || (keys.size( ) && std::find( keys.begin( ), keys.end( ), key ) != keys.end( )) )
break;
keys.push_back( key );
time_out = 0;
}
if ( keys.size( ) )
{
controls_file << std::get<0>( controls[c] ) + " = ";
for ( uint i = 0; i < keys.size( ); i++ )
if ( i == 0 )
controls_file << keys[i];
else
controls_file << ", " << keys[i];
controls_file << std::endl;
}
}
controls_file.close( );
TTF_CloseFont( font );
}

View File

@ -25,9 +25,11 @@
#include "Video/IVideo.h"
#include "Video/VideoFactory.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <list>
#include <stack>
#include <map>
#include <string>
class CollectionInfo;
@ -113,4 +115,8 @@ private:
std::map<std::string, unsigned int> lastMenuOffsets_;
std::map<std::string, std::string> lastMenuPlaylists_;
std::string get_key( );
void print_string( std::string message, TTF_Font *font );
void get_controls_config( );
};

View File

@ -21,7 +21,7 @@
std::string retrofe_version_major = "0";
std::string retrofe_version_minor = "8";
std::string retrofe_version_build = "14";
std::string retrofe_version_build = "15b1";
std::string Version::getString( )