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 @@

Hotkeys

Control + R - + + Load random ROM + Control-Alt + R + Control-Alt + R + - + Open Options dialog Control + O @@ -4232,6 +4238,9 @@

ROM Info Viewer

  • 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 @@

    ROM Info Viewer

  • - 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();