Merge branch 'release/6.0'

This commit is contained in:
Christian Speckner 2018-08-06 09:52:47 +02:00
commit 58f4cf19d3
34 changed files with 139 additions and 145 deletions

View File

@ -12,29 +12,29 @@
Release History 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 * 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 * 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 * 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; * Extra functionality for Time Machine dialog (start/stop recording;
minor fixes; TODO button and initial key repeats...) 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 * Changes in 'Game Properties' dialog
- 'Default' button now affects only current tab like in all other dialogs. - '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 * The Linux builds now use the system-installed PNG and ZLIB libraries
by default. 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 * 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 * Fixed missing TV format update in frame stats dialog when switching display
type. type.
@ -57,7 +60,7 @@
* Updated included PNG library to latest stable version. * Updated included PNG library to latest stable version.
* For better compatibility, the Windows 32-bit version does not requires SSE2 * For better compatibility, the Windows 32-bit version does not requires SSE2
anymore anymore.
-Have fun! -Have fun!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -10,7 +10,7 @@
<br><br> <br><br>
<center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center> <center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
<center><h4><b>Release 5.1.1</b></h4></center> <center><h4><b>Release 6.0</b></h4></center>
<br><br> <br><br>
<center><h2><b>User's Guide</b></h2></center> <center><h2><b>User's Guide</b></h2></center>
@ -61,7 +61,7 @@
<br><br><br> <br><br><br>
<center><b>February 1999 - February 2018</b></center> <center><b>February 1999 - TODO 2018</b></center>
<center><b>The Stella Team</b></center> <center><b>The Stella Team</b></center>
<center><b><a href="https://stella-emu.github.io">Stella Homepage</a></b></center> <center><b><a href="https://stella-emu.github.io">Stella Homepage</a></b></center>
@ -2736,8 +2736,8 @@
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr> <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
<tr><td>Save path</td><td>Specifies where to save snapshots</td><td>-snapsavedir</td></tr> <tr><td>Save path</td><td>Specifies where to save snapshots</td><td>-snapsavedir</td></tr>
<tr><td>Load path</td><td>Specifies where to load snapshots</td><td>-snaploaddir</td></tr> <tr><td>Load path</td><td>Specifies where to load snapshots</td><td>-snaploaddir</td></tr>
<tr><td>Save snapshots according to</td><td>Specifies how to name saved snapshots</td><td>-snapname</td></tr>
<tr><td>Continuous snapshot interval</td><td>Interval (in seconds) between snapshots</td><td>-ssinterval</td></tr> <tr><td>Continuous snapshot interval</td><td>Interval (in seconds) between snapshots</td><td>-ssinterval</td></tr>
<tr><td>Use actual ROM name</td><td>Use the actual ROM filename instead of the internal database name.</td><td>-snapname</td></tr>
<tr><td>Overwrite existing files</td><td>Whether to overwrite old snapshots</td><td>-sssingle</td></tr> <tr><td>Overwrite existing files</td><td>Whether to overwrite old snapshots</td><td>-sssingle</td></tr>
<tr><td>Ignore scaling (1x mode)</td><td>Save snapshot in 1x mode without scaling</td><td>-ss1x</td></tr> <tr><td>Ignore scaling (1x mode)</td><td>Save snapshot in 1x mode without scaling</td><td>-ss1x</td></tr>
</table> </table>

View File

@ -40,19 +40,19 @@ class FilesystemNodeFactory
enum Type { SYSTEM, ZIP }; enum Type { SYSTEM, ZIP };
public: public:
static AbstractFSNode* create(const string& path, Type type) static unique_ptr<AbstractFSNode> create(const string& path, Type type)
{ {
switch(type) switch(type)
{ {
case SYSTEM: case SYSTEM:
#if defined(BSPF_UNIX) || defined(BSPF_MAC_OSX) #if defined(BSPF_UNIX) || defined(BSPF_MAC_OSX)
return new FilesystemNodePOSIX(path); return make_unique<FilesystemNodePOSIX>(path);
#elif defined(BSPF_WINDOWS) #elif defined(BSPF_WINDOWS)
return new FilesystemNodeWINDOWS(path); return make_unique<FilesystemNodeWINDOWS>(path);
#endif #endif
break; break;
case ZIP: case ZIP:
return new FilesystemNodeZIP(path); return make_unique<FilesystemNodeZIP>(path);
break; break;
} }
return nullptr; return nullptr;

View File

@ -29,8 +29,6 @@ FilesystemNodeZIP::FilesystemNodeZIP()
_isDirectory(false), _isDirectory(false),
_isFile(false) _isFile(false)
{ {
// We need a name, else the node is invalid
_realNode = shared_ptr<AbstractFSNode>(nullptr);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -92,9 +90,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
else else
_isDirectory = true; _isDirectory = true;
AbstractFSNode* tmp = _realNode = FilesystemNodeFactory::create(_zipFile, FilesystemNodeFactory::SYSTEM);
FilesystemNodeFactory::create(_zipFile, FilesystemNodeFactory::SYSTEM);
_realNode = shared_ptr<AbstractFSNode>(tmp);
setFlags(_zipFile, _virtualPath, _realNode); setFlags(_zipFile, _virtualPath, _realNode);
} }
@ -102,7 +98,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(const string& p)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilesystemNodeZIP::FilesystemNodeZIP( FilesystemNodeZIP::FilesystemNodeZIP(
const string& zipfile, const string& virtualpath, const string& zipfile, const string& virtualpath,
shared_ptr<AbstractFSNode> realnode, bool isdir) AbstractFSNodePtr realnode, bool isdir)
: _error(ZIPERR_NONE), : _error(ZIPERR_NONE),
_numFiles(0), _numFiles(0),
_isDirectory(isdir), _isDirectory(isdir),
@ -114,7 +110,7 @@ FilesystemNodeZIP::FilesystemNodeZIP(
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FilesystemNodeZIP::setFlags(const string& zipfile, void FilesystemNodeZIP::setFlags(const string& zipfile,
const string& virtualpath, const string& virtualpath,
shared_ptr<AbstractFSNode> realnode) AbstractFSNodePtr realnode)
{ {
_zipFile = zipfile; _zipFile = zipfile;
_virtualPath = virtualpath; _virtualPath = virtualpath;
@ -195,7 +191,7 @@ uInt32 FilesystemNodeZIP::read(BytePtr& image) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFSNode* FilesystemNodeZIP::getParent() const AbstractFSNodePtr FilesystemNodeZIP::getParent() const
{ {
if(_virtualPath == "") if(_virtualPath == "")
return _realNode ? _realNode->getParent() : nullptr; return _realNode ? _realNode->getParent() : nullptr;
@ -203,7 +199,7 @@ AbstractFSNode* FilesystemNodeZIP::getParent() const
const char* start = _path.c_str(); const char* start = _path.c_str();
const char* end = lastPathComponent(_path); const char* end = lastPathComponent(_path);
return new FilesystemNodeZIP(string(start, end - start - 1)); return make_shared<FilesystemNodeZIP>(string(start, end - start - 1));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -61,16 +61,16 @@ class FilesystemNodeZIP : public AbstractFSNode
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const;
AbstractFSNode* getParent() const; AbstractFSNodePtr getParent() const;
uInt32 read(BytePtr& image) const; uInt32 read(BytePtr& image) const;
private: private:
FilesystemNodeZIP(const string& zipfile, const string& virtualpath, FilesystemNodeZIP(const string& zipfile, const string& virtualpath,
shared_ptr<AbstractFSNode> realnode, bool isdir); AbstractFSNodePtr realnode, bool isdir);
void setFlags(const string& zipfile, const string& virtualpath, void setFlags(const string& zipfile, const string& virtualpath,
shared_ptr<AbstractFSNode> realnode); AbstractFSNodePtr realnode);
friend ostream& operator<<(ostream& os, const FilesystemNodeZIP& node) friend ostream& operator<<(ostream& os, const FilesystemNodeZIP& node)
{ {
@ -91,7 +91,7 @@ class FilesystemNodeZIP : public AbstractFSNode
ZIPERR_NO_ROMS ZIPERR_NO_ROMS
}; };
shared_ptr<AbstractFSNode> _realNode; AbstractFSNodePtr _realNode;
string _zipFile, _virtualPath; string _zipFile, _virtualPath;
string _name, _path, _shortPath; string _name, _path, _shortPath;
zip_error _error; zip_error _error;

View File

@ -18,7 +18,7 @@
#ifndef VERSION_HXX #ifndef VERSION_HXX
#define VERSION_HXX #define VERSION_HXX
#define STELLA_VERSION "5.2_soundtest-1" #define STELLA_VERSION "6.0_pre1"
#define STELLA_BUILD "4138" #define STELLA_BUILD "4409"
#endif #endif

View File

@ -30,7 +30,7 @@ FilesystemNode::FilesystemNode()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilesystemNode::FilesystemNode(AbstractFSNode *realNode) FilesystemNode::FilesystemNode(AbstractFSNodePtr realNode)
: _realNode(realNode) : _realNode(realNode)
{ {
} }
@ -38,15 +38,11 @@ FilesystemNode::FilesystemNode(AbstractFSNode *realNode)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilesystemNode::FilesystemNode(const string& p) FilesystemNode::FilesystemNode(const string& p)
{ {
AbstractFSNode* tmp = nullptr;
// Is this potentially a ZIP archive? // Is this potentially a ZIP archive?
if(BSPF::containsIgnoreCase(p, ".zip")) if(BSPF::containsIgnoreCase(p, ".zip"))
tmp = FilesystemNodeFactory::create(p, FilesystemNodeFactory::ZIP); _realNode = FilesystemNodeFactory::create(p, FilesystemNodeFactory::ZIP);
else else
tmp = FilesystemNodeFactory::create(p, FilesystemNodeFactory::SYSTEM); _realNode = FilesystemNodeFactory::create(p, FilesystemNodeFactory::SYSTEM);
_realNode = shared_ptr<AbstractFSNode>(tmp);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -132,7 +128,7 @@ FilesystemNode FilesystemNode::getParent() const
if (_realNode == nullptr) if (_realNode == nullptr)
return *this; return *this;
AbstractFSNode* node = _realNode->getParent(); AbstractFSNodePtr node = _realNode->getParent();
return node ? FilesystemNode(node) : *this; return node ? FilesystemNode(node) : *this;
} }

View File

@ -49,6 +49,7 @@
class FilesystemNode; class FilesystemNode;
class AbstractFSNode; class AbstractFSNode;
using AbstractFSNodePtr = shared_ptr<AbstractFSNode>;
/** /**
* List of multiple file system nodes. E.g. the contents of a given directory. * 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 * @return true if successful, false otherwise (e.g. when the directory
* does not exist). * does not exist).
*/ */
virtual bool getChildren(FSList &fslist, ListMode mode = kListDirectoriesOnly, virtual bool getChildren(FSList& fslist, ListMode mode = kListDirectoriesOnly,
bool hidden = false) const; bool hidden = false) const;
/** /**
@ -261,8 +262,8 @@ class FilesystemNode
string getShortPathWithExt(const string& ext) const; // FIXME - dead code string getShortPathWithExt(const string& ext) const; // FIXME - dead code
private: private:
shared_ptr<AbstractFSNode> _realNode; AbstractFSNodePtr _realNode;
FilesystemNode(AbstractFSNode* realNode); FilesystemNode(AbstractFSNodePtr realNode);
}; };
@ -275,7 +276,7 @@ class FilesystemNode
* the semantics. * the semantics.
*/ */
using AbstractFSList = vector<AbstractFSNode*>; using AbstractFSList = vector<AbstractFSNodePtr>;
class AbstractFSNode class AbstractFSNode
{ {
@ -403,7 +404,7 @@ class AbstractFSNode
* The parent node of this directory. * The parent node of this directory.
* The parent of the root is the root itself. * The parent of the root is the root itself.
*/ */
virtual AbstractFSNode* getParent() const = 0; virtual AbstractFSNodePtr getParent() const = 0;
}; };
#endif #endif

View File

@ -29,7 +29,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font, ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
const VariantList& combolist) const VariantList& combolist)
: Dialog(boss->instance(), boss->parent(), font, ""), : Dialog(boss->instance(), boss->parent(), font, "Add..."),
myComboEvent(Event::NoType) myComboEvent(Event::NoType)
{ {
const int lineHeight = font.getLineHeight(), const int lineHeight = font.getLineHeight(),
@ -38,7 +38,7 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
WidgetArray wid; WidgetArray wid;
// Set real dimensions // Set real dimensions
_w = 35 * fontWidth + 10; _w = 33 * fontWidth + 10*2;
_h = 10 * (lineHeight + 4) + 10 + _th; _h = 10 * (lineHeight + 4) + 10 + _th;
xpos = 10; xpos = 10;
ypos = 10 + _th; ypos = 10 + _th;
@ -57,7 +57,6 @@ ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font,
ypos += lineHeight + 4; ypos += lineHeight + 4;
}; };
xpos = 10;
myEvents[0] = nullptr; ADD_EVENT_POPUP(0, "Event 1 "); myEvents[0] = nullptr; ADD_EVENT_POPUP(0, "Event 1 ");
myEvents[1] = nullptr; ADD_EVENT_POPUP(1, "Event 2 "); myEvents[1] = nullptr; ADD_EVENT_POPUP(1, "Event 2 ");
myEvents[2] = nullptr; ADD_EVENT_POPUP(2, "Event 3 "); myEvents[2] = nullptr; ADD_EVENT_POPUP(2, "Event 3 ");

View File

@ -56,6 +56,7 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font
_okWidget(nullptr), _okWidget(nullptr),
_cancelWidget(nullptr), _cancelWidget(nullptr),
_visible(false), _visible(false),
_onTop(true),
_processCancel(false), _processCancel(false),
_title(title), _title(title),
_th(0), _th(0),
@ -331,25 +332,25 @@ void Dialog::drawDialog()
cerr << COUNT++ << " Dialog::drawDialog()\n"; cerr << COUNT++ << " Dialog::drawDialog()\n";
// Dialog is still on top if e.g a ContextMenu is opened // 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.get(parent().myDialogStack.size() - 2) == this
&& !parent().myDialogStack.top()->hasTitle()); && !parent().myDialogStack.top()->hasTitle());
if(_flags & WIDGET_CLEARBG) if(_flags & WIDGET_CLEARBG)
{ {
// cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; // 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) 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), s.drawString(_font, _title, _x + 10, _y + 2 + 1, _font.getStringWidth(_title),
onTop ? kColorTitleText : kColorTitleTextLo); _onTop ? kColorTitleText : kColorTitleTextLo);
} }
} }
else else
s.invalidate(); s.invalidate();
if(_flags & WIDGET_BORDER) if(_flags & WIDGET_BORDER) // currently only used by Dialog itself
s.frameRect(_x, _y, _w, _h, onTop ? kColor : kShadowColor); s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor);
// Make all child widget dirty // Make all child widget dirty
Widget* w = _firstWidget; Widget* w = _firstWidget;

View File

@ -55,6 +55,7 @@ class Dialog : public GuiObject
void close(); void close();
bool isVisible() const override { return _visible; } bool isVisible() const override { return _visible; }
bool isOnTop() { return _onTop; }
virtual void center(); virtual void center();
virtual void drawDialog(); virtual void drawDialog();
@ -152,6 +153,7 @@ class Dialog : public GuiObject
Widget* _cancelWidget; Widget* _cancelWidget;
bool _visible; bool _visible;
bool _onTop;
bool _processCancel; bool _processCancel;
string _title; string _title;
int _th; int _th;

View File

@ -28,7 +28,7 @@ EditTextWidget::EditTextWidget(GuiObject* boss, const GUI::Font& font,
_changed(false) _changed(false)
{ {
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS; _flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS;
startEditMode(); // We're always in edit mode startEditMode(); // We're always in edit mode
} }
@ -85,7 +85,10 @@ void EditTextWidget::drawWidget(bool hilite)
if(_changed) if(_changed)
s.fillRect(_x, _y, _w, _h, kDbgChangedColor); s.fillRect(_x, _y, _w, _h, kDbgChangedColor);
else if(!isEditable()) 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. // Draw a thin frame around us.
s.frameRect(_x, _y, _w, _h, hilite && isEditable() && isEnabled() ? kWidColorHi : kColor); s.frameRect(_x, _y, _w, _h, hilite && isEditable() && isEnabled() ? kWidColorHi : kColor);

View File

@ -39,6 +39,7 @@ EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font,
_bgcolor = kWidColor; _bgcolor = kWidColor;
_bgcolorhi = kWidColor; _bgcolorhi = kWidColor;
_bgcolorlo = kDlgColor;
_textcolor = kTextColor; _textcolor = kTextColor;
_textcolorhi = kTextColor; _textcolorhi = kTextColor;

View File

@ -57,17 +57,19 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
const string ELLIPSIS = "\x1d"; const string ELLIPSIS = "\x1d";
const GUI::Font& font = instance().frameBuffer().launcherFont(); const GUI::Font& font = instance().frameBuffer().launcherFont();
const int HBORDER = 10;
const int BUTTON_GAP = 8;
const int fontWidth = font.getMaxCharWidth(), const int fontWidth = font.getMaxCharWidth(),
fontHeight = font.getFontHeight(), fontHeight = font.getFontHeight(),
lineHeight = font.getLineHeight(), lineHeight = font.getLineHeight(),
bwidth = (_w - 2 * 10 - 8 * (4 - 1)) / 4, bwidth = (_w - 2 * HBORDER - BUTTON_GAP * (4 - 1)),
bheight = lineHeight + 4; bheight = lineHeight + 4;
int xpos = 0, ypos = 0, lwidth = 0, lwidth2 = 0; int xpos, ypos = 0, lwidth = 0, lwidth2 = 0;
WidgetArray wid; WidgetArray wid;
// Show game name // Show game name
lwidth = font.getStringWidth("Select a ROM from the list" + ELLIPSIS); 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, new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight,
"Select a ROM from the list" + ELLIPSIS); "Select a ROM from the list" + ELLIPSIS);
@ -131,35 +133,35 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
// Add four buttons at the bottom // Add four buttons at the bottom
xpos = 10; ypos += myDir->getHeight() + 8; xpos = 10; ypos += myDir->getHeight() + 8;
#ifndef BSPF_MAC_OSX #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); "Select", kLoadROMCmd);
wid.push_back(myStartButton); wid.push_back(myStartButton);
xpos += bwidth + 8; xpos += (bwidth + 0) / 4 + BUTTON_GAP;
myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight, myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 1) / 4, bheight,
"Go Up", kPrevDirCmd); "Go Up", kPrevDirCmd);
wid.push_back(myPrevDirButton); wid.push_back(myPrevDirButton);
xpos += bwidth + 8; xpos += (bwidth + 1) / 4 + BUTTON_GAP;
myOptionsButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight, myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 2) / 4, bheight,
"Options" + ELLIPSIS, kOptionsCmd); "Options" + ELLIPSIS, kOptionsCmd);
wid.push_back(myOptionsButton); wid.push_back(myOptionsButton);
xpos += bwidth + 8; xpos += (bwidth + 2) / 4 + BUTTON_GAP;
myQuitButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight, myQuitButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 3) / 4, bheight,
"Quit", kQuitCmd); "Quit", kQuitCmd);
wid.push_back(myQuitButton); wid.push_back(myQuitButton);
#else #else
myQuitButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight, myQuitButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 0) / 4, bheight,
"Quit", kQuitCmd); "Quit", kQuitCmd);
wid.push_back(myQuitButton); wid.push_back(myQuitButton);
xpos += bwidth + 8; xpos += (bwidth + 0) / 4 + BUTTON_GAP;
myOptionsButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight, myOptionsButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 1) / 4, bheight,
"Options" + ELLIPSIS, kOptionsCmd); "Options" + ELLIPSIS, kOptionsCmd);
wid.push_back(myOptionsButton); wid.push_back(myOptionsButton);
xpos += bwidth + 8; xpos += (bwidth + 1) / 4 + BUTTON_GAP;
myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight, myPrevDirButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 2) / 4, bheight,
"Go Up", kPrevDirCmd); "Go Up", kPrevDirCmd);
wid.push_back(myPrevDirButton); wid.push_back(myPrevDirButton);
xpos += bwidth + 8; xpos += (bwidth + 2) / 4 + BUTTON_GAP;
myStartButton = new ButtonWidget(this, font, xpos, ypos, bwidth, bheight, myStartButton = new ButtonWidget(this, font, xpos, ypos, (bwidth + 3) / 4, bheight,
"Select", kLoadROMCmd); "Select", kLoadROMCmd);
wid.push_back(myStartButton); wid.push_back(myStartButton);
#endif #endif
@ -214,31 +216,12 @@ const string& LauncherDialog::selectedRomMD5()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::loadConfig() 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& tmpromdir = instance().settings().getString("tmpromdir");
const string& romdir = tmpromdir != "" ? tmpromdir : const string& romdir = tmpromdir != "" ? tmpromdir :
instance().settings().getString("romdir"); 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<GUI::MessageBox>
(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() // Assume that if the list is empty, this is the first time that loadConfig()
// has been called (and we should reload the list) // has been called (and we should reload the list)
if(myList->getList().empty()) if(myList->getList().empty())
@ -486,7 +469,13 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
const string& result = const string& result =
instance().createConsole(romnode, myGameList->md5(item)); instance().createConsole(romnode, myGameList->md5(item));
if(result == EmptyString) if(result == EmptyString)
{
instance().settings().setValue("lastrom", myList->getSelectedString()); 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 else
instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true); instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true);
} }
@ -513,20 +502,6 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
instance().eventHandler().quit(); instance().eventHandler().quit();
break; break;
case kFirstRunMsgChosenCmd:
// Show a file browser, starting from the users' home directory
if(!myRomDir)
myRomDir = make_unique<BrowserDialog>(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: case kRomDirChosenCmd:
myCurrentNode = FilesystemNode(instance().settings().getString("romdir")); myCurrentNode = FilesystemNode(instance().settings().getString("romdir"));
if(!(myCurrentNode.exists() && myCurrentNode.isDirectory())) if(!(myCurrentNode.exists() && myCurrentNode.isDirectory()))

View File

@ -48,7 +48,7 @@ class LauncherDialog : public Dialog
// These must be accessible from dialogs created by this class // These must be accessible from dialogs created by this class
enum { enum {
kLoadROMCmd = 'STRT', // load currently selected ROM kLoadROMCmd = 'STRT', // load currently selected ROM
kRomDirChosenCmd = 'romc', // rom chosen kRomDirChosenCmd = 'romc', // rom dir chosen
kReloadRomDirCmd = 'rdrl', // reload the current listing kReloadRomDirCmd = 'rdrl', // reload the current listing
kReloadFiltersCmd = 'rlfl' // reload filtering options and current listing kReloadFiltersCmd = 'rlfl' // reload filtering options and current listing
}; };
@ -98,7 +98,6 @@ class LauncherDialog : public Dialog
unique_ptr<GlobalPropsDialog> myGlobalProps; unique_ptr<GlobalPropsDialog> myGlobalProps;
unique_ptr<LauncherFilterDialog> myFilters; unique_ptr<LauncherFilterDialog> myFilters;
unique_ptr<BrowserDialog> myRomDir; unique_ptr<BrowserDialog> myRomDir;
unique_ptr<GUI::MessageBox> myFirstRunMsg;
ButtonWidget* myStartButton; ButtonWidget* myStartButton;
ButtonWidget* myPrevDirButton; ButtonWidget* myPrevDirButton;
@ -122,10 +121,7 @@ class LauncherDialog : public Dialog
enum { enum {
kPrevDirCmd = 'PRVD', kPrevDirCmd = 'PRVD',
kOptionsCmd = 'OPTI', kOptionsCmd = 'OPTI',
kQuitCmd = 'QUIT', kQuitCmd = 'QUIT'
kFirstRunMsgChosenCmd = 'frmc',
kStartupRomDirChosenCmd = 'rmsc'
}; };
private: private:

View File

@ -39,7 +39,8 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font,
GUI::Size(320, TIAConstants::maxViewableHeight)) GUI::Size(320, TIAConstants::maxViewableHeight))
{ {
_flags = WIDGET_ENABLED; _flags = WIDGET_ENABLED;
_bgcolor = _bgcolorhi = kWidColor; _bgcolor = kDlgColor;
_bgcolorlo = kBGColorLo;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -139,10 +140,11 @@ void RomInfoWidget::parseProperties()
void RomInfoWidget::drawWidget(bool hilite) void RomInfoWidget::drawWidget(bool hilite)
{ {
FBSurface& s = dialog().surface(); FBSurface& s = dialog().surface();
bool onTop = _boss->dialog().isOnTop();
const int yoff = myAvail.h + 10; 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, _w, _h, kColor);
s.frameRect(_x, _y+yoff, _w, _h-yoff, kColor); s.frameRect(_x, _y+yoff, _w, _h-yoff, kColor);

View File

@ -29,6 +29,7 @@ StringListWidget::StringListWidget(GuiObject* boss, const GUI::Font& font,
boss->instance().settings().getInt("listdelay") >= 300), boss->instance().settings().getInt("listdelay") >= 300),
_hilite(hilite) _hilite(hilite)
{ {
_bgcolorlo = kDlgColor;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -77,7 +78,10 @@ void StringListWidget::drawWidget(bool hilite)
textColor = kTextColorInv; textColor = kTextColorInv;
} }
else 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()); GUI::Rect r(getEditRect());

View File

@ -262,6 +262,7 @@ void TabWidget::drawWidget(bool hilite)
Widget::setDirtyInChain(_tabs[_activeTab].firstWidget); Widget::setDirtyInChain(_tabs[_activeTab].firstWidget);
FBSurface& s = dialog().surface(); FBSurface& s = dialog().surface();
bool onTop = _boss->dialog().isOnTop();
// Iterate over all tabs and draw them // Iterate over all tabs and draw them
int i, x = _x + kTabLeftOffset; int i, x = _x + kTabLeftOffset;
@ -269,25 +270,27 @@ void TabWidget::drawWidget(bool hilite)
{ {
uInt32 fontcolor = _tabs[i].enabled ? kTextColor : kColor; uInt32 fontcolor = _tabs[i].enabled ? kTextColor : kColor;
int yOffset = (i == _activeTab) ? 0 : 1; int yOffset = (i == _activeTab) ? 0 : 1;
s.fillRect(x, _y + 1, _tabWidth, _tabHeight - 1, (i == _activeTab) s.fillRect(x, _y + 1, _tabWidth, _tabHeight - 1,
? kDlgColor : kBGColorHi); // ? kWidColor : kDlgColor (i == _activeTab)
? onTop ? kDlgColor : kBGColorLo
: onTop ? kBGColorHi : kDlgColor); // ? kWidColor : kDlgColor
s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset, s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset,
_y + yOffset + (_tabHeight - _fontHeight - 1), _y + yOffset + (_tabHeight - _fontHeight - 1),
_tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center); _tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center);
if(i == _activeTab) if(i == _activeTab)
{ {
s.hLine(x, _y, x + _tabWidth - 1, kWidColor); s.hLine(x, _y, x + _tabWidth - 1, onTop ? kWidColor : kDlgColor);
s.vLine(x + _tabWidth, _y + 1, _y + _tabHeight - 1, kBGColorLo); s.vLine(x + _tabWidth, _y + 1, _y + _tabHeight - 1, onTop ? kBGColorLo : kColor);
} }
else else
s.hLine(x, _y + _tabHeight, x + _tabWidth, kWidColor); s.hLine(x, _y + _tabHeight, x + _tabWidth, onTop ? kWidColor : kDlgColor);
x += _tabWidth + kTabSpacing; x += _tabWidth + kTabSpacing;
} }
// fill empty right space // fill empty right space
s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, kWidColor); s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, onTop ? kWidColor : kDlgColor);
s.hLine(_x, _y + _h - 1, _x + _w - 1, kBGColorLo); s.hLine(_x, _y + _h - 1, _x + _w - 1, onTop ? kBGColorLo : kColor);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -38,8 +38,10 @@ Widget::Widget(GuiObject* boss, const GUI::Font& font,
_hasFocus(false), _hasFocus(false),
_bgcolor(kWidColor), _bgcolor(kWidColor),
_bgcolorhi(kWidColor), _bgcolorhi(kWidColor),
_bgcolorlo(kBGColorLo),
_textcolor(kTextColor), _textcolor(kTextColor),
_textcolorhi(kTextColorHi), _textcolorhi(kTextColorHi),
_textcolorlo(kBGColorLo),
_shadowcolor(kShadowColor) _shadowcolor(kShadowColor)
{ {
// Insert into the widget list of the boss // Insert into the widget list of the boss
@ -77,7 +79,9 @@ void Widget::draw()
FBSurface& s = _boss->dialog().surface(); 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; int oldX = _x, oldY = _y;
// Account for our relative position in the dialog // Account for our relative position in the dialog
@ -92,13 +96,13 @@ void Widget::draw()
{ {
x++; y++; w-=2; h-=2; 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 // Draw border
if(hasBorder) 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; _x += 4;
_y += 4; _y += 4;
_w -= 8; _w -= 8;
@ -203,6 +207,8 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
FBSurface& s = boss->dialog().surface(); FBSurface& s = boss->dialog().surface();
int size = int(arr.size()), pos = -1; int size = int(arr.size()), pos = -1;
Widget* tmp; Widget* tmp;
bool onTop = boss->dialog().isOnTop();
for(int i = 0; i < size; ++i) for(int i = 0; i < size; ++i)
{ {
tmp = arr[i]; tmp = arr[i];
@ -226,7 +232,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
else else
tmp->_hasFocus = false; tmp->_hasFocus = false;
s.frameRect(x, y, w, h, kDlgColor); s.frameRect(x, y, w, h, onTop ? kDlgColor : kBGColorLo);
tmp->setDirty(); tmp->setDirty();
} }
@ -279,7 +285,8 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
else else
tmp->_hasFocus = true; 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(); tmp->setDirty();
@ -368,8 +375,10 @@ ButtonWidget::ButtonWidget(GuiObject* boss, const GUI::Font& font,
_flags = WIDGET_ENABLED | WIDGET_CLEARBG; _flags = WIDGET_ENABLED | WIDGET_CLEARBG;
_bgcolor = kBtnColor; _bgcolor = kBtnColor;
_bgcolorhi = kBtnColorHi; _bgcolorhi = kBtnColorHi;
_bgcolorlo = kColor;
_textcolor = kBtnTextColor; _textcolor = kBtnTextColor;
_textcolorhi = kBtnTextColorHi; _textcolorhi = kBtnTextColorHi;
_textcolorlo = kBGColorLo;
_editable = false; _editable = false;
} }
@ -457,16 +466,17 @@ void ButtonWidget::setBitmap(uInt32* bitmap, int bmw, int bmh)
void ButtonWidget::drawWidget(bool hilite) void ButtonWidget::drawWidget(bool hilite)
{ {
FBSurface& s = _boss->dialog().surface(); 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) if (!_useBitmap)
s.drawString(_font, _label, _x, _y + (_h - _fontHeight)/2 + 1, _w, s.drawString(_font, _label, _x, _y + (_h - _fontHeight)/2 + 1, _w,
!isEnabled() ? /*hilite ? uInt32(kColor) :*/ uInt32(kBGColorLo) : !(isEnabled() && onTop) ? _textcolorlo :
hilite ? _textcolorhi : _textcolor, _align); hilite ? _textcolorhi : _textcolor, _align);
else else
s.drawBitmap(_bitmap, _x + (_w - _bmw) / 2, _y + (_h - _bmh) / 2, s.drawBitmap(_bitmap, _x + (_w - _bmw) / 2, _y + (_h - _bmh) / 2,
!isEnabled() ? /*hilite ? uInt32(kColor) :*/ uInt32(kBGColorLo) : !(isEnabled() && onTop) ? _textcolorlo :
hilite ? _textcolorhi : _textcolor, hilite ? _textcolorhi : _textcolor,
_bmw, _bmh); _bmw, _bmh);

View File

@ -142,8 +142,10 @@ class Widget : public GuiObject
int _fontHeight; int _fontHeight;
uInt32 _bgcolor; uInt32 _bgcolor;
uInt32 _bgcolorhi; uInt32 _bgcolorhi;
uInt32 _bgcolorlo;
uInt32 _textcolor; uInt32 _textcolor;
uInt32 _textcolorhi; uInt32 _textcolorhi;
uInt32 _textcolorlo;
uInt32 _shadowcolor; uInt32 _shadowcolor;
public: public:

View File

@ -97,12 +97,11 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
assert(_isDirectory); assert(_isDirectory);
DIR* dirp = opendir(_path.c_str()); DIR* dirp = opendir(_path.c_str());
struct dirent* dp;
if (dirp == nullptr) if (dirp == nullptr)
return false; return false;
// loop over dir entries using readdir // Loop over dir entries using readdir
struct dirent* dp;
while ((dp = readdir(dirp)) != nullptr) while ((dp = readdir(dirp)) != nullptr)
{ {
// Skip 'invisible' files if necessary // Skip 'invisible' files if necessary
@ -137,7 +136,6 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
} }
else else
{ {
entry._isValid = (dp->d_type == DT_DIR) || (dp->d_type == DT_REG) || (dp->d_type == DT_LNK);
if (dp->d_type == DT_LNK) if (dp->d_type == DT_LNK)
{ {
struct stat st; struct stat st;
@ -157,6 +155,8 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode,
if (entry._isDirectory) if (entry._isDirectory)
entry._path += "/"; entry._path += "/";
entry._isValid = entry._isDirectory || entry._isFile;
} }
#endif #endif
@ -226,7 +226,7 @@ bool FilesystemNodePOSIX::rename(const string& newfile)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFSNode* FilesystemNodePOSIX::getParent() const AbstractFSNodePtr FilesystemNodePOSIX::getParent() const
{ {
if (_path == "/") if (_path == "/")
return nullptr; return nullptr;
@ -234,5 +234,5 @@ AbstractFSNode* FilesystemNodePOSIX::getParent() const
const char* start = _path.c_str(); const char* start = _path.c_str();
const char* end = lastPathComponent(_path); const char* end = lastPathComponent(_path);
return new FilesystemNodePOSIX(string(start, size_t(end - start))); return make_unique<FilesystemNodePOSIX>(string(start, size_t(end - start)));
} }

View File

@ -72,7 +72,7 @@ class FilesystemNodePOSIX : public AbstractFSNode
bool rename(const string& newfile) override; bool rename(const string& newfile) override;
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override; bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override;
AbstractFSNode* getParent() const override; AbstractFSNodePtr getParent() const override;
protected: protected:
string _path; string _path;

View File

@ -296,7 +296,7 @@ bool FilesystemNodeWINDOWS::rename(const string& newfile)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFSNode* FilesystemNodeWINDOWS::getParent() const AbstractFSNodePtr FilesystemNodeWINDOWS::getParent() const
{ {
if(_isPseudoRoot) if(_isPseudoRoot)
return nullptr; return nullptr;
@ -306,8 +306,8 @@ AbstractFSNode* FilesystemNodeWINDOWS::getParent() const
const char* start = _path.c_str(); const char* start = _path.c_str();
const char* end = lastPathComponent(_path); const char* end = lastPathComponent(_path);
return new FilesystemNodeWINDOWS(string(start, size_t(end - start))); return make_shared<FilesystemNodeWINDOWS>(string(start, size_t(end - start)));
} }
else else
return new FilesystemNodeWINDOWS(); return make_shared<FilesystemNodeWINDOWS>();
} }

View File

@ -69,7 +69,7 @@ class FilesystemNodeWINDOWS : public AbstractFSNode
bool rename(const string& newfile) override; bool rename(const string& newfile) override;
bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override; bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const override;
AbstractFSNode* getParent() const override; AbstractFSNodePtr getParent() const override;
protected: protected:
string _displayName; string _displayName;