aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/qt_sdl/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/qt_sdl/main.cpp')
-rw-r--r--src/frontend/qt_sdl/main.cpp1311
1 files changed, 823 insertions, 488 deletions
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 31bb3c0..88704b6 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -1,5 +1,5 @@
/*
- Copyright 2016-2021 Arisotura
+ Copyright 2016-2022 melonDS team
This file is part of melonDS.
@@ -25,6 +25,7 @@
#include <string>
#include <algorithm>
+#include <QProcess>
#include <QApplication>
#include <QMessageBox>
#include <QMenuBar>
@@ -54,12 +55,17 @@
#include "EmuSettingsDialog.h"
#include "InputConfig/InputConfigDialog.h"
#include "VideoSettingsDialog.h"
+#include "CameraSettingsDialog.h"
#include "AudioSettingsDialog.h"
#include "FirmwareSettingsDialog.h"
+#include "PathSettingsDialog.h"
+#include "MPSettingsDialog.h"
#include "WifiSettingsDialog.h"
#include "InterfaceSettingsDialog.h"
#include "ROMInfoDialog.h"
+#include "RAMInfoDialog.h"
#include "TitleManagerDialog.h"
+#include "PowerManagement/PowerManagementDialog.h"
#include "types.h"
#include "version.h"
@@ -74,13 +80,16 @@
#include "SPU.h"
#include "Wifi.h"
#include "Platform.h"
+#include "LocalMP.h"
#include "Config.h"
#include "Savestate.h"
#include "main_shaders.h"
+#include "ROMManager.h"
#include "ArchiveUtil.h"
+#include "CameraManager.h"
// TODO: uniform variable spelling
@@ -97,6 +106,7 @@ bool videoSettingsDirty;
SDL_AudioDeviceID audioDevice;
int audioFreq;
+bool audioMuted;
SDL_cond* audioSync;
SDL_mutex* audioSyncLock;
@@ -107,9 +117,22 @@ u32 micExtBufferWritePos;
u32 micWavLength;
s16* micWavBuffer;
+CameraManager* camManager[2];
+bool camStarted[2];
+
+const struct { int id; float ratio; const char* label; } aspectRatios[] =
+{
+ { 0, 1, "4:3 (native)" },
+ { 4, (5.f / 3) / (4.f / 3), "5:3 (3DS)"},
+ { 1, (16.f / 9) / (4.f / 3), "16:9" },
+ { 2, (21.f / 9) / (4.f / 3), "21:9" },
+ { 3, 0, "window" }
+};
+
void micCallback(void* data, Uint8* stream, int len);
+
void audioCallback(void* data, Uint8* stream, int len)
{
len /= (sizeof(s16) * 2);
@@ -125,7 +148,7 @@ void audioCallback(void* data, Uint8* stream, int len)
SDL_CondSignal(audioSync);
SDL_UnlockMutex(audioSyncLock);
- if (num_in < 1)
+ if ((num_in < 1) || audioMuted)
{
memset(stream, 0, len*sizeof(s16)*2);
return;
@@ -145,6 +168,23 @@ void audioCallback(void* data, Uint8* stream, int len)
Frontend::AudioOut_Resample(buf_in, num_in, (s16*)stream, len, Config::AudioVolume);
}
+void audioMute()
+{
+ int inst = Platform::InstanceID();
+ audioMuted = false;
+
+ switch (Config::MPAudioMode)
+ {
+ case 1: // only instance 1
+ if (inst > 0) audioMuted = true;
+ break;
+
+ case 2: // only currently focused instance
+ if (!mainWindow->isActiveWindow()) audioMuted = true;
+ break;
+ }
+}
+
void micOpen()
{
@@ -180,7 +220,7 @@ void micClose()
micDevice = 0;
}
-void micLoadWav(const char* name)
+void micLoadWav(std::string name)
{
SDL_AudioSpec format;
memset(&format, 0, sizeof(SDL_AudioSpec));
@@ -191,7 +231,7 @@ void micLoadWav(const char* name)
u8* buf;
u32 len;
- if (!SDL_LoadWAV(name, &format, &buf, &len))
+ if (!SDL_LoadWAV(name.c_str(), &format, &buf, &len))
return;
const u64 dstfreq = 44100;
@@ -317,7 +357,7 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)
EmuPause = 0;
RunningSomething = false;
- connect(this, SIGNAL(windowUpdate()), mainWindow->panel, SLOT(repaint()));
+ connect(this, SIGNAL(windowUpdate()), mainWindow->panelWidget, SLOT(repaint()));
connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString)));
connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart()));
connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop()));
@@ -325,7 +365,7 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)
connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger()));
connect(this, SIGNAL(windowEmuFrameStep()), mainWindow->actFrameStep, SLOT(trigger()));
connect(this, SIGNAL(windowLimitFPSChange()), mainWindow->actLimitFramerate, SLOT(trigger()));
- connect(this, SIGNAL(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged()));
+ connect(this, SIGNAL(screenLayoutChange()), mainWindow->panelWidget, SLOT(onScreenLayoutChanged()));
connect(this, SIGNAL(windowFullscreenToggle()), mainWindow, SLOT(onFullscreenToggled()));
connect(this, SIGNAL(swapScreensToggle()), mainWindow->actScreenSwap, SLOT(trigger()));
@@ -413,6 +453,8 @@ void EmuThread::run()
double frameLimitError = 0.0;
double lastMeasureTime = lastTime;
+ u32 winUpdateCount = 0, winUpdateFreq = 1;
+
char melontitle[100];
while (EmuRunning != 0)
@@ -499,7 +541,7 @@ void EmuThread::run()
micProcess();
// auto screen layout
- if (Config::ScreenSizing == 3)
+ if (Config::ScreenSizing == screenSizing_Auto)
{
mainScreenPos[2] = mainScreenPos[1];
mainScreenPos[1] = mainScreenPos[0];
@@ -511,14 +553,14 @@ void EmuThread::run()
{
// constant flickering, likely displaying 3D on both screens
// TODO: when both screens are used for 2D only...???
- guess = 0;
+ guess = screenSizing_Even;
}
else
{
if (mainScreenPos[0] == 1)
- guess = 1;
+ guess = screenSizing_EmphTop;
else
- guess = 2;
+ guess = screenSizing_EmphBot;
}
if (guess != autoScreenSizing)
@@ -541,6 +583,12 @@ void EmuThread::run()
// emulate
u32 nlines = NDS::RunFrame();
+ if (ROMManager::NDSSave)
+ ROMManager::NDSSave->CheckFlush();
+
+ if (ROMManager::GBASave)
+ ROMManager::GBASave->CheckFlush();
+
FrontBufferLock.lock();
FrontBuffer = GPU::FrontBuffer;
#ifdef OGLRENDERER_ENABLED
@@ -563,11 +611,16 @@ void EmuThread::run()
if (EmuRunning == 0) break;
- emit windowUpdate();
+ winUpdateCount++;
+ if (winUpdateCount >= winUpdateFreq)
+ {
+ emit windowUpdate();
+ winUpdateCount = 0;
+ }
bool fastforward = Input::HotkeyDown(HK_FastForward);
- if (Config::AudioSync && (!fastforward) && audioDevice)
+ if (Config::AudioSync && !fastforward && audioDevice)
{
SDL_LockMutex(audioSyncLock);
while (SPU::GetOutputSize() > 1024)
@@ -616,7 +669,15 @@ void EmuThread::run()
float fpstarget = 1.0/frametimeStep;
- sprintf(melontitle, "[%d/%.0f] melonDS " MELONDS_VERSION, fps, fpstarget);
+ winUpdateFreq = fps / (u32)round(fpstarget);
+ if (winUpdateFreq < 1)
+ winUpdateFreq = 1;
+
+ int inst = Platform::InstanceID();
+ if (inst == 0)
+ sprintf(melontitle, "[%d/%.0f] melonDS " MELONDS_VERSION, fps, fpstarget);
+ else
+ sprintf(melontitle, "[%d/%.0f] melonDS (%d)", fps, fpstarget, inst+1);
changeWindowTitle(melontitle);
}
}
@@ -631,7 +692,11 @@ void EmuThread::run()
EmuStatus = EmuRunning;
- sprintf(melontitle, "melonDS " MELONDS_VERSION);
+ int inst = Platform::InstanceID();
+ if (inst == 0)
+ sprintf(melontitle, "melonDS " MELONDS_VERSION);
+ else
+ sprintf(melontitle, "melonDS (%d)", inst+1);
changeWindowTitle(melontitle);
SDL_Delay(75);
@@ -719,19 +784,39 @@ bool EmuThread::emuIsActive()
return (RunningSomething == 1);
}
+ScreenHandler::ScreenHandler(QWidget* widget)
+{
+ widget->setMouseTracking(true);
+ widget->setAttribute(Qt::WA_AcceptTouchEvents);
+ QTimer* mouseTimer = setupMouseTimer();
+ widget->connect(mouseTimer, &QTimer::timeout, [=] { if (Config::MouseHide) widget->setCursor(Qt::BlankCursor);});
+}
+
+ScreenHandler::~ScreenHandler()
+{
+ mouseTimer->stop();
+}
void ScreenHandler::screenSetupLayout(int w, int h)
{
int sizing = Config::ScreenSizing;
if (sizing == 3) sizing = autoScreenSizing;
- float aspectRatios[] =
+ float aspectTop, aspectBot;
+
+ for (auto ratio : aspectRatios)
{
- 1.f,
- (16.f/9)/(4.f/3),
- (21.f/9)/(4.f/3),
- ((float)w/h)/(4.f/3)
- };
+ if (ratio.id == Config::ScreenAspectTop)
+ aspectTop = ratio.ratio;
+ if (ratio.id == Config::ScreenAspectBot)
+ aspectBot = ratio.ratio;
+ }
+
+ if (aspectTop == 0)
+ aspectTop = (float) w / h;
+
+ if (aspectBot == 0)
+ aspectBot = (float) w / h;
Frontend::SetupScreenLayout(w, h,
Config::ScreenLayout,
@@ -740,8 +825,8 @@ void ScreenHandler::screenSetupLayout(int w, int h)
Config::ScreenGap,
Config::IntegerScaling != 0,
Config::ScreenSwap != 0,
- aspectRatios[Config::ScreenAspectTop],
- aspectRatios[Config::ScreenAspectBot]);
+ aspectTop,
+ aspectBot);
numScreens = Frontend::GetScreenTransforms(screenMatrix[0], screenKind);
}
@@ -754,6 +839,11 @@ QSize ScreenHandler::screenGetMinSize(int factor = 1)
int w = 256 * factor;
int h = 192 * factor;
+ if (Config::ScreenSizing == 4 || Config::ScreenSizing == 5)
+ {
+ return QSize(w, h);
+ }
+
if (Config::ScreenLayout == 0) // natural
{
if (isHori)
@@ -889,7 +979,7 @@ void ScreenHandler::screenHandleTouch(QTouchEvent* event)
void ScreenHandler::showCursor()
{
- mainWindow->panel->setCursor(Qt::ArrowCursor);
+ mainWindow->panelWidget->setCursor(Qt::ArrowCursor);
mouseTimer->start();
}
@@ -903,7 +993,7 @@ QTimer* ScreenHandler::setupMouseTimer()
return mouseTimer;
}
-ScreenPanelNative::ScreenPanelNative(QWidget* parent) : QWidget(parent)
+ScreenPanelNative::ScreenPanelNative(QWidget* parent) : QWidget(parent), ScreenHandler(this)
{
screen[0] = QImage(256, 192, QImage::Format_RGB32);
screen[1] = QImage(256, 192, QImage::Format_RGB32);
@@ -911,17 +1001,12 @@ ScreenPanelNative::ScreenPanelNative(QWidget* parent) : QWidget(parent)
screenTrans[0].reset();
screenTrans[1].reset();
- touching = false;
-
- setAttribute(Qt::WA_AcceptTouchEvents);
-
OSD::Init(nullptr);
}
ScreenPanelNative::~ScreenPanelNative()
{
OSD::DeInit(nullptr);
- mouseTimer->stop();
}
void ScreenPanelNative::setupScreenLayout()
@@ -1020,17 +1105,11 @@ void ScreenPanelNative::onScreenLayoutChanged()
}
-ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent)
-{
- touching = false;
-
- setAttribute(Qt::WA_AcceptTouchEvents);
-}
+ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent), ScreenHandler(this)
+{}
ScreenPanelGL::~ScreenPanelGL()
{
- mouseTimer->stop();
-
makeCurrent();
OSD::DeInit(this);
@@ -1281,11 +1360,14 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
oldW = Config::WindowWidth;
oldH = Config::WindowHeight;
- oldMax = Config::WindowMaximized!=0;
+ oldMax = Config::WindowMaximized;
setWindowTitle("melonDS " MELONDS_VERSION);
setAttribute(Qt::WA_DeleteOnClose);
setAcceptDrops(true);
+ setFocusPolicy(Qt::ClickFocus);
+
+ int inst = Platform::InstanceID();
QMenuBar* menubar = new QMenuBar();
{
@@ -1295,16 +1377,16 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile);
actOpenROM->setShortcut(QKeySequence(QKeySequence::StandardKey::Open));
- actOpenROMArchive = menu->addAction("Open ROM inside archive...");
+ /*actOpenROMArchive = menu->addAction("Open ROM inside archive...");
connect(actOpenROMArchive, &QAction::triggered, this, &MainWindow::onOpenFileArchive);
- actOpenROMArchive->setShortcut(QKeySequence(Qt::Key_O | Qt::CTRL | Qt::SHIFT));
+ actOpenROMArchive->setShortcut(QKeySequence(Qt::Key_O | Qt::CTRL | Qt::SHIFT));*/
recentMenu = menu->addMenu("Open recent");
for (int i = 0; i < 10; ++i)
{
- char* item = Config::RecentROMList[i];
- if (strlen(item) > 0)
- recentFileList.push_back(item);
+ std::string item = Config::RecentROMList[i];
+ if (!item.empty())
+ recentFileList.push_back(QString::fromStdString(item));
}
updateRecentFilesMenu();
@@ -1314,6 +1396,41 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
menu->addSeparator();
+ actCurrentCart = menu->addAction("DS slot: " + ROMManager::CartLabel());
+ actCurrentCart->setEnabled(false);
+
+ actInsertCart = menu->addAction("Insert cart...");
+ connect(actInsertCart, &QAction::triggered, this, &MainWindow::onInsertCart);
+
+ actEjectCart = menu->addAction("Eject cart");
+ connect(actEjectCart, &QAction::triggered, this, &MainWindow::onEjectCart);
+
+ menu->addSeparator();
+
+ actCurrentGBACart = menu->addAction("GBA slot: " + ROMManager::GBACartLabel());
+ actCurrentGBACart->setEnabled(false);
+
+ actInsertGBACart = menu->addAction("Insert ROM cart...");
+ connect(actInsertGBACart, &QAction::triggered, this, &MainWindow::onInsertGBACart);
+
+ {
+ QMenu* submenu = menu->addMenu("Insert add-on cart");
+
+ actInsertGBAAddon[0] = submenu->addAction("Memory expansion");
+ actInsertGBAAddon[0]->setData(QVariant(NDS::GBAAddon_RAMExpansion));
+ connect(actInsertGBAAddon[0], &QAction::triggered, this, &MainWindow::onInsertGBAAddon);
+ }
+
+ actEjectGBACart = menu->addAction("Eject cart");
+ connect(actEjectGBACart, &QAction::triggered, this, &MainWindow::onEjectGBACart);
+
+ menu->addSeparator();
+
+ actImportSavefile = menu->addAction("Import savefile");
+ connect(actImportSavefile, &QAction::triggered, this, &MainWindow::onImportSavefile);
+
+ menu->addSeparator();
+
{
QMenu* submenu = menu->addMenu("Save state");
@@ -1351,9 +1468,6 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actUndoStateLoad->setShortcut(QKeySequence(Qt::Key_F12));
connect(actUndoStateLoad, &QAction::triggered, this, &MainWindow::onUndoStateLoad);
- actImportSavefile = menu->addAction("Import savefile");
- connect(actImportSavefile, &QAction::triggered, this, &MainWindow::onImportSavefile);
-
menu->addSeparator();
actQuit = menu->addAction("Quit");
@@ -1377,20 +1491,39 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
menu->addSeparator();
+ actPowerManagement = menu->addAction("Power management");
+ connect(actPowerManagement, &QAction::triggered, this, &MainWindow::onOpenPowerManagement);
+
+ menu->addSeparator();
+
actEnableCheats = menu->addAction("Enable cheats");
actEnableCheats->setCheckable(true);
connect(actEnableCheats, &QAction::triggered, this, &MainWindow::onEnableCheats);
- actSetupCheats = menu->addAction("Setup cheat codes");
- actSetupCheats->setMenuRole(QAction::NoRole);
- connect(actSetupCheats, &QAction::triggered, this, &MainWindow::onSetupCheats);
+ //if (inst == 0)
+ {
+ actSetupCheats = menu->addAction("Setup cheat codes");
+ actSetupCheats->setMenuRole(QAction::NoRole);
+ connect(actSetupCheats, &QAction::triggered, this, &MainWindow::onSetupCheats);
+
+ menu->addSeparator();
+ actROMInfo = menu->addAction("ROM info");
+ connect(actROMInfo, &QAction::triggered, this, &MainWindow::onROMInfo);
- menu->addSeparator();
- actROMInfo = menu->addAction("ROM info");
- connect(actROMInfo, &QAction::triggered, this, &MainWindow::onROMInfo);
+ actRAMInfo = menu->addAction("RAM search");
+ connect(actRAMInfo, &QAction::triggered, this, &MainWindow::onRAMInfo);
+
+ actTitleManager = menu->addAction("Manage DSi titles");
+ connect(actTitleManager, &QAction::triggered, this, &MainWindow::onOpenTitleManager);
+ }
- actTitleManager = menu->addAction("Manage DSi titles");
- connect(actTitleManager, &QAction::triggered, this, &MainWindow::onOpenTitleManager);
+ {
+ menu->addSeparator();
+ QMenu* submenu = menu->addMenu("Multiplayer");
+
+ actMPNewInstance = submenu->addAction("Launch new instance");
+ connect(actMPNewInstance, &QAction::triggered, this, &MainWindow::onMPNewInstance);
+ }
}
{
QMenu* menu = menubar->addMenu("Config");
@@ -1399,7 +1532,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
connect(actEmuSettings, &QAction::triggered, this, &MainWindow::onOpenEmuSettings);
#ifdef __APPLE__
- QAction* actPreferences = menu->addAction("Preferences...");
+ actPreferences = menu->addAction("Preferences...");
connect(actPreferences, &QAction::triggered, this, &MainWindow::onOpenEmuSettings);
actPreferences->setMenuRole(QAction::PreferencesRole);
#endif
@@ -1410,17 +1543,26 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actVideoSettings = menu->addAction("Video settings");
connect(actVideoSettings, &QAction::triggered, this, &MainWindow::onOpenVideoSettings);
+ actCameraSettings = menu->addAction("Camera settings");
+ connect(actCameraSettings, &QAction::triggered, this, &MainWindow::onOpenCameraSettings);
+
actAudioSettings = menu->addAction("Audio settings");
connect(actAudioSettings, &QAction::triggered, this, &MainWindow::onOpenAudioSettings);
+ actMPSettings = menu->addAction("Multiplayer settings");
+ connect(actMPSettings, &QAction::triggered, this, &MainWindow::onOpenMPSettings);
+
actWifiSettings = menu->addAction("Wifi settings");
connect(actWifiSettings, &QAction::triggered, this, &MainWindow::onOpenWifiSettings);
+ actFirmwareSettings = menu->addAction("Firmware settings");
+ connect(actFirmwareSettings, &QAction::triggered, this, &MainWindow::onOpenFirmwareSettings);
+
actInterfaceSettings = menu->addAction("Interface settings");
connect(actInterfaceSettings, &QAction::triggered, this, &MainWindow::onOpenInterfaceSettings);
- actFirmwareSettings = menu->addAction("Firmware settings");
- connect(actFirmwareSettings, &QAction::triggered, this, &MainWindow::onOpenFirmwareSettings);
+ actPathSettings = menu->addAction("Path settings");
+ connect(actPathSettings, &QAction::triggered, this, &MainWindow::onOpenPathSettings);
{
QMenu* submenu = menu->addMenu("Savestate settings");
@@ -1503,7 +1645,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
const char* screensizing[] = {"Even", "Emphasize top", "Emphasize bottom", "Auto", "Top only", "Bottom only"};
- for (int i = 0; i < 6; i++)
+ for (int i = 0; i < screenSizing_MAX; i++)
{
actScreenSizing[i] = submenu->addAction(QString(screensizing[i]));
actScreenSizing[i]->setActionGroup(grpScreenSizing);
@@ -1522,34 +1664,34 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
{
QMenu* submenu = menu->addMenu("Aspect ratio");
grpScreenAspectTop = new QActionGroup(submenu);
+ grpScreenAspectBot = new QActionGroup(submenu);
+ actScreenAspectTop = new QAction*[sizeof(aspectRatios) / sizeof(aspectRatios[0])];
+ actScreenAspectBot = new QAction*[sizeof(aspectRatios) / sizeof(aspectRatios[0])];
- const char* aspectRatiosTop[] = {"Top 4:3 (native)", "Top 16:9", "Top 21:9", "Top window"};
-
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 2; i++)
{
- actScreenAspectTop[i] = submenu->addAction(QString(aspectRatiosTop[i]));
- actScreenAspectTop[i]->setActionGroup(grpScreenAspectTop);
- actScreenAspectTop[i]->setData(QVariant(i));
- actScreenAspectTop[i]->setCheckable(true);
- }
-
- connect(grpScreenAspectTop, &QActionGroup::triggered, this, &MainWindow::onChangeScreenAspectTop);
+ QActionGroup* group = grpScreenAspectTop;
+ QAction** actions = actScreenAspectTop;
- submenu->addSeparator();
-
- grpScreenAspectBot = new QActionGroup(submenu);
+ if (i == 1)
+ {
+ group = grpScreenAspectBot;
+ submenu->addSeparator();
+ actions = actScreenAspectBot;
+ }
- const char* aspectRatiosBot[] = {"Bottom 4:3 (native)", "Bottom 16:9", "Bottom 21:9", "Bottom window"};
+ for (int j = 0; j < sizeof(aspectRatios) / sizeof(aspectRatios[0]); j++)
+ {
+ auto ratio = aspectRatios[j];
+ QString label = QString("%1 %2").arg(i ? "Bottom" : "Top", ratio.label);
+ actions[j] = submenu->addAction(label);
+ actions[j]->setActionGroup(group);
+ actions[j]->setData(QVariant(ratio.id));
+ actions[j]->setCheckable(true);
+ }
- for (int i = 0; i < 4; i++)
- {
- actScreenAspectBot[i] = submenu->addAction(QString(aspectRatiosBot[i]));
- actScreenAspectBot[i]->setActionGroup(grpScreenAspectBot);
- actScreenAspectBot[i]->setData(QVariant(i));
- actScreenAspectBot[i]->setCheckable(true);
+ connect(group, &QActionGroup::triggered, this, &MainWindow::onChangeScreenAspect);
}
-
- connect(grpScreenAspectBot, &QActionGroup::triggered, this, &MainWindow::onChangeScreenAspectBot);
}
actScreenFiltering = menu->addAction("Screen filtering");
@@ -1574,6 +1716,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
resize(Config::WindowWidth, Config::WindowHeight);
+ if (Config::FirmwareUsername == "Arisotura")
+ actMPNewInstance->setText("Fart");
+
#ifdef Q_OS_MAC
QPoint screenCenter = screen()->availableGeometry().center();
QRect frameGeo = frameGeometry();
@@ -1588,6 +1733,16 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
createScreenPanel();
+ actEjectCart->setEnabled(false);
+ actEjectGBACart->setEnabled(false);
+
+ if (Config::ConsoleType == 1)
+ {
+ actInsertGBACart->setEnabled(false);
+ for (int i = 0; i < 1; i++)
+ actInsertGBAAddon[i]->setEnabled(false);
+ }
+
for (int i = 0; i < 9; i++)
{
actSaveState[i]->setEnabled(false);
@@ -1601,14 +1756,17 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actStop->setEnabled(false);
actFrameStep->setEnabled(false);
+ actPowerManagement->setEnabled(false);
+
actSetupCheats->setEnabled(false);
- actTitleManager->setEnabled(strlen(Config::DSiNANDPath) > 0);
+ actTitleManager->setEnabled(!Config::DSiNANDPath.empty());
- actEnableCheats->setChecked(Config::EnableCheats != 0);
+ actEnableCheats->setChecked(Config::EnableCheats);
actROMInfo->setEnabled(false);
+ actRAMInfo->setEnabled(false);
- actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM != 0);
+ actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM);
actScreenRotation[Config::ScreenRotation]->setChecked(true);
@@ -1623,18 +1781,36 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actScreenLayout[Config::ScreenLayout]->setChecked(true);
actScreenSizing[Config::ScreenSizing]->setChecked(true);
- actIntegerScaling->setChecked(Config::IntegerScaling != 0);
+ actIntegerScaling->setChecked(Config::IntegerScaling);
- actScreenSwap->setChecked(Config::ScreenSwap != 0);
+ actScreenSwap->setChecked(Config::ScreenSwap);
- actScreenAspectTop[Config::ScreenAspectTop]->setChecked(true);
- actScreenAspectBot[Config::ScreenAspectBot]->setChecked(true);
+ for (int i = 0; i < sizeof(aspectRatios) / sizeof(aspectRatios[0]); i++)
+ {
+ if (Config::ScreenAspectTop == aspectRatios[i].id)
+ actScreenAspectTop[i]->setChecked(true);
+ if (Config::ScreenAspectBot == aspectRatios[i].id)
+ actScreenAspectBot[i]->setChecked(true);
+ }
- actScreenFiltering->setChecked(Config::ScreenFilter != 0);
- actShowOSD->setChecked(Config::ShowOSD != 0);
+ actScreenFiltering->setChecked(Config::ScreenFilter);
+ actShowOSD->setChecked(Config::ShowOSD);
- actLimitFramerate->setChecked(Config::LimitFPS != 0);
- actAudioSync->setChecked(Config::AudioSync != 0);
+ actLimitFramerate->setChecked(Config::LimitFPS);
+ actAudioSync->setChecked(Config::AudioSync);
+
+ if (inst > 0)
+ {
+ actEmuSettings->setEnabled(false);
+ actVideoSettings->setEnabled(false);
+ actMPSettings->setEnabled(false);
+ actWifiSettings->setEnabled(false);
+ actInterfaceSettings->setEnabled(false);
+
+#ifdef __APPLE__
+ actPreferences->setEnabled(false);
+#endif // __APPLE__
+ }
}
MainWindow::~MainWindow()
@@ -1645,17 +1821,13 @@ void MainWindow::createScreenPanel()
{
hasOGL = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
- QTimer* mouseTimer;
-
if (hasOGL)
{
- panelGL = new ScreenPanelGL(this);
+ ScreenPanelGL* panelGL = new ScreenPanelGL(this);
panelGL->show();
panel = panelGL;
- panelGL->setMouseTracking(true);
- mouseTimer = panelGL->setupMouseTimer();
- connect(mouseTimer, &QTimer::timeout, [=] { if (Config::MouseHide) panelGL->setCursor(Qt::BlankCursor);});
+ panelWidget = panelGL;
if (!panelGL->isValid())
hasOGL = false;
@@ -1672,17 +1844,14 @@ void MainWindow::createScreenPanel()
if (!hasOGL)
{
- panelNative = new ScreenPanelNative(this);
+ ScreenPanelNative* panelNative = new ScreenPanelNative(this);
panel = panelNative;
- panel->show();
-
- panelNative->setMouseTracking(true);
- mouseTimer = panelNative->setupMouseTimer();
- connect(mouseTimer, &QTimer::timeout, [=] { if (Config::MouseHide) panelNative->setCursor(Qt::BlankCursor);});
+ panelWidget = panelNative;
+ panelWidget->show();
}
- setCentralWidget(panel);
+ setCentralWidget(panelWidget);
- connect(this, SIGNAL(screenLayoutChange()), panel, SLOT(onScreenLayoutChanged()));
+ connect(this, SIGNAL(screenLayoutChange()), panelWidget, SLOT(onScreenLayoutChanged()));
emit screenLayoutChange();
}
@@ -1690,7 +1859,7 @@ QOpenGLContext* MainWindow::getOGLContext()
{
if (!hasOGL) return nullptr;
- QOpenGLWidget* glpanel = (QOpenGLWidget*)panel;
+ QOpenGLWidget* glpanel = dynamic_cast<QOpenGLWidget*>(panel);
return glpanel->context();
}
@@ -1755,9 +1924,9 @@ void MainWindow::dragEnterEvent(QDragEnterEvent* event)
QStringList acceptedExts{".nds", ".srl", ".dsi", ".gba", ".rar",
".zip", ".7z", ".tar", ".tar.gz", ".tar.xz", ".tar.bz2"};
- for(const QString &ext : acceptedExts)
+ for (const QString &ext : acceptedExts)
{
- if(filename.endsWith(ext, Qt::CaseInsensitive))
+ if (filename.endsWith(ext, Qt::CaseInsensitive))
event->acceptProposedAction();
}
}
@@ -1769,69 +1938,79 @@ void MainWindow::dropEvent(QDropEvent* event)
QList<QUrl> urls = event->mimeData()->urls();
if (urls.count() > 1) return; // not handling more than one file at once
- emuThread->emuPause();
-
QString filename = urls.at(0).toLocalFile();
- QString ext = filename.right(3).toLower();
+ QStringList arcexts{".zip", ".7z", ".rar", ".tar", ".tar.gz", ".tar.xz", ".tar.bz2"};
- recentFileList.removeAll(filename);
- recentFileList.prepend(filename);
- updateRecentFilesMenu();
-
- char _filename[1024];
- strncpy(_filename, filename.toStdString().c_str(), 1023); _filename[1023] = '\0';
+ emuThread->emuPause();
- int slot; int res;
- if (ext == "gba")
- {
- slot = 1;
- res = Frontend::LoadROM(_filename, Frontend::ROMSlot_GBA);
- }
- else if(ext == "nds" || ext == "srl" || ext == "dsi")
+ if (!verifySetup())
{
- slot = 0;
- res = Frontend::LoadROM(_filename, Frontend::ROMSlot_NDS);
+ emuThread->emuUnpause();
+ return;
}
- else
+
+ for (const QString &ext : arcexts)
{
- QByteArray romBuffer;
- QString romFileName = pickAndExtractFileFromArchive(_filename, &romBuffer);
- if(romFileName.isEmpty())
- {
- res = Frontend::Load_ROMLoadError;
- }
- else
+ if (filename.endsWith(ext, Qt::CaseInsensitive))
{
- slot = (romFileName.endsWith(".gba", Qt::CaseInsensitive) ? 1 : 0);
- QString sramFileName = QFileInfo(_filename).absolutePath() + QDir::separator() + QFileInfo(romFileName).completeBaseName() + ".sav";
-
- if(slot == 0)
- strncpy(Frontend::NDSROMExtension, QFileInfo(romFileName).suffix().toStdString().c_str(), 4);
+ QString arcfile = pickFileFromArchive(filename);
+ if (arcfile.isEmpty())
+ {
+ emuThread->emuUnpause();
+ return;
+ }
- res = Frontend::LoadROM((const u8*)romBuffer.constData(), romBuffer.size(),
- _filename, romFileName.toStdString().c_str(), sramFileName.toStdString().c_str(),
- slot);
+ filename += "|" + arcfile;
}
}
- if (res != Frontend::Load_OK)
- {
- QMessageBox::critical(this,
- "melonDS",
- loadErrorStr(res));
- emuThread->emuUnpause();
- }
- else if (slot == 1)
+ QStringList file = filename.split('|');
+
+ if (filename.endsWith(".gba", Qt::CaseInsensitive))
{
- // checkme
+ if (!ROMManager::LoadGBAROM(file))
+ {
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
+ emuThread->emuUnpause();
+ return;
+ }
+
emuThread->emuUnpause();
+
+ updateCartInserted(true);
}
else
{
+ if (!ROMManager::LoadROM(file, true))
+ {
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
+ emuThread->emuUnpause();
+ return;
+ }
+
+ recentFileList.removeAll(filename);
+ recentFileList.prepend(filename);
+ updateRecentFilesMenu();
+
+ NDS::Start();
emuThread->emuRun();
+
+ updateCartInserted(false);
}
}
+void MainWindow::focusInEvent(QFocusEvent* event)
+{
+ audioMute();
+}
+
+void MainWindow::focusOutEvent(QFocusEvent* event)
+{
+ audioMute();
+}
+
void MainWindow::onAppStateChanged(Qt::ApplicationState state)
{
if (state == Qt::ApplicationInactive)
@@ -1846,145 +2025,179 @@ void MainWindow::onAppStateChanged(Qt::ApplicationState state)
}
}
-QString MainWindow::loadErrorStr(int error)
+bool MainWindow::verifySetup()
{
- switch (error)
+ QString res = ROMManager::VerifySetup();
+ if (!res.isEmpty())
{
- case Frontend::Load_BIOS9Missing:
- return "DS ARM9 BIOS was not found or could not be accessed. Check your emu settings.";
- case Frontend::Load_BIOS9Bad:
- return "DS ARM9 BIOS is not a valid BIOS dump.";
+ QMessageBox::critical(this, "melonDS", res);
+ return false;
+ }
- case Frontend::Load_BIOS7Missing:
- return "DS ARM7 BIOS was not found or could not be accessed. Check your emu settings.";
- case Frontend::Load_BIOS7Bad:
- return "DS ARM7 BIOS is not a valid BIOS dump.";
+ return true;
+}
- case Frontend::Load_FirmwareMissing:
- return "DS firmware was not found or could not be accessed. Check your emu settings.";
- case Frontend::Load_FirmwareBad:
- return "DS firmware is not a valid firmware dump.";
- case Frontend::Load_FirmwareNotBootable:
- return "DS firmware is not bootable.";
+bool MainWindow::preloadROMs(QString filename, QString gbafilename)
+{
+ if (!verifySetup())
+ {
+ return false;
+ }
- case Frontend::Load_DSiBIOS9Missing:
- return "DSi ARM9 BIOS was not found or could not be accessed. Check your emu settings.";
- case Frontend::Load_DSiBIOS9Bad:
- return "DSi ARM9 BIOS is not a valid BIOS dump.";
+ bool gbaloaded = false;
+ if (!gbafilename.isEmpty())
+ {
+ QStringList gbafile = gbafilename.split('|');
+ if (!ROMManager::LoadGBAROM(gbafile))
+ {
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "Failed to load the GBA ROM.");
+ return false;
+ }
- case Frontend::Load_DSiBIOS7Missing:
- return "DSi ARM7 BIOS was not found or could not be accessed. Check your emu settings.";
- case Frontend::Load_DSiBIOS7Bad:
- return "DSi ARM7 BIOS is not a valid BIOS dump.";
+ gbaloaded = true;
+ }
- case Frontend::Load_DSiNANDMissing:
- return "DSi NAND was not found or could not be accessed. Check your emu settings.";
- case Frontend::Load_DSiNANDBad:
- return "DSi NAND is not a valid NAND dump.";
+ QStringList file = filename.split('|');
+ if (!ROMManager::LoadROM(file, true))
+ {
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
+ return false;
+ }
- case Frontend::Load_ROMLoadError:
- return "Failed to load the ROM. Make sure the file is accessible and isn't used by another application.";
+ recentFileList.removeAll(filename);
+ recentFileList.prepend(filename);
+ updateRecentFilesMenu();
+
+ NDS::Start();
+ emuThread->emuRun();
- default: return "Unknown error during launch; smack Arisotura.";
+ updateCartInserted(false);
+
+ if (gbaloaded)
+ {
+ updateCartInserted(true);
}
+
+ return true;
}
-void MainWindow::loadROM(QByteArray *romData, QString archiveFileName, QString romFileName)
+QString MainWindow::pickFileFromArchive(QString archiveFileName)
{
- recentFileList.removeAll(archiveFileName);
- recentFileList.prepend(archiveFileName);
- updateRecentFilesMenu();
+ QVector<QString> archiveROMList = Archive::ListArchive(archiveFileName);
- // Strip entire archive name and get folder path
- strncpy(Config::LastROMFolder, QFileInfo(archiveFileName).absolutePath().toStdString().c_str(), 1024);
+ QString romFileName = ""; // file name inside archive
- QString sramFileName = QFileInfo(archiveFileName).absolutePath() + QDir::separator() + QFileInfo(romFileName).completeBaseName() + ".sav";
+ if (archiveROMList.size() > 2)
+ {
+ archiveROMList.removeFirst();
- int slot; int res;
- if (romFileName.endsWith("gba"))
+ bool ok;
+ QString toLoad = QInputDialog::getItem(this, "melonDS",
+ "This archive contains multiple files. Select which ROM you want to load.", archiveROMList.toList(), 0, false, &ok);
+ if (!ok) // User clicked on cancel
+ return QString();
+
+ romFileName = toLoad;
+ }
+ else if (archiveROMList.size() == 2)
{
- slot = 1;
- res = Frontend::LoadROM((const u8*)romData->constData(), romData->size(),
- archiveFileName.toStdString().c_str(),
- romFileName.toStdString().c_str(), sramFileName.toStdString().c_str(),
- Frontend::ROMSlot_GBA);
+ romFileName = archiveROMList.at(1);
}
- else
+ else if ((archiveROMList.size() == 1) && (archiveROMList[0] == QString("OK")))
{
- strncpy(Frontend::NDSROMExtension, QFileInfo(romFileName).suffix().toStdString().c_str(), 4);
- slot = 0;
- res = Frontend::LoadROM((const u8*)romData->constData(), romData->size(),
- archiveFileName.toStdString().c_str(),
- romFileName.toStdString().c_str(), sramFileName.toStdString().c_str(),
- Frontend::ROMSlot_NDS);
+ QMessageBox::warning(this, "melonDS", "This archive is empty.");
}
-
- if (res != Frontend::Load_OK)
+ else
{
- QMessageBox::critical(this,
- "melonDS",
- loadErrorStr(res));
- emuThread->emuUnpause();
+ QMessageBox::critical(this, "melonDS", "This archive could not be read. It may be corrupt or you don't have the permissions.");
}
- else if (slot == 1)
+
+ return romFileName;
+}
+
+QStringList MainWindow::pickROM(bool gba)
+{
+ QString console;
+ QStringList romexts;
+ QStringList arcexts{"*.zip", "*.7z", "*.rar", "*.tar", "*.tar.gz", "*.tar.xz", "*.tar.bz2"};
+ QStringList ret;
+
+ if (gba)
{
- // checkme
- emuThread->emuUnpause();
+ console = "GBA";
+ romexts.append("*.gba");
}
else
{
- emuThread->emuRun();
+ console = "DS";
+ romexts.append({"*.nds", "*.dsi", "*.ids", "*.srl"});
}
-}
-void MainWindow::loadROM(QString filename)
-{
- recentFileList.removeAll(filename);
- recentFileList.prepend(filename);
- updateRecentFilesMenu();
+ QString filter = romexts.join(' ') + " " + arcexts.join(' ');
+ filter = console + " ROMs (" + filter + ");;Any file (*.*)";
- // TODO: validate the input file!!
- // * check that it is a proper ROM
- // * ensure the binary offsets are sane
- // * etc
+ QString filename = QFileDialog::getOpenFileName(this,
+ "Open "+console+" ROM",
+ QString::fromStdString(Config::LastROMFolder),
+ filter);
+ if (filename.isEmpty())
+ return ret;
- // this shit is stupid
- char file[1024];
- strncpy(file, filename.toStdString().c_str(), 1023); file[1023] = '\0';
+ int pos = filename.length() - 1;
+ while (filename[pos] != '/' && filename[pos] != '\\' && pos > 0) pos--;
+ QString path_dir = filename.left(pos);
+ QString path_file = filename.mid(pos+1);
- int pos = strlen(file)-1;
- while (file[pos] != '/' && file[pos] != '\\' && pos > 0) pos--;
- strncpy(Config::LastROMFolder, file, pos);
- Config::LastROMFolder[pos] = '\0';
- char* ext = &file[strlen(file)-3];
+ Config::LastROMFolder = path_dir.toStdString();
- int slot; int res;
- if (!strcasecmp(ext, "gba"))
+ bool isarc = false;
+ for (const auto& ext : arcexts)
{
- slot = 1;
- res = Frontend::LoadROM(file, Frontend::ROMSlot_GBA);
+ int l = ext.length() - 1;
+ if (path_file.right(l).toLower() == ext.right(l))
+ {
+ isarc = true;
+ break;
+ }
}
- else
+
+ if (isarc)
{
- slot = 0;
- res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS);
- }
+ path_file = pickFileFromArchive(filename);
+ if (path_file.isEmpty())
+ return ret;
- if (res != Frontend::Load_OK)
+ ret.append(filename);
+ ret.append(path_file);
+ }
+ else
{
- QMessageBox::critical(this,
- "melonDS",
- loadErrorStr(res));
- emuThread->emuUnpause();
+ ret.append(filename);
}
- else if (slot == 1)
+
+ return ret;
+}
+
+void MainWindow::updateCartInserted(bool gba)
+{
+ bool inserted;
+ if (gba)
{
- // checkme
- emuThread->emuUnpause();
+ inserted = ROMManager::GBACartInserted() && (Config::ConsoleType == 0);
+ actCurrentGBACart->setText("GBA slot: " + ROMManager::GBACartLabel());
+ actEjectGBACart->setEnabled(inserted);
}
else
{
- emuThread->emuRun();
+ inserted = ROMManager::CartInserted();
+ actCurrentCart->setText("DS slot: " + ROMManager::CartLabel());
+ actEjectCart->setEnabled(inserted);
+ actImportSavefile->setEnabled(inserted);
+ actSetupCheats->setEnabled(inserted);
+ actROMInfo->setEnabled(inserted);
+ actRAMInfo->setEnabled(inserted);
}
}
@@ -1992,99 +2205,43 @@ void MainWindow::onOpenFile()
{
emuThread->emuPause();
- QString filename = QFileDialog::getOpenFileName(this,
- "Open ROM",
- Config::LastROMFolder,
- "DS ROMs (*.nds *.dsi *.srl);;GBA ROMs (*.gba *.zip);;Any file (*.*)");
- if (filename.isEmpty())
+ if (!verifySetup())
{
emuThread->emuUnpause();
return;
}
- loadROM(filename);
-}
-
-void MainWindow::onOpenFileArchive()
-{
- emuThread->emuPause();
-
- QString archiveFileName = QFileDialog::getOpenFileName(this,
- "Open ROM Archive",
- Config::LastROMFolder,
- "Archived ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *.tar.bz2);;Any file (*.*)");
- if (archiveFileName.isEmpty())
+ QStringList file = pickROM(false);
+ if (file.isEmpty())
{
emuThread->emuUnpause();
return;
}
- QByteArray romBuffer;
- QString romFileName = pickAndExtractFileFromArchive(archiveFileName, &romBuffer);
- if(!romFileName.isEmpty())
+ if (!ROMManager::LoadROM(file, true))
{
- loadROM(&romBuffer, archiveFileName, romFileName);
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
+ emuThread->emuUnpause();
+ return;
}
-}
-QString MainWindow::pickAndExtractFileFromArchive(QString archiveFileName, QByteArray *romBuffer)
-{
- printf("Finding list of ROMs...\n");
- QVector<QString> archiveROMList = Archive::ListArchive(archiveFileName.toUtf8().constData());
-
-
- QString romFileName; // file name inside archive
-
- if (archiveROMList.size() > 2)
- {
- archiveROMList.removeFirst();
-
- bool ok;
- QString toLoad = QInputDialog::getItem(this, "melonDS",
- "The archive was found to have multiple files. Select which ROM you want to load.", archiveROMList.toList(), 0, false, &ok);
- if(!ok) // User clicked on cancel
- return QString();
+ QString filename = file.join('|');
+ recentFileList.removeAll(filename);
+ recentFileList.prepend(filename);
+ updateRecentFilesMenu();
- printf("Extracting '%s'\n", toLoad.toUtf8().constData());
- QVector<QString> extractResult = Archive::ExtractFileFromArchive(archiveFileName.toUtf8().constData(), toLoad.toUtf8().constData(), romBuffer);
- if (extractResult[0] != QString("Err"))
- {
- romFileName = extractResult[0];
- }
- else
- {
- QMessageBox::critical(this, "melonDS", QString("There was an error while trying to extract the ROM from the archive: ") + extractResult[1]);
- }
- }
- else if (archiveROMList.size() == 2)
- {
- printf("Extracting the only ROM in archive\n");
- QVector<QString> extractResult = Archive::ExtractFileFromArchive(archiveFileName.toUtf8().constData(), archiveROMList.at(1).toUtf8().constData(), romBuffer);
- if (extractResult[0] != QString("Err"))
- {
- romFileName = extractResult[0];
- }
- else
- {
- QMessageBox::critical(this, "melonDS", QString("There was an error while trying to extract the ROM from the archive: ") + extractResult[1]);
- }
- }
- else if ((archiveROMList.size() == 1) && (archiveROMList[0] == QString("OK")))
- {
- QMessageBox::warning(this, "melonDS", "The archive is intact, but there are no files inside.");
- }
- else
- {
- QMessageBox::critical(this, "melonDS", "The archive could not be read. It may be corrupt or you don't have the permissions.");
- }
+ NDS::Start();
+ emuThread->emuRun();
- return romFileName;
+ updateCartInserted(false);
}
void MainWindow::onClearRecentFiles()
{
recentFileList.clear();
- memset(Config::RecentROMList, 0, 10 * 1024);
+ for (int i = 0; i < 10; i++)
+ Config::RecentROMList[i] = "";
updateRecentFilesMenu();
}
@@ -2092,8 +2249,10 @@ void MainWindow::updateRecentFilesMenu()
{
recentMenu->clear();
- for(int i = 0; i < recentFileList.size(); ++i)
+ for (int i = 0; i < recentFileList.size(); ++i)
{
+ if (i >= 10) break;
+
QString item_full = recentFileList.at(i);
QString item_display = item_full;
int itemlen = item_full.length();
@@ -2120,16 +2279,18 @@ void MainWindow::updateRecentFilesMenu()
actRecentFile_i->setData(item_full);
connect(actRecentFile_i, &QAction::triggered, this, &MainWindow::onClickRecentFile);
- if(i < 10)
- strncpy(Config::RecentROMList[i], recentFileList.at(i).toStdString().c_str(), 1024);
+ Config::RecentROMList[i] = recentFileList.at(i).toStdString();
}
+ while (recentFileList.size() > 10)
+ recentFileList.removeLast();
+
recentMenu->addSeparator();
QAction *actClearRecentList = recentMenu->addAction("Clear");
connect(actClearRecentList, &QAction::triggered, this, &MainWindow::onClearRecentFiles);
- if(recentFileList.empty())
+ if (recentFileList.empty())
actClearRecentList->setEnabled(false);
Config::Save();
@@ -2138,48 +2299,139 @@ void MainWindow::updateRecentFilesMenu()
void MainWindow::onClickRecentFile()
{
QAction *act = (QAction *)sender();
- QString fileName = act->data().toString();
+ QString filename = act->data().toString();
+ QStringList file = filename.split('|');
+
+ emuThread->emuPause();
- if (fileName.endsWith(".gba", Qt::CaseInsensitive) ||
- fileName.endsWith(".nds", Qt::CaseInsensitive) ||
- fileName.endsWith(".srl", Qt::CaseInsensitive) ||
- fileName.endsWith(".dsi", Qt::CaseInsensitive))
+ if (!verifySetup())
{
- emuThread->emuPause();
- loadROM(fileName);
+ emuThread->emuUnpause();
+ return;
}
- else
+
+ if (!ROMManager::LoadROM(file, true))
{
- // Archives
- QString archiveFileName = fileName;
- QByteArray romBuffer;
- QString romFileName = MainWindow::pickAndExtractFileFromArchive(archiveFileName, &romBuffer);
- if(!romFileName.isEmpty())
- {
- emuThread->emuPause();
- loadROM(&romBuffer, archiveFileName, romFileName);
- }
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
+ emuThread->emuUnpause();
+ return;
}
+
+ recentFileList.removeAll(filename);
+ recentFileList.prepend(filename);
+ updateRecentFilesMenu();
+
+ NDS::Start();
+ emuThread->emuRun();
+
+ updateCartInserted(false);
}
void MainWindow::onBootFirmware()
{
- // TODO: check the whole GBA cart shito
+ emuThread->emuPause();
+ if (!verifySetup())
+ {
+ emuThread->emuUnpause();
+ return;
+ }
+
+ if (!ROMManager::LoadBIOS())
+ {
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "This firmware is not bootable.");
+ emuThread->emuUnpause();
+ return;
+ }
+
+ NDS::Start();
+ emuThread->emuRun();
+}
+
+void MainWindow::onInsertCart()
+{
emuThread->emuPause();
- int res = Frontend::LoadBIOS();
- if (res != Frontend::Load_OK)
+ QStringList file = pickROM(false);
+ if (file.isEmpty())
{
- QMessageBox::critical(this,
- "melonDS",
- loadErrorStr(res));
emuThread->emuUnpause();
+ return;
}
- else
+
+ if (!ROMManager::LoadROM(file, false))
{
- emuThread->emuRun();
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
+ emuThread->emuUnpause();
+ return;
}
+
+ emuThread->emuUnpause();
+
+ updateCartInserted(false);
+}
+
+void MainWindow::onEjectCart()
+{
+ emuThread->emuPause();
+
+ ROMManager::EjectCart();
+
+ emuThread->emuUnpause();
+
+ updateCartInserted(false);
+}
+
+void MainWindow::onInsertGBACart()
+{
+ emuThread->emuPause();
+
+ QStringList file = pickROM(true);
+ if (file.isEmpty())
+ {
+ emuThread->emuUnpause();
+ return;
+ }
+
+ if (!ROMManager::LoadGBAROM(file))
+ {
+ // TODO: better error reporting?
+ QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
+ emuThread->emuUnpause();
+ return;
+ }
+
+ emuThread->emuUnpause();
+
+ updateCartInserted(true);
+}
+
+void MainWindow::onInsertGBAAddon()
+{
+ QAction* act = (QAction*)sender();
+ int type = act->data().toInt();
+
+ emuThread->emuPause();
+
+ ROMManager::LoadGBAAddon(type);
+
+ emuThread->emuUnpause();
+
+ updateCartInserted(true);
+}
+
+void MainWindow::onEjectGBACart()
+{
+ emuThread->emuPause();
+
+ ROMManager::EjectGBACart();
+
+ emuThread->emuUnpause();
+
+ updateCartInserted(true);
}
void MainWindow::onSaveState()
@@ -2188,17 +2440,17 @@ void MainWindow::onSaveState()
emuThread->emuPause();
- char filename[1024];
+ std::string filename;
if (slot > 0)
{
- Frontend::GetSavestateName(slot, filename, 1024);
+ filename = ROMManager::GetSavestateName(slot);
}
else
{
// TODO: specific 'last directory' for savestate files?
QString qfilename = QFileDialog::getSaveFileName(this,
"Save state",
- Config::LastROMFolder,
+ QString::fromStdString(Config::LastROMFolder),
"melonDS savestates (*.mln);;Any file (*.*)");
if (qfilename.isEmpty())
{
@@ -2206,10 +2458,10 @@ void MainWindow::onSaveState()
return;
}
- strncpy(filename, qfilename.toStdString().c_str(), 1023); filename[1023] = '\0';
+ filename = qfilename.toStdString();
}
- if (Frontend::SaveState(filename))
+ if (ROMManager::SaveState(filename))
{
char msg[64];
if (slot > 0) sprintf(msg, "State saved to slot %d", slot);
@@ -2232,17 +2484,17 @@ void MainWindow::onLoadState()
emuThread->emuPause();
- char filename[1024];
+ std::string filename;
if (slot > 0)
{
- Frontend::GetSavestateName(slot, filename, 1024);
+ filename = ROMManager::GetSavestateName(slot);
}
else
{
// TODO: specific 'last directory' for savestate files?
QString qfilename = QFileDialog::getOpenFileName(this,
"Load state",
- Config::LastROMFolder,
+ QString::fromStdString(Config::LastROMFolder),
"melonDS savestates (*.ml*);;Any file (*.*)");
if (qfilename.isEmpty())
{
@@ -2250,7 +2502,7 @@ void MainWindow::onLoadState()
return;
}
- strncpy(filename, qfilename.toStdString().c_str(), 1023); filename[1023] = '\0';
+ filename = qfilename.toStdString();
}
if (!Platform::FileExists(filename))
@@ -2264,7 +2516,7 @@ void MainWindow::onLoadState()
return;
}
- if (Frontend::LoadState(filename))
+ if (ROMManager::LoadState(filename))
{
char msg[64];
if (slot > 0) sprintf(msg, "State loaded from slot %d", slot);
@@ -2284,7 +2536,7 @@ void MainWindow::onLoadState()
void MainWindow::onUndoStateLoad()
{
emuThread->emuPause();
- Frontend::UndoStateLoad();
+ ROMManager::UndoStateLoad();
emuThread->emuUnpause();
OSD::AddMessage(0, "State load undone");
@@ -2292,36 +2544,52 @@ void MainWindow::onUndoStateLoad()
void MainWindow::onImportSavefile()
{
- if (!RunningSomething) return;
-
emuThread->emuPause();
QString path = QFileDialog::getOpenFileName(this,
"Select savefile",
- Config::LastROMFolder,
+ QString::fromStdString(Config::LastROMFolder),
"Savefiles (*.sav *.bin *.dsv);;Any file (*.*)");
- if (!path.isEmpty())
+ if (path.isEmpty())
+ {
+ emuThread->emuUnpause();
+ return;
+ }
+
+ FILE* f = Platform::OpenFile(path.toStdString(), "rb", true);
+ if (!f)
+ {
+ QMessageBox::critical(this, "melonDS", "Could not open the given savefile.");
+ emuThread->emuUnpause();
+ return;
+ }
+
+ if (RunningSomething)
{
if (QMessageBox::warning(this,
- "Emulation will be reset and data overwritten",
+ "melonDS",
"The emulation will be reset and the current savefile overwritten.",
- QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok)
+ QMessageBox::Ok, QMessageBox::Cancel) != QMessageBox::Ok)
{
- int res = Frontend::Reset();
- if (res != Frontend::Load_OK)
- {
- QMessageBox::critical(this, "melonDS", "Reset failed\n" + loadErrorStr(res));
- }
- else
- {
- int diff = Frontend::ImportSRAM(path.toStdString().c_str());
- if (diff > 0)
- OSD::AddMessage(0, "Trimmed savefile");
- else if (diff < 0)
- OSD::AddMessage(0, "Savefile shorter than SRAM");
- }
+ emuThread->emuUnpause();
+ return;
}
+
+ ROMManager::Reset();
}
+
+ u32 len;
+ fseek(f, 0, SEEK_END);
+ len = (u32)ftell(f);
+
+ u8* data = new u8[len];
+ fseek(f, 0, SEEK_SET);
+ fread(data, len, 1, f);
+
+ NDS::LoadSave(data, len);
+ delete[] data;
+
+ fclose(f);
emuThread->emuUnpause();
}
@@ -2360,19 +2628,10 @@ void MainWindow::onReset()
actUndoStateLoad->setEnabled(false);
- int res = Frontend::Reset();
- if (res != Frontend::Load_OK)
- {
- QMessageBox::critical(this,
- "melonDS",
- loadErrorStr(res));
- emuThread->emuUnpause();
- }
- else
- {
- OSD::AddMessage(0, "Reset");
- emuThread->emuRun();
- }
+ ROMManager::Reset();
+
+ OSD::AddMessage(0, "Reset");
+ emuThread->emuRun();
}
void MainWindow::onStop()
@@ -2393,7 +2652,7 @@ void MainWindow::onFrameStep()
void MainWindow::onEnableCheats(bool checked)
{
Config::EnableCheats = checked?1:0;
- Frontend::EnableCheats(Config::EnableCheats != 0);
+ ROMManager::EnableCheats(Config::EnableCheats != 0);
}
void MainWindow::onSetupCheats()
@@ -2414,11 +2673,33 @@ void MainWindow::onROMInfo()
ROMInfoDialog* dlg = ROMInfoDialog::openDlg(this);
}
+void MainWindow::onRAMInfo()
+{
+ RAMInfoDialog* dlg = RAMInfoDialog::openDlg(this);
+}
+
void MainWindow::onOpenTitleManager()
{
TitleManagerDialog* dlg = TitleManagerDialog::openDlg(this);
}
+void MainWindow::onMPNewInstance()
+{
+ //QProcess::startDetached(QApplication::applicationFilePath());
+ QProcess newinst;
+ newinst.setProgram(QApplication::applicationFilePath());
+ newinst.setArguments(QApplication::arguments().mid(1, QApplication::arguments().length()-1));
+
+#ifdef __WIN32__
+ newinst.setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)
+ {
+ args->flags |= CREATE_NEW_CONSOLE;
+ });
+#endif
+
+ newinst.startDetached();
+}
+
void MainWindow::onOpenEmuSettings()
{
emuThread->emuPause();
@@ -2431,11 +2712,33 @@ void MainWindow::onEmuSettingsDialogFinished(int res)
{
emuThread->emuUnpause();
+ if (Config::ConsoleType == 1)
+ {
+ actInsertGBACart->setEnabled(false);
+ for (int i = 0; i < 1; i++)
+ actInsertGBAAddon[i]->setEnabled(false);
+ actEjectGBACart->setEnabled(false);
+ }
+ else
+ {
+ actInsertGBACart->setEnabled(true);
+ for (int i = 0; i < 1; i++)
+ actInsertGBAAddon[i]->setEnabled(true);
+ actEjectGBACart->setEnabled(ROMManager::GBACartInserted());
+ }
+
if (EmuSettingsDialog::needsReset)
onReset();
+ actCurrentGBACart->setText("GBA slot: " + ROMManager::GBACartLabel());
+
if (!RunningSomething)
- actTitleManager->setEnabled(strlen(Config::DSiNANDPath) > 0);
+ actTitleManager->setEnabled(!Config::DSiNANDPath.empty());
+}
+
+void MainWindow::onOpenPowerManagement()
+{
+ PowerManagementDialog* dlg = PowerManagementDialog::openDlg(this);
}
void MainWindow::onOpenInputConfig()
@@ -2457,6 +2760,27 @@ void MainWindow::onOpenVideoSettings()
connect(dlg, &VideoSettingsDialog::updateVideoSettings, this, &MainWindow::onUpdateVideoSettings);
}
+void MainWindow::onOpenCameraSettings()
+{
+ emuThread->emuPause();
+
+ camStarted[0] = camManager[0]->isStarted();
+ camStarted[1] = camManager[1]->isStarted();
+ if (camStarted[0]) camManager[0]->stop();
+ if (camStarted[1]) camManager[1]->stop();
+
+ CameraSettingsDialog* dlg = CameraSettingsDialog::openDlg(this);
+ connect(dlg, &CameraSettingsDialog::finished, this, &MainWindow::onCameraSettingsFinished);
+}
+
+void MainWindow::onCameraSettingsFinished(int res)
+{
+ if (camStarted[0]) camManager[0]->start();
+ if (camStarted[1]) camManager[1]->start();
+
+ emuThread->emuUnpause();
+}
+
void MainWindow::onOpenAudioSettings()
{
AudioSettingsDialog* dlg = AudioSettingsDialog::openDlg(this);
@@ -2480,6 +2804,22 @@ void MainWindow::onFirmwareSettingsFinished(int res)
emuThread->emuUnpause();
}
+void MainWindow::onOpenPathSettings()
+{
+ emuThread->emuPause();
+
+ PathSettingsDialog* dlg = PathSettingsDialog::openDlg(this);
+ connect(dlg, &PathSettingsDialog::finished, this, &MainWindow::onPathSettingsFinished);
+}
+
+void MainWindow::onPathSettingsFinished(int res)
+{
+ if (PathSettingsDialog::needsReset)
+ onReset();
+
+ emuThread->emuUnpause();
+}
+
void MainWindow::onUpdateAudioSettings()
{
SPU::SetInterpolation(Config::AudioInterp);
@@ -2515,6 +2855,22 @@ void MainWindow::onAudioSettingsFinished(int res)
micOpen();
}
+void MainWindow::onOpenMPSettings()
+{
+ emuThread->emuPause();
+
+ MPSettingsDialog* dlg = MPSettingsDialog::openDlg(this);
+ connect(dlg, &MPSettingsDialog::finished, this, &MainWindow::onMPSettingsFinished);
+}
+
+void MainWindow::onMPSettingsFinished(int res)
+{
+ audioMute();
+ LocalMP::SetRecvTimeout(Config::MPRecvTimeout);
+
+ emuThread->emuUnpause();
+}
+
void MainWindow::onOpenWifiSettings()
{
emuThread->emuPause();
@@ -2525,12 +2881,6 @@ void MainWindow::onOpenWifiSettings()
void MainWindow::onWifiSettingsFinished(int res)
{
- if (Wifi::MPInited)
- {
- Platform::MP_DeInit();
- Platform::MP_Init();
- }
-
Platform::LAN_DeInit();
Platform::LAN_Init();
@@ -2550,10 +2900,7 @@ void MainWindow::onOpenInterfaceSettings()
void MainWindow::onUpdateMouseTimer()
{
- if (hasOGL)
- panelGL->mouseTimer->setInterval(Config::MouseHideSeconds*1000);
- else
- panelNative->mouseTimer->setInterval(Config::MouseHideSeconds*1000);
+ panel->mouseTimer->setInterval(Config::MouseHideSeconds*1000);
}
void MainWindow::onInterfaceSettingsFinished(int res)
@@ -2569,8 +2916,8 @@ void MainWindow::onChangeSavestateSRAMReloc(bool checked)
void MainWindow::onChangeScreenSize()
{
int factor = ((QAction*)sender())->data().toInt();
- QSize diff = size() - panel->size();
- resize(dynamic_cast<ScreenHandler*>(panel)->screenGetMinSize(factor) + diff);
+ QSize diff = size() - panelWidget->size();
+ resize(panel->screenGetMinSize(factor) + diff);
}
void MainWindow::onChangeScreenRotation(QAction* act)
@@ -2601,6 +2948,22 @@ void MainWindow::onChangeScreenSwap(bool checked)
{
Config::ScreenSwap = checked?1:0;
+ // Swap between top and bottom screen when displaying one screen.
+ if (Config::ScreenSizing == screenSizing_TopOnly)
+ {
+ // Bottom Screen.
+ Config::ScreenSizing = screenSizing_BotOnly;
+ actScreenSizing[screenSizing_TopOnly]->setChecked(false);
+ actScreenSizing[Config::ScreenSizing]->setChecked(true);
+ }
+ else if (Config::ScreenSizing == screenSizing_BotOnly)
+ {
+ // Top Screen.
+ Config::ScreenSizing = screenSizing_TopOnly;
+ actScreenSizing[screenSizing_BotOnly]->setChecked(false);
+ actScreenSizing[Config::ScreenSizing]->setChecked(true);
+ }
+
emit screenLayoutChange();
}
@@ -2612,18 +2975,19 @@ void MainWindow::onChangeScreenSizing(QAction* act)
emit screenLayoutChange();
}
-void MainWindow::onChangeScreenAspectTop(QAction* act)
+void MainWindow::onChangeScreenAspect(QAction* act)
{
int aspect = act->data().toInt();
- Config::ScreenAspectTop = aspect;
-
- emit screenLayoutChange();
-}
+ QActionGroup* group = act->actionGroup();
-void MainWindow::onChangeScreenAspectBot(QAction* act)
-{
- int aspect = act->data().toInt();
- Config::ScreenAspectBot = aspect;
+ if (group == grpScreenAspectTop)
+ {
+ Config::ScreenAspectTop = aspect;
+ }
+ else
+ {
+ Config::ScreenAspectBot = aspect;
+ }
emit screenLayoutChange();
}
@@ -2678,39 +3042,24 @@ void MainWindow::onFullscreenToggled()
void MainWindow::onEmuStart()
{
- // TODO: make savestates work in DSi mode!!
- if (Config::ConsoleType == 1)
+ for (int i = 1; i < 9; i++)
{
- for (int i = 0; i < 9; i++)
- {
- actSaveState[i]->setEnabled(false);
- actLoadState[i]->setEnabled(false);
- }
- actUndoStateLoad->setEnabled(false);
- }
- else
- {
- for (int i = 1; i < 9; i++)
- {
- actSaveState[i]->setEnabled(true);
- actLoadState[i]->setEnabled(Frontend::SavestateExists(i));
- }
- actSaveState[0]->setEnabled(true);
- actLoadState[0]->setEnabled(true);
- actUndoStateLoad->setEnabled(false);
+ actSaveState[i]->setEnabled(true);
+ actLoadState[i]->setEnabled(ROMManager::SavestateExists(i));
}
+ actSaveState[0]->setEnabled(true);
+ actLoadState[0]->setEnabled(true);
+ actUndoStateLoad->setEnabled(false);
actPause->setEnabled(true);
actPause->setChecked(false);
actReset->setEnabled(true);
actStop->setEnabled(true);
actFrameStep->setEnabled(true);
- actImportSavefile->setEnabled(true);
- actSetupCheats->setEnabled(true);
- actTitleManager->setEnabled(false);
+ actPowerManagement->setEnabled(true);
- actROMInfo->setEnabled(true);
+ actTitleManager->setEnabled(false);
}
void MainWindow::onEmuStop()
@@ -2723,17 +3072,15 @@ void MainWindow::onEmuStop()
actLoadState[i]->setEnabled(false);
}
actUndoStateLoad->setEnabled(false);
- actImportSavefile->setEnabled(false);
actPause->setEnabled(false);
actReset->setEnabled(false);
actStop->setEnabled(false);
actFrameStep->setEnabled(false);
- actSetupCheats->setEnabled(false);
- actTitleManager->setEnabled(strlen(Config::DSiNANDPath) > 0);
+ actPowerManagement->setEnabled(false);
- actROMInfo->setEnabled(false);
+ actTitleManager->setEnabled(!Config::DSiNANDPath.empty());
}
void MainWindow::onUpdateVideoSettings(bool glchange)
@@ -2743,16 +3090,10 @@ void MainWindow::onUpdateVideoSettings(bool glchange)
emuThread->emuPause();
if (hasOGL)
- {
emuThread->deinitOpenGL();
- delete panelGL;
- }
- else
- {
- delete panelNative;
- }
+ delete panel;
createScreenPanel();
- connect(emuThread, SIGNAL(windowUpdate()), panel, SLOT(repaint()));
+ connect(emuThread, SIGNAL(windowUpdate()), panelWidget, SLOT(repaint()));
if (hasOGL) emuThread->initOpenGL();
}
@@ -2767,9 +3108,6 @@ void emuStop()
{
RunningSomething = false;
- Frontend::UnloadROM(Frontend::ROMSlot_NDS);
- Frontend::UnloadROM(Frontend::ROMSlot_GBA);
-
emit emuThread->windowEmuStop();
OSD::AddMessage(0xFFC040, "Shutdown");
@@ -2788,7 +3126,8 @@ bool MelonApplication::event(QEvent *event)
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent*>(event);
emuThread->emuPause();
- mainWindow->loadROM(openEvent->file());
+ if (!mainWindow->preloadROMs(openEvent->file(), ""))
+ emuThread->emuUnpause();
}
return QApplication::event(event);
@@ -2796,7 +3135,7 @@ bool MelonApplication::event(QEvent *event)
int main(int argc, char** argv)
{
- srand(time(NULL));
+ srand(time(nullptr));
printf("melonDS " MELONDS_VERSION "\n");
printf(MELONDS_URL "\n");
@@ -2816,9 +3155,13 @@ int main(int argc, char** argv)
{
printf("SDL couldn't init joystick\n");
}
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
+ if (SDL_Init(SDL_INIT_AUDIO) < 0)
{
- QMessageBox::critical(NULL, "melonDS", "SDL shat itself :(");
+ const char* err = SDL_GetError();
+ QString errorStr = "Failed to initialize SDL. This could indicate an issue with your audio driver.\n\nThe error was: ";
+ errorStr += err;
+
+ QMessageBox::critical(NULL, "melonDS", errorStr);
return 1;
}
@@ -2843,7 +3186,7 @@ int main(int argc, char** argv)
SANITIZE(Config::ScreenRotation, 0, 3);
SANITIZE(Config::ScreenGap, 0, 500);
SANITIZE(Config::ScreenLayout, 0, 3);
- SANITIZE(Config::ScreenSizing, 0, 5);
+ SANITIZE(Config::ScreenSizing, 0, (int)screenSizing_MAX);
SANITIZE(Config::ScreenAspectTop, 0, 4);
SANITIZE(Config::ScreenAspectBot, 0, 4);
#undef SANITIZE
@@ -2856,6 +3199,7 @@ int main(int argc, char** argv)
format.setSwapInterval(0);
QSurfaceFormat::setDefaultFormat(format);
+ audioMuted = false;
audioSync = SDL_CreateCond();
audioSyncLock = SDL_CreateMutex();
@@ -2881,13 +3225,18 @@ int main(int argc, char** argv)
micDevice = 0;
-
memset(micExtBuffer, 0, sizeof(micExtBuffer));
micExtBufferWritePos = 0;
micWavBuffer = nullptr;
- Frontend::Init_ROM();
- Frontend::EnableCheats(Config::EnableCheats != 0);
+ camStarted[0] = false;
+ camStarted[1] = false;
+ camManager[0] = new CameraManager(0, 640, 480, true);
+ camManager[1] = new CameraManager(1, 640, 480, true);
+ camManager[0]->setXFlip(Config::Camera[0].XFlip);
+ camManager[1]->setXFlip(Config::Camera[1].XFlip);
+
+ ROMManager::EnableCheats(Config::EnableCheats != 0);
Frontend::Init_Audio(audioFreq);
@@ -2910,33 +3259,17 @@ int main(int argc, char** argv)
emuThread->start();
emuThread->emuPause();
+ audioMute();
+
QObject::connect(&melon, &QApplication::applicationStateChanged, mainWindow, &MainWindow::onAppStateChanged);
if (argc > 1)
{
- char* file = argv[1];
- char* ext = &file[strlen(file)-3];
-
- if (!strcasecmp(ext, "nds") || !strcasecmp(ext, "srl") || !strcasecmp(ext, "dsi"))
- {
- int res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS);
+ QString file = argv[1];
+ QString gbafile = "";
+ if (argc > 2) gbafile = argv[2];
- if (res == Frontend::Load_OK)
- {
- if (argc > 2)
- {
- file = argv[2];
- ext = &file[strlen(file)-3];
-
- if (!strcasecmp(ext, "gba"))
- {
- Frontend::LoadROM(file, Frontend::ROMSlot_GBA);
- }
- }
-
- emuThread->emuRun();
- }
- }
+ mainWindow->preloadROMs(file, gbafile);
}
int ret = melon.exec();
@@ -2947,8 +3280,6 @@ int main(int argc, char** argv)
Input::CloseJoystick();
- Frontend::DeInit_ROM();
-
if (audioDevice) SDL_CloseAudioDevice(audioDevice);
micClose();
@@ -2957,6 +3288,9 @@ int main(int argc, char** argv)
if (micWavBuffer) delete[] micWavBuffer;
+ delete camManager[0];
+ delete camManager[1];
+
Config::Save();
SDL_Quit();
@@ -2972,7 +3306,7 @@ int CALLBACK WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdsho
{
int argc = 0;
wchar_t** argv_w = CommandLineToArgvW(GetCommandLineW(), &argc);
- char* nullarg = "";
+ char nullarg[] = {'\0'};
char** argv = new char*[argc];
for (int i = 0; i < argc; i++)
@@ -2987,7 +3321,8 @@ int CALLBACK WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdsho
if (argv_w) LocalFree(argv_w);
- /*if (AttachConsole(ATTACH_PARENT_PROCESS))
+ //if (AttachConsole(ATTACH_PARENT_PROCESS))
+ /*if (AllocConsole())
{
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);