diff --git a/Changes.txt b/Changes.txt
index d5bed8aad..96cfa4531 100644
--- a/Changes.txt
+++ b/Changes.txt
@@ -20,6 +20,8 @@
* Added searching by filename for ROM launcher images.
+ * Added option to start random ROM.
+
* Enhanced Game Properties dialog for multigame ROMs.
* Added 2nd UI theme and hotkey for toggling UI theme.
diff --git a/docs/graphics/launcher.png b/docs/graphics/launcher.png
index d01426c4d..4c3bf043c 100644
Binary files a/docs/graphics/launcher.png and b/docs/graphics/launcher.png differ
diff --git a/docs/graphics/rominfo_1x_large.png b/docs/graphics/rominfo_1x_large.png
index 80032b74d..3176a1246 100644
Binary files a/docs/graphics/rominfo_1x_large.png and b/docs/graphics/rominfo_1x_large.png differ
diff --git a/docs/graphics/rominfo_1x_small.png b/docs/graphics/rominfo_1x_small.png
index f1c3ca7f5..c9509ade6 100644
Binary files a/docs/graphics/rominfo_1x_small.png and b/docs/graphics/rominfo_1x_small.png differ
diff --git a/docs/graphics/rominfo_2x_small.png b/docs/graphics/rominfo_2x_small.png
index ee9a2c723..593b68c5b 100644
Binary files a/docs/graphics/rominfo_2x_small.png and b/docs/graphics/rominfo_2x_small.png differ
diff --git a/docs/graphics/select_random_rom.png b/docs/graphics/select_random_rom.png
new file mode 100644
index 000000000..e50844d38
Binary files /dev/null and b/docs/graphics/select_random_rom.png differ
diff --git a/docs/index.html b/docs/index.html
index 2ffd14b96..1c2749767 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -2172,6 +2172,12 @@
Control + R |
- |
+
+ Load random ROM |
+ Control-Alt + R |
+ Control-Alt + R |
+ - |
+
Open Options dialog |
Control + O |
@@ -4232,6 +4238,9 @@
Open this help for the launcher.
+
+
+ Reload the file list.
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
@@ -4246,7 +4255,10 @@
- Display either files from current directory only or all subdirectories too.
+ Display either files from current directory only, or all subdirectories too.
+
+
+ Load a random ROM from the current file list.
diff --git a/src/gui/Icons.hxx b/src/gui/Icons.hxx
index e51fdc138..4ebb308bd 100644
--- a/src/gui/Icons.hxx
+++ b/src/gui/Icons.hxx
@@ -27,7 +27,9 @@ namespace GUI {
/* Exported structure definition. */
static constexpr IconDesc iconSmallDesc(14, 14);
+static constexpr IconDesc iconSmallWDesc(24, 14);
static constexpr IconDesc iconLargeDesc(19, 20);
+static constexpr IconDesc iconLargeWDesc(32, 20);
// Settings icon
static const Icon icon_settings_small(
@@ -149,44 +151,6 @@ static const Icon icon_reload_small(
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
static const Icon icon_subdirs_small_off(
iconSmallDesc,
@@ -224,6 +188,27 @@ static const Icon icon_subdirs_small_on(
0b00001000000001,
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
static const Icon icon_help_small(
iconSmallDesc,
@@ -401,55 +386,6 @@ static const Icon icon_reload_large(
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
static const Icon icon_subdirs_large_off(
@@ -501,6 +437,31 @@ static const Icon icon_subdirs_large_on(
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(
iconLargeDesc,
{
diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx
index 1b226325e..f7981d46e 100644
--- a/src/gui/LauncherDialog.cxx
+++ b/src/gui/LauncherDialog.cxx
@@ -61,6 +61,7 @@
#include "Version.hxx"
#include "MediaFactory.hxx"
#include "LauncherDialog.hxx"
+#include "Random.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
@@ -129,10 +130,12 @@ void LauncherDialog::addFilteringWidgets(int& ypos)
// Figure out general icon button size
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 int iconWidth = dummyIcon.width();
const int iconGap = ((fontWidth + 1) & ~0b1) + 1; // round up to next even
const int iconButtonWidth = iconWidth + iconGap;
+ const int randomButtonWidth = randomIcon.width() + iconGap;
int xpos = HBORDER;
@@ -151,8 +154,8 @@ void LauncherDialog::addFilteringWidgets(int& ypos)
int fwFilter = EditTextWidget::calcWidth(_font, "123456"); // at least 6 chars
// Calculate how much space everything will take
- int wTotal = xpos + (iconButtonWidth * 3) + lwFilter + fwFilter + lwFound + bwSettings
- + LBL_GAP * 6 + btnGap * 2 + HBORDER;
+ int wTotal = xpos + (iconButtonWidth * 2) + randomButtonWidth + lwFilter + fwFilter + lwFound + bwSettings
+ + LBL_GAP * 5 + btnGap * 3 + HBORDER;
// make sure there is space for at least 6 characters in the filter field
if(_w < wTotal)
@@ -175,7 +178,7 @@ void LauncherDialog::addFilteringWidgets(int& ypos)
// Show the reload button
myReloadButton = new ButtonWidget(this, _font, xpos, ypos - btnYOfs,
iconButtonWidth, buttonHeight, reloadIcon, kReloadCmd);
- myReloadButton->setToolTip("Reload listing. (Ctrl+R)");
+ myReloadButton->setToolTip("Reload listing (Ctrl+R)");
wid.push_back(myReloadButton);
xpos = myReloadButton->getRight() + LBL_GAP * 2;
@@ -203,13 +206,20 @@ void LauncherDialog::addFilteringWidgets(int& ypos)
// Show the files counter
myRomCount = new StaticTextWidget(this, _font, xpos, ypos,
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)
xpos = _w - HBORDER - bwSettings;
mySettingsButton = new ButtonWidget(this, _font, xpos, ypos - btnYOfs,
iconWidth, buttonHeight, settingsIcon,
iconGap, lblSettings, kOptionsCmd);
- mySettingsButton-> setToolTip("(Ctrl+O)");
+ mySettingsButton-> setToolTip("Open Options dialog (Ctrl+O)");
wid.push_back(mySettingsButton);
ypos = mySettingsButton->getBottom() + Dialog::vGap();
@@ -821,7 +831,10 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod, bool repeated)
break;
case KBDK_R:
- reload();
+ if(StellaModTest::isAlt(mod))
+ loadRandomRom();
+ else
+ reload();
break;
case KBDK_S:
@@ -993,6 +1006,10 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
loadRom();
break;
+ case kLoadRndRomCmd:
+ loadRandomRom();
+ break;
+
case kOptionsCmd:
openSettings();
break;
@@ -1227,6 +1244,19 @@ void LauncherDialog::openContextMenu(int x, int y)
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()
{
diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx
index 119d7306d..608ef2d91 100644
--- a/src/gui/LauncherDialog.hxx
+++ b/src/gui/LauncherDialog.hxx
@@ -149,6 +149,7 @@ class LauncherDialog : public Dialog, CommandSender
void loadRom();
void loadRomInfo();
void loadPendingRomInfo();
+ void loadRandomRom();
void openSettings();
void openGameProperties();
void openContextMenu(int x = -1, int y = -1);
@@ -178,6 +179,7 @@ class LauncherDialog : public Dialog, CommandSender
ButtonWidget* mySettingsButton{nullptr};
EditTextWidget* myPattern{nullptr};
ButtonWidget* mySubDirsButton{nullptr};
+ ButtonWidget* myRandomRomButton{nullptr};
StaticTextWidget* myRomCount{nullptr};
ButtonWidget* myHelpButton{nullptr};
@@ -211,6 +213,7 @@ class LauncherDialog : public Dialog, CommandSender
enum {
kSubDirsCmd = 'lred',
+ kLoadRndRomCmd = 'lrnd', // load random ROM
kOptionsCmd = 'OPTI',
kQuitCmd = 'QUIT',
kReloadCmd = 'relc',
diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx
index dc6a40444..ae64bb6e7 100644
--- a/src/gui/RomInfoWidget.cxx
+++ b/src/gui/RomInfoWidget.cxx
@@ -166,11 +166,13 @@ void RomInfoWidget::parseProperties(const FSNode& node, bool full)
+ (isPlusCart ? " - PlusROM" : "")
+ buf.str());
}
+#ifdef DEBUG_BUILD
// Debug bezel properties:
- //if(myProperties.get(PropType::Bezel_Name).empty())
- // myRomInfo.push_back("*Bezel: " + Bezel::getName(instance().bezelDir().getPath(), myProperties));
- //else
- // myRomInfo.push_back(" Bezel: " + myProperties.get(PropType::Bezel_Name));
+ if(myProperties.get(PropType::Bezel_Name).empty())
+ myRomInfo.push_back("*Bezel: " + Bezel::getName(instance().bezelDir().getPath(), myProperties));
+ else
+ myRomInfo.push_back(" Bezel: " + myProperties.get(PropType::Bezel_Name));
+#endif
}
setDirty();