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
This commit is contained in:
stephena 2010-07-29 15:22:27 +00:00
parent 6faa9b4b69
commit ee43255ea1
19 changed files with 265 additions and 229 deletions

View File

@ -1776,7 +1776,9 @@
<tr>
<td><pre>-joydeadzone &lt;number&gt;</pre></td>
<td>Sets the joystick deadzone area for analog joysticks.
<td>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.</td>
@ -2329,7 +2331,7 @@
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
<tr><td>Stelladaptor X is</td><td>Specifies which virtual port each Stelladaptor uses (See <b>Advanced Configuration - <a href="#Adaptor">Stelladaptor Support</a></b>)</td><td>-sa1 &amp; -sa2</td></tr>
<tr><td>AVox serial port</td><td>Described in further detail in <b>Advanced Configuration - <a href="#AtariVox">AtariVox/SaveKey Support</a></b> </td><td>-avoxport</td></tr>
<tr><td>Joy deadzone</td><td>Joystick deadzone area for analog joysticks</td><td>-joydeadzone</td></tr>
<tr><td>Joy deadzone</td><td>Deadzone area for axes on joysticks/gamepads</td><td>-joydeadzone</td></tr>
<tr><td>Paddle speed</td><td>Speed used when emulating a paddle using a digital device</td><td>-pspeed</td></tr>
<tr><td>Allow all 4 ...</td><td>Allow all 4 joystick directions to be pressed simultaneously</td><td>-joyallow4</td></tr>
<tr><td>Use mouse as ...</td><td>Use the mouse for various controllers (paddles, driving, etc)</td><td>-usemouse</td></tr>

View File

@ -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") &&

View File

@ -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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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'
};
};

View File

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

View File

@ -55,7 +55,7 @@ class VideoDialog : public Dialog
TabWidget* myTab;
// General options
EditTextWidget* myRenderer;
StaticTextWidget* myRenderer;
PopUpWidget* myRendererPopup;
PopUpWidget* myTIAFilterPopup;
PopUpWidget* myTIAPalettePopup;

View File

@ -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);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

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