2017-07-02 20:55:56 +01:00
|
|
|
#include "qapple.h"
|
|
|
|
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "Common.h"
|
|
|
|
#include "Applewin.h"
|
|
|
|
#include "Disk.h"
|
|
|
|
#include "Harddisk.h"
|
|
|
|
#include "Log.h"
|
|
|
|
#include "CPU.h"
|
|
|
|
#include "Frame.h"
|
|
|
|
#include "Memory.h"
|
|
|
|
#include "ParallelPrinter.h"
|
|
|
|
#include "Video.h"
|
|
|
|
#include "SaveState.h"
|
2017-09-26 18:03:02 +01:00
|
|
|
#include "Registry.h"
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
#include "linux/data.h"
|
2017-07-07 21:04:21 +01:00
|
|
|
#include "linux/benchmark.h"
|
2017-10-06 20:48:14 +01:00
|
|
|
#include "linux/paddle.h"
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-07-03 21:00:42 +01:00
|
|
|
#include "emulator.h"
|
2017-07-15 15:46:18 +01:00
|
|
|
#include "memorycontainer.h"
|
2017-10-06 20:48:14 +01:00
|
|
|
#include "gamepadpaddle.h"
|
2017-10-10 14:26:40 +01:00
|
|
|
#include "settings.h"
|
2017-07-03 21:00:42 +01:00
|
|
|
|
2017-07-04 14:05:06 +01:00
|
|
|
#include <QMdiSubWindow>
|
2017-07-07 21:13:17 +01:00
|
|
|
#include <QMessageBox>
|
2017-10-15 18:20:25 +01:00
|
|
|
#include <QFileDialog>
|
2017-07-04 14:05:06 +01:00
|
|
|
|
2017-07-02 20:55:56 +01:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
void initialiseEmulator()
|
|
|
|
{
|
|
|
|
g_fh = fopen("/tmp/applewin.txt", "w");
|
|
|
|
setbuf(g_fh, NULL);
|
|
|
|
|
|
|
|
LogFileOutput("Initialisation\n");
|
|
|
|
|
|
|
|
ImageInitialize();
|
|
|
|
DiskInitialize();
|
|
|
|
}
|
|
|
|
|
2017-09-26 18:03:02 +01:00
|
|
|
void startEmulator(QWidget * window)
|
2017-07-02 20:55:56 +01:00
|
|
|
{
|
|
|
|
LoadConfiguration();
|
|
|
|
|
|
|
|
CheckCpu();
|
|
|
|
|
2017-07-04 14:05:06 +01:00
|
|
|
SetWindowTitle();
|
2017-09-26 18:03:02 +01:00
|
|
|
window->setWindowTitle(g_pAppTitle);
|
2017-07-04 14:05:06 +01:00
|
|
|
|
2017-07-02 20:55:56 +01:00
|
|
|
FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES);
|
|
|
|
|
|
|
|
MemInitialize();
|
|
|
|
VideoInitialize();
|
|
|
|
}
|
|
|
|
|
2017-07-15 15:46:18 +01:00
|
|
|
void stopEmulator()
|
|
|
|
{
|
|
|
|
MemDestroy();
|
|
|
|
}
|
|
|
|
|
2017-07-02 20:55:56 +01:00
|
|
|
void uninitialiseEmulator()
|
|
|
|
{
|
|
|
|
HD_Destroy();
|
|
|
|
PrintDestroy();
|
|
|
|
CpuDestroy();
|
|
|
|
MemDestroy();
|
|
|
|
|
|
|
|
DiskDestroy();
|
|
|
|
}
|
|
|
|
|
2017-09-19 20:47:15 +01:00
|
|
|
void insertDisk(const QString & filename, const int disk)
|
|
|
|
{
|
2017-09-22 19:19:16 +01:00
|
|
|
if (filename.isEmpty())
|
2017-09-19 20:47:15 +01:00
|
|
|
{
|
2017-09-22 19:19:16 +01:00
|
|
|
DiskEject(disk);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const bool createMissingDisk = true;
|
|
|
|
const ImageError_e result = DiskInsert(disk, filename.toStdString().c_str(), IMAGE_USE_FILES_WRITE_PROTECT_STATUS, createMissingDisk);
|
|
|
|
if (result != eIMAGE_ERROR_NONE)
|
|
|
|
{
|
|
|
|
const QString message = QString("Error [%1] inserting '%2'").arg(QString::number(result), filename);
|
|
|
|
QMessageBox::warning(NULL, "Disk error", message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void insertHD(const QString & filename, const int disk)
|
|
|
|
{
|
|
|
|
if (filename.isEmpty())
|
|
|
|
{
|
|
|
|
HD_Unplug(disk);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!HD_Insert(disk, filename.toStdString().c_str()))
|
|
|
|
{
|
|
|
|
const QString message = QString("Error inserting '%1'").arg(filename);
|
|
|
|
QMessageBox::warning(NULL, "Hard Disk error", message);
|
|
|
|
}
|
2017-09-19 20:47:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-26 18:03:02 +01:00
|
|
|
void setSlot4(const SS_CARDTYPE newCardType)
|
|
|
|
{
|
|
|
|
g_Slot4 = newCardType;
|
|
|
|
REGSAVE(TEXT(REGVALUE_SLOT4), (DWORD)g_Slot4);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setSlot5(const SS_CARDTYPE newCardType)
|
|
|
|
{
|
|
|
|
g_Slot5 = newCardType;
|
|
|
|
REGSAVE(TEXT(REGVALUE_SLOT5), (DWORD)g_Slot5);
|
|
|
|
}
|
|
|
|
|
2017-09-29 20:58:13 +01:00
|
|
|
const std::vector<eApple2Type> computerTypes = {A2TYPE_APPLE2, A2TYPE_APPLE2PLUS, A2TYPE_APPLE2E, A2TYPE_APPLE2EENHANCED,
|
|
|
|
A2TYPE_PRAVETS82, A2TYPE_PRAVETS8M, A2TYPE_PRAVETS8A, A2TYPE_TK30002E};
|
2017-09-26 18:03:02 +01:00
|
|
|
|
|
|
|
int getApple2ComputerType()
|
|
|
|
{
|
|
|
|
const eApple2Type type = GetApple2Type();
|
|
|
|
const auto it = std::find(computerTypes.begin(), computerTypes.end(), type);
|
|
|
|
if (it != computerTypes.end())
|
|
|
|
{
|
|
|
|
return std::distance(computerTypes.begin(), it);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// default to A2E
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
2017-07-02 20:55:56 +01:00
|
|
|
}
|
|
|
|
|
2017-07-04 12:14:04 +01:00
|
|
|
void FrameDrawDiskLEDS(HDC)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void FrameDrawDiskStatus(HDC)
|
|
|
|
{
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-07-04 12:14:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void FrameRefreshStatus(int, bool)
|
|
|
|
{
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-07-04 12:14:04 +01:00
|
|
|
}
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
// Speaker
|
|
|
|
|
2017-07-04 12:14:04 +01:00
|
|
|
BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
|
|
|
{
|
|
|
|
Q_UNUSED(pc)
|
|
|
|
Q_UNUSED(addr)
|
|
|
|
Q_UNUSED(bWrite)
|
|
|
|
Q_UNUSED(d)
|
|
|
|
Q_UNUSED(nCyclesLeft)
|
|
|
|
return 0;
|
|
|
|
}
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
void VideoInitialize() {}
|
|
|
|
|
2017-10-15 18:58:23 +01:00
|
|
|
// MessageBox
|
|
|
|
|
|
|
|
int MessageBox(HWND, const char * text, const char * caption, UINT type)
|
|
|
|
{
|
|
|
|
QMessageBox::StandardButtons buttons = QMessageBox::Ok;
|
|
|
|
if (type & MB_YESNO)
|
|
|
|
{
|
|
|
|
buttons = QMessageBox::Yes | QMessageBox::No;
|
|
|
|
}
|
|
|
|
else if (type & MB_YESNOCANCEL)
|
|
|
|
{
|
|
|
|
buttons = QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel;
|
|
|
|
}
|
|
|
|
|
|
|
|
QMessageBox::StandardButton result = QMessageBox::information(nullptr, caption, text, buttons);
|
|
|
|
|
|
|
|
switch (result)
|
|
|
|
{
|
|
|
|
case QMessageBox::Ok:
|
|
|
|
return IDOK;
|
|
|
|
case QMessageBox::Yes:
|
|
|
|
return IDYES;
|
|
|
|
case QMessageBox::No:
|
|
|
|
return IDNO;
|
|
|
|
case QMessageBox::Cancel:
|
|
|
|
return IDCANCEL;
|
|
|
|
default:
|
|
|
|
return IDOK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-02 20:55:56 +01:00
|
|
|
QApple::QApple(QWidget *parent) :
|
2017-09-21 20:31:52 +01:00
|
|
|
QMainWindow(parent), myTimerID(0), myPreferences(this)
|
2017-07-02 20:55:56 +01:00
|
|
|
{
|
|
|
|
setupUi(this);
|
|
|
|
|
2017-10-14 20:42:23 +01:00
|
|
|
actionStart->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
|
|
|
|
actionPause->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
|
2017-10-15 18:20:25 +01:00
|
|
|
actionReboot->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward));
|
|
|
|
|
|
|
|
actionSave_state->setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton));
|
|
|
|
actionLoad_state->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton));
|
2017-10-14 20:42:23 +01:00
|
|
|
|
2017-07-03 21:00:42 +01:00
|
|
|
myEmulator = new Emulator(mdiArea);
|
2017-07-04 12:14:04 +01:00
|
|
|
myEmulatorWindow = mdiArea->addSubWindow(myEmulator, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint);
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-07-09 16:49:11 +01:00
|
|
|
myMSGap = 5;
|
2017-07-02 20:55:56 +01:00
|
|
|
|
2017-10-14 20:42:23 +01:00
|
|
|
on_actionPause_triggered();
|
2017-07-02 20:55:56 +01:00
|
|
|
initialiseEmulator();
|
2017-09-26 18:03:02 +01:00
|
|
|
startEmulator(myEmulatorWindow);
|
2017-07-04 14:05:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::closeEvent(QCloseEvent *)
|
|
|
|
{
|
2017-07-07 21:04:21 +01:00
|
|
|
stopTimer();
|
2017-07-04 14:05:06 +01:00
|
|
|
uninitialiseEmulator();
|
2017-07-02 20:55:56 +01:00
|
|
|
}
|
|
|
|
|
2017-07-09 16:49:11 +01:00
|
|
|
void QApple::on_timer()
|
2017-07-02 20:55:56 +01:00
|
|
|
{
|
2017-07-09 16:49:11 +01:00
|
|
|
const qint64 elapsed = myElapsedTimer.restart();
|
2017-07-02 20:55:56 +01:00
|
|
|
const double fUsecPerSec = 1.e6;
|
2017-07-09 16:49:11 +01:00
|
|
|
const UINT nExecutionPeriodUsec = 1000 * elapsed;
|
2017-07-02 20:55:56 +01:00
|
|
|
|
|
|
|
const double fExecutionPeriodClks = g_fCurrentCLK6502 * ((double)nExecutionPeriodUsec / fUsecPerSec);
|
|
|
|
const DWORD uCyclesToExecute = fExecutionPeriodClks;
|
|
|
|
|
|
|
|
const bool bVideoUpdate = false;
|
|
|
|
|
2017-07-09 16:49:11 +01:00
|
|
|
do
|
2017-07-02 20:55:56 +01:00
|
|
|
{
|
2017-07-09 16:49:11 +01:00
|
|
|
const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate);
|
|
|
|
g_dwCyclesThisFrame += uActualCyclesExecuted;
|
|
|
|
if (g_dwCyclesThisFrame >= dwClksPerFrame)
|
|
|
|
{
|
|
|
|
g_dwCyclesThisFrame -= dwClksPerFrame;
|
|
|
|
myEmulator->redrawScreen();
|
|
|
|
}
|
2017-10-06 20:48:14 +01:00
|
|
|
//Input::instance().poll();
|
2017-07-02 20:55:56 +01:00
|
|
|
}
|
2017-07-09 16:49:11 +01:00
|
|
|
while (DiskIsSpinning());
|
2017-07-04 14:05:06 +01:00
|
|
|
}
|
|
|
|
|
2017-07-07 21:04:21 +01:00
|
|
|
void QApple::stopTimer()
|
|
|
|
{
|
|
|
|
if (myTimerID)
|
|
|
|
{
|
|
|
|
killTimer(myTimerID);
|
|
|
|
myTimerID = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-02 20:55:56 +01:00
|
|
|
void QApple::on_actionStart_triggered()
|
|
|
|
{
|
2017-07-04 14:05:06 +01:00
|
|
|
// always restart with the same timer gap that was last used
|
2017-07-09 16:49:11 +01:00
|
|
|
myTimerID = startTimer(myMSGap, Qt::PreciseTimer);
|
|
|
|
myElapsedTimer.start();
|
2017-07-02 20:55:56 +01:00
|
|
|
actionPause->setEnabled(true);
|
|
|
|
actionStart->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_actionPause_triggered()
|
|
|
|
{
|
2017-07-07 21:04:21 +01:00
|
|
|
stopTimer();
|
2017-07-02 20:55:56 +01:00
|
|
|
actionPause->setEnabled(false);
|
|
|
|
actionStart->setEnabled(true);
|
|
|
|
}
|
2017-07-04 12:14:04 +01:00
|
|
|
|
|
|
|
void QApple::on_actionX1_triggered()
|
|
|
|
{
|
|
|
|
myEmulator->setZoom(myEmulatorWindow, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_actionX2_triggered()
|
|
|
|
{
|
|
|
|
myEmulator->setZoom(myEmulatorWindow, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_action4_3_triggered()
|
|
|
|
{
|
|
|
|
myEmulator->set43AspectRatio(myEmulatorWindow);
|
|
|
|
}
|
2017-07-04 19:25:10 +01:00
|
|
|
|
2017-07-04 21:17:40 +01:00
|
|
|
void QApple::on_actionReboot_triggered()
|
|
|
|
{
|
2017-07-15 15:46:18 +01:00
|
|
|
emit endEmulator();
|
|
|
|
stopEmulator();
|
2017-09-26 18:03:02 +01:00
|
|
|
startEmulator(myEmulatorWindow);
|
|
|
|
myEmulatorWindow->setWindowTitle(g_pAppTitle);
|
2017-07-04 21:17:40 +01:00
|
|
|
}
|
2017-07-07 21:04:21 +01:00
|
|
|
|
|
|
|
void QApple::on_actionBenchmark_triggered()
|
|
|
|
{
|
|
|
|
VideoBenchmark([this]() { myEmulator->redrawScreen(); });
|
|
|
|
on_actionReboot_triggered();
|
|
|
|
}
|
2017-07-09 16:49:11 +01:00
|
|
|
|
|
|
|
void QApple::timerEvent(QTimerEvent *)
|
|
|
|
{
|
|
|
|
on_timer();
|
|
|
|
}
|
2017-07-15 15:46:18 +01:00
|
|
|
|
|
|
|
void QApple::on_actionMemory_triggered()
|
|
|
|
{
|
|
|
|
MemoryContainer * container = new MemoryContainer(mdiArea);
|
|
|
|
QMdiSubWindow * window = mdiArea->addSubWindow(container);
|
|
|
|
|
|
|
|
// need to close as it points to old memory
|
|
|
|
connect(this, SIGNAL(endEmulator()), window, SLOT(close()));
|
|
|
|
|
|
|
|
window->setWindowTitle("Memory viewer");
|
|
|
|
window->show();
|
|
|
|
}
|
2017-09-19 20:47:15 +01:00
|
|
|
|
|
|
|
void QApple::on_actionOptions_triggered()
|
|
|
|
{
|
|
|
|
Preferences::Data currentOptions;
|
|
|
|
|
|
|
|
const std::vector<size_t> diskIDs = {DRIVE_1, DRIVE_2};
|
|
|
|
currentOptions.disks.resize(diskIDs.size());
|
|
|
|
for (size_t i = 0; i < diskIDs.size(); ++i)
|
|
|
|
{
|
|
|
|
const char * diskName = DiskGetFullName(diskIDs[i]);
|
|
|
|
if (diskName)
|
|
|
|
{
|
|
|
|
currentOptions.disks[i] = diskName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<size_t> hdIDs = {HARDDISK_1, HARDDISK_2};
|
|
|
|
currentOptions.hds.resize(hdIDs.size());
|
|
|
|
for (size_t i = 0; i < hdIDs.size(); ++i)
|
|
|
|
{
|
|
|
|
const char * diskName = HD_GetFullName(hdIDs[i]);
|
|
|
|
if (diskName)
|
|
|
|
{
|
|
|
|
currentOptions.hds[i] = diskName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-26 18:03:02 +01:00
|
|
|
currentOptions.mouseInSlot4 = g_Slot4 == CT_MouseInterface;
|
|
|
|
currentOptions.cpmInSlot5 = g_Slot5 == CT_Z80;
|
|
|
|
currentOptions.hdInSlot7 = HD_CardIsEnabled();
|
|
|
|
|
|
|
|
currentOptions.apple2Type = getApple2ComputerType();
|
|
|
|
|
2017-10-06 20:48:14 +01:00
|
|
|
if (myGamepad)
|
|
|
|
{
|
|
|
|
currentOptions.joystick = myGamepad->name();
|
|
|
|
currentOptions.joystickId = myGamepad->deviceId();
|
|
|
|
}
|
2017-10-10 14:27:07 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
currentOptions.joystickId = 0;
|
|
|
|
}
|
2017-10-06 20:48:14 +01:00
|
|
|
|
2017-10-15 18:20:25 +01:00
|
|
|
const char* saveState = Snapshot_GetFilename();
|
|
|
|
if (saveState)
|
|
|
|
{
|
|
|
|
currentOptions.saveState = QString::fromUtf8(saveState);;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-10 14:26:40 +01:00
|
|
|
QSettings settings; // the function will "modify" it
|
|
|
|
myPreferences.setup(currentOptions, settings);
|
2017-09-19 20:47:15 +01:00
|
|
|
|
2017-09-21 20:31:52 +01:00
|
|
|
if (myPreferences.exec())
|
2017-09-19 20:47:15 +01:00
|
|
|
{
|
2017-09-21 20:31:52 +01:00
|
|
|
const Preferences::Data newOptions = myPreferences.getData();
|
2017-09-19 20:47:15 +01:00
|
|
|
|
2017-09-26 18:03:02 +01:00
|
|
|
if (currentOptions.apple2Type != newOptions.apple2Type)
|
|
|
|
{
|
|
|
|
const eApple2Type type = computerTypes[newOptions.apple2Type];
|
|
|
|
SetApple2Type(type);
|
|
|
|
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE), type);
|
|
|
|
const eCpuType cpu = ProbeMainCpuDefault(type);
|
|
|
|
SetMainCpu(cpu);
|
|
|
|
REGSAVE(TEXT(REGVALUE_CPU_TYPE), cpu);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currentOptions.mouseInSlot4 != newOptions.mouseInSlot4)
|
|
|
|
{
|
|
|
|
const SS_CARDTYPE card = newOptions.mouseInSlot4 ? CT_MouseInterface : CT_Empty;
|
|
|
|
setSlot4(card);
|
|
|
|
}
|
|
|
|
if (currentOptions.cpmInSlot5 != newOptions.cpmInSlot5)
|
|
|
|
{
|
|
|
|
const SS_CARDTYPE card = newOptions.cpmInSlot5 ? CT_Z80 : CT_Empty;
|
|
|
|
setSlot5(card);
|
|
|
|
}
|
|
|
|
if (currentOptions.hdInSlot7 != newOptions.hdInSlot7)
|
|
|
|
{
|
|
|
|
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), newOptions.hdInSlot7 ? 1 : 0);
|
|
|
|
HD_SetEnabled(newOptions.hdInSlot7);
|
|
|
|
}
|
|
|
|
|
2017-10-06 20:48:14 +01:00
|
|
|
if (newOptions.joystick.isEmpty())
|
|
|
|
{
|
|
|
|
myGamepad.reset();
|
|
|
|
Paddle::instance() = std::make_shared<Paddle>();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (newOptions.joystickId != currentOptions.joystickId)
|
|
|
|
{
|
|
|
|
myGamepad.reset(new QGamepad(newOptions.joystickId));
|
|
|
|
Paddle::instance() = std::make_shared<GamepadPaddle>(myGamepad);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-19 20:47:15 +01:00
|
|
|
for (size_t i = 0; i < diskIDs.size(); ++i)
|
|
|
|
{
|
|
|
|
if (currentOptions.disks[i] != newOptions.disks[i])
|
|
|
|
{
|
|
|
|
insertDisk(newOptions.disks[i], diskIDs[i]);
|
|
|
|
}
|
|
|
|
}
|
2017-09-22 19:19:16 +01:00
|
|
|
|
|
|
|
for (size_t i = 0; i < hdIDs.size(); ++i)
|
|
|
|
{
|
|
|
|
if (currentOptions.hds[i] != newOptions.hds[i])
|
|
|
|
{
|
|
|
|
insertHD(newOptions.hds[i], hdIDs[i]);
|
|
|
|
}
|
|
|
|
}
|
2017-10-06 20:48:14 +01:00
|
|
|
|
2017-10-15 18:20:25 +01:00
|
|
|
if (currentOptions.saveState != newOptions.saveState)
|
|
|
|
{
|
|
|
|
const std::string name = newOptions.saveState.toStdString();
|
|
|
|
Snapshot_SetFilename(name);
|
|
|
|
RegSaveString(TEXT(REG_CONFIG), REGVALUE_SAVESTATE_FILENAME, 1, name.c_str());
|
|
|
|
}
|
|
|
|
|
2017-09-19 20:47:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2017-10-15 18:20:25 +01:00
|
|
|
|
|
|
|
void QApple::on_actionSave_state_triggered()
|
|
|
|
{
|
|
|
|
Snapshot_SaveState();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QApple::on_actionLoad_state_triggered()
|
|
|
|
{
|
|
|
|
emit endEmulator();
|
|
|
|
Snapshot_LoadState();
|
|
|
|
myEmulatorWindow->setWindowTitle(g_pAppTitle);
|
|
|
|
myEmulator->redrawScreen();
|
|
|
|
}
|