This commit is contained in:
thrust26 2019-05-15 18:18:11 +02:00
commit c61f3e9a1d
18 changed files with 211 additions and 88 deletions

View File

@ -48,6 +48,10 @@
* Added automatic controller detection. (TODO: Stella.pro cleanup)
* Added 'HiDPI' mode, which scales the UI by 2x when enabled. This is
meant for 4k and above monitors, but can actually be used at any
lower resolution that is large enough to display the scaled UI.
* Removed 'tia.fsfill' option, replacing it with 'tia.fs_stretch'. This
new option allows to preserve TIA image aspect ratio in fullscreen
mode, or stretch to fill the entire screen.

View File

@ -18,6 +18,7 @@
#include "KeyValueRepositorySqlite.hxx"
#include "Logger.hxx"
#include "SqliteError.hxx"
#include "SqliteTransaction.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyValueRepositorySqlite::KeyValueRepositorySqlite(
@ -51,9 +52,9 @@ std::map<string, Variant> KeyValueRepositorySqlite::load()
void KeyValueRepositorySqlite::save(const std::map<string, Variant>& values)
{
try {
myStmtInsert->reset();
SqliteTransaction tx(myDb);
myDb.exec("BEGIN TRANSACTION");
myStmtInsert->reset();
for (const auto& pair: values) {
(*myStmtInsert)
@ -64,7 +65,7 @@ void KeyValueRepositorySqlite::save(const std::map<string, Variant>& values)
myStmtInsert->reset();
}
myDb.exec("COMMIT");
tx.commit();
}
catch (SqliteError err) {
Logger::log(err.message, 1);

View File

@ -0,0 +1,51 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "SqliteTransaction.hxx"
#include "SqliteDatabase.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SqliteTransaction::SqliteTransaction(SqliteDatabase& db)
: myDb(db),
myTransactionClosed(false)
{
myDb.exec("BEGIN TRANSACTION");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SqliteTransaction::~SqliteTransaction()
{
if (!myTransactionClosed) rollback();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SqliteTransaction::commit()
{
if (myTransactionClosed) return;
myTransactionClosed = true;
myDb.exec("COMMIT TRANSACTION");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SqliteTransaction::rollback()
{
if (myTransactionClosed) return;
myTransactionClosed = true;
myDb.exec("ROLLBACK TRANSACTION");
}

View File

@ -0,0 +1,48 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef SQLITE_TRANSACTION_HXX
#define SQLITE_TRANSACTION_HXX
class SqliteDatabase;
class SqliteTransaction {
public:
SqliteTransaction(SqliteDatabase& db);
~SqliteTransaction();
void commit();
void rollback();
private:
SqliteDatabase& myDb;
bool myTransactionClosed;
private:
SqliteTransaction(const SqliteTransaction&) = delete;
SqliteTransaction(SqliteTransaction&&) = delete;
SqliteTransaction& operator=(const SqliteTransaction&) = delete;
SqliteTransaction& operator=(SqliteTransaction&&) = delete;
};
#endif // SQLITE_TRANSACTION_HXX

View File

@ -4,7 +4,8 @@ MODULE_OBJS := \
src/common/repository/sqlite/KeyValueRepositorySqlite.o \
src/common/repository/sqlite/SettingsDb.o \
src/common/repository/sqlite/SqliteDatabase.o \
src/common/repository/sqlite/SqliteStatement.o
src/common/repository/sqlite/SqliteStatement.o \
src/common/repository/sqlite/SqliteTransaction.o
MODULE_DIRS += \
src/common/repository/sqlite

View File

@ -23,6 +23,7 @@
#include "Debugger.hxx"
#include "CartDebug.hxx"
#include "Font.hxx"
#include "FBSurface.hxx"
#include "Widget.hxx"
#include "RamWidget.hxx"
@ -330,7 +331,7 @@ void RamWidget::showInputBox(int cmd)
uInt32 x = getAbsX() + ((getWidth() - myInputBox->getWidth()) >> 1);
uInt32 y = getAbsY() + ((getHeight() - myInputBox->getHeight()) >> 1);
myInputBox->show(x, y);
myInputBox->show(x, y, dialog().surface().dstRect());
myInputBox->setText("");
myInputBox->setMessage("");
myInputBox->setFocus(0);

View File

@ -48,7 +48,9 @@ TiaOutputWidget::TiaOutputWidget(GuiObject* boss, const GUI::Font& font,
VarList::push_back(l, "Fill to scanline", "scanline");
VarList::push_back(l, "Toggle breakpoint", "bp");
VarList::push_back(l, "Set zoom position", "zoom");
#ifdef PNG_SUPPORT
VarList::push_back(l, "Save snapshot", "snap");
#endif
myMenu = make_unique<ContextMenu>(this, font, l);
}

View File

@ -262,8 +262,11 @@ void OSystem::setConfigPaths()
buildDirIfRequired(myStateDir, myBaseDir + "state");
buildDirIfRequired(myNVRamDir, myBaseDir + "nvram");
#ifdef DEBUGGER_SUPPORT
buildDirIfRequired(myCfgDir, myBaseDir + "cfg");
#endif
#ifdef PNG_SUPPORT
mySnapshotSaveDir = mySettings->getString("snapsavedir");
if(mySnapshotSaveDir == "") mySnapshotSaveDir = defaultSaveDir();
buildDirIfRequired(mySnapshotSaveDir, mySnapshotSaveDir);
@ -271,6 +274,7 @@ void OSystem::setConfigPaths()
mySnapshotLoadDir = mySettings->getString("snaploaddir");
if(mySnapshotLoadDir == "") mySnapshotLoadDir = defaultLoadDir();
buildDirIfRequired(mySnapshotLoadDir, mySnapshotLoadDir);
#endif
myCheatFile = FilesystemNode(myBaseDir + "stella.cht").getPath();
myPaletteFile = FilesystemNode(myBaseDir + "stella.pal").getPath();

View File

@ -174,15 +174,6 @@ class OSystem
*/
void saveConfig();
#ifdef DEBUGGER_SUPPORT
/**
Get the ROM debugger of the system.
@return The debugger object
*/
Debugger& debugger() const { return *myDebugger; }
#endif
#ifdef CHEATCODE_SUPPORT
/**
Get the cheat manager of the system.
@ -192,13 +183,13 @@ class OSystem
CheatManager& cheat() const { return *myCheatManager; }
#endif
#ifdef PNG_SUPPORT
#ifdef DEBUGGER_SUPPORT
/**
Get the PNG handler of the system.
Get the ROM debugger of the system.
@return The PNGlib object
@return The debugger object
*/
PNGLibrary& png() const { return *myPNGLib; }
Debugger& debugger() const { return *myDebugger; }
#endif
#ifdef GUI_SUPPORT
@ -231,6 +222,15 @@ class OSystem
TimeMachine& timeMachine() const { return *myTimeMachine; }
#endif
#ifdef PNG_SUPPORT
/**
Get the PNG handler of the system.
@return The PNGlib object
*/
PNGLibrary& png() const { return *myPNGLib; }
#endif
/**
Set all config file paths for the OSystem.
*/
@ -246,30 +246,36 @@ class OSystem
*/
const string& stateDir() const { return myStateDir; }
/**
Return the full/complete directory name for saving and loading
PNG snapshots.
*/
const string& snapshotSaveDir() const { return mySnapshotSaveDir; }
const string& snapshotLoadDir() const { return mySnapshotLoadDir; }
/**
Return the full/complete directory name for storing nvram
(flash/EEPROM) files.
*/
const string& nvramDir() const { return myNVRamDir; }
/**
Return the full/complete directory name for storing Distella cfg files.
*/
const string& cfgDir() const { return myCfgDir; }
#ifdef CHEATCODE_SUPPORT
/**
This method should be called to get the full path of the cheat file.
@return String representing the full path of the cheat filename.
*/
const string& cheatFile() const { return myCheatFile; }
#endif
#ifdef DEBUGGER_SUPPORT
/**
Return the full/complete directory name for storing Distella cfg files.
*/
const string& cfgDir() const { return myCfgDir; }
#endif
#ifdef PNG_SUPPORT
/**
Return the full/complete directory name for saving and loading
PNG snapshots.
*/
const string& snapshotSaveDir() const { return mySnapshotSaveDir; }
const string& snapshotLoadDir() const { return mySnapshotLoadDir; }
#endif
/**
This method should be called to get the full path of the
@ -483,6 +489,16 @@ class OSystem
// Pointer to audio settings object
unique_ptr<AudioSettings> myAudioSettings;
#ifdef CHEATCODE_SUPPORT
// Pointer to the CheatManager object
unique_ptr<CheatManager> myCheatManager;
#endif
#ifdef DEBUGGER_SUPPORT
// Pointer to the Debugger object
unique_ptr<Debugger> myDebugger;
#endif
#ifdef GUI_SUPPORT
// Pointer to the Menu object
unique_ptr<Menu> myMenu;
@ -497,16 +513,6 @@ class OSystem
unique_ptr<TimeMachine> myTimeMachine;
#endif
#ifdef DEBUGGER_SUPPORT
// Pointer to the Debugger object
unique_ptr<Debugger> myDebugger;
#endif
#ifdef CHEATCODE_SUPPORT
// Pointer to the CheatManager object
unique_ptr<CheatManager> myCheatManager;
#endif
#ifdef PNG_SUPPORT
// PNG object responsible for loading/saving PNG images
unique_ptr<PNGLibrary> myPNGLib;

View File

@ -885,17 +885,18 @@ Widget* Dialog::TabFocus::getNewFocus()
bool Dialog::getDynamicBounds(uInt32& w, uInt32& h) const
{
const Common::Rect& r = instance().frameBuffer().imageRect();
const uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
if(r.width() <= FBMinimum::Width || r.height() <= FBMinimum::Height)
{
w = r.width();
h = r.height();
w = r.width() / scale;
h = r.height() / scale;
return false;
}
else
{
w = uInt32(0.95 * r.width());
h = uInt32(0.95 * r.height());
w = uInt32(0.95 * r.width() / scale);
h = uInt32(0.95 * r.height() / scale);
return true;
}
}

View File

@ -96,7 +96,9 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font)
new StaticTextWidget(this, font, xpos, ypos+1, "Startup mode");
items.clear();
VarList::push_back(items, "Console", "false");
#ifdef DEBUGGER_SUPPORT
VarList::push_back(items, "Debugger", "true");
#endif
myDebug = new PopUpWidget(this, font, xpos+lwidth, ypos,
pwidth, lineHeight, items, "");
wid.push_back(myDebug);

View File

@ -118,10 +118,16 @@ void InputTextDialog::show()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void InputTextDialog::show(uInt32 x, uInt32 y)
void InputTextDialog::show(uInt32 x, uInt32 y, const Common::Rect& bossRect)
{
myXOrig = x;
myYOrig = y;
uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
myXOrig = bossRect.x() + x * scale;
myYOrig = bossRect.y() + y * scale;
// Only show dialog if we're inside the visible area
if(!bossRect.contains(myXOrig, myYOrig))
return;
myEnableCenter = false;
open();
}
@ -131,17 +137,14 @@ void InputTextDialog::center()
{
if(!myEnableCenter)
{
// Make sure the menu is exactly where it should be, in case the image
// offset has changed
const Common::Rect& image = instance().frameBuffer().imageRect();
uInt32 x = image.x() + myXOrig;
uInt32 y = image.y() + myYOrig;
uInt32 tx = image.x() + image.width();
uInt32 ty = image.y() + image.height();
if(x + _w > tx) x -= (x + _w - tx);
if(y + _h > ty) y -= (y + _h - ty);
// First set position according to original coordinates
surface().setDstPos(myXOrig, myYOrig);
surface().setDstPos(x, y);
// Now make sure that the entire menu can fit inside the image bounds
// If not, we reset its position
if(!instance().frameBuffer().imageRect().contains(
myXOrig, myXOrig, surface().dstRect()))
surface().setDstPos(myXOrig, myYOrig);
}
else
Dialog::center();

View File

@ -39,7 +39,7 @@ class InputTextDialog : public Dialog, public CommandSender
void show();
/** Show input dialog onscreen at the specified coordinates */
void show(uInt32 x, uInt32 y);
void show(uInt32 x, uInt32 y, const Common::Rect& bossRect);
const string& getResult(int idx = 0);

View File

@ -36,6 +36,7 @@
RomAuditDialog::RomAuditDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h)
: Dialog(osystem, parent, font, "Audit ROMs"),
myFont(font),
myMaxWidth(max_w),
myMaxHeight(max_h)
{
@ -87,9 +88,6 @@ RomAuditDialog::RomAuditDialog(OSystem& osystem, DialogContainer& parent,
// Add OK and Cancel buttons
addOKCancelBGroup(wid, font, "Audit", "Close");
addBGroupToFocusList(wid);
// Create file browser dialog
myBrowser = make_unique<BrowserDialog>(this, font, myMaxWidth, myMaxHeight, "Select ROM directory to audit");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -187,9 +185,8 @@ void RomAuditDialog::handleCommand(CommandSender* sender, int cmd,
msg.push_back("If you're sure you want to proceed with the");
msg.push_back("audit, click 'OK', otherwise click 'Cancel'.");
myConfirmMsg = make_unique<GUI::MessageBox>
(this, instance().frameBuffer().font(), msg,
myMaxWidth, myMaxHeight, kConfirmAuditCmd,
"OK", "Cancel", "ROM Audit", false);
(this, myFont, msg, myMaxWidth, myMaxHeight, kConfirmAuditCmd,
"OK", "Cancel", "ROM Audit", false);
}
myConfirmMsg->show();
break;
@ -200,6 +197,7 @@ void RomAuditDialog::handleCommand(CommandSender* sender, int cmd,
break;
case kChooseAuditDirCmd:
createBrowser("Select ROM directory to audit");
myBrowser->show(myRomPath->getText(),
BrowserDialog::Directories, kAuditDirChosenCmd);
break;
@ -218,3 +216,17 @@ void RomAuditDialog::handleCommand(CommandSender* sender, int cmd,
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomAuditDialog::createBrowser(const string& title)
{
uInt32 w = 0, h = 0;
getDynamicBounds(w, h);
// Create file browser dialog
if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||
uInt32(myBrowser->getHeight()) != h)
myBrowser = make_unique<BrowserDialog>(this, myFont, w, h, title);
else
myBrowser->setTitle(title);
}

View File

@ -42,8 +42,7 @@ class RomAuditDialog : public Dialog
private:
void loadConfig() override;
void auditRoms();
void openBrowser(const string& title, const string& startpath,
FilesystemNode::ListMode mode, int cmd);
void createBrowser(const string& title);
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
private:
@ -55,6 +54,7 @@ class RomAuditDialog : public Dialog
// Select a new ROM audit path
unique_ptr<BrowserDialog> myBrowser;
const GUI::Font& myFont;
// ROM audit path
EditTextWidget* myRomPath;

View File

@ -402,7 +402,7 @@ else ifneq (,$(findstring windows_msvc2017,$(platform)))
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VsInstallRoot)/Common7/IDE")
INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/include")
ifneq (,$(findstring uwp,$(PlatformSuffix)))
LIB := $(shell IFS=$$'\n'; cygpath -w "$(LIB)/store")
LIB := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/lib/$(TargetArchMoniker/store)")
else
LIB := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/lib/$(TargetArchMoniker)")
endif

View File

@ -62,30 +62,14 @@ bool StellaLIBRETRO::create(bool logging)
FilesystemNode rom("rom");
// auto-detect properties
destroy();
myOSystem = make_unique<OSystemLIBRETRO>();
myOSystem->create();
myOSystem->settings().setValue("format", console_format);
if(myOSystem->createConsole(rom) != EmptyString)
return false;
// auto-detect settings
console_timing = myOSystem->console().timing();
phosphor_default = myOSystem->frameBuffer().tiaSurface().phosphorEnabled();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// build play system
destroy();
myOSystem = make_unique<OSystemLIBRETRO>();
myOSystem->create();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Settings& settings = myOSystem->settings();
if(logging)
@ -133,6 +117,9 @@ bool StellaLIBRETRO::create(bool logging)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
console_timing = myOSystem->console().timing();
phosphor_default = myOSystem->frameBuffer().tiaSurface().phosphorEnabled();
if(video_phosphor == "never") setVideoPhosphor(1, video_phosphor_blend);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -447,12 +447,12 @@ void retro_set_environment(retro_environment_t cb)
struct retro_variable variables[] = {
// Adding more variables and rearranging them is safe.
{ "stella_console", "Console display; auto|ntsc|pal|secam|ntsc50|pal60|secam60" },
{ "stella_palette", "Palette colors; standard|z26" },
{ "stella_filter", "TV effects; disabled|composite|s-video|rgb|badly adjusted" },
{ "stella_ntsc_aspect", "NTSC aspect %; par|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|50|75|76|77|78|79|80|81|82|83|84|85" },
{ "stella_pal_aspect", "PAL aspect %; par|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|50|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103" },
{ "stella_ntsc_aspect", "NTSC aspect %; par|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|50|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99" },
{ "stella_pal_aspect", "PAL aspect %; par|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|50|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99" },
{ "stella_crop_hoverscan", "Crop horizontal overscan; disabled|enabled" },
{ "stella_stereo", "Stereo sound; auto|off|on" },
{ "stella_palette", "Palette colors; standard|z26" },
{ "stella_phosphor", "Phosphor mode; auto|off|on" },
{ "stella_phosphor_blend", "Phosphor blend %; 60|65|70|75|80|85|90|95|100|0|5|10|15|20|25|30|35|40|45|50|55" },
{ "stella_paddle_joypad_sensitivity", "Paddle joypad sensitivity; 3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|1|2" },