added random ROM loading option (resolves #995)
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
* Added searching by filename for ROM launcher images.
|
* Added searching by filename for ROM launcher images.
|
||||||
|
|
||||||
|
* Added option to start random ROM.
|
||||||
|
|
||||||
* Enhanced Game Properties dialog for multigame ROMs.
|
* Enhanced Game Properties dialog for multigame ROMs.
|
||||||
|
|
||||||
* Added 2nd UI theme and hotkey for toggling UI theme.
|
* Added 2nd UI theme and hotkey for toggling UI theme.
|
||||||
|
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 218 B |
|
@ -2172,6 +2172,12 @@
|
||||||
<td>Control + R</td>
|
<td>Control + R</td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Load random ROM</td>
|
||||||
|
<td>Control-Alt + R</td>
|
||||||
|
<td>Control-Alt + R</td>
|
||||||
|
<td>-</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Open Options dialog</td>
|
<td>Open Options dialog</td>
|
||||||
<td>Control + O</td>
|
<td>Control + O</td>
|
||||||
|
@ -4232,6 +4238,9 @@
|
||||||
</li><li>
|
</li><li>
|
||||||
<img src="graphics/open_help.png" style="vertical-align: middle; margin-top: 4px; margin-bottom: 4px; margin-right: 4px">
|
<img src="graphics/open_help.png" style="vertical-align: middle; margin-top: 4px; margin-bottom: 4px; margin-right: 4px">
|
||||||
Open this help for the launcher.
|
Open this help for the launcher.
|
||||||
|
</li><li>
|
||||||
|
<img src="graphics/reload_list.png" style="vertical-align: middle; margin-top: 4px; margin-bottom: 4px; margin-right: 4px">
|
||||||
|
Reload the file list.
|
||||||
</li><li>
|
</li><li>
|
||||||
The 'Filter' text box can be used to narrow down the results in the
|
The 'Filter' text box can be used to narrow down the results in the
|
||||||
ROM listing. When this box is empty, all files are shown. Typing
|
ROM listing. When this box is empty, all files are shown. Typing
|
||||||
|
@ -4246,7 +4255,10 @@
|
||||||
</li><li>
|
</li><li>
|
||||||
<img src="graphics/show_current_dir.png" style="vertical-align: middle; margin-top: 4px; margin-bottom: 4px">
|
<img src="graphics/show_current_dir.png" style="vertical-align: middle; margin-top: 4px; margin-bottom: 4px">
|
||||||
<img src="graphics/show_sub_dirs.png" style="vertical-align: middle; margin-top: 4px; margin-bottom: 4px; margin-right: 4px">
|
<img src="graphics/show_sub_dirs.png" style="vertical-align: middle; margin-top: 4px; margin-bottom: 4px; margin-right: 4px">
|
||||||
Display either files from current directory only or all subdirectories too.
|
Display either files from current directory only, or all subdirectories too.
|
||||||
|
</li><li>
|
||||||
|
<img src="graphics/select_random_rom.png" style="vertical-align: middle; margin-top: 4px; margin-bottom: 4px; margin-right: 4px">
|
||||||
|
Load a random ROM from the current file list.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</br>
|
</br>
|
||||||
|
|
|
@ -27,7 +27,9 @@ namespace GUI {
|
||||||
|
|
||||||
/* Exported structure definition. */
|
/* Exported structure definition. */
|
||||||
static constexpr IconDesc iconSmallDesc(14, 14);
|
static constexpr IconDesc iconSmallDesc(14, 14);
|
||||||
|
static constexpr IconDesc iconSmallWDesc(24, 14);
|
||||||
static constexpr IconDesc iconLargeDesc(19, 20);
|
static constexpr IconDesc iconLargeDesc(19, 20);
|
||||||
|
static constexpr IconDesc iconLargeWDesc(32, 20);
|
||||||
|
|
||||||
// Settings icon
|
// Settings icon
|
||||||
static const Icon icon_settings_small(
|
static const Icon icon_settings_small(
|
||||||
|
@ -149,44 +151,6 @@ static const Icon icon_reload_small(
|
||||||
0b00000111110000
|
0b00000111110000
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allfiles icons
|
|
||||||
static const Icon icon_onlyroms_small_on (
|
|
||||||
iconSmallDesc,
|
|
||||||
{
|
|
||||||
0b00000000000000,
|
|
||||||
0b00000111100000,
|
|
||||||
0b00000111100000,
|
|
||||||
0b00000111100000,
|
|
||||||
0b00000111100000,
|
|
||||||
0b00000111100000,
|
|
||||||
0b00000111100000,
|
|
||||||
0b00001111110000,
|
|
||||||
0b00001111110000,
|
|
||||||
0b00011111111000,
|
|
||||||
0b00011011011000,
|
|
||||||
0b00110011001100,
|
|
||||||
0b11110011001111,
|
|
||||||
0b11100011000111
|
|
||||||
});
|
|
||||||
static const Icon icon_onlyroms_small_off (
|
|
||||||
iconSmallDesc,
|
|
||||||
{
|
|
||||||
0b01111111111000,
|
|
||||||
0b01000000001100,
|
|
||||||
0b01000000000110,
|
|
||||||
0b01000000000010,
|
|
||||||
0b01001000010010,
|
|
||||||
0b01001100110010,
|
|
||||||
0b01000111100010,
|
|
||||||
0b01011111111010,
|
|
||||||
0b01000111100010,
|
|
||||||
0b01001100110010,
|
|
||||||
0b01001000010010,
|
|
||||||
0b01000000000010,
|
|
||||||
0b01000000000010,
|
|
||||||
0b01111111111110
|
|
||||||
});
|
|
||||||
|
|
||||||
// Subdirs icons
|
// Subdirs icons
|
||||||
static const Icon icon_subdirs_small_off(
|
static const Icon icon_subdirs_small_off(
|
||||||
iconSmallDesc,
|
iconSmallDesc,
|
||||||
|
@ -224,6 +188,27 @@ static const Icon icon_subdirs_small_on(
|
||||||
0b00001000000001,
|
0b00001000000001,
|
||||||
0b00001111111111
|
0b00001111111111
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// random ROM icon
|
||||||
|
static const Icon icon_random_small(
|
||||||
|
iconSmallWDesc,
|
||||||
|
{
|
||||||
|
0b100000000000000000000100,
|
||||||
|
0b110000000000000000000110,
|
||||||
|
0b111000000011100000011111,
|
||||||
|
0b111100000011110000111111,
|
||||||
|
0b111110000000011001100110,
|
||||||
|
0b111111000000001100000100,
|
||||||
|
0b111111100000000110000000,
|
||||||
|
0b111111100000000110000000,
|
||||||
|
0b111111000000000011000100,
|
||||||
|
0b111110000000011001100110,
|
||||||
|
0b111100000011110000111111,
|
||||||
|
0b111000000011100000011111,
|
||||||
|
0b110000000000000000000110,
|
||||||
|
0b100000000000000000000100
|
||||||
|
});
|
||||||
|
|
||||||
// Help icon
|
// Help icon
|
||||||
static const Icon icon_help_small(
|
static const Icon icon_help_small(
|
||||||
iconSmallDesc,
|
iconSmallDesc,
|
||||||
|
@ -401,55 +386,6 @@ static const Icon icon_reload_large(
|
||||||
0b0000001111111000000
|
0b0000001111111000000
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allfiles icons
|
|
||||||
static const Icon icon_onlyroms_large_on(
|
|
||||||
iconLargeDesc,
|
|
||||||
{
|
|
||||||
0b00000000000000000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000001011010000000,
|
|
||||||
0b00000011011011000000,
|
|
||||||
0b00000011011011000000,
|
|
||||||
0b00000111011011100000,
|
|
||||||
0b00000110011001100000,
|
|
||||||
0b00001110011001110000,
|
|
||||||
0b00011100011000111000,
|
|
||||||
0b01111100011000011110,
|
|
||||||
0b11111000011000001111,
|
|
||||||
0b11100000011000000111
|
|
||||||
});
|
|
||||||
static const Icon icon_onlyroms_large_off(
|
|
||||||
iconLargeDesc,
|
|
||||||
{
|
|
||||||
0b0111111111111100000,
|
|
||||||
0b0100000000000110000,
|
|
||||||
0b0100000000000011000,
|
|
||||||
0b0100000000000001100,
|
|
||||||
0b0100011000011000100,
|
|
||||||
0b0100011100111000100,
|
|
||||||
0b0100001100110000100,
|
|
||||||
0b0100001111110000100,
|
|
||||||
0b0100000111100000100,
|
|
||||||
0b0101111111111110100,
|
|
||||||
0b0101111111111110100,
|
|
||||||
0b0100000111100000100,
|
|
||||||
0b0100001111110000100,
|
|
||||||
0b0100001100110000100,
|
|
||||||
0b0100011100111000100,
|
|
||||||
0b0100011000011000100,
|
|
||||||
0b0100000000000000100,
|
|
||||||
0b0100000000000000100,
|
|
||||||
0b0100000000000000100,
|
|
||||||
0b0111111111111111100
|
|
||||||
});
|
|
||||||
|
|
||||||
// Subdirs icons
|
// Subdirs icons
|
||||||
static const Icon icon_subdirs_large_off(
|
static const Icon icon_subdirs_large_off(
|
||||||
|
@ -501,6 +437,31 @@ static const Icon icon_subdirs_large_on(
|
||||||
0b0000111111111111111
|
0b0000111111111111111
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static const Icon icon_random_large(
|
||||||
|
iconLargeWDesc,
|
||||||
|
{
|
||||||
|
0b00000000000000000000000000001100,
|
||||||
|
0b10000000000000000000000000001110,
|
||||||
|
0b11000000000001111000000001111111,
|
||||||
|
0b11100000000001111100000011111111,
|
||||||
|
0b11110000000001111110000111001110,
|
||||||
|
0b11111000000000000111000110001100,
|
||||||
|
0b11111100000000000011100000001000,
|
||||||
|
0b11111110000000000001110000000000,
|
||||||
|
0b11111111000000000001110000000000,
|
||||||
|
0b11111111100000000000111000000000,
|
||||||
|
0b11111111100000000000011100000000,
|
||||||
|
0b11111111000000000000011100001000,
|
||||||
|
0b11111110000000000110001110001100,
|
||||||
|
0b11111100000001111110000111001110,
|
||||||
|
0b11111000000001111100000011111111,
|
||||||
|
0b11110000000001111000000001111111,
|
||||||
|
0b11100000000000000000000000001110,
|
||||||
|
0b11000000000000000000000000001100,
|
||||||
|
0b10000000000000000000000000001000,
|
||||||
|
0b00000000000000000000000000001000,
|
||||||
|
});
|
||||||
|
|
||||||
static const Icon icon_help_large(
|
static const Icon icon_help_large(
|
||||||
iconLargeDesc,
|
iconLargeDesc,
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include "Version.hxx"
|
#include "Version.hxx"
|
||||||
#include "MediaFactory.hxx"
|
#include "MediaFactory.hxx"
|
||||||
#include "LauncherDialog.hxx"
|
#include "LauncherDialog.hxx"
|
||||||
|
#include "Random.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
|
@ -129,10 +130,12 @@ void LauncherDialog::addFilteringWidgets(int& ypos)
|
||||||
|
|
||||||
// Figure out general icon button size
|
// Figure out general icon button size
|
||||||
const GUI::Icon& reloadIcon = smallIcon ? GUI::icon_reload_small : GUI::icon_reload_large;
|
const GUI::Icon& reloadIcon = smallIcon ? GUI::icon_reload_small : GUI::icon_reload_large;
|
||||||
|
const GUI::Icon& randomIcon = smallIcon ? GUI::icon_random_small : GUI::icon_random_large;
|
||||||
const GUI::Icon& dummyIcon = reloadIcon; //-- used for sizing all the other icons
|
const GUI::Icon& dummyIcon = reloadIcon; //-- used for sizing all the other icons
|
||||||
const int iconWidth = dummyIcon.width();
|
const int iconWidth = dummyIcon.width();
|
||||||
const int iconGap = ((fontWidth + 1) & ~0b1) + 1; // round up to next even
|
const int iconGap = ((fontWidth + 1) & ~0b1) + 1; // round up to next even
|
||||||
const int iconButtonWidth = iconWidth + iconGap;
|
const int iconButtonWidth = iconWidth + iconGap;
|
||||||
|
const int randomButtonWidth = randomIcon.width() + iconGap;
|
||||||
|
|
||||||
int xpos = HBORDER;
|
int xpos = HBORDER;
|
||||||
|
|
||||||
|
@ -151,8 +154,8 @@ void LauncherDialog::addFilteringWidgets(int& ypos)
|
||||||
int fwFilter = EditTextWidget::calcWidth(_font, "123456"); // at least 6 chars
|
int fwFilter = EditTextWidget::calcWidth(_font, "123456"); // at least 6 chars
|
||||||
|
|
||||||
// Calculate how much space everything will take
|
// Calculate how much space everything will take
|
||||||
int wTotal = xpos + (iconButtonWidth * 3) + lwFilter + fwFilter + lwFound + bwSettings
|
int wTotal = xpos + (iconButtonWidth * 2) + randomButtonWidth + lwFilter + fwFilter + lwFound + bwSettings
|
||||||
+ LBL_GAP * 6 + btnGap * 2 + HBORDER;
|
+ LBL_GAP * 5 + btnGap * 3 + HBORDER;
|
||||||
|
|
||||||
// make sure there is space for at least 6 characters in the filter field
|
// make sure there is space for at least 6 characters in the filter field
|
||||||
if(_w < wTotal)
|
if(_w < wTotal)
|
||||||
|
@ -175,7 +178,7 @@ void LauncherDialog::addFilteringWidgets(int& ypos)
|
||||||
// Show the reload button
|
// Show the reload button
|
||||||
myReloadButton = new ButtonWidget(this, _font, xpos, ypos - btnYOfs,
|
myReloadButton = new ButtonWidget(this, _font, xpos, ypos - btnYOfs,
|
||||||
iconButtonWidth, buttonHeight, reloadIcon, kReloadCmd);
|
iconButtonWidth, buttonHeight, reloadIcon, kReloadCmd);
|
||||||
myReloadButton->setToolTip("Reload listing. (Ctrl+R)");
|
myReloadButton->setToolTip("Reload listing (Ctrl+R)");
|
||||||
wid.push_back(myReloadButton);
|
wid.push_back(myReloadButton);
|
||||||
xpos = myReloadButton->getRight() + LBL_GAP * 2;
|
xpos = myReloadButton->getRight() + LBL_GAP * 2;
|
||||||
|
|
||||||
|
@ -203,13 +206,20 @@ void LauncherDialog::addFilteringWidgets(int& ypos)
|
||||||
// Show the files counter
|
// Show the files counter
|
||||||
myRomCount = new StaticTextWidget(this, _font, xpos, ypos,
|
myRomCount = new StaticTextWidget(this, _font, xpos, ypos,
|
||||||
lwFound, fontHeight, "", TextAlign::Right);
|
lwFound, fontHeight, "", TextAlign::Right);
|
||||||
|
xpos = myRomCount->getRight() + LBL_GAP;
|
||||||
|
|
||||||
|
// Show the random ROM button
|
||||||
|
myRandomRomButton = new ButtonWidget(this, _font, xpos, ypos - btnYOfs,
|
||||||
|
randomButtonWidth, buttonHeight, randomIcon, kLoadRndRomCmd);
|
||||||
|
myRandomRomButton->setToolTip("Load random ROM (Ctrl-Alt+R)");
|
||||||
|
wid.push_back(myRandomRomButton);
|
||||||
|
|
||||||
// Show the Settings / Options button (positioned from the right)
|
// Show the Settings / Options button (positioned from the right)
|
||||||
xpos = _w - HBORDER - bwSettings;
|
xpos = _w - HBORDER - bwSettings;
|
||||||
mySettingsButton = new ButtonWidget(this, _font, xpos, ypos - btnYOfs,
|
mySettingsButton = new ButtonWidget(this, _font, xpos, ypos - btnYOfs,
|
||||||
iconWidth, buttonHeight, settingsIcon,
|
iconWidth, buttonHeight, settingsIcon,
|
||||||
iconGap, lblSettings, kOptionsCmd);
|
iconGap, lblSettings, kOptionsCmd);
|
||||||
mySettingsButton-> setToolTip("(Ctrl+O)");
|
mySettingsButton-> setToolTip("Open Options dialog (Ctrl+O)");
|
||||||
wid.push_back(mySettingsButton);
|
wid.push_back(mySettingsButton);
|
||||||
|
|
||||||
ypos = mySettingsButton->getBottom() + Dialog::vGap();
|
ypos = mySettingsButton->getBottom() + Dialog::vGap();
|
||||||
|
@ -821,7 +831,10 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod, bool repeated)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KBDK_R:
|
case KBDK_R:
|
||||||
reload();
|
if(StellaModTest::isAlt(mod))
|
||||||
|
loadRandomRom();
|
||||||
|
else
|
||||||
|
reload();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KBDK_S:
|
case KBDK_S:
|
||||||
|
@ -993,6 +1006,10 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
loadRom();
|
loadRom();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case kLoadRndRomCmd:
|
||||||
|
loadRandomRom();
|
||||||
|
break;
|
||||||
|
|
||||||
case kOptionsCmd:
|
case kOptionsCmd:
|
||||||
openSettings();
|
openSettings();
|
||||||
break;
|
break;
|
||||||
|
@ -1227,6 +1244,19 @@ void LauncherDialog::openContextMenu(int x, int y)
|
||||||
contextMenu().show(x + getAbsX(), y + getAbsY(), surface().dstRect(), 0);
|
contextMenu().show(x + getAbsX(), y + getAbsY(), surface().dstRect(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void LauncherDialog::loadRandomRom()
|
||||||
|
{
|
||||||
|
const Random rand;
|
||||||
|
int tries = 100; // limit to 100 tries, in case the directory contains no ROMs
|
||||||
|
|
||||||
|
do {
|
||||||
|
myList->setSelected(rand.next() % myList->getList().size());
|
||||||
|
} while(myList->isDirectory(myList->selected()) && --tries);
|
||||||
|
if(tries)
|
||||||
|
loadRom();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::openSettings()
|
void LauncherDialog::openSettings()
|
||||||
{
|
{
|
||||||
|
|
|
@ -149,6 +149,7 @@ class LauncherDialog : public Dialog, CommandSender
|
||||||
void loadRom();
|
void loadRom();
|
||||||
void loadRomInfo();
|
void loadRomInfo();
|
||||||
void loadPendingRomInfo();
|
void loadPendingRomInfo();
|
||||||
|
void loadRandomRom();
|
||||||
void openSettings();
|
void openSettings();
|
||||||
void openGameProperties();
|
void openGameProperties();
|
||||||
void openContextMenu(int x = -1, int y = -1);
|
void openContextMenu(int x = -1, int y = -1);
|
||||||
|
@ -178,6 +179,7 @@ class LauncherDialog : public Dialog, CommandSender
|
||||||
ButtonWidget* mySettingsButton{nullptr};
|
ButtonWidget* mySettingsButton{nullptr};
|
||||||
EditTextWidget* myPattern{nullptr};
|
EditTextWidget* myPattern{nullptr};
|
||||||
ButtonWidget* mySubDirsButton{nullptr};
|
ButtonWidget* mySubDirsButton{nullptr};
|
||||||
|
ButtonWidget* myRandomRomButton{nullptr};
|
||||||
StaticTextWidget* myRomCount{nullptr};
|
StaticTextWidget* myRomCount{nullptr};
|
||||||
ButtonWidget* myHelpButton{nullptr};
|
ButtonWidget* myHelpButton{nullptr};
|
||||||
|
|
||||||
|
@ -211,6 +213,7 @@ class LauncherDialog : public Dialog, CommandSender
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kSubDirsCmd = 'lred',
|
kSubDirsCmd = 'lred',
|
||||||
|
kLoadRndRomCmd = 'lrnd', // load random ROM
|
||||||
kOptionsCmd = 'OPTI',
|
kOptionsCmd = 'OPTI',
|
||||||
kQuitCmd = 'QUIT',
|
kQuitCmd = 'QUIT',
|
||||||
kReloadCmd = 'relc',
|
kReloadCmd = 'relc',
|
||||||
|
|
|
@ -166,11 +166,13 @@ void RomInfoWidget::parseProperties(const FSNode& node, bool full)
|
||||||
+ (isPlusCart ? " - PlusROM" : "")
|
+ (isPlusCart ? " - PlusROM" : "")
|
||||||
+ buf.str());
|
+ buf.str());
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_BUILD
|
||||||
// Debug bezel properties:
|
// Debug bezel properties:
|
||||||
//if(myProperties.get(PropType::Bezel_Name).empty())
|
if(myProperties.get(PropType::Bezel_Name).empty())
|
||||||
// myRomInfo.push_back("*Bezel: " + Bezel::getName(instance().bezelDir().getPath(), myProperties));
|
myRomInfo.push_back("*Bezel: " + Bezel::getName(instance().bezelDir().getPath(), myProperties));
|
||||||
//else
|
else
|
||||||
// myRomInfo.push_back(" Bezel: " + myProperties.get(PropType::Bezel_Name));
|
myRomInfo.push_back(" Bezel: " + myProperties.get(PropType::Bezel_Name));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
setDirty();
|
setDirty();
|
||||||
|
|