diff --git a/Changes.txt b/Changes.txt
index 845bd1416..0a0fe01cc 100644
--- a/Changes.txt
+++ b/Changes.txt
@@ -12,29 +12,29 @@
Release History
===========================================================================
-5.1.3 to 5.2: (MMM d, 2018)
+5.1.3 to 6.0: (MMM d, 2018)
* New cycle exact audio core based on work by Chris Brenner (crispy); greatly
- improved audio emulation accuracy (i.e. E.T., Ms. Pacman)
+ improved audio emulation accuracy (i.e. E.T., Ms. Pacman).
* Full rewrite of the audio subsystem; resample TIA output to target sample
- rate directly in Stella
+ rate directly in Stella.
- * Threading: decouple emulation from frame rendering
+ * Threading: decouple emulation from frame rendering.
* Main loop rewritten; emulating speed and timing is now much more faithful
- (i.e. speed in Pick'n'Pile)
+ (i.e. speed in Pick'n'Pile).
- * Audio settings replaced with new audio.xxx settings
+ * Audio settings replaced with new 'audio.xxx' settings.
- * FPS setting replaced with speed setting for adjusting emulation speed
+ * FPS setting replaced with speed setting for adjusting emulation speed.
* Extra functionality for Time Machine dialog (start/stop recording;
minor fixes; TODO button and initial key repeats...)
- * Fixes for collision corner cases (during HBlank)
+ * Fixes for collision corner cases (during HBlank).
- * UI modernization (new widget look, dialog titles added, dialogs refactored)
+ * UI modernization (new widget look, dialog titles added, dialogs refactored).
* Changes in 'Game Properties' dialog
- 'Default' button now affects only current tab like in all other dialogs.
@@ -46,8 +46,11 @@
* The Linux builds now use the system-installed PNG and ZLIB libraries
by default.
+ * When starting Stella for the first time, the first ROM selected will
+ determine which path to use by default for subsequent runs.
+
* Fixed emulator crash when starting SaveKey ROMs from commandline with
- SaveKey messages enabled
+ SaveKey messages enabled.
* Fixed missing TV format update in frame stats dialog when switching display
type.
@@ -57,7 +60,7 @@
* Updated included PNG library to latest stable version.
* For better compatibility, the Windows 32-bit version does not requires SSE2
- anymore
+ anymore.
-Have fun!
diff --git a/docs/graphics/cheat.png b/docs/graphics/cheat.png
index 9f2187653..63c4bc1be 100644
Binary files a/docs/graphics/cheat.png and b/docs/graphics/cheat.png differ
diff --git a/docs/graphics/commandmenu.png b/docs/graphics/commandmenu.png
index 448fd61be..fdd894e27 100644
Binary files a/docs/graphics/commandmenu.png and b/docs/graphics/commandmenu.png differ
diff --git a/docs/graphics/eventmapping_combo.png b/docs/graphics/eventmapping_combo.png
index 96eac8f6d..5f4be9f43 100644
Binary files a/docs/graphics/eventmapping_combo.png and b/docs/graphics/eventmapping_combo.png differ
diff --git a/docs/graphics/launcher.png b/docs/graphics/launcher.png
index 7ec6e825d..09dd9b107 100644
Binary files a/docs/graphics/launcher.png and b/docs/graphics/launcher.png differ
diff --git a/docs/graphics/launcher_filter.png b/docs/graphics/launcher_filter.png
index e56e8bee6..6549c986e 100644
Binary files a/docs/graphics/launcher_filter.png and b/docs/graphics/launcher_filter.png differ
diff --git a/docs/graphics/launcher_options_files.png b/docs/graphics/launcher_options_files.png
index cb39f01d2..fc417a97c 100644
Binary files a/docs/graphics/launcher_options_files.png and b/docs/graphics/launcher_options_files.png differ
diff --git a/docs/graphics/launcher_options_snapshots.png b/docs/graphics/launcher_options_snapshots.png
index 9441e2479..40de9d003 100644
Binary files a/docs/graphics/launcher_options_snapshots.png and b/docs/graphics/launcher_options_snapshots.png differ
diff --git a/docs/graphics/launcher_override.png b/docs/graphics/launcher_override.png
index a6c3dcfe0..bd4e7a21d 100644
Binary files a/docs/graphics/launcher_override.png and b/docs/graphics/launcher_override.png differ
diff --git a/docs/graphics/options.png b/docs/graphics/options.png
index 3d877baa2..f57902fd6 100644
Binary files a/docs/graphics/options.png and b/docs/graphics/options.png differ
diff --git a/docs/graphics/romaudit.png b/docs/graphics/romaudit.png
index cae6dc145..a4017257e 100644
Binary files a/docs/graphics/romaudit.png and b/docs/graphics/romaudit.png differ
diff --git a/docs/index.html b/docs/index.html
index 615a894a2..7445bd288 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -10,7 +10,7 @@
A multi-platform Atari 2600 VCS emulator
- Release 5.1.1
+ Release 6.0
User's Guide
@@ -61,7 +61,7 @@
- February 1999 - February 2018
+ February 1999 - TODO 2018
The Stella Team
Stella Homepage
@@ -2736,8 +2736,8 @@
Item | Brief description | For more information, see CommandLine |
Save path | Specifies where to save snapshots | -snapsavedir |
Load path | Specifies where to load snapshots | -snaploaddir |
- Save snapshots according to | Specifies how to name saved snapshots | -snapname |
Continuous snapshot interval | Interval (in seconds) between snapshots | -ssinterval |
+ Use actual ROM name | Use the actual ROM filename instead of the internal database name. | -snapname |
Overwrite existing files | Whether to overwrite old snapshots | -sssingle |
Ignore scaling (1x mode) | Save snapshot in 1x mode without scaling | -ss1x |
diff --git a/src/common/FSNodeFactory.hxx b/src/common/FSNodeFactory.hxx
index c3b958c2e..4519c95d5 100644
--- a/src/common/FSNodeFactory.hxx
+++ b/src/common/FSNodeFactory.hxx
@@ -40,19 +40,19 @@ class FilesystemNodeFactory
enum Type { SYSTEM, ZIP };
public:
- static AbstractFSNode* create(const string& path, Type type)
+ static unique_ptr create(const string& path, Type type)
{
switch(type)
{
case SYSTEM:
#if defined(BSPF_UNIX) || defined(BSPF_MAC_OSX)
- return new FilesystemNodePOSIX(path);
+ return make_unique(path);
#elif defined(BSPF_WINDOWS)
- return new FilesystemNodeWINDOWS(path);
+ return make_unique(path);
#endif
break;
case ZIP:
- return new FilesystemNodeZIP(path);
+ return make_unique(path);
break;
}
return nullptr;
diff --git a/src/common/FSNodeZIP.cxx b/src/common/FSNodeZIP.cxx
index 0528e9469..0af148608 100644
--- a/src/common/FSNodeZIP.cxx
+++ b/src/common/FSNodeZIP.cxx
@@ -29,8 +29,6 @@ FilesystemNodeZIP::FilesystemNodeZIP()
_isDirectory(false),
_isFile(false)
{
- // We need a name, else the node is invalid
- _realNode = shared_ptr(nullptr);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -92,9 +90,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
else
_isDirectory = true;
- AbstractFSNode* tmp =
- FilesystemNodeFactory::create(_zipFile, FilesystemNodeFactory::SYSTEM);
- _realNode = shared_ptr(tmp);
+ _realNode = FilesystemNodeFactory::create(_zipFile, FilesystemNodeFactory::SYSTEM);
setFlags(_zipFile, _virtualPath, _realNode);
}
@@ -102,7 +98,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilesystemNodeZIP::FilesystemNodeZIP(
const string& zipfile, const string& virtualpath,
- shared_ptr realnode, bool isdir)
+ AbstractFSNodePtr realnode, bool isdir)
: _error(ZIPERR_NONE),
_numFiles(0),
_isDirectory(isdir),
@@ -114,7 +110,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FilesystemNodeZIP::setFlags(const string& zipfile,
const string& virtualpath,
- shared_ptr realnode)
+ AbstractFSNodePtr realnode)
{
_zipFile = zipfile;
_virtualPath = virtualpath;
@@ -195,7 +191,7 @@ uInt32 FilesystemNodeZIP::read(BytePtr& image) const
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-AbstractFSNode* FilesystemNodeZIP::getParent() const
+AbstractFSNodePtr FilesystemNodeZIP::getParent() const
{
if(_virtualPath == "")
return _realNode ? _realNode->getParent() : nullptr;
@@ -203,7 +199,7 @@ AbstractFSNode* FilesystemNodeZIP::getParent() const
const char* start = _path.c_str();
const char* end = lastPathComponent(_path);
- return new FilesystemNodeZIP(string(start, end - start - 1));
+ return make_shared(string(start, end - start - 1));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/common/FSNodeZIP.hxx b/src/common/FSNodeZIP.hxx
index 29b51df00..56d83d378 100644
--- a/src/common/FSNodeZIP.hxx
+++ b/src/common/FSNodeZIP.hxx
@@ -61,16 +61,16 @@ class FilesystemNodeZIP : public AbstractFSNode
//////////////////////////////////////////////////////////
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const;
- AbstractFSNode* getParent() const;
+ AbstractFSNodePtr getParent() const;
uInt32 read(BytePtr& image) const;
private:
FilesystemNodeZIP(const string& zipfile, const string& virtualpath,
- shared_ptr realnode, bool isdir);
+ AbstractFSNodePtr realnode, bool isdir);
void setFlags(const string& zipfile, const string& virtualpath,
- shared_ptr realnode);
+ AbstractFSNodePtr realnode);
friend ostream& operator<<(ostream& os, const FilesystemNodeZIP& node)
{
@@ -91,7 +91,7 @@ class FilesystemNodeZIP : public AbstractFSNode
ZIPERR_NO_ROMS
};
- shared_ptr _realNode;
+ AbstractFSNodePtr _realNode;
string _zipFile, _virtualPath;
string _name, _path, _shortPath;
zip_error _error;
diff --git a/src/common/Version.hxx b/src/common/Version.hxx
index ef52325c7..bc1d304a5 100644
--- a/src/common/Version.hxx
+++ b/src/common/Version.hxx
@@ -18,7 +18,7 @@
#ifndef VERSION_HXX
#define VERSION_HXX
-#define STELLA_VERSION "5.2_soundtest-1"
-#define STELLA_BUILD "4138"
+#define STELLA_VERSION "6.0_pre1"
+#define STELLA_BUILD "4409"
#endif
diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx
index c118ece2e..514131c4a 100644
--- a/src/emucore/FSNode.cxx
+++ b/src/emucore/FSNode.cxx
@@ -30,7 +30,7 @@ FilesystemNode::FilesystemNode()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-FilesystemNode::FilesystemNode(AbstractFSNode *realNode)
+FilesystemNode::FilesystemNode(AbstractFSNodePtr realNode)
: _realNode(realNode)
{
}
@@ -38,15 +38,11 @@ FilesystemNode::FilesystemNode(AbstractFSNode *realNode)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilesystemNode::FilesystemNode(const string& p)
{
- AbstractFSNode* tmp = nullptr;
-
// Is this potentially a ZIP archive?
if(BSPF::containsIgnoreCase(p, ".zip"))
- tmp = FilesystemNodeFactory::create(p, FilesystemNodeFactory::ZIP);
+ _realNode = FilesystemNodeFactory::create(p, FilesystemNodeFactory::ZIP);
else
- tmp = FilesystemNodeFactory::create(p, FilesystemNodeFactory::SYSTEM);
-
- _realNode = shared_ptr(tmp);
+ _realNode = FilesystemNodeFactory::create(p, FilesystemNodeFactory::SYSTEM);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -132,7 +128,7 @@ FilesystemNode FilesystemNode::getParent() const
if (_realNode == nullptr)
return *this;
- AbstractFSNode* node = _realNode->getParent();
+ AbstractFSNodePtr node = _realNode->getParent();
return node ? FilesystemNode(node) : *this;
}
diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx
index 4291466ce..160274a5b 100644
--- a/src/emucore/FSNode.hxx
+++ b/src/emucore/FSNode.hxx
@@ -49,6 +49,7 @@
class FilesystemNode;
class AbstractFSNode;
+using AbstractFSNodePtr = shared_ptr;
/**
* List of multiple file system nodes. E.g. the contents of a given directory.
@@ -144,7 +145,7 @@ class FilesystemNode
* @return true if successful, false otherwise (e.g. when the directory
* does not exist).
*/
- virtual bool getChildren(FSList &fslist, ListMode mode = kListDirectoriesOnly,
+ virtual bool getChildren(FSList& fslist, ListMode mode = kListDirectoriesOnly,
bool hidden = false) const;
/**
@@ -261,8 +262,8 @@ class FilesystemNode
string getShortPathWithExt(const string& ext) const; // FIXME - dead code
private:
- shared_ptr _realNode;
- FilesystemNode(AbstractFSNode* realNode);
+ AbstractFSNodePtr _realNode;
+ FilesystemNode(AbstractFSNodePtr realNode);
};
@@ -275,7 +276,7 @@ class FilesystemNode
* the semantics.
*/
-using AbstractFSList = vector;
+using AbstractFSList = vector;
class AbstractFSNode
{
@@ -403,7 +404,7 @@ class AbstractFSNode
* The parent node of this directory.
* The parent of the root is the root itself.
*/
- virtual AbstractFSNode* getParent() const = 0;
+ virtual AbstractFSNodePtr getParent() const = 0;
};
#endif
diff --git a/src/gui/ComboDialog.cxx b/src/gui/ComboDialog.cxx
index 9a3df6087..c9879335e 100644
--- a/src/gui/ComboDialog.cxx
+++ b/src/gui/ComboDialog.cxx
@@ -29,7 +29,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
const VariantList& combolist)
- : Dialog(boss->instance(), boss->parent(), font, ""),
+ : Dialog(boss->instance(), boss->parent(), font, "Add..."),
myComboEvent(Event::NoType)
{
const int lineHeight = font.getLineHeight(),
@@ -38,7 +38,7 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
WidgetArray wid;
// Set real dimensions
- _w = 35 * fontWidth + 10;
+ _w = 33 * fontWidth + 10*2;
_h = 10 * (lineHeight + 4) + 10 + _th;
xpos = 10;
ypos = 10 + _th;
@@ -57,7 +57,6 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
ypos += lineHeight + 4;
};
- xpos = 10;
myEvents[0] = nullptr; ADD_EVENT_POPUP(0, "Event 1 ");
myEvents[1] = nullptr; ADD_EVENT_POPUP(1, "Event 2 ");
myEvents[2] = nullptr; ADD_EVENT_POPUP(2, "Event 3 ");
diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx
index 3d9a76b0a..4f3ffd074 100644
--- a/src/gui/Dialog.cxx
+++ b/src/gui/Dialog.cxx
@@ -56,6 +56,7 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font
_okWidget(nullptr),
_cancelWidget(nullptr),
_visible(false),
+ _onTop(true),
_processCancel(false),
_title(title),
_th(0),
@@ -331,25 +332,25 @@ void Dialog::drawDialog()
cerr << COUNT++ << " Dialog::drawDialog()\n";
// Dialog is still on top if e.g a ContextMenu is opened
- bool onTop = parent().myDialogStack.top() == this
+ _onTop = parent().myDialogStack.top() == this
|| (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
&& !parent().myDialogStack.top()->hasTitle());
if(_flags & WIDGET_CLEARBG)
{
// cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl;
- s.fillRect(_x, _y + _th, _w, _h - _th, onTop ? kDlgColor : kBGColorLo);
+ s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo);
if(_th)
{
- s.fillRect(_x, _y, _w, _th, onTop ? kColorTitleBar : kColorTitleBarLo);
+ s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo);
s.drawString(_font, _title, _x + 10, _y + 2 + 1, _font.getStringWidth(_title),
- onTop ? kColorTitleText : kColorTitleTextLo);
+ _onTop ? kColorTitleText : kColorTitleTextLo);
}
}
else
s.invalidate();
- if(_flags & WIDGET_BORDER)
- s.frameRect(_x, _y, _w, _h, onTop ? kColor : kShadowColor);
+ if(_flags & WIDGET_BORDER) // currently only used by Dialog itself
+ s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor);
// Make all child widget dirty
Widget* w = _firstWidget;
diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx
index 71df684a3..444848ac1 100644
--- a/src/gui/Dialog.hxx
+++ b/src/gui/Dialog.hxx
@@ -55,6 +55,7 @@ class Dialog : public GuiObject
void close();
bool isVisible() const override { return _visible; }
+ bool isOnTop() { return _onTop; }
virtual void center();
virtual void drawDialog();
@@ -152,6 +153,7 @@ class Dialog : public GuiObject
Widget* _cancelWidget;
bool _visible;
+ bool _onTop;
bool _processCancel;
string _title;
int _th;
diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx
index 7223bc834..d0dcf8fa8 100644
--- a/src/gui/EditTextWidget.cxx
+++ b/src/gui/EditTextWidget.cxx
@@ -28,7 +28,7 @@ EditTextWidget::EditTextWidget(GuiObject* boss, const GUI::Font& font,
_changed(false)
{
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS;
-
+
startEditMode(); // We're always in edit mode
}
@@ -85,7 +85,10 @@ void EditTextWidget::drawWidget(bool hilite)
if(_changed)
s.fillRect(_x, _y, _w, _h, kDbgChangedColor);
else if(!isEditable())
- s.fillRect(_x, _y, _w, _h, kDlgColor);
+ {
+ bool onTop = _boss->dialog().isOnTop();
+ s.fillRect(_x, _y, _w, _h, onTop ? kDlgColor : kBGColorLo);
+ }
// Draw a thin frame around us.
s.frameRect(_x, _y, _w, _h, hilite && isEditable() && isEnabled() ? kWidColorHi : kColor);
diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx
index 24790dfef..47bf5a447 100644
--- a/src/gui/EditableWidget.cxx
+++ b/src/gui/EditableWidget.cxx
@@ -39,6 +39,7 @@ EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font,
_bgcolor = kWidColor;
_bgcolorhi = kWidColor;
+ _bgcolorlo = kDlgColor;
_textcolor = kTextColor;
_textcolorhi = kTextColor;
diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx
index c163e2a6f..fc964af32 100644
--- a/src/gui/LauncherDialog.cxx
+++ b/src/gui/LauncherDialog.cxx
@@ -57,17 +57,19 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
const string ELLIPSIS = "\x1d";
const GUI::Font& font = instance().frameBuffer().launcherFont();
+ const int HBORDER = 10;
+ const int BUTTON_GAP = 8;
const int fontWidth = font.getMaxCharWidth(),
fontHeight = font.getFontHeight(),
lineHeight = font.getLineHeight(),
- bwidth = (_w - 2 * 10 - 8 * (4 - 1)) / 4,
+ bwidth = (_w - 2 * HBORDER - BUTTON_GAP * (4 - 1)),
bheight = lineHeight + 4;
- int xpos = 0, ypos = 0, lwidth = 0, lwidth2 = 0;
+ int xpos, ypos = 0, lwidth = 0, lwidth2 = 0;
WidgetArray wid;
// Show game name
lwidth = font.getStringWidth("Select a ROM from the list" + ELLIPSIS);
- xpos += 10; ypos += 8;
+ xpos = HBORDER; ypos += 8;
new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight,
"Select a ROM from the list" + ELLIPSIS);
@@ -131,35 +133,35 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
// Add four buttons at the bottom
xpos = 10; ypos += myDir->getHeight() + 8;
#ifndef BSPF_MAC_OSX
- myStartButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
+ myStartButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 0) / 4, bheight,
"Select", kLoadROMCmd);
wid.push_back(myStartButton);
- xpos += bwidth + 8;
- myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
- "Go Up", kPrevDirCmd);
+ xpos += (bwidth + 0) / 4 + BUTTON_GAP;
+ myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 1) / 4, bheight,
+ "Go Up", kPrevDirCmd);
wid.push_back(myPrevDirButton);
- xpos += bwidth + 8;
- myOptionsButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
+ xpos += (bwidth + 1) / 4 + BUTTON_GAP;
+ myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 2) / 4, bheight,
"Options" + ELLIPSIS, kOptionsCmd);
wid.push_back(myOptionsButton);
- xpos += bwidth + 8;
- myQuitButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
+ xpos += (bwidth + 2) / 4 + BUTTON_GAP;
+ myQuitButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 3) / 4, bheight,
"Quit", kQuitCmd);
wid.push_back(myQuitButton);
#else
- myQuitButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
+ myQuitButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 0) / 4, bheight,
"Quit", kQuitCmd);
wid.push_back(myQuitButton);
- xpos += bwidth + 8;
- myOptionsButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
+ xpos += (bwidth + 0) / 4 + BUTTON_GAP;
+ myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 1) / 4, bheight,
"Options" + ELLIPSIS, kOptionsCmd);
wid.push_back(myOptionsButton);
- xpos += bwidth + 8;
- myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
+ xpos += (bwidth + 1) / 4 + BUTTON_GAP;
+ myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 2) / 4, bheight,
"Go Up", kPrevDirCmd);
wid.push_back(myPrevDirButton);
- xpos += bwidth + 8;
- myStartButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight,
+ xpos += (bwidth + 2) / 4 + BUTTON_GAP;
+ myStartButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 3) / 4, bheight,
"Select", kLoadROMCmd);
wid.push_back(myStartButton);
#endif
@@ -214,31 +216,12 @@ const string& LauncherDialog::selectedRomMD5()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::loadConfig()
{
+ // Should we use a temporary directory specified on the commandline, or the
+ // default one specified by the settings?
const string& tmpromdir = instance().settings().getString("tmpromdir");
const string& romdir = tmpromdir != "" ? tmpromdir :
instance().settings().getString("romdir");
- // When romdir hasn't been set, it probably indicates that this is the first
- // time running Stella; in this case, we should prompt the user
- if(romdir == "")
- {
- if(!myFirstRunMsg)
- {
- StringList msg;
- msg.push_back("This seems to be your first time running Stella.");
- msg.push_back("Before you can start a game, you need to");
- msg.push_back("specify where your ROMs are located.");
- msg.push_back("");
- msg.push_back("Click 'Default' to select a default ROM directory,");
- msg.push_back("or 'Browse' to browse the filesystem manually.");
- myFirstRunMsg = make_unique
- (this, instance().frameBuffer().font(),
- msg, _w, _h, kFirstRunMsgChosenCmd,
- "Default", "Browse", "ROM directory");
- }
- myFirstRunMsg->show();
- }
-
// Assume that if the list is empty, this is the first time that loadConfig()
// has been called (and we should reload the list)
if(myList->getList().empty())
@@ -486,7 +469,13 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
const string& result =
instance().createConsole(romnode, myGameList->md5(item));
if(result == EmptyString)
+ {
instance().settings().setValue("lastrom", myList->getSelectedString());
+
+ // If romdir has never been set, set it now based on the selected rom
+ if(instance().settings().getString("romdir") == EmptyString)
+ instance().settings().setValue("romdir", romnode.getParent().getShortPath());
+ }
else
instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true);
}
@@ -513,20 +502,6 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
instance().eventHandler().quit();
break;
- case kFirstRunMsgChosenCmd:
- // Show a file browser, starting from the users' home directory
- if(!myRomDir)
- myRomDir = make_unique(this, instance().frameBuffer().font(),
- _w, _h, "Select ROM directory");
- myRomDir->show("~", BrowserDialog::Directories, kStartupRomDirChosenCmd);
- break;
-
- case kStartupRomDirChosenCmd:
- {
- FilesystemNode dir(myRomDir->getResult());
- instance().settings().setValue("romdir", dir.getShortPath());
- [[fallthrough]];
- }
case kRomDirChosenCmd:
myCurrentNode = FilesystemNode(instance().settings().getString("romdir"));
if(!(myCurrentNode.exists() && myCurrentNode.isDirectory()))
diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx
index 61400f461..0b60e0c2f 100644
--- a/src/gui/LauncherDialog.hxx
+++ b/src/gui/LauncherDialog.hxx
@@ -48,7 +48,7 @@ class LauncherDialog : public Dialog
// These must be accessible from dialogs created by this class
enum {
kLoadROMCmd = 'STRT', // load currently selected ROM
- kRomDirChosenCmd = 'romc', // rom chosen
+ kRomDirChosenCmd = 'romc', // rom dir chosen
kReloadRomDirCmd = 'rdrl', // reload the current listing
kReloadFiltersCmd = 'rlfl' // reload filtering options and current listing
};
@@ -98,7 +98,6 @@ class LauncherDialog : public Dialog
unique_ptr myGlobalProps;
unique_ptr myFilters;
unique_ptr myRomDir;
- unique_ptr myFirstRunMsg;
ButtonWidget* myStartButton;
ButtonWidget* myPrevDirButton;
@@ -122,10 +121,7 @@ class LauncherDialog : public Dialog
enum {
kPrevDirCmd = 'PRVD',
kOptionsCmd = 'OPTI',
- kQuitCmd = 'QUIT',
-
- kFirstRunMsgChosenCmd = 'frmc',
- kStartupRomDirChosenCmd = 'rmsc'
+ kQuitCmd = 'QUIT'
};
private:
diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx
index bdd6278ef..744f0e215 100644
--- a/src/gui/RomInfoWidget.cxx
+++ b/src/gui/RomInfoWidget.cxx
@@ -39,7 +39,8 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font,
GUI::Size(320, TIAConstants::maxViewableHeight))
{
_flags = WIDGET_ENABLED;
- _bgcolor = _bgcolorhi = kWidColor;
+ _bgcolor = kDlgColor;
+ _bgcolorlo = kBGColorLo;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -139,10 +140,11 @@ void RomInfoWidget::parseProperties()
void RomInfoWidget::drawWidget(bool hilite)
{
FBSurface& s = dialog().surface();
+ bool onTop = _boss->dialog().isOnTop();
const int yoff = myAvail.h + 10;
- s.fillRect(_x+2, _y+2, _w-4, _h-4, kDlgColor);
+ s.fillRect(_x+2, _y+2, _w-4, _h-4, onTop ? _bgcolor : _bgcolorlo);
s.frameRect(_x, _y, _w, _h, kColor);
s.frameRect(_x, _y+yoff, _w, _h-yoff, kColor);
diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx
index cd5a6fe9b..6ddd46dbe 100644
--- a/src/gui/StringListWidget.cxx
+++ b/src/gui/StringListWidget.cxx
@@ -29,6 +29,7 @@ StringListWidget::StringListWidget(GuiObject* boss, const GUI::Font& font,
boss->instance().settings().getInt("listdelay") >= 300),
_hilite(hilite)
{
+ _bgcolorlo = kDlgColor;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -77,7 +78,10 @@ void StringListWidget::drawWidget(bool hilite)
textColor = kTextColorInv;
}
else
- s.frameRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, kWidColorHi);
+ {
+ bool onTop = _boss->dialog().isOnTop();
+ s.frameRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, onTop ? kWidColorHi : kBGColorLo);
+ }
}
GUI::Rect r(getEditRect());
diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx
index 55dd450de..64fe23df7 100644
--- a/src/gui/TabWidget.cxx
+++ b/src/gui/TabWidget.cxx
@@ -262,6 +262,7 @@ void TabWidget::drawWidget(bool hilite)
Widget::setDirtyInChain(_tabs[_activeTab].firstWidget);
FBSurface& s = dialog().surface();
+ bool onTop = _boss->dialog().isOnTop();
// Iterate over all tabs and draw them
int i, x = _x + kTabLeftOffset;
@@ -269,25 +270,27 @@ void TabWidget::drawWidget(bool hilite)
{
uInt32 fontcolor = _tabs[i].enabled ? kTextColor : kColor;
int yOffset = (i == _activeTab) ? 0 : 1;
- s.fillRect(x, _y + 1, _tabWidth, _tabHeight - 1, (i == _activeTab)
- ? kDlgColor : kBGColorHi); // ? kWidColor : kDlgColor
+ s.fillRect(x, _y + 1, _tabWidth, _tabHeight - 1,
+ (i == _activeTab)
+ ? onTop ? kDlgColor : kBGColorLo
+ : onTop ? kBGColorHi : kDlgColor); // ? kWidColor : kDlgColor
s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset,
_y + yOffset + (_tabHeight - _fontHeight - 1),
_tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center);
if(i == _activeTab)
{
- s.hLine(x, _y, x + _tabWidth - 1, kWidColor);
- s.vLine(x + _tabWidth, _y + 1, _y + _tabHeight - 1, kBGColorLo);
+ s.hLine(x, _y, x + _tabWidth - 1, onTop ? kWidColor : kDlgColor);
+ s.vLine(x + _tabWidth, _y + 1, _y + _tabHeight - 1, onTop ? kBGColorLo : kColor);
}
else
- s.hLine(x, _y + _tabHeight, x + _tabWidth, kWidColor);
+ s.hLine(x, _y + _tabHeight, x + _tabWidth, onTop ? kWidColor : kDlgColor);
x += _tabWidth + kTabSpacing;
}
// fill empty right space
- s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, kWidColor);
- s.hLine(_x, _y + _h - 1, _x + _w - 1, kBGColorLo);
+ s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, onTop ? kWidColor : kDlgColor);
+ s.hLine(_x, _y + _h - 1, _x + _w - 1, onTop ? kBGColorLo : kColor);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx
index fad6d82f4..4c20e8745 100644
--- a/src/gui/Widget.cxx
+++ b/src/gui/Widget.cxx
@@ -38,8 +38,10 @@ Widget::Widget(GuiObject* boss, const GUI::Font& font,
_hasFocus(false),
_bgcolor(kWidColor),
_bgcolorhi(kWidColor),
+ _bgcolorlo(kBGColorLo),
_textcolor(kTextColor),
_textcolorhi(kTextColorHi),
+ _textcolorlo(kBGColorLo),
_shadowcolor(kShadowColor)
{
// Insert into the widget list of the boss
@@ -77,7 +79,9 @@ void Widget::draw()
FBSurface& s = _boss->dialog().surface();
- bool hasBorder = _flags & WIDGET_BORDER;
+ bool onTop = _boss->dialog().isOnTop();
+
+ bool hasBorder = _flags & WIDGET_BORDER; // currently only used by Dialog widget
int oldX = _x, oldY = _y;
// Account for our relative position in the dialog
@@ -92,13 +96,13 @@ void Widget::draw()
{
x++; y++; w-=2; h-=2;
}
- s.fillRect(x, y, w, h, (_flags & WIDGET_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor);
+ s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & WIDGET_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor);
}
// Draw border
if(hasBorder)
{
- s.frameRect(_x, _y, _w, _h, (_flags & WIDGET_HILITED) && isEnabled() ? kWidColorHi : kColor);
+ s.frameRect(_x, _y, _w, _h, !onTop ? kColor : (_flags & WIDGET_HILITED) && isEnabled() ? kWidColorHi : kColor);
_x += 4;
_y += 4;
_w -= 8;
@@ -203,6 +207,8 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
FBSurface& s = boss->dialog().surface();
int size = int(arr.size()), pos = -1;
Widget* tmp;
+ bool onTop = boss->dialog().isOnTop();
+
for(int i = 0; i < size; ++i)
{
tmp = arr[i];
@@ -226,7 +232,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
else
tmp->_hasFocus = false;
- s.frameRect(x, y, w, h, kDlgColor);
+ s.frameRect(x, y, w, h, onTop ? kDlgColor : kBGColorLo);
tmp->setDirty();
}
@@ -279,7 +285,8 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
else
tmp->_hasFocus = true;
- s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed);
+ if (onTop)
+ s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed);
tmp->setDirty();
@@ -368,8 +375,10 @@ ButtonWidget::ButtonWidget(GuiObject* boss, const GUI::Font& font,
_flags = WIDGET_ENABLED | WIDGET_CLEARBG;
_bgcolor = kBtnColor;
_bgcolorhi = kBtnColorHi;
+ _bgcolorlo = kColor;
_textcolor = kBtnTextColor;
_textcolorhi = kBtnTextColorHi;
+ _textcolorlo = kBGColorLo;
_editable = false;
}
@@ -457,16 +466,17 @@ void ButtonWidget::setBitmap(uInt32* bitmap, int bmw, int bmh)
void ButtonWidget::drawWidget(bool hilite)
{
FBSurface& s = _boss->dialog().surface();
+ bool onTop = _boss->dialog().isOnTop();
- s.frameRect(_x, _y, _w, _h, hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor);
+ s.frameRect(_x, _y, _w, _h, !onTop ? kShadowColor : hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor);
if (!_useBitmap)
s.drawString(_font, _label, _x, _y + (_h - _fontHeight)/2 + 1, _w,
- !isEnabled() ? /*hilite ? uInt32(kColor) :*/ uInt32(kBGColorLo) :
+ !(isEnabled() && onTop) ? _textcolorlo :
hilite ? _textcolorhi : _textcolor, _align);
else
s.drawBitmap(_bitmap, _x + (_w - _bmw) / 2, _y + (_h - _bmh) / 2,
- !isEnabled() ? /*hilite ? uInt32(kColor) :*/ uInt32(kBGColorLo) :
+ !(isEnabled() && onTop) ? _textcolorlo :
hilite ? _textcolorhi : _textcolor,
_bmw, _bmh);
diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx
index a550073cd..62cb82404 100644
--- a/src/gui/Widget.hxx
+++ b/src/gui/Widget.hxx
@@ -142,8 +142,10 @@ class Widget : public GuiObject
int _fontHeight;
uInt32 _bgcolor;
uInt32 _bgcolorhi;
+ uInt32 _bgcolorlo;
uInt32 _textcolor;
uInt32 _textcolorhi;
+ uInt32 _textcolorlo;
uInt32 _shadowcolor;
public:
diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx
index c9ae65112..8cdff324f 100644
--- a/src/unix/FSNodePOSIX.cxx
+++ b/src/unix/FSNodePOSIX.cxx
@@ -97,12 +97,11 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
assert(_isDirectory);
DIR* dirp = opendir(_path.c_str());
- struct dirent* dp;
-
if (dirp == nullptr)
return false;
- // loop over dir entries using readdir
+ // Loop over dir entries using readdir
+ struct dirent* dp;
while ((dp = readdir(dirp)) != nullptr)
{
// Skip 'invisible' files if necessary
@@ -137,7 +136,6 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
}
else
{
- entry._isValid = (dp->d_type == DT_DIR) || (dp->d_type == DT_REG) || (dp->d_type == DT_LNK);
if (dp->d_type == DT_LNK)
{
struct stat st;
@@ -157,6 +155,8 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
if (entry._isDirectory)
entry._path += "/";
+
+ entry._isValid = entry._isDirectory || entry._isFile;
}
#endif
@@ -226,7 +226,7 @@ bool FilesystemNodePOSIX::rename(const string& newfile)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-AbstractFSNode* FilesystemNodePOSIX::getParent() const
+AbstractFSNodePtr FilesystemNodePOSIX::getParent() const
{
if (_path == "/")
return nullptr;
@@ -234,5 +234,5 @@ AbstractFSNode* FilesystemNodePOSIX::getParent() const
const char* start = _path.c_str();
const char* end = lastPathComponent(_path);
- return new FilesystemNodePOSIX(string(start, size_t(end - start)));
+ return make_unique(string(start, size_t(end - start)));
}
diff --git a/src/unix/FSNodePOSIX.hxx b/src/unix/FSNodePOSIX.hxx
index f05720d65..d6fb7346b 100644
--- a/src/unix/FSNodePOSIX.hxx
+++ b/src/unix/FSNodePOSIX.hxx
@@ -72,7 +72,7 @@ class FilesystemNodePOSIX : public AbstractFSNode
bool rename(const string& newfile) override;
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override;
- AbstractFSNode* getParent() const override;
+ AbstractFSNodePtr getParent() const override;
protected:
string _path;
diff --git a/src/windows/FSNodeWINDOWS.cxx b/src/windows/FSNodeWINDOWS.cxx
index acd948b1f..0671d1e05 100644
--- a/src/windows/FSNodeWINDOWS.cxx
+++ b/src/windows/FSNodeWINDOWS.cxx
@@ -296,7 +296,7 @@ bool FilesystemNodeWINDOWS::rename(const string& newfile)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-AbstractFSNode* FilesystemNodeWINDOWS::getParent() const
+AbstractFSNodePtr FilesystemNodeWINDOWS::getParent() const
{
if(_isPseudoRoot)
return nullptr;
@@ -306,8 +306,8 @@ AbstractFSNode* FilesystemNodeWINDOWS::getParent() const
const char* start = _path.c_str();
const char* end = lastPathComponent(_path);
- return new FilesystemNodeWINDOWS(string(start, size_t(end - start)));
+ return make_shared(string(start, size_t(end - start)));
}
else
- return new FilesystemNodeWINDOWS();
+ return make_shared();
}
diff --git a/src/windows/FSNodeWINDOWS.hxx b/src/windows/FSNodeWINDOWS.hxx
index f8b601365..3a700c6b8 100644
--- a/src/windows/FSNodeWINDOWS.hxx
+++ b/src/windows/FSNodeWINDOWS.hxx
@@ -69,7 +69,7 @@ class FilesystemNodeWINDOWS : public AbstractFSNode
bool rename(const string& newfile) override;
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override;
- AbstractFSNode* getParent() const override;
+ AbstractFSNodePtr getParent() const override;
protected:
string _displayName;