From ee43255ea115db4cf5d1778d9a9bbddc5326af67 Mon Sep 17 00:00:00 2001 From: stephena Date: Thu, 29 Jul 2010 15:22:27 +0000 Subject: [PATCH] Many changes to the UI to fully support the smallest resolution that Stella can use (320x240). The app should no longer crash in such low-res situations. Various improvements to the UI, adding many finishing touches. The text is more descriptive, and the options are somewhat better labeled. As well, the available options are better presented based on the restrictions currently in use (ie, if the maximum resolution is very small, then the high-res resolutions are not shown in selectors, etc). Added MessageBox to ROM Audit functionality, to warn that it is a dangerous operation and that a file backup is advised. Updated OSX build script to not crash when an older image has already been created. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2076 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- docs/index.html | 6 +- src/common/FrameBufferGL.cxx | 12 ++- src/emucore/OSystem.cxx | 22 ++++- src/gui/AudioDialog.cxx | 28 +++--- src/gui/FileSnapDialog.cxx | 48 +++++----- src/gui/FileSnapDialog.hxx | 10 +- src/gui/HelpDialog.cxx | 54 ++++------- src/gui/InputDialog.cxx | 9 +- src/gui/LauncherDialog.cxx | 2 +- src/gui/MessageBox.cxx | 9 +- src/gui/MessageBox.hxx | 2 +- src/gui/RomAuditDialog.cxx | 30 +++++- src/gui/RomAuditDialog.hxx | 10 +- src/gui/UIDialog.cxx | 175 ++++++++++++++++++----------------- src/gui/UIDialog.hxx | 14 +-- src/gui/VideoDialog.cxx | 36 +++---- src/gui/VideoDialog.hxx | 2 +- src/gui/Widget.cxx | 5 +- src/macosx/Create_build.sh | 20 ++-- 19 files changed, 265 insertions(+), 229 deletions(-) diff --git a/docs/index.html b/docs/index.html index fa03be01e..5ea3f57ed 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1776,7 +1776,9 @@
-joydeadzone <number>
- Sets the joystick deadzone area for analog joysticks. + Sets the joystick axis deadzone area for joysticks/gamepads. + All values within the deadzone are treated as zero-axis values, + while only those values outside are registered as valid input. Accepts a number from 0 - 29, and uses the formula 3200 + number * 1000. So the possible deadzone values range from 3200 to 32200. @@ -2329,7 +2331,7 @@ ItemBrief descriptionFor more information,
see CommandLine Stelladaptor X isSpecifies which virtual port each Stelladaptor uses (See Advanced Configuration - Stelladaptor Support)-sa1 & -sa2 AVox serial portDescribed in further detail in Advanced Configuration - AtariVox/SaveKey Support -avoxport - Joy deadzoneJoystick deadzone area for analog joysticks-joydeadzone + Joy deadzoneDeadzone area for axes on joysticks/gamepads-joydeadzone Paddle speedSpeed used when emulating a paddle using a digital device-pspeed Allow all 4 ...Allow all 4 joystick directions to be pressed simultaneously-joyallow4 Use mouse as ...Use the mouse for various controllers (paddles, driving, etc)-usemouse diff --git a/src/common/FrameBufferGL.cxx b/src/common/FrameBufferGL.cxx index 5ee34e26f..1b57435f3 100644 --- a/src/common/FrameBufferGL.cxx +++ b/src/common/FrameBufferGL.cxx @@ -292,10 +292,14 @@ bool FrameBufferGL::setVidMode(VideoMode& mode) if(!inUIMode) { // Aspect ratio (depends on whether NTSC or PAL is detected) - const string& frate = myOSystem->console().about().InitialFrameRate; - int aspect = - myOSystem->settings().getInt(frate == "60" ? "gl_aspectn" : "gl_aspectp"); - mode.image_w = (uInt16)(float(mode.image_w * aspect) / 100.0); + // Not available in 'small' resolutions + if(myOSystem->desktopWidth() >= 640) + { + const string& frate = myOSystem->console().about().InitialFrameRate; + int aspect = + myOSystem->settings().getInt(frate == "60" ? "gl_aspectn" : "gl_aspectp"); + mode.image_w = (uInt16)(float(mode.image_w * aspect) / 100.0); + } // Fullscreen mode stretching if(fullScreen() && myOSystem->settings().getBool("gl_fsmax") && diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 7cbffdf20..a8e9951ca 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -1057,14 +1057,28 @@ bool OSystem::queryVideoHardware() else { for(uInt32 i = 0; modes[i]; ++i) + { + if(modes[i]->w >= 320 && modes[i]->w <= myDesktopWidth && + modes[i]->h >= 240 && modes[i]->h <= myDesktopHeight) + { + Resolution r; + r.width = modes[i]->w; + r.height = modes[i]->h; + buf.str(""); + buf << r.width << "x" << r.height; + r.name = buf.str(); + myResolutions.insert_at(0, r); // insert in opposite (of descending) order + } + } + // If no modes were valid, use the desktop dimensions + if(myResolutions.size() == 0) { Resolution r; - r.width = modes[i]->w; - r.height = modes[i]->h; - buf.str(""); + r.width = myDesktopWidth; + r.height = myDesktopHeight; buf << r.width << "x" << r.height; r.name = buf.str(); - myResolutions.insert_at(0, r); // insert in opposite (of descending) order + myResolutions.push_back(r); } } diff --git a/src/gui/AudioDialog.cxx b/src/gui/AudioDialog.cxx index 4a3b978c3..9d47f78ca 100644 --- a/src/gui/AudioDialog.cxx +++ b/src/gui/AudioDialog.cxx @@ -49,7 +49,7 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent, buttonHeight = font.getLineHeight() + 4; int xpos, ypos; int lwidth = font.getStringWidth("Fragment Size: "), - pwidth = font.getStringWidth("4096"); + pwidth = font.getStringWidth("512 bytes"); WidgetArray wid; StringMap items; @@ -74,12 +74,12 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent, // Fragment size items.clear(); - items.push_back("128", "128"); - items.push_back("256", "256"); - items.push_back("512", "512"); - items.push_back("1024", "1024"); - items.push_back("2048", "2048"); - items.push_back("4096", "4096"); + items.push_back("128 bytes", "128"); + items.push_back("256 bytes", "256"); + items.push_back("512 bytes", "512"); + items.push_back("1 KB", "1024"); + items.push_back("2 KB", "2048"); + items.push_back("4 KB", "4096"); myFragsizePopup = new PopUpWidget(this, font, xpos, ypos, pwidth + myVolumeLabel->getWidth() - 4, lineHeight, items, "Fragment size: ", lwidth); @@ -88,11 +88,11 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent, // Output frequency items.clear(); - items.push_back("11025", "11025"); - items.push_back("22050", "22050"); - items.push_back("31400", "31400"); - items.push_back("44100", "44100"); - items.push_back("48000", "48000"); + items.push_back("11025 Hz", "11025"); + items.push_back("22050 Hz", "22050"); + items.push_back("31400 Hz", "31400"); + items.push_back("44100 Hz", "44100"); + items.push_back("48000 Hz", "48000"); myFreqPopup = new PopUpWidget(this, font, xpos, ypos, pwidth + myVolumeLabel->getWidth() - 4, lineHeight, items, "Output freq: ", lwidth); @@ -108,13 +108,13 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent, ypos += lineHeight + 4; // Clip volume - myClipVolumeCheckbox = new CheckboxWidget(this, font, xpos+28, ypos, + myClipVolumeCheckbox = new CheckboxWidget(this, font, xpos+50, ypos, "Clip volume", 0); wid.push_back(myClipVolumeCheckbox); ypos += lineHeight + 4; // Enable sound - mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos+28, ypos, + mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos+50, ypos, "Enable sound", kSoundEnableChanged); wid.push_back(mySoundEnableCheckbox); ypos += lineHeight + 12; diff --git a/src/gui/FileSnapDialog.cxx b/src/gui/FileSnapDialog.cxx index 0938262c2..6456214cd 100644 --- a/src/gui/FileSnapDialog.cxx +++ b/src/gui/FileSnapDialog.cxx @@ -26,6 +26,7 @@ #include "EditTextWidget.hxx" #include "FSNode.hxx" #include "LauncherDialog.hxx" +#include "PopUpWidget.hxx" #include "Settings.hxx" #include "FileSnapDialog.hxx" @@ -128,7 +129,7 @@ FileSnapDialog::FileSnapDialog( // Snapshot single or multiple saves xpos = 30; ypos += b->getHeight() + 5; mySnapSingle = new CheckboxWidget(this, font, xpos, ypos, - "Multiple snapshots"); + "Overwrite snapshots"); wid.push_back(mySnapSingle); // Snapshot in 1x mode (ignore scaling) @@ -138,18 +139,23 @@ FileSnapDialog::FileSnapDialog( wid.push_back(mySnap1x); // Snapshot interval (continuous mode) + StringMap items; + items.clear(); + items.push_back("1 second", "1"); + items.push_back("2 seconds", "2"); + items.push_back("3 seconds", "3"); + items.push_back("4 seconds", "4"); + items.push_back("5 seconds", "5"); + items.push_back("6 seconds", "6"); + items.push_back("7 seconds", "7"); + items.push_back("8 seconds", "8"); + items.push_back("9 seconds", "9"); + items.push_back("10 seconds", "10"); xpos = 30; ypos += b->getHeight(); - mySnapSlider = - new SliderWidget(this, font, xpos, ypos, 6*fontWidth, lineHeight, - "Snapshot interval: ", font.getStringWidth("Snapshot interval: "), - kSnapIntervalChanged); - mySnapSlider->setMinValue(1); mySnapSlider->setMaxValue(10); - wid.push_back(mySnapSlider); - mySnapLabel = - new StaticTextWidget(this, font, xpos + mySnapSlider->getWidth() + 4, - ypos + 1, 3*fontWidth, font.getFontHeight(), "", - kTextAlignLeft); - mySnapLabel->setFlags(WIDGET_CLEARBG); + mySnapInterval = new PopUpWidget(this, font, xpos, ypos, + font.getStringWidth("10 seconds"), lineHeight, + items, "Continuous snapshot interval: "); + wid.push_back(mySnapInterval); // Add Defaults, OK and Cancel buttons b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10, @@ -188,10 +194,9 @@ void FileSnapDialog::loadConfig() myPropsFile->setEditString(settings.getString("propsfile")); mySnapPath->setEditString(settings.getString("ssdir")); myEEPROMPath->setEditString(settings.getString("eepromdir")); - mySnapSingle->setState(!settings.getBool("sssingle")); + mySnapSingle->setState(settings.getBool("sssingle")); mySnap1x->setState(settings.getBool("ss1x")); - mySnapSlider->setValue(instance().settings().getInt("ssinterval")); - mySnapLabel->setLabel(instance().settings().getString("ssinterval")); + mySnapInterval->setSelected(instance().settings().getString("ssinterval"), "2"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -204,9 +209,9 @@ void FileSnapDialog::saveConfig() instance().settings().setString("propsfile", myPropsFile->getEditString()); instance().settings().setString("ssdir", mySnapPath->getEditString()); instance().settings().setString("eepromdir", myEEPROMPath->getEditString()); - instance().settings().setBool("sssingle", !mySnapSingle->getState()); + instance().settings().setBool("sssingle", mySnapSingle->getState()); instance().settings().setBool("ss1x", mySnap1x->getState()); - instance().settings().setInt("ssinterval", mySnapSlider->getValue()); + instance().settings().setString("ssinterval", mySnapInterval->getSelectedTag()); // Flush changes to disk and inform the OSystem instance().settings().saveConfig(); @@ -248,10 +253,9 @@ void FileSnapDialog::setDefaults() node = FilesystemNode(ssdir); mySnapPath->setEditString(node.getRelativePath()); - mySnapSingle->setState(true); + mySnapSingle->setState(false); mySnap1x->setState(false); - mySnapSlider->setValue(2); - mySnapLabel->setLabel("2"); + mySnapInterval->setSelected("2", "2"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -359,10 +363,6 @@ void FileSnapDialog::handleCommand(CommandSender* sender, int cmd, sendCommand(kReloadRomDirCmd, 0, 0); break; - case kSnapIntervalChanged: - mySnapLabel->setValue(mySnapSlider->getValue()); - break; - default: Dialog::handleCommand(sender, cmd, data, 0); break; diff --git a/src/gui/FileSnapDialog.hxx b/src/gui/FileSnapDialog.hxx index ce594f691..6380f3c38 100644 --- a/src/gui/FileSnapDialog.hxx +++ b/src/gui/FileSnapDialog.hxx @@ -65,8 +65,7 @@ class FileSnapDialog : public Dialog, public CommandSender kCheatFileChosenCmd = 'LOcc', // cheatfile changed kPaletteFileChosenCmd = 'LOpc', // palette file changed kPropsFileChosenCmd = 'LOrc', // properties file changed - kEEPROMDirChosenCmd = 'LOec', // eeprom dir changed - kSnapIntervalChanged = 'LOsi' // continuous snapshot interval + kEEPROMDirChosenCmd = 'LOec' // eeprom dir changed }; BrowserDialog* myBrowser; @@ -81,10 +80,9 @@ class FileSnapDialog : public Dialog, public CommandSender EditTextWidget* mySnapPath; // Other snapshot settings - CheckboxWidget* mySnapSingle; - CheckboxWidget* mySnap1x; - SliderWidget* mySnapSlider; - StaticTextWidget* mySnapLabel; + CheckboxWidget* mySnapSingle; + CheckboxWidget* mySnap1x; + PopUpWidget* mySnapInterval; // Indicates if this dialog is used for global (vs. in-game) settings bool myIsGlobal; diff --git a/src/gui/HelpDialog.cxx b/src/gui/HelpDialog.cxx index 030e6625c..041373634 100644 --- a/src/gui/HelpDialog.cxx +++ b/src/gui/HelpDialog.cxx @@ -103,19 +103,31 @@ void HelpDialog::updateStrings(uInt8 page, uInt8 lines, string& title) uInt8 i = 0; switch(page) { -#ifndef MAC_OSX case 1: title = "Common commands:"; +#ifndef MAC_OSX ADD_BIND("Ctrl Q", "Quit emulation"); +#else + ADD_BIND("Cmd Q", "Quit emulation"); +#endif ADD_BIND("Escape", "Exit current game"); ADD_BIND("Tab", "Enter options menu"); ADD_BIND("\\", "Toggle command menu"); +#ifndef MAC_OSX ADD_BIND("Alt =", "Increase window size"); ADD_BIND("Alt -", "Decrease window size"); ADD_BIND("Alt Enter", "Toggle fullscreen /"); ADD_BIND("", " windowed mode"); ADD_BIND("Alt ]", "Increase volume by 2%"); ADD_BIND("Alt [", "Decrease volume by 2%"); +#else + ADD_BIND("Cmd =", "Increase window size"); + ADD_BIND("Cmd -", "Decrease window size"); + ADD_BIND("Cmd Enter", "Toggle fullscreen /"); + ADD_BIND("", " windowed mode"); + ADD_BIND("Cmd ]", "Increase volume by 2%"); + ADD_BIND("Cmd [", "Decrease volume by 2%"); +#endif break; case 2: @@ -133,47 +145,17 @@ void HelpDialog::updateStrings(uInt8 page, uInt8 lines, string& title) case 3: title = "Developer commands:"; +#ifndef MAC_OSX ADD_BIND("Alt PgUp", "Increase Display.YStart"); ADD_BIND("Alt PgDn", "Decrease Display.YStart"); +#else + ADD_BIND("Cmd PgUp", "Increase Display.YStart"); + ADD_BIND("Cmd PgDn", "Decrease Display.YStart"); +#endif ADD_BIND("Ctrl PgUp", "Increase Display.Height"); ADD_BIND("Ctrl PgDn", "Decrease Display.Height"); break; -#else - case 1: - title = "Common commands:"; - ADD_BIND("Cmd Q", "Quit emulation"); - ADD_BIND("Escape", "Exit current game"); - ADD_BIND("Tab", "Enter options menu"); - ADD_BIND("\\", "Toggle command menu"); - ADD_BIND("Cmd =", "Increase window size"); - ADD_BIND("Cmd -", "Decrease window size"); - ADD_BIND("Cmd Enter", "Toggle fullscreen /"); - ADD_BIND("", " windowed mode"); - ADD_BIND("Shift-Cmd ]", "Increase volume by 2%"); - ADD_BIND("Shift-Cmd [", "Decrease volume by 2%"); - break; - case 2: - title = "Special commands:"; - ADD_BIND("Cmd g", "Grab mouse (keep in window)"); - ADD_BIND("Cmd f", "Switch between NTSC/PAL/SECAM"); - ADD_BIND("Cmd s", "Save game properties"); - ADD_BIND("", " to a new file"); - ADD_LINE; - ADD_BIND("Cmd 0", "Mouse emulates paddle 0"); - ADD_BIND("Cmd 1", "Mouse emulates paddle 1"); - ADD_BIND("Cmd 2", "Mouse emulates paddle 2"); - ADD_BIND("Cmd 3", "Mouse emulates paddle 3"); - break; - - case 3: - title = "Developer commands:"; - ADD_BIND("Shift-Cmd PgUp", "Increase Display.YStart"); - ADD_BIND("Shift-Cmd PgDn", "Decrease Display.YStart"); - ADD_BIND("Cmd PgUp", "Increase Display.Height"); - ADD_BIND("Cmd PgDn", "Decrease Display.Height"); - break; -#endif case 4: title = "All other commands:"; ADD_LINE; diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index f0fc866af..e9607560e 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -99,6 +99,7 @@ InputDialog::~InputDialog() void InputDialog::addVDeviceTab(const GUI::Font& font) { const int lineHeight = font.getLineHeight(), + fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(); int xpos, ypos, lwidth, pwidth, tabID; WidgetArray wid; @@ -143,8 +144,8 @@ void InputDialog::addVDeviceTab(const GUI::Font& font) "Joystick deadzone: ", lwidth, kDeadzoneChanged); myDeadzone->setMinValue(0); myDeadzone->setMaxValue(29); xpos += myDeadzone->getWidth() + 5; - myDeadzoneLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 24, lineHeight, - "", kTextAlignLeft); + myDeadzoneLabel = new StaticTextWidget(myTab, font, xpos, ypos+1, 5*fontWidth, + lineHeight, "", kTextAlignLeft); myDeadzoneLabel->setFlags(WIDGET_CLEARBG); wid.push_back(myDeadzone); @@ -189,7 +190,7 @@ void InputDialog::loadConfig() // Joystick deadzone myDeadzone->setValue(instance().settings().getInt("joydeadzone")); - myDeadzoneLabel->setLabel(instance().settings().getString("joydeadzone")); + myDeadzoneLabel->setValue(Joystick::deadzone()); // Mouse/paddle enabled bool usemouse = instance().settings().getBool("usemouse"); @@ -315,7 +316,7 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd, break; case kDeadzoneChanged: - myDeadzoneLabel->setValue(myDeadzone->getValue()); + myDeadzoneLabel->setValue(3200 + 1000*myDeadzone->getValue()); break; case kPSpeedChanged: diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index b2642b413..ed8c801e2 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -249,7 +249,7 @@ void LauncherDialog::loadConfig() msg.push_back("Click 'OK' to select a default ROM directory,"); msg.push_back("or 'Cancel' to browse the filesystem manually."); myFirstRunMsg = new MessageBox(this, instance().font(), msg, - kFirstRunMsgChosenCmd); + _w, _h, kFirstRunMsgChosenCmd); } myFirstRunMsg->show(); } diff --git a/src/gui/MessageBox.cxx b/src/gui/MessageBox.cxx index 4fc7c91b3..64ecf8a5c 100644 --- a/src/gui/MessageBox.cxx +++ b/src/gui/MessageBox.cxx @@ -26,7 +26,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MessageBox::MessageBox(GuiObject* boss, const GUI::Font& font, - const StringList& text, int cmd) + const StringList& text, int max_w, int max_h, int cmd) : Dialog(&boss->instance(), &boss->parent(), 0, 0, 16, 16), CommandSender(boss), myCmd(cmd) @@ -38,8 +38,11 @@ MessageBox::MessageBox(GuiObject* boss, const GUI::Font& font, WidgetArray wid; // Set real dimensions - _w = 50 * fontWidth + 8; - _h = (text.size() + 2) * lineHeight + 20; + int str_w = 0; + for(uInt32 i = 0; i < text.size(); ++i) + str_w = BSPF_max((int)text[i].length(), str_w); + _w = BSPF_min(str_w * fontWidth + 20, max_w); + _h = BSPF_min(((text.size() + 2) * lineHeight + 20), (uInt32)max_h); xpos = 10; ypos = 10; for(uInt32 i = 0; i < text.size(); ++i) diff --git a/src/gui/MessageBox.hxx b/src/gui/MessageBox.hxx index 2b13b2f35..e36e77b83 100644 --- a/src/gui/MessageBox.hxx +++ b/src/gui/MessageBox.hxx @@ -36,7 +36,7 @@ class MessageBox : public Dialog, public CommandSender { public: MessageBox(GuiObject* boss, const GUI::Font& font, const StringList& text, - int cmd = 0); + int max_w, int max_h, int cmd = 0); virtual ~MessageBox(); /** Place the input dialog onscreen and center it */ diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx index ee0a0f17c..94f660e18 100644 --- a/src/gui/RomAuditDialog.cxx +++ b/src/gui/RomAuditDialog.cxx @@ -28,6 +28,7 @@ #include "EditTextWidget.hxx" #include "ProgressDialog.hxx" #include "FSNode.hxx" +#include "MessageBox.hxx" #include "Props.hxx" #include "PropsSet.hxx" #include "Settings.hxx" @@ -37,7 +38,10 @@ RomAuditDialog::RomAuditDialog(OSystem* osystem, DialogContainer* parent, const GUI::Font& font, int max_w, int max_h) : Dialog(osystem, parent, 0, 0, 0, 0), - myBrowser(NULL) + myBrowser(NULL), + myConfirmMsg(NULL), + myMaxWidth(max_w), + myMaxHeight(max_h) { const int vBorder = 8; @@ -46,7 +50,7 @@ RomAuditDialog::RomAuditDialog(OSystem* osystem, DialogContainer* parent, fontHeight = font.getFontHeight(), buttonWidth = font.getStringWidth("Audit path:") + 20, buttonHeight = font.getLineHeight() + 4, - lwidth = font.getStringWidth("ROMs with properties (renamed): "); + lwidth = font.getStringWidth("ROMs without properties (skipped): "); int xpos = vBorder, ypos = vBorder; WidgetArray wid; @@ -74,7 +78,7 @@ RomAuditDialog::RomAuditDialog(OSystem* osystem, DialogContainer* parent, myResults1->setFlags(WIDGET_CLEARBG); ypos += buttonHeight; new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight, - "ROMs without properties: ", kTextAlignLeft); + "ROMs without properties (skipped): ", kTextAlignLeft); myResults2 = new StaticTextWidget(this, font, xpos + lwidth, ypos, _w - lwidth - 20, fontHeight, "", kTextAlignLeft); @@ -91,7 +95,7 @@ RomAuditDialog::RomAuditDialog(OSystem* osystem, DialogContainer* parent, addBGroupToFocusList(wid); // Create file browser dialog - myBrowser = new BrowserDialog(this, font, max_w, max_h); + myBrowser = new BrowserDialog(this, font, myMaxWidth, myMaxHeight); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -173,6 +177,24 @@ void RomAuditDialog::handleCommand(CommandSender* sender, int cmd, switch (cmd) { case kOKCmd: + if(!myConfirmMsg) + { + StringList msg; + msg.push_back("This operation cannot be undone. Your ROMs"); + msg.push_back("will be modified, and as such there is a chance"); + msg.push_back("that files may be lost. You are recommended"); + msg.push_back("to back up your files before proceeding."); + msg.push_back(""); + msg.push_back("If you're sure you want to proceed with the"); + msg.push_back("audit, click 'OK', otherwise click 'Cancel'."); + myConfirmMsg = + new MessageBox(this, instance().font(), msg, myMaxWidth, myMaxHeight, + kConfirmAuditCmd); + } + myConfirmMsg->show(); + break; + + case kConfirmAuditCmd: auditRoms(); break; diff --git a/src/gui/RomAuditDialog.hxx b/src/gui/RomAuditDialog.hxx index fc5d48625..e67a76f27 100644 --- a/src/gui/RomAuditDialog.hxx +++ b/src/gui/RomAuditDialog.hxx @@ -29,6 +29,7 @@ class DialogContainer; class BrowserDialog; class EditTextWidget; class StaticTextWidget; +class MessageBox; #include "Dialog.hxx" #include "Command.hxx" @@ -52,7 +53,8 @@ class RomAuditDialog : public Dialog private: enum { kChooseAuditDirCmd = 'RAsl', // audit dir select - kAuditDirChosenCmd = 'RAch' // audit dir changed + kAuditDirChosenCmd = 'RAch', // audit dir changed + kConfirmAuditCmd = 'RAcf' // confirm rom audit }; // ROM audit path @@ -64,6 +66,12 @@ class RomAuditDialog : public Dialog // Select a new ROM audit path BrowserDialog* myBrowser; + + // Show a message about the dangers of using this function + MessageBox* myConfirmMsg; + + // Maximum width and height for this dialog + int myMaxWidth, myMaxHeight; }; #endif diff --git a/src/gui/UIDialog.cxx b/src/gui/UIDialog.cxx index 866ce00d5..cb65cbfc2 100644 --- a/src/gui/UIDialog.cxx +++ b/src/gui/UIDialog.cxx @@ -72,8 +72,16 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent, myLauncherWidthSlider = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight, "Launcher Width: ", lwidth, kLWidthChanged); - myLauncherWidthSlider->setMinValue(320); - myLauncherWidthSlider->setMaxValue(1920); + if(instance().desktopWidth() < 640) + { + myLauncherWidthSlider->setMinValue(320); + myLauncherWidthSlider->setMaxValue(instance().desktopWidth()); + } + else + { + myLauncherWidthSlider->setMinValue(640); + myLauncherWidthSlider->setMaxValue(1920); + } myLauncherWidthSlider->setStepValue(10); wid.push_back(myLauncherWidthSlider); myLauncherWidthLabel = @@ -86,8 +94,16 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent, myLauncherHeightSlider = new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight, "Launcher Height: ", lwidth, kLHeightChanged); - myLauncherHeightSlider->setMinValue(240); - myLauncherHeightSlider->setMaxValue(1200); + if(instance().desktopHeight() < 480) + { + myLauncherHeightSlider->setMinValue(240); + myLauncherHeightSlider->setMaxValue(instance().desktopHeight()); + } + else + { + myLauncherHeightSlider->setMinValue(480); + myLauncherHeightSlider->setMaxValue(1200); + } myLauncherHeightSlider->setStepValue(10); wid.push_back(myLauncherHeightSlider); myLauncherHeightLabel = @@ -166,6 +182,22 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent, ypos + 1, 4*fontWidth, fontHeight, "", kTextAlignLeft); myDebuggerHeightLabel->setFlags(WIDGET_CLEARBG); + // Debugger is only realistically available in windowed modes 800x600 or greater + // (and when it's actually been compiled into the app) + bool debuggerAvailable = +#if defined(DEBUGGER_SUPPORT) && defined(WINDOWED_SUPPORT) + (instance().desktopWidth() >= 800 && instance().desktopHeight() >= 600); +#else + false; +#endif + if(!debuggerAvailable) + { + myDebuggerWidthSlider->clearFlags(WIDGET_ENABLED); + myDebuggerWidthLabel->clearFlags(WIDGET_ENABLED); + myDebuggerHeightSlider->clearFlags(WIDGET_ENABLED); + myDebuggerHeightLabel->clearFlags(WIDGET_ENABLED); + } + // Add message concerning usage xpos = vBorder; ypos += 2*(lineHeight + 4); lwidth = font.getStringWidth("(*) Changes require ROM reload"); @@ -193,48 +225,45 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent, ypos += lineHeight + 4; // Delay between quick-selecting characters in ListWidget - myListDelaySlider = new SliderWidget(myTab, font, xpos, ypos, pwidth, - lineHeight, "List quick delay: ", - lwidth, kLQDelayChanged); - myListDelaySlider->setMinValue(300); - myListDelaySlider->setMaxValue(1000); - myListDelaySlider->setStepValue(100); - wid.push_back(myListDelaySlider); - myListDelayLabel = - new StaticTextWidget(myTab, font, - xpos + myListDelaySlider->getWidth() + 4, - ypos + 1, 4*fontWidth, fontHeight, "", kTextAlignLeft); - myListDelayLabel->setFlags(WIDGET_CLEARBG); + items.clear(); + items.push_back("300 ms", "300"); + items.push_back("400 ms", "400"); + items.push_back("500 ms", "500"); + items.push_back("600 ms", "600"); + items.push_back("700 ms", "700"); + items.push_back("800 ms", "800"); + items.push_back("900 ms", "900"); + items.push_back("1 sec", "1000"); + myListDelayPopup = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, + items, "List quick delay: ", lwidth); + wid.push_back(myListDelayPopup); ypos += lineHeight + 4; // Number of lines a mouse wheel will scroll - myWheelLinesSlider = new SliderWidget(myTab, font, xpos, ypos, pwidth, - lineHeight, "Mouse wheel scroll: ", - lwidth, kWLinesChanged); - myWheelLinesSlider->setMinValue(1); - myWheelLinesSlider->setMaxValue(10); - myWheelLinesSlider->setStepValue(1); - wid.push_back(myWheelLinesSlider); - myWheelLinesLabel = - new StaticTextWidget(myTab, font, - xpos + myWheelLinesSlider->getWidth() + 4, - ypos + 1, 2*fontWidth, fontHeight, "", kTextAlignLeft); - myWheelLinesLabel->setFlags(WIDGET_CLEARBG); + items.clear(); + items.push_back("1 line", "1"); + items.push_back("2 lines", "2"); + items.push_back("3 lines", "3"); + items.push_back("4 lines", "4"); + items.push_back("5 lines", "5"); + items.push_back("6 lines", "6"); + items.push_back("7 lines", "7"); + items.push_back("8 lines", "8"); + items.push_back("9 lines", "9"); + items.push_back("10 lines", "10"); + myWheelLinesPopup = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, + items, "Mouse wheel scroll: ", lwidth); + wid.push_back(myWheelLinesPopup); ypos += lineHeight + 4; // Amount of output to show with 'showinfo' - myShowInfoSlider = new SliderWidget(myTab, font, xpos, ypos, pwidth, - lineHeight, "Show Info level: ", - lwidth, kSInfoChanged); - myShowInfoSlider->setMinValue(0); - myShowInfoSlider->setMaxValue(2); - myShowInfoSlider->setStepValue(1); - wid.push_back(myShowInfoSlider); - myShowInfoLabel = - new StaticTextWidget(myTab, font, - xpos + myShowInfoSlider->getWidth() + 4, - ypos + 1, 2*fontWidth, fontHeight, "", kTextAlignLeft); - myShowInfoLabel->setFlags(WIDGET_CLEARBG); + items.clear(); + items.push_back("None", "0"); + items.push_back("Basic", "1"); + items.push_back("Verbose", "2"); + myShowInfoPopup = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, + items, "Show Info level: ", lwidth); + wid.push_back(myShowInfoPopup); ypos += lineHeight + 4; // Add items for tab 2 @@ -251,17 +280,6 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent, wid.push_back(b); addOKCancelBGroup(wid, font); addBGroupToFocusList(wid); - -#ifndef DEBUGGER_SUPPORT - myDebuggerWidthSlider->clearFlags(WIDGET_ENABLED); - myDebuggerWidthLabel->clearFlags(WIDGET_ENABLED); - myDebuggerHeightSlider->clearFlags(WIDGET_ENABLED); - myDebuggerHeightLabel->clearFlags(WIDGET_ENABLED); -#endif - -#ifdef _WIN32_WCE - myLauncherPopup->clearFlags(WIDGET_ENABLED); -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -294,6 +312,7 @@ void UIDialog::loadConfig() const string& viewer = instance().settings().getString("romviewer"); myRomViewerPopup->setSelected(viewer, "0"); +#ifdef DEBUGGER_SUPPORT // Debugger size instance().settings().getSize("debuggerres", w, h); w = BSPF_max(w, 1050); @@ -305,27 +324,23 @@ void UIDialog::loadConfig() myDebuggerWidthLabel->setValue(w); myDebuggerHeightSlider->setValue(h); myDebuggerHeightLabel->setValue(h); +#endif // UI palette const string& pal = instance().settings().getString("uipalette"); myPalettePopup->setSelected(pal, "1"); // Listwidget quick delay - int delay = instance().settings().getInt("listdelay"); - if(delay < 300 || delay > 1000) delay = 300; - myListDelaySlider->setValue(delay); - myListDelayLabel->setValue(delay); + const string& delay = instance().settings().getString("listdelay"); + myListDelayPopup->setSelected(delay, "300"); // Mouse wheel lines - int mw = instance().settings().getInt("mwheel"); - if(mw < 1 || mw > 10) mw = 1; - myWheelLinesSlider->setValue(mw); - myWheelLinesLabel->setValue(mw); + const string& mw = instance().settings().getString("mwheel"); + myWheelLinesPopup->setSelected(mw, "1"); // Showinfo - int si = instance().settings().getInt("showinfo"); - myShowInfoSlider->setValue(si); - myShowInfoLabel->setValue(si); + const string& si = instance().settings().getString("showinfo"); + myShowInfoPopup->setSelected(si, "1"); myTab->loadConfig(); } @@ -354,17 +369,18 @@ void UIDialog::saveConfig() myPalettePopup->getSelectedTag()); // Listwidget quick delay - int delay = myListDelaySlider->getValue(); - instance().settings().setInt("listdelay", delay); - ListWidget::setQuickSelectDelay(delay); + instance().settings().setString("listdelay", + myListDelayPopup->getSelectedTag()); + ListWidget::setQuickSelectDelay(atoi(myListDelayPopup->getSelectedTag().c_str())); // Mouse wheel lines - int mw = myWheelLinesSlider->getValue(); - instance().settings().setInt("mwheel", mw); - ScrollBarWidget::setWheelLines(mw); + instance().settings().setString("mwheel", + myWheelLinesPopup->getSelectedTag()); + ScrollBarWidget::setWheelLines(atoi(myWheelLinesPopup->getSelectedTag().c_str())); // Show info - instance().settings().setInt("showinfo", myShowInfoSlider->getValue()); + instance().settings().setString("showinfo", + myShowInfoPopup->getSelectedTag()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -394,12 +410,9 @@ void UIDialog::setDefaults() case 2: // Misc. options myPalettePopup->setSelected("1", "1"); - myListDelaySlider->setValue(300); - myListDelayLabel->setValue(300); - myWheelLinesSlider->setValue(4); - myWheelLinesLabel->setValue(4); - myShowInfoSlider->setValue(1); - myShowInfoLabel->setValue(1); + myListDelayPopup->setSelected("300", "300"); + myWheelLinesPopup->setSelected("4", "4"); + myShowInfoPopup->setSelected("1", "1"); break; default: @@ -430,18 +443,6 @@ void UIDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) myDebuggerHeightLabel->setValue(myDebuggerHeightSlider->getValue()); break; - case kLQDelayChanged: - myListDelayLabel->setValue(myListDelaySlider->getValue()); - break; - - case kWLinesChanged: - myWheelLinesLabel->setValue(myWheelLinesSlider->getValue()); - break; - - case kSInfoChanged: - myShowInfoLabel->setValue(myShowInfoSlider->getValue()); - break; - case kOKCmd: saveConfig(); close(); diff --git a/src/gui/UIDialog.hxx b/src/gui/UIDialog.hxx index cb6ecf36a..44bac1edd 100644 --- a/src/gui/UIDialog.hxx +++ b/src/gui/UIDialog.hxx @@ -60,12 +60,9 @@ class UIDialog : public Dialog // Misc options PopUpWidget* myPalettePopup; - SliderWidget* myListDelaySlider; - StaticTextWidget* myListDelayLabel; - SliderWidget* myWheelLinesSlider; - StaticTextWidget* myWheelLinesLabel; - SliderWidget* myShowInfoSlider; - StaticTextWidget* myShowInfoLabel; + PopUpWidget* myListDelayPopup; + PopUpWidget* myWheelLinesPopup; + PopUpWidget* myShowInfoPopup; private: void loadConfig(); @@ -78,10 +75,7 @@ class UIDialog : public Dialog kLWidthChanged = 'UIlw', kLHeightChanged = 'UIlh', kDWidthChanged = 'UIdw', - kDHeightChanged = 'UIdh', - kLQDelayChanged = 'UIqd', - kWLinesChanged = 'UIsl', - kSInfoChanged = 'UIsi' + kDHeightChanged = 'UIdh' }; }; diff --git a/src/gui/VideoDialog.cxx b/src/gui/VideoDialog.cxx index c8c4f1be2..9deb69119 100644 --- a/src/gui/VideoDialog.cxx +++ b/src/gui/VideoDialog.cxx @@ -74,8 +74,8 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent, // Video renderer new StaticTextWidget(myTab, font, xpos + (lwidth-fwidth), ypos, fwidth, fontHeight, "Renderer:", kTextAlignLeft); - myRenderer = new EditTextWidget(myTab, font, xpos+lwidth, ypos, - pwidth, fontHeight, ""); + myRenderer = new StaticTextWidget(myTab, font, xpos+lwidth, ypos, + fwidth, fontHeight, "", kTextAlignLeft); ypos += lineHeight + 4; items.clear(); @@ -163,10 +163,11 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent, new SliderWidget(myTab, font, xpos, ypos, pwidth, lineHeight, "Framerate: ", lwidth, kFrameRateChanged); myFrameRateSlider->setMinValue(0); myFrameRateSlider->setMaxValue(300); + myFrameRateSlider->setStepValue(10); wid.push_back(myFrameRateSlider); myFrameRateLabel = new StaticTextWidget(myTab, font, xpos + myFrameRateSlider->getWidth() + 4, - ypos + 1, fontWidth * 3, fontHeight, "", kTextAlignLeft); + ypos + 1, fontWidth * 4, fontHeight, "", kTextAlignLeft); myFrameRateLabel->setFlags(WIDGET_CLEARBG); // Add message concerning usage @@ -176,7 +177,7 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent, "(*) Requires application restart", kTextAlignLeft); // Move over to the next column - xpos += myNAspectRatioSlider->getWidth() + myNAspectRatioLabel->getWidth() + 10; + xpos += myNAspectRatioSlider->getWidth() + myNAspectRatioLabel->getWidth() + 14; ypos = 10; // Fullscreen @@ -357,7 +358,7 @@ void VideoDialog::loadConfig() bool gl = (instance().frameBuffer().type() == kGLBuffer); // Renderer settings - myRenderer->setEditString(gl ? "OpenGL" : "Software"); + myRenderer->setLabel(gl ? "OpenGL" : "Software"); myRendererPopup->setSelected( instance().settings().getString("video"), "soft"); @@ -397,22 +398,23 @@ void VideoDialog::loadConfig() myPAspectRatioLabel->setLabel(instance().settings().getString("gl_aspectp")); myPAspectRatioLabel->setEnabled(gl); - // Framerate (0 or -1 means disabled) + // Framerate (0 or -1 means automatic framerate calculation) int rate = instance().settings().getInt("framerate"); myFrameRateSlider->setValue(rate < 0 ? 0 : rate); - myFrameRateLabel->setLabel(rate < 0 ? "0" : + myFrameRateLabel->setLabel(rate <= 0 ? "Auto" : instance().settings().getString("framerate")); // Fullscreen const string& fullscreen = instance().settings().getString("fullscreen"); myFullscreenPopup->setSelected(fullscreen, "0"); - handleFullscreenChange(fullscreen == "1"); + handleFullscreenChange(fullscreen == "0" || fullscreen == "1"); // PAL color-loss effect myColorLossCheckbox->setState(instance().settings().getBool("colorloss")); - // GL stretch setting (item is enabled/disabled in ::handleFullscreenChange) + // GL stretch setting (GL mode only) myGLStretchCheckbox->setState(instance().settings().getBool("gl_fsmax")); + myGLStretchCheckbox->setEnabled(gl); // Use sync to vertical blank (GL mode only) myUseVSyncCheckbox->setState(instance().settings().getBool("gl_vsync")); @@ -559,7 +561,7 @@ void VideoDialog::setDefaults() myPAspectRatioSlider->setValue(100); myPAspectRatioLabel->setLabel("100"); myFrameRateSlider->setValue(0); - myFrameRateLabel->setLabel("0"); + myFrameRateLabel->setLabel("Auto"); myFullscreenPopup->setSelected("0", ""); myColorLossCheckbox->setState(false); @@ -576,7 +578,7 @@ void VideoDialog::setDefaults() myPhosphorCheckbox->setState(false); // Make sure that mutually-exclusive items are not enabled at the same time - handleFullscreenChange(false); + handleFullscreenChange(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -584,11 +586,6 @@ void VideoDialog::handleFullscreenChange(bool enable) { #ifdef WINDOWED_SUPPORT myFSResPopup->setEnabled(enable); - - // GL stretch is only enabled in OpenGL mode - myGLStretchCheckbox->setEnabled( - enable && instance().frameBuffer().type() == kGLBuffer); - _dirty = true; #endif } @@ -617,11 +614,14 @@ void VideoDialog::handleCommand(CommandSender* sender, int cmd, break; case kFrameRateChanged: - myFrameRateLabel->setValue(myFrameRateSlider->getValue()); + if(myFrameRateSlider->getValue() == 0) + myFrameRateLabel->setLabel("Auto"); + else + myFrameRateLabel->setValue(myFrameRateSlider->getValue()); break; case kFullScrChanged: - handleFullscreenChange(myFullscreenPopup->getSelectedTag() == "1"); + handleFullscreenChange(myFullscreenPopup->getSelectedTag() != "-1"); break; default: diff --git a/src/gui/VideoDialog.hxx b/src/gui/VideoDialog.hxx index 00adf7f2f..d82b6a134 100644 --- a/src/gui/VideoDialog.hxx +++ b/src/gui/VideoDialog.hxx @@ -55,7 +55,7 @@ class VideoDialog : public Dialog TabWidget* myTab; // General options - EditTextWidget* myRenderer; + StaticTextWidget* myRenderer; PopUpWidget* myRendererPopup; PopUpWidget* myTIAFilterPopup; PopUpWidget* myTIAPalettePopup; diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index e96ec3f86..1ca9b7eb1 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -670,8 +670,9 @@ int SliderWidget::valueToPos(int value) { if(value < _valueMin) value = _valueMin; else if(value > _valueMax) value = _valueMax; - - return ((_w - _labelWidth - 4) * (value - _valueMin) / (_valueMax - _valueMin)); + int range = BSPF_max(_valueMax - _valueMin, 1); // don't divide by zero + + return ((_w - _labelWidth - 4) * (value - _valueMin) / range); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/macosx/Create_build.sh b/src/macosx/Create_build.sh index f61aea4ec..62a7f8911 100755 --- a/src/macosx/Create_build.sh +++ b/src/macosx/Create_build.sh @@ -14,22 +14,28 @@ fi VER="$1" DMG="Stella-${VER}-macosx.dmg" DISK="/Volumes/Stella" +DEST=~/Desktop/${DMG} echo "Creating ${DMG} file ..." -gunzip -c template.dmg.gz > ${DMG} +gunzip -c template.dmg.gz > "${DMG}" echo "Mounting ${DMG} file ..." -hdiutil attach ${DMG} +hdiutil attach "${DMG}" echo "Copying documentation ..." -ditto ../../Announce.txt ../../Changes.txt ../../Copyright.txt ../../License.txt ../../Readme.txt ../../Todo.txt ${DISK} +ditto ../../Announce.txt ../../Changes.txt ../../Copyright.txt ../../License.txt ../../Readme.txt ../../Todo.txt "${DISK}" echo "Copying application ..." -cp -r build/Deployment/Stella.app ${DISK} +cp -r build/Deployment/Stella.app "${DISK}" echo "Ejecting ${DMG} ..." -hdiutil eject ${DISK} +hdiutil eject "${DISK}" + +if [ -f "${DEST}" ]; then + echo "Removing duplicate image found on desktop ..." + rm -f "${DEST}" +fi echo "Compressing image, moving to Desktop ..." -hdiutil convert ${DMG} -format UDZO -imagekey zlib-level=9 -o ~/Desktop/${DMG} -rm -f ${DMG} +hdiutil convert "${DMG}" -format UDZO -imagekey zlib-level=9 -o "${DEST}" +rm -f "${DMG}"