mirror of
https://github.com/FunKey-Project/RetroFE.git
synced 2026-10-24 20:46:19 +02:00
- 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:
@@ -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
|
||||
Executable
BIN
Binary file not shown.
+2768
File diff suppressed because it is too large
Load Diff
+2717
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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)
|
||||
|
||||
+226
-4
@@ -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 );
|
||||
|
||||
}
|
||||
|
||||
@@ -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( );
|
||||
|
||||
};
|
||||
|
||||
@@ -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( )
|
||||
|
||||
Reference in New Issue
Block a user