all repos — mgba @ d0771b78e22e89b5523badee256ec6e15467dc54

mGBA Game Boy Advance Emulator

Qt: Sloppy first pass at refactor
Jeffrey Pfau jeffrey@endrift.com
Sun, 07 Feb 2016 20:07:35 -0800
commit

d0771b78e22e89b5523badee256ec6e15467dc54

parent

fc905657adeba406a2c280bbb94b09533a89e3f8

M src/gba/gba.csrc/gba/gba.c

@@ -922,7 +922,7 @@ if (gba->memory.hw.devices & (HW_GB_PLAYER | HW_GB_PLAYER_DETECTION)) {

GBAHardwarePlayerUpdate(gba); } - struct GBAThread* thread = GBAThreadGetContext(); + struct mCoreThread* thread = mCoreThreadGet(); if (!thread) { return; }

@@ -931,12 +931,7 @@ if (thread->frameCallback) {

thread->frameCallback(thread); } - if (gba->rr && gba->rr->queryReset(gba->rr)) { - // TODO: Clean up reset scheduling - MutexLock(&thread->stateMutex); - thread->state = THREAD_RESETING; - MutexUnlock(&thread->stateMutex); - } + // TODO: Put back RR } void GBASetBreakpoint(struct GBA* gba, struct mCPUComponent* component, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) {
M src/platform/qt/AudioDevice.cppsrc/platform/qt/AudioDevice.cpp

@@ -8,9 +8,9 @@

#include "LogController.h" extern "C" { +#include "core/thread.h" #include "gba/gba.h" #include "gba/audio.h" -#include "gba/supervisor/thread.h" } using namespace QGBA;

@@ -25,18 +25,18 @@ setOpenMode(ReadOnly);

} void AudioDevice::setFormat(const QAudioFormat& format) { - if (!m_context || !GBAThreadIsActive(m_context)) { + if (!m_context || !mCoreThreadIsActive(m_context)) { LOG(INFO) << tr("Can't set format of context-less audio device"); return; } - double fauxClock = GBAAudioCalculateRatio(1, m_context->fpsTarget, 1); + double fauxClock = GBAAudioCalculateRatio(1, 60, 1); // TODO: Put back fpsTarget mCoreSyncLockAudio(&m_context->sync); - blip_set_rates(m_context->gba->audio.psg.left, GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock); - blip_set_rates(m_context->gba->audio.psg.right, GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock); + blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0), GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock); + blip_set_rates(m_context->core->getAudioChannel(m_context->core, 1), GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock); mCoreSyncUnlockAudio(&m_context->sync); } -void AudioDevice::setInput(GBAThread* input) { +void AudioDevice::setInput(mCoreThread* input) { m_context = input; }

@@ -45,18 +45,18 @@ if (maxSize > 0xFFFFFFFF) {

maxSize = 0xFFFFFFFF; } - if (!m_context->gba) { - LOG(WARN) << tr("Audio device is missing its GBA"); + if (!m_context->core) { + LOG(WARN) << tr("Audio device is missing its core"); return 0; } mCoreSyncLockAudio(&m_context->sync); - int available = blip_samples_avail(m_context->gba->audio.psg.left); + int available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)); if (available > maxSize / sizeof(GBAStereoSample)) { available = maxSize / sizeof(GBAStereoSample); } - blip_read_samples(m_context->gba->audio.psg.left, &reinterpret_cast<GBAStereoSample*>(data)->left, available, true); - blip_read_samples(m_context->gba->audio.psg.right, &reinterpret_cast<GBAStereoSample*>(data)->right, available, true); + blip_read_samples(m_context->core->getAudioChannel(m_context->core, 0), &reinterpret_cast<GBAStereoSample*>(data)->left, available, true); + blip_read_samples(m_context->core->getAudioChannel(m_context->core, 1), &reinterpret_cast<GBAStereoSample*>(data)->right, available, true); mCoreSyncConsumeAudio(&m_context->sync); return available * sizeof(GBAStereoSample); }
M src/platform/qt/AudioDevice.hsrc/platform/qt/AudioDevice.h

@@ -9,7 +9,7 @@

#include <QAudioFormat> #include <QIODevice> -struct GBAThread; +struct mCoreThread; namespace QGBA {

@@ -19,7 +19,7 @@

public: AudioDevice(QObject* parent = nullptr); - void setInput(GBAThread* input); + void setInput(mCoreThread* input); void setFormat(const QAudioFormat& format); protected:

@@ -27,7 +27,7 @@ virtual qint64 readData(char* data, qint64 maxSize) override;

virtual qint64 writeData(const char* data, qint64 maxSize) override; private: - GBAThread* m_context; + mCoreThread* m_context; float m_drift; float m_ratio; };
M src/platform/qt/AudioProcessor.cppsrc/platform/qt/AudioProcessor.cpp

@@ -13,10 +13,6 @@ #ifdef BUILD_QT_MULTIMEDIA

#include "AudioProcessorQt.h" #endif -extern "C" { -#include "gba/supervisor/thread.h" -} - using namespace QGBA; #ifndef BUILD_SDL

@@ -49,11 +45,11 @@

AudioProcessor::AudioProcessor(QObject* parent) : QObject(parent) , m_context(nullptr) - , m_samples(GBA_AUDIO_SAMPLES) + , m_samples(2048) { } -void AudioProcessor::setInput(GBAThread* input) { +void AudioProcessor::setInput(mCoreThread* input) { m_context = input; }
M src/platform/qt/AudioProcessor.hsrc/platform/qt/AudioProcessor.h

@@ -7,7 +7,7 @@ #ifndef QGBA_AUDIO_PROCESSOR

#define QGBA_AUDIO_PROCESSOR #include <QObject> -struct GBAThread; +struct mCoreThread; namespace QGBA {

@@ -29,7 +29,7 @@ static void setDriver(Driver driver) { s_driver = driver; }

AudioProcessor(QObject* parent = nullptr); - virtual void setInput(GBAThread* input); + virtual void setInput(mCoreThread* input); int getBufferSamples() const { return m_samples; } virtual unsigned sampleRate() const = 0;

@@ -43,10 +43,10 @@

virtual void requestSampleRate(unsigned) = 0; protected: - GBAThread* input() { return m_context; } + mCoreThread* input() { return m_context; } private: - GBAThread* m_context; + mCoreThread* m_context; int m_samples; static Driver s_driver; };
M src/platform/qt/AudioProcessorQt.cppsrc/platform/qt/AudioProcessorQt.cpp

@@ -24,7 +24,7 @@ , m_sampleRate(44100)

{ } -void AudioProcessorQt::setInput(GBAThread* input) { +void AudioProcessorQt::setInput(mCoreThread* input) { AudioProcessor::setInput(input); if (m_device) { m_device->setInput(input);

@@ -59,7 +59,7 @@ }

m_device->setInput(input()); m_device->setFormat(m_audioOutput->format()); - m_audioOutput->setBufferSize(input()->audioBuffers * 4); + m_audioOutput->setBufferSize(2048 * 4); // TODO? m_audioOutput->start(m_device); return m_audioOutput->state() == QAudio::ActiveState;
M src/platform/qt/AudioProcessorQt.hsrc/platform/qt/AudioProcessorQt.h

@@ -19,7 +19,7 @@

public: AudioProcessorQt(QObject* parent = nullptr); - virtual void setInput(GBAThread* input) override; + virtual void setInput(mCoreThread* input) override; virtual unsigned sampleRate() const override; public slots:
M src/platform/qt/AudioProcessorSDL.cppsrc/platform/qt/AudioProcessorSDL.cpp

@@ -34,9 +34,15 @@ mSDLResumeAudio(&m_audio);

return true; } else { if (!m_audio.samples) { - m_audio.samples = input()->audioBuffers; + m_audio.samples = 2048; // TODO? } - return mSDLInitAudio(&m_audio, input()); + if (mSDLInitAudio(&m_audio, nullptr)) { + m_audio.core = input()->core; + m_audio.sync = &input()->sync; + mSDLResumeAudio(&m_audio); + return true; + } + return false; } }

@@ -49,7 +55,10 @@ AudioProcessor::setBufferSamples(samples);

m_audio.samples = samples; if (m_audio.thread) { mSDLDeinitAudio(&m_audio); - mSDLInitAudio(&m_audio, input()); + mSDLInitAudio(&m_audio, nullptr); + m_audio.core = input()->core; + m_audio.sync = &input()->sync; + mSDLResumeAudio(&m_audio); } }

@@ -60,7 +69,10 @@ void AudioProcessorSDL::requestSampleRate(unsigned rate) {

m_audio.sampleRate = rate; if (m_audio.thread) { mSDLDeinitAudio(&m_audio); - mSDLInitAudio(&m_audio, input()); + mSDLInitAudio(&m_audio, nullptr); + m_audio.core = input()->core; + m_audio.sync = &input()->sync; + mSDLResumeAudio(&m_audio); } }
M src/platform/qt/CheatsView.cppsrc/platform/qt/CheatsView.cpp

@@ -30,8 +30,8 @@ connect(m_ui.load, SIGNAL(clicked()), this, SLOT(load()));

connect(m_ui.save, SIGNAL(clicked()), this, SLOT(save())); connect(m_ui.addSet, SIGNAL(clicked()), this, SLOT(addSet())); connect(m_ui.remove, SIGNAL(clicked()), this, SLOT(removeSet())); - connect(controller, SIGNAL(gameStopped(GBAThread*)), &m_model, SLOT(invalidated())); - connect(controller, SIGNAL(stateLoaded(GBAThread*)), &m_model, SLOT(invalidated())); + connect(controller, SIGNAL(gameStopped(mCoreThread*)), &m_model, SLOT(invalidated())); + connect(controller, SIGNAL(stateLoaded(mCoreThread*)), &m_model, SLOT(invalidated())); connect(m_ui.add, &QPushButton::clicked, [this]() { enterCheat(GBACheatAddLine);
M src/platform/qt/ConfigController.cppsrc/platform/qt/ConfigController.cpp

@@ -109,7 +109,7 @@ m_opts.videoSync = GameController::VIDEO_SYNC;

m_opts.fpsTarget = 60; m_opts.audioBuffers = 1536; m_opts.sampleRate = 44100; - m_opts.volume = GBA_AUDIO_VOLUME_MAX; + m_opts.volume = 0x100; m_opts.logLevel = GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL | GBA_LOG_STATUS; m_opts.rewindEnable = false; m_opts.rewindBufferInterval = 0;
M src/platform/qt/ConfigController.hsrc/platform/qt/ConfigController.h

@@ -82,6 +82,8 @@ void saveOverride(const GBACartridgeOverride&);

Configuration* input() { return mCoreConfigGetInput(&m_config); } + const mCoreConfig* config() { return &m_config; } + public slots: void setOption(const char* key, bool value); void setOption(const char* key, int value);
M src/platform/qt/Display.hsrc/platform/qt/Display.h

@@ -10,7 +10,7 @@ #include <QWidget>

#include "MessagePainter.h" -struct GBAThread; +struct mCoreThread; struct VDir; struct VideoShader;

@@ -47,7 +47,7 @@ void showCursor();

void hideCursor(); public slots: - virtual void startDrawing(GBAThread* context) = 0; + virtual void startDrawing(mCoreThread* context) = 0; virtual void stopDrawing() = 0; virtual void pauseDrawing() = 0; virtual void unpauseDrawing() = 0;
M src/platform/qt/DisplayGL.cppsrc/platform/qt/DisplayGL.cpp

@@ -62,7 +62,7 @@ }

return shaders; } -void DisplayGL::startDrawing(GBAThread* thread) { +void DisplayGL::startDrawing(mCoreThread* thread) { if (m_drawThread) { return; }

@@ -90,14 +90,14 @@

void DisplayGL::stopDrawing() { if (m_drawThread) { m_isDrawing = false; - if (GBAThreadIsActive(m_context)) { - GBAThreadInterrupt(m_context); + if (mCoreThreadIsActive(m_context)) { + mCoreThreadInterrupt(m_context); } QMetaObject::invokeMethod(m_painter, "stop", Qt::BlockingQueuedConnection); m_drawThread->exit(); m_drawThread = nullptr; - if (GBAThreadIsActive(m_context)) { - GBAThreadContinue(m_context); + if (mCoreThreadIsActive(m_context)) { + mCoreThreadContinue(m_context); } } }

@@ -105,12 +105,12 @@

void DisplayGL::pauseDrawing() { if (m_drawThread) { m_isDrawing = false; - if (GBAThreadIsActive(m_context)) { - GBAThreadInterrupt(m_context); + if (mCoreThreadIsActive(m_context)) { + mCoreThreadInterrupt(m_context); } QMetaObject::invokeMethod(m_painter, "pause", Qt::BlockingQueuedConnection); - if (GBAThreadIsActive(m_context)) { - GBAThreadContinue(m_context); + if (mCoreThreadIsActive(m_context)) { + mCoreThreadContinue(m_context); } } }

@@ -118,12 +118,12 @@

void DisplayGL::unpauseDrawing() { if (m_drawThread) { m_isDrawing = true; - if (GBAThreadIsActive(m_context)) { - GBAThreadInterrupt(m_context); + if (mCoreThreadIsActive(m_context)) { + mCoreThreadInterrupt(m_context); } QMetaObject::invokeMethod(m_painter, "unpause", Qt::BlockingQueuedConnection); - if (GBAThreadIsActive(m_context)) { - GBAThreadContinue(m_context); + if (mCoreThreadIsActive(m_context)) { + mCoreThreadContinue(m_context); } } }

@@ -260,7 +260,7 @@ delete m_backend;

m_backend = nullptr; } -void PainterGL::setContext(GBAThread* context) { +void PainterGL::setContext(mCoreThread* context) { m_context = context; }

@@ -307,7 +307,7 @@ m_started = true;

} void PainterGL::draw() { - if (m_queue.isEmpty() || !GBAThreadIsActive(m_context)) { + if (m_queue.isEmpty() || !mCoreThreadIsActive(m_context)) { return; } if (mCoreSyncWaitFrameStart(&m_context->sync) || !m_queue.isEmpty()) {
M src/platform/qt/DisplayGL.hsrc/platform/qt/DisplayGL.h

@@ -26,8 +26,6 @@ extern "C" {

#include "platform/video-backend.h" } -struct GBAThread; - namespace QGBA { class EmptyGLWidget : public QGLWidget {

@@ -53,7 +51,7 @@ bool supportsShaders() const override;

VideoShader* shaders() override; public slots: - void startDrawing(GBAThread* context) override; + void startDrawing(mCoreThread* context) override; void stopDrawing() override; void pauseDrawing() override; void unpauseDrawing() override;

@@ -75,7 +73,7 @@ bool m_isDrawing;

QGLWidget* m_gl; PainterGL* m_painter; QThread* m_drawThread; - GBAThread* m_context; + mCoreThread* m_context; }; class PainterGL : public QObject {

@@ -85,7 +83,7 @@ public:

PainterGL(QGLWidget* parent, QGLFormat::OpenGLVersionFlags = QGLFormat::OpenGL_Version_1_1); ~PainterGL(); - void setContext(GBAThread*); + void setContext(mCoreThread*); void setMessagePainter(MessagePainter*); void enqueue(const uint32_t* backing);

@@ -118,7 +116,7 @@ QMutex m_mutex;

QGLWidget* m_gl; bool m_active; bool m_started; - GBAThread* m_context; + mCoreThread* m_context; bool m_supportsShaders; VideoShader m_shader; VideoBackend* m_backend;
M src/platform/qt/DisplayQt.cppsrc/platform/qt/DisplayQt.cpp

@@ -20,7 +20,7 @@ , m_backing(nullptr)

{ } -void DisplayQt::startDrawing(GBAThread*) { +void DisplayQt::startDrawing(mCoreThread*) { m_isDrawing = true; }
M src/platform/qt/DisplayQt.hsrc/platform/qt/DisplayQt.h

@@ -11,8 +11,6 @@

#include <QImage> #include <QTimer> -struct GBAThread; - namespace QGBA { class DisplayQt : public Display {

@@ -26,7 +24,7 @@ bool supportsShaders() const override { return false; }

VideoShader* shaders() override { return nullptr; } public slots: - void startDrawing(GBAThread* context) override; + void startDrawing(mCoreThread* context) override; void stopDrawing() override { m_isDrawing = false; } void pauseDrawing() override { m_isDrawing = false; } void unpauseDrawing() override { m_isDrawing = true; }
M src/platform/qt/GBAApp.cppsrc/platform/qt/GBAApp.cpp

@@ -43,7 +43,7 @@ #endif

SocketSubsystemInit(); qRegisterMetaType<const uint32_t*>("const uint32_t*"); - qRegisterMetaType<GBAThread*>("GBAThread*"); + qRegisterMetaType<mCoreThread*>("mCoreThread*"); QApplication::setApplicationName(projectName); QApplication::setApplicationVersion(projectVersion);
M src/platform/qt/GameController.cppsrc/platform/qt/GameController.cpp

@@ -21,6 +21,7 @@ extern "C" {

#include "core/config.h" #include "core/directories.h" #include "gba/audio.h" +#include "gba/core.h" #include "gba/gba.h" #include "gba/serialize.h" #include "gba/sharkport.h"

@@ -56,30 +57,15 @@ , m_autofire{}

, m_autofireStatus{} , m_inputController(nullptr) , m_multiplayer(nullptr) + , m_stream(nullptr) , m_stateSlot(1) , m_backupLoadState(nullptr) , m_backupSaveState(nullptr) , m_saveStateFlags(SAVESTATE_SCREENSHOT | SAVESTATE_SAVEDATA | SAVESTATE_CHEATS) , m_loadStateFlags(SAVESTATE_SCREENSHOT) { - m_renderer = new GBAVideoSoftwareRenderer; - GBAVideoSoftwareRendererCreate(m_renderer); - m_renderer->outputBuffer = (color_t*) m_drawContext; - m_renderer->outputBufferStride = VIDEO_HORIZONTAL_PIXELS; - GBACheatDeviceCreate(&m_cheatDevice); - m_threadContext.state = THREAD_INITIALIZED; - m_threadContext.debugger = 0; - m_threadContext.frameskip = 0; - m_threadContext.bios = 0; - m_threadContext.renderer = &m_renderer->d; - m_threadContext.userData = this; - m_threadContext.rewindBufferCapacity = 0; - m_threadContext.cheats = &m_cheatDevice; - m_threadContext.logLevel = GBA_LOG_ALL; - mDirectorySetInit(&m_threadContext.dirs); - m_lux.p = this; m_lux.sample = [](GBALuminanceSource* context) { GameControllerLux* lux = static_cast<GameControllerLux*>(context);

@@ -92,63 +78,65 @@ return lux->value;

}; setLuminanceLevel(0); - m_threadContext.startCallback = [](GBAThread* context) { + m_threadContext.startCallback = [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); if (controller->m_audioProcessor) { controller->m_audioProcessor->setInput(context); } - context->gba->luminanceSource = &controller->m_lux; - GBARTCGenericSourceInit(&controller->m_rtc, context->gba); - context->gba->rtcSource = &controller->m_rtc.d; - context->gba->rumble = controller->m_inputController->rumble(); - context->gba->rotationSource = controller->m_inputController->rotationSource(); - context->gba->audio.psg.forceDisableCh[0] = !controller->m_audioChannels[0]; - context->gba->audio.psg.forceDisableCh[1] = !controller->m_audioChannels[1]; - context->gba->audio.psg.forceDisableCh[2] = !controller->m_audioChannels[2]; - context->gba->audio.psg.forceDisableCh[3] = !controller->m_audioChannels[3]; - context->gba->audio.forceDisableChA = !controller->m_audioChannels[4]; - context->gba->audio.forceDisableChB = !controller->m_audioChannels[5]; - context->gba->video.renderer->disableBG[0] = !controller->m_videoLayers[0]; - context->gba->video.renderer->disableBG[1] = !controller->m_videoLayers[1]; - context->gba->video.renderer->disableBG[2] = !controller->m_videoLayers[2]; - context->gba->video.renderer->disableBG[3] = !controller->m_videoLayers[3]; - context->gba->video.renderer->disableOBJ = !controller->m_videoLayers[4]; - controller->m_fpsTarget = context->fpsTarget; + mRTCGenericSourceInit(&controller->m_rtc, context->core); + context->core->setRTC(context->core, &controller->m_rtc.d); + + GBA* gba = static_cast<GBA*>(context->core->board); + gba->luminanceSource = &controller->m_lux; + gba->rumble = controller->m_inputController->rumble(); + gba->rotationSource = controller->m_inputController->rotationSource(); + gba->audio.psg.forceDisableCh[0] = !controller->m_audioChannels[0]; + gba->audio.psg.forceDisableCh[1] = !controller->m_audioChannels[1]; + gba->audio.psg.forceDisableCh[2] = !controller->m_audioChannels[2]; + gba->audio.psg.forceDisableCh[3] = !controller->m_audioChannels[3]; + gba->audio.forceDisableChA = !controller->m_audioChannels[4]; + gba->audio.forceDisableChB = !controller->m_audioChannels[5]; + gba->video.renderer->disableBG[0] = !controller->m_videoLayers[0]; + gba->video.renderer->disableBG[1] = !controller->m_videoLayers[1]; + gba->video.renderer->disableBG[2] = !controller->m_videoLayers[2]; + gba->video.renderer->disableBG[3] = !controller->m_videoLayers[3]; + gba->video.renderer->disableOBJ = !controller->m_videoLayers[4]; + // TODO: Put back fpsTarget - if (context->dirs.state && GBALoadState(context, context->dirs.state, 0, controller->m_loadStateFlags)) { - GBADeleteState(context->gba, context->dirs.state, 0); + if (mCoreLoadState(context->core, 0, controller->m_loadStateFlags)) { + mCoreDeleteState(context->core, 0); } - QMetaObject::invokeMethod(controller, "gameStarted", Q_ARG(GBAThread*, context)); + QMetaObject::invokeMethod(controller, "gameStarted", Q_ARG(mCoreThread*, context)); }; - m_threadContext.cleanCallback = [](GBAThread* context) { + m_threadContext.cleanCallback = [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); - QMetaObject::invokeMethod(controller, "gameStopped", Q_ARG(GBAThread*, context)); + QMetaObject::invokeMethod(controller, "gameStopped", Q_ARG(mCoreThread*, context)); }; - m_threadContext.frameCallback = [](GBAThread* context) { + m_threadContext.frameCallback = [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); memcpy(controller->m_frontBuffer, controller->m_drawContext, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); QMetaObject::invokeMethod(controller, "frameAvailable", Q_ARG(const uint32_t*, controller->m_frontBuffer)); if (controller->m_pauseAfterFrame.testAndSetAcquire(true, false)) { - GBAThreadPauseFromThread(context); - QMetaObject::invokeMethod(controller, "gamePaused", Q_ARG(GBAThread*, context)); + mCoreThreadPauseFromThread(context); + QMetaObject::invokeMethod(controller, "gamePaused", Q_ARG(mCoreThread*, context)); } }; - m_threadContext.stopCallback = [](GBAThread* context) { + /*m_threadContext.stopCallback = [](mCoreThread* context) { if (!context) { return false; } GameController* controller = static_cast<GameController*>(context->userData); - if (!GBASaveState(context, context->dirs.state, 0, controller->m_saveStateFlags)) { + if (!mCoreSaveState(context->core, 0, controller->m_saveStateFlags)) { return false; } QMetaObject::invokeMethod(controller, "closeGame"); return true; - }; + };*/ - m_threadContext.logHandler = [](GBAThread* context, enum GBALogLevel level, const char* format, va_list args) { + /*m_threadContext.logHandler = [](mCoreThread* context, enum GBALogLevel level, const char* format, va_list args) { static const char* stubMessage = "Stub software interrupt: %02X"; static const char* savestateMessage = "State %i loaded"; static const char* savestateFailedMessage = "State %i failed to load";

@@ -192,10 +180,12 @@ if (level == GBA_LOG_STATUS) {

QMetaObject::invokeMethod(controller, "statusPosted", Q_ARG(const QString&, message)); } QMetaObject::invokeMethod(controller, "postLog", Q_ARG(int, level), Q_ARG(const QString&, message)); - }; + };*/ + + m_threadContext.userData = this; connect(&m_rewindTimer, &QTimer::timeout, [this]() { - GBARewind(&m_threadContext, 1); + // TODO: Put rewind back emit frameAvailable(m_drawContext); emit rewound(&m_threadContext); });

@@ -204,7 +194,7 @@

m_audioThread->setObjectName("Audio Thread"); m_audioThread->start(QThread::TimeCriticalPriority); m_audioProcessor->moveToThread(m_audioThread); - connect(this, SIGNAL(gamePaused(GBAThread*)), m_audioProcessor, SLOT(pause())); + connect(this, SIGNAL(gamePaused(mCoreThread*)), m_audioProcessor, SLOT(pause())); connect(this, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(pollEvents())); connect(this, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(updateAutofire())); }

@@ -216,8 +206,6 @@ disconnect();

clearMultiplayerController(); closeGame(); GBACheatDeviceDestroy(&m_cheatDevice); - mDirectorySetDeinit(&m_threadContext.dirs); - delete m_renderer; delete[] m_drawContext; delete[] m_frontBuffer; delete m_backupLoadState;

@@ -241,40 +229,27 @@ m_multiplayer = nullptr;

} void GameController::setOverride(const GBACartridgeOverride& override) { - m_threadContext.override = override; - m_threadContext.hasOverride = true; + // TODO: Put back overrides } -void GameController::setOptions(const mCoreOptions* opts) { - setFrameskip(opts->frameskip); - setAudioSync(opts->audioSync); - setVideoSync(opts->videoSync); - setSkipBIOS(opts->skipBios); - setUseBIOS(opts->useBios); - setRewind(opts->rewindEnable, opts->rewindBufferCapacity, opts->rewindBufferInterval); - setVolume(opts->volume); - setMute(opts->mute); - +void GameController::setConfig(const mCoreConfig* config) { + if (!m_gameOpen) { + return; + } threadInterrupt(); - mDirectorySetMapOptions(&m_threadContext.dirs, opts); - // TODO: Put back idle optimization + mCoreLoadForeignConfig(m_threadContext.core, config); threadContinue(); } #ifdef USE_GDB_STUB Debugger* GameController::debugger() { - return m_threadContext.debugger; + // TODO: Put back debugger + return nullptr; } void GameController::setDebugger(Debugger* debugger) { threadInterrupt(); - if (m_threadContext.debugger && GBAThreadIsActive(&m_threadContext)) { - GBADetachDebugger(m_threadContext.gba); - } - m_threadContext.debugger = debugger; - if (m_threadContext.debugger && GBAThreadIsActive(&m_threadContext)) { - GBAAttachDebugger(m_threadContext.gba, m_threadContext.debugger); - } + // TODO: Put back debugger threadContinue(); } #endif

@@ -315,28 +290,36 @@ m_threadContext.sync.videoFrameWait = m_videoSync;

m_threadContext.sync.audioWait = m_audioSync; } - m_threadContext.bootBios = biosOnly; - if (biosOnly) { - m_threadContext.fname = nullptr; - } else { - m_threadContext.fname = strdup(m_fname.toUtf8().constData()); - GBAThreadLoadROM(&m_threadContext, m_threadContext.fname); + m_threadContext.core = GBACoreCreate(); + m_threadContext.core->init(m_threadContext.core); + m_threadContext.core->setVideoBuffer(m_threadContext.core, m_drawContext, VIDEO_HORIZONTAL_PIXELS); + + if (!biosOnly) { + mCoreLoadFile(m_threadContext.core, m_fname.toUtf8().constData()); } if (!m_bios.isNull() && m_useBios) { - m_threadContext.bios = VFileDevice::open(m_bios, O_RDONLY); - } else { - m_threadContext.bios = nullptr; + VFile* bios = VFileDevice::open(m_bios, O_RDONLY); + if (bios) { + // TODO: Lifetime issues? + m_threadContext.core->loadBIOS(m_threadContext.core, bios, 0); + } } if (!m_patch.isNull()) { - m_threadContext.patch = VFileDevice::open(m_patch, O_RDONLY); + VFile* patch = VFileDevice::open(m_patch, O_RDONLY); + if (patch) { + m_threadContext.core->loadPatch(m_threadContext.core, patch); + } + patch->close(patch); } m_inputController->recalibrateAxes(); memset(m_drawContext, 0xF8, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * 4); - if (!GBAThreadStart(&m_threadContext)) { + m_threadContext.core->setAVStream(m_threadContext.core, m_stream); + + if (!mCoreThreadStart(&m_threadContext)) { m_gameOpen = false; emit gameFailed(); } else if (m_audioProcessor) {

@@ -360,7 +343,7 @@ if (!m_gameOpen) {

return; } threadInterrupt(); - GBAYankROM(m_threadContext.gba); + GBAYankROM(static_cast<GBA*>(m_threadContext.core->board)); threadContinue(); }

@@ -371,8 +354,7 @@ }

m_fname = path; threadInterrupt(); - m_threadContext.fname = strdup(m_fname.toLocal8Bit().constData()); - GBAThreadReplaceROM(&m_threadContext, m_threadContext.fname); + mCoreLoadFile(m_threadContext.core, m_fname.toLocal8Bit().constData()); threadContinue(); }

@@ -396,7 +378,7 @@ postLog(GBA_LOG_ERROR, tr("Failed to open snapshot file for reading: %1").arg(path));

return; } threadInterrupt(); - GBASavedataImportSharkPort(m_threadContext.gba, vf, false); + GBASavedataImportSharkPort(static_cast<GBA*>(m_threadContext.core->board), vf, false); threadContinue(); vf->close(vf); }

@@ -411,7 +393,7 @@ postLog(GBA_LOG_ERROR, tr("Failed to open snapshot file for writing: %1").arg(path));

return; } threadInterrupt(); - GBASavedataExportSharkPort(m_threadContext.gba, vf); + GBASavedataExportSharkPort(static_cast<GBA*>(m_threadContext.core->board), vf); threadContinue(); vf->close(vf); }

@@ -423,18 +405,14 @@ }

m_gameOpen = false; m_rewindTimer.stop(); - if (GBAThreadIsPaused(&m_threadContext)) { - GBAThreadUnpause(&m_threadContext); + if (mCoreThreadIsPaused(&m_threadContext)) { + mCoreThreadUnpause(&m_threadContext); } m_audioProcessor->pause(); - GBAThreadEnd(&m_threadContext); - GBAThreadJoin(&m_threadContext); + mCoreThreadEnd(&m_threadContext); + mCoreThreadJoin(&m_threadContext); // Make sure the event queue clears out before the thread is reused QCoreApplication::processEvents(); - if (m_threadContext.fname) { - free(const_cast<char*>(m_threadContext.fname)); - m_threadContext.fname = nullptr; - } m_patch = QString();

@@ -444,6 +422,8 @@ GBACheatSetDeinit(set);

delete set; } GBACheatSetsClear(&m_cheatDevice.cheats); + + m_threadContext.core->deinit(m_threadContext.core); m_gameOpen = false; emit gameStopped(&m_threadContext);

@@ -459,17 +439,17 @@ bool GameController::isPaused() {

if (!m_gameOpen) { return false; } - return GBAThreadIsPaused(&m_threadContext); + return mCoreThreadIsPaused(&m_threadContext); } void GameController::setPaused(bool paused) { - if (!isLoaded() || m_rewindTimer.isActive() || paused == GBAThreadIsPaused(&m_threadContext)) { + if (!isLoaded() || m_rewindTimer.isActive() || paused == mCoreThreadIsPaused(&m_threadContext)) { return; } if (paused) { m_pauseAfterFrame.testAndSetRelaxed(false, true); } else { - GBAThreadUnpause(&m_threadContext); + mCoreThreadUnpause(&m_threadContext); startAudio(); emit gameUnpaused(&m_threadContext); }

@@ -481,7 +461,7 @@ return;

} bool wasPaused = isPaused(); setPaused(false); - GBAThreadReset(&m_threadContext); + mCoreThreadReset(&m_threadContext); if (wasPaused) { setPaused(true); }

@@ -489,13 +469,13 @@ }

void GameController::threadInterrupt() { if (m_gameOpen) { - GBAThreadInterrupt(&m_threadContext); + mCoreThreadInterrupt(&m_threadContext); } } void GameController::threadContinue() { if (m_gameOpen) { - GBAThreadContinue(&m_threadContext); + mCoreThreadContinue(&m_threadContext); } }

@@ -511,25 +491,19 @@

void GameController::setRewind(bool enable, int capacity, int interval) { if (m_gameOpen) { threadInterrupt(); - GBARewindSettingsChanged(&m_threadContext, enable ? capacity : 0, enable ? interval : 0); + // TODO: Put back rewind threadContinue(); } else { - if (enable) { - m_threadContext.rewindBufferInterval = interval; - m_threadContext.rewindBufferCapacity = capacity; - } else { - m_threadContext.rewindBufferInterval = 0; - m_threadContext.rewindBufferCapacity = 0; - } + // TODO: Put back rewind } } void GameController::rewind(int states) { threadInterrupt(); if (!states) { - GBARewindAll(&m_threadContext); + // TODO: Put back rewind } else { - GBARewind(&m_threadContext, states); + // TODO: Put back rewind } threadContinue(); emit frameAvailable(m_drawContext);

@@ -544,8 +518,8 @@ if (m_multiplayer && m_multiplayer->attached() > 1) {

return; } m_wasPaused = isPaused(); - if (!GBAThreadIsPaused(&m_threadContext)) { - GBAThreadPause(&m_threadContext); + if (!mCoreThreadIsPaused(&m_threadContext)) { + mCoreThreadPause(&m_threadContext); } m_rewindTimer.start(); }

@@ -631,6 +605,7 @@ void GameController::setAudioChannelEnabled(int channel, bool enable) {

if (channel > 5 || channel < 0) { return; } + GBA* gba = static_cast<GBA*>(m_threadContext.core->board); m_audioChannels[channel] = enable; if (isLoaded()) { switch (channel) {

@@ -638,13 +613,13 @@ case 0:

case 1: case 2: case 3: - m_threadContext.gba->audio.psg.forceDisableCh[channel] = !enable; + gba->audio.psg.forceDisableCh[channel] = !enable; break; case 4: - m_threadContext.gba->audio.forceDisableChA = !enable; + gba->audio.forceDisableChA = !enable; break; case 5: - m_threadContext.gba->audio.forceDisableChB = !enable; + gba->audio.forceDisableChB = !enable; break; } }

@@ -667,6 +642,7 @@ void GameController::setVideoLayerEnabled(int layer, bool enable) {

if (layer > 4 || layer < 0) { return; } + GBA* gba = static_cast<GBA*>(m_threadContext.core->board); m_videoLayers[layer] = enable; if (isLoaded()) { switch (layer) {

@@ -674,10 +650,10 @@ case 0:

case 1: case 2: case 3: - m_threadContext.gba->video.renderer->disableBG[layer] = !enable; + gba->video.renderer->disableBG[layer] = !enable; break; case 4: - m_threadContext.gba->video.renderer->disableOBJ = !enable; + gba->video.renderer->disableOBJ = !enable; break; } }

@@ -686,19 +662,13 @@

void GameController::setFPSTarget(float fps) { threadInterrupt(); m_fpsTarget = fps; - m_threadContext.fpsTarget = fps; + // TODO: Put back fpsTarget if (m_turbo && m_turboSpeed > 0) { - m_threadContext.fpsTarget *= m_turboSpeed; + // TODO: Put back fpsTarget } if (m_audioProcessor) { redoSamples(m_audioProcessor->getBufferSamples()); } - threadContinue(); -} - -void GameController::setSkipBIOS(bool set) { - threadInterrupt(); - m_threadContext.skipBios = set; threadContinue(); }

@@ -714,7 +684,7 @@ }

} void GameController::loadState(int slot) { - if (!m_threadContext.fname) { + if (m_fname.isEmpty()) { // We're in the BIOS return; }

@@ -722,13 +692,13 @@ if (slot > 0 && slot != m_stateSlot) {

m_stateSlot = slot; m_backupSaveState.clear(); } - GBARunOnThread(&m_threadContext, [](GBAThread* context) { + mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); if (!controller->m_backupLoadState) { - controller->m_backupLoadState = new GBASerializedState; + controller->m_backupLoadState = VFileMemChunk(nullptr, 0); } - GBASerialize(context->gba, controller->m_backupLoadState); - if (GBALoadState(context, context->dirs.state, controller->m_stateSlot, controller->m_loadStateFlags)) { + context->core->saveState(context->core, controller->m_backupLoadState, controller->m_saveStateFlags); + if (mCoreLoadState(context->core, controller->m_stateSlot, controller->m_loadStateFlags)) { controller->frameAvailable(controller->m_drawContext); controller->stateLoaded(context); }

@@ -736,22 +706,22 @@ });

} void GameController::saveState(int slot) { - if (!m_threadContext.fname) { + if (m_fname.isEmpty()) { // We're in the BIOS return; } if (slot > 0) { m_stateSlot = slot; } - GBARunOnThread(&m_threadContext, [](GBAThread* context) { + mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); - VFile* vf = GBAGetState(context->gba, context->dirs.state, controller->m_stateSlot, false); + VFile* vf = mCoreGetState(context->core, controller->m_stateSlot, false); if (vf) { controller->m_backupSaveState.resize(vf->size(vf)); vf->read(vf, controller->m_backupSaveState.data(), controller->m_backupSaveState.size()); vf->close(vf); } - GBASaveState(context, context->dirs.state, controller->m_stateSlot, controller->m_saveStateFlags); + mCoreSaveState(context->core, controller->m_stateSlot, controller->m_saveStateFlags); }); }

@@ -760,14 +730,15 @@ if (!m_backupLoadState) {

return; } - GBARunOnThread(&m_threadContext, [](GBAThread* context) { + mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); - if (GBADeserialize(context->gba, controller->m_backupLoadState)) { - GBALog(context->gba, GBA_LOG_STATUS, "Undid state load"); + controller->m_backupLoadState->seek(controller->m_backupLoadState, 0, SEEK_SET); + if (context->core->loadState(context->core, controller->m_backupLoadState, controller->m_loadStateFlags)) { + mLOG(STATUS, INFO, "Undid state load"); controller->frameAvailable(controller->m_drawContext); controller->stateLoaded(context); } - delete controller->m_backupLoadState; + controller->m_backupLoadState->close(controller->m_backupLoadState); controller->m_backupLoadState = nullptr; }); }

@@ -777,60 +748,21 @@ if (m_backupSaveState.isEmpty()) {

return; } - GBARunOnThread(&m_threadContext, [](GBAThread* context) { + mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) { GameController* controller = static_cast<GameController*>(context->userData); - VFile* vf = GBAGetState(context->gba, context->dirs.state, controller->m_stateSlot, true); + VFile* vf = mCoreGetState(context->core, controller->m_stateSlot, true); if (vf) { vf->write(vf, controller->m_backupSaveState.constData(), controller->m_backupSaveState.size()); vf->close(vf); - GBALog(context->gba, GBA_LOG_STATUS, "Undid state save"); + mLOG(STATUS, INFO, "Undid state save"); } controller->m_backupSaveState.clear(); }); } -void GameController::setVideoSync(bool set) { - m_videoSync = set; - if (!m_turbo) { - threadInterrupt(); - m_threadContext.sync.videoFrameWait = set; - threadContinue(); - } -} - -void GameController::setAudioSync(bool set) { - m_audioSync = set; - if (!m_turbo) { - threadInterrupt(); - m_threadContext.sync.audioWait = set; - threadContinue(); - } -} - -void GameController::setFrameskip(int skip) { - threadInterrupt(); - m_threadContext.frameskip = skip; - if (isLoaded()) { - m_threadContext.gba->video.frameskip = skip; - } - threadContinue(); -} - -void GameController::setVolume(int volume) { - threadInterrupt(); - m_threadContext.volume = volume; - if (isLoaded()) { - m_threadContext.gba->audio.masterVolume = volume; - } - threadContinue(); -} - void GameController::setMute(bool mute) { threadInterrupt(); - m_threadContext.mute = mute; - if (isLoaded()) { - m_threadContext.gba->audio.masterVolume = mute ? 0 : m_threadContext.volume; - } + // TODO: Put back mute threadContinue(); }

@@ -855,15 +787,15 @@

void GameController::enableTurbo() { threadInterrupt(); if (!m_turbo) { - m_threadContext.fpsTarget = m_fpsTarget; + // TODO: Put back fpsTarget m_threadContext.sync.audioWait = m_audioSync; m_threadContext.sync.videoFrameWait = m_videoSync; } else if (m_turboSpeed <= 0) { - m_threadContext.fpsTarget = m_fpsTarget; + // TODO: Put back fpsTarget m_threadContext.sync.audioWait = false; m_threadContext.sync.videoFrameWait = false; } else { - m_threadContext.fpsTarget = m_fpsTarget * m_turboSpeed; + // TODO: Put back fpsTarget m_threadContext.sync.audioWait = true; m_threadContext.sync.videoFrameWait = false; }

@@ -875,25 +807,27 @@ }

void GameController::setAVStream(mAVStream* stream) { threadInterrupt(); - m_threadContext.stream = stream; + m_stream = stream; if (isLoaded()) { - m_threadContext.gba->stream = stream; + m_threadContext.core->setAVStream(m_threadContext.core, stream); } threadContinue(); } void GameController::clearAVStream() { threadInterrupt(); - m_threadContext.stream = nullptr; + m_stream = nullptr; if (isLoaded()) { - m_threadContext.gba->stream = nullptr; + m_threadContext.core->setAVStream(m_threadContext.core, nullptr); } threadContinue(); } #ifdef USE_PNG void GameController::screenshot() { - GBARunOnThread(&m_threadContext, GBAThreadTakeScreenshot); + mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) { + mCoreTakeScreenshot(context->core); + }); } #endif

@@ -914,7 +848,7 @@ if (sampleRate) {

m_audioProcessor->requestSampleRate(sampleRate); } m_audioProcessor->moveToThread(m_audioThread); - connect(this, SIGNAL(gamePaused(GBAThread*)), m_audioProcessor, SLOT(pause())); + connect(this, SIGNAL(gamePaused(mCoreThread*)), m_audioProcessor, SLOT(pause())); if (isLoaded()) { m_audioProcessor->setInput(&m_threadContext); startAudio();

@@ -969,13 +903,15 @@ void GameController::updateKeys() {

int activeKeys = m_activeKeys; activeKeys |= m_activeButtons; activeKeys &= ~m_inactiveKeys; - m_threadContext.activeKeys = activeKeys; + if (isLoaded()) { + m_threadContext.core->setKeys(m_threadContext.core, activeKeys); + } } void GameController::redoSamples(int samples) { - m_threadContext.audioBuffers = samples; - if (m_threadContext.gba) { - GBAAudioResizeBuffer(&m_threadContext.gba->audio, m_threadContext.audioBuffers); + // TODO: Put back audio buffers + if (m_threadContext.core) { + GBAAudioResizeBuffer(&static_cast<GBA*>(m_threadContext.core->board)->audio, samples); } QMetaObject::invokeMethod(m_audioProcessor, "inputParametersChanged"); }
M src/platform/qt/GameController.hsrc/platform/qt/GameController.h

@@ -16,18 +16,20 @@

#include <memory> extern "C" { +#include "core/thread.h" #include "gba/cheats.h" +#include "gba/context/overrides.h" #include "gba/hardware.h" -#include "gba/supervisor/thread.h" +#include "gba/input.h" #ifdef BUILD_SDL #include "sdl-events.h" #endif } struct GBAAudio; -struct mCoreOptions; -struct GBAVideoSoftwareRenderer; +struct mCoreConfig; struct Configuration; +struct Debugger; class QThread;

@@ -48,29 +50,28 @@ GameController(QObject* parent = nullptr);

~GameController(); const uint32_t* drawContext() const { return m_drawContext; } - GBAThread* thread() { return &m_threadContext; } + mCoreThread* thread() { return &m_threadContext; } GBACheatDevice* cheatDevice() { return &m_cheatDevice; } void threadInterrupt(); void threadContinue(); bool isPaused(); - bool isLoaded() { return m_gameOpen && GBAThreadIsActive(&m_threadContext); } + bool isLoaded() { return m_gameOpen && mCoreThreadIsActive(&m_threadContext); } bool audioSync() const { return m_audioSync; } bool videoSync() const { return m_videoSync; } void setInputController(InputController* controller) { m_inputController = controller; } - void setOverrides(Configuration* overrides) { m_threadContext.overrides = overrides; } void setMultiplayerController(MultiplayerController* controller); MultiplayerController* multiplayerController() { return m_multiplayer; } void clearMultiplayerController(); void setOverride(const GBACartridgeOverride& override); - void clearOverride() { m_threadContext.hasOverride = false; } + void clearOverride() { /* TODO: Put back overrides */ } - void setOptions(const mCoreOptions*); + void setConfig(const mCoreConfig*); int stateSlot() const { return m_stateSlot; }

@@ -81,14 +82,14 @@ #endif

signals: void frameAvailable(const uint32_t*); - void gameStarted(GBAThread*); - void gameStopped(GBAThread*); - void gamePaused(GBAThread*); - void gameUnpaused(GBAThread*); + void gameStarted(mCoreThread*); + void gameStopped(mCoreThread*); + void gamePaused(mCoreThread*); + void gameUnpaused(mCoreThread*); void gameCrashed(const QString& errorMessage); void gameFailed(); - void stateLoaded(GBAThread*); - void rewound(GBAThread*); + void stateLoaded(mCoreThread*); + void rewound(mCoreThread*); void unimplementedBiosCall(int); void luminanceValueChanged(int);

@@ -101,7 +102,6 @@ void loadGame(const QString& path);

void loadBIOS(const QString& path); void yankPak(); void replaceGame(const QString& path); - void setSkipBIOS(bool); void setUseBIOS(bool); void loadPatch(const QString& path); void importSharkport(const QString& path);

@@ -129,10 +129,6 @@ void loadState(int slot = 0);

void saveState(int slot = 0); void loadBackupState(); void saveBackupState(); - void setVideoSync(bool); - void setAudioSync(bool); - void setFrameskip(int); - void setVolume(int); void setMute(bool); void setTurbo(bool, bool forced = true); void setTurboSpeed(float ratio = -1);

@@ -174,8 +170,7 @@ void enableTurbo();

uint32_t* m_drawContext; uint32_t* m_frontBuffer; - GBAThread m_threadContext; - GBAVideoSoftwareRenderer* m_renderer; + mCoreThread m_threadContext; GBACheatDevice m_cheatDevice; int m_activeKeys; int m_activeButtons;

@@ -210,13 +205,15 @@ bool m_autofire[GBA_KEY_MAX];

int m_autofireStatus[GBA_KEY_MAX]; int m_stateSlot; - GBASerializedState* m_backupLoadState; + struct VFile* m_backupLoadState; QByteArray m_backupSaveState; int m_saveStateFlags; int m_loadStateFlags; InputController* m_inputController; MultiplayerController* m_multiplayer; + + mAVStream* m_stream; struct GameControllerLux : GBALuminanceSource { GameController* p;

@@ -225,7 +222,7 @@ } m_lux;

uint8_t m_luxValue; int m_luxLevel; - GBARTCGenericSource m_rtc; + mRTCGenericSource m_rtc; }; }
M src/platform/qt/IOViewer.cppsrc/platform/qt/IOViewer.cpp

@@ -1073,7 +1073,7 @@ m_value = 0;

uint16_t value = 0; m_controller->threadInterrupt(); if (m_controller->isLoaded()) { - value = GBAView16(m_controller->thread()->cpu, BASE_IO | m_register); + value = GBAView16(static_cast<ARMCore*>(m_controller->thread()->core->cpu), BASE_IO | m_register); } m_controller->threadContinue();

@@ -1096,7 +1096,7 @@

void IOViewer::writeback() { m_controller->threadInterrupt(); if (m_controller->isLoaded()) { - GBAIOWrite(m_controller->thread()->gba, m_register, m_value); + GBAIOWrite(static_cast<GBA*>(m_controller->thread()->core->board), m_register, m_value); } m_controller->threadContinue(); updateRegister();
M src/platform/qt/LoadSaveState.cppsrc/platform/qt/LoadSaveState.cpp

@@ -169,8 +169,8 @@ return false;

} void LoadSaveState::loadState(int slot) { - GBAThread* thread = m_controller->thread(); - VFile* vf = GBAGetState(thread->gba, thread->dirs.state, slot, false); + mCoreThread* thread = m_controller->thread(); + VFile* vf = mCoreGetState(thread->core, slot, 0); if (!vf) { m_slots[slot - 1]->setText(tr("Empty")); return;
M src/platform/qt/MemoryModel.cppsrc/platform/qt/MemoryModel.cpp

@@ -87,7 +87,7 @@ setRegion(0, 0x10000000, tr("All"));

} void MemoryModel::setController(GameController* controller) { - m_cpu = controller->thread()->cpu; + m_cpu = static_cast<ARMCore*>(controller->thread()->core->cpu); } void MemoryModel::setRegion(uint32_t base, uint32_t size, const QString& name) {
M src/platform/qt/MemoryView.cppsrc/platform/qt/MemoryView.cpp

@@ -9,6 +9,7 @@

#include "GameController.h" extern "C" { +#include "core/core.h" #include "gba/memory.h" }

@@ -31,12 +32,12 @@ connect(m_ui.setAddress, SIGNAL(valueChanged(const QString&)), m_ui.hexfield, SLOT(jumpToAddress(const QString&)));

connect(m_ui.hexfield, SIGNAL(selectionChanged(uint32_t, uint32_t)), this, SLOT(updateSelection(uint32_t, uint32_t))); - connect(controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(close())); + connect(controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close())); connect(controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(update())); - connect(controller, SIGNAL(gamePaused(GBAThread*)), this, SLOT(update())); - connect(controller, SIGNAL(stateLoaded(GBAThread*)), this, SLOT(update())); - connect(controller, SIGNAL(rewound(GBAThread*)), this, SLOT(update())); + connect(controller, SIGNAL(gamePaused(mCoreThread*)), this, SLOT(update())); + connect(controller, SIGNAL(stateLoaded(mCoreThread*)), this, SLOT(update())); + connect(controller, SIGNAL(rewound(mCoreThread*)), this, SLOT(update())); } void MemoryView::setIndex(int index) {

@@ -83,7 +84,7 @@ }

if (!m_controller->isLoaded()) { return; } - ARMCore* cpu = m_controller->thread()->cpu; + ARMCore* cpu = static_cast<ARMCore*>(m_controller->thread()->core->cpu); union { uint32_t u32; int32_t i32;
M src/platform/qt/MultiplayerController.cppsrc/platform/qt/MultiplayerController.cpp

@@ -29,13 +29,13 @@ GBASIOLockstepAttachNode(&m_lockstep, node);

MutexUnlock(&m_lockstep.mutex); controller->threadInterrupt(); - GBAThread* thread = controller->thread(); - if (controller->isLoaded()) { + mCoreThread* thread = controller->thread(); + /*if (controller->isLoaded()) { GBASIOSetDriver(&thread->gba->sio, &node->d, SIO_MULTI); GBASIOSetDriver(&thread->gba->sio, &node->d, SIO_NORMAL_32); } thread->sioDrivers.multiplayer = &node->d; - thread->sioDrivers.normal = &node->d; + thread->sioDrivers.normal = &node->d;*/ controller->threadContinue(); emit gameAttached(); return true;

@@ -44,8 +44,8 @@

void MultiplayerController::detachGame(GameController* controller) { controller->threadInterrupt(); MutexLock(&m_lockstep.mutex); - GBAThread* thread = nullptr; - for (int i = 0; i < m_lockstep.attached; ++i) { + mCoreThread* thread = nullptr; + /*for (int i = 0; i < m_lockstep.attached; ++i) { thread = controller->thread(); if (thread->sioDrivers.multiplayer == &m_lockstep.players[i]->d) { break;

@@ -62,7 +62,7 @@ thread->sioDrivers.multiplayer = nullptr;

thread->sioDrivers.normal = nullptr; GBASIOLockstepDetachNode(&m_lockstep, node); delete node; - } + }*/ MutexUnlock(&m_lockstep.mutex); controller->threadContinue(); emit gameDetached();

@@ -72,11 +72,11 @@ int MultiplayerController::playerId(GameController* controller) {

MutexLock(&m_lockstep.mutex); int id = -1; for (int i = 0; i < m_lockstep.attached; ++i) { - GBAThread* thread = controller->thread(); - if (thread->sioDrivers.multiplayer == &m_lockstep.players[i]->d) { + mCoreThread* thread = controller->thread(); + /*if (thread->sioDrivers.multiplayer == &m_lockstep.players[i]->d) { id = i; break; - } + }*/ } MutexUnlock(&m_lockstep.mutex); return id;
M src/platform/qt/OverrideView.cppsrc/platform/qt/OverrideView.cpp

@@ -21,8 +21,8 @@ , m_config(config)

{ m_ui.setupUi(this); - connect(controller, SIGNAL(gameStarted(GBAThread*)), this, SLOT(gameStarted(GBAThread*))); - connect(controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(gameStopped())); + connect(controller, SIGNAL(gameStarted(mCoreThread*)), this, SLOT(gameStarted(mCoreThread*))); + connect(controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(gameStopped())); connect(m_ui.hwAutodetect, &QAbstractButton::toggled, [this] (bool enabled) { m_ui.hwRTC->setEnabled(!enabled);

@@ -99,12 +99,13 @@ m_controller->clearOverride();

} } -void OverrideView::gameStarted(GBAThread* thread) { - if (!thread->gba) { +void OverrideView::gameStarted(mCoreThread* thread) { + if (!thread->core) { gameStopped(); return; } - m_ui.savetype->setCurrentIndex(thread->gba->memory.savedata.type + 1); + GBA* gba = static_cast<GBA*>(thread->core->board); + m_ui.savetype->setCurrentIndex(gba->memory.savedata.type + 1); m_ui.savetype->setEnabled(false); m_ui.hwAutodetect->setEnabled(false);

@@ -114,23 +115,23 @@ m_ui.hwLight->setEnabled(false);

m_ui.hwTilt->setEnabled(false); m_ui.hwRumble->setEnabled(false); - m_ui.hwRTC->setChecked(thread->gba->memory.hw.devices & HW_RTC); - m_ui.hwGyro->setChecked(thread->gba->memory.hw.devices & HW_GYRO); - m_ui.hwLight->setChecked(thread->gba->memory.hw.devices & HW_LIGHT_SENSOR); - m_ui.hwTilt->setChecked(thread->gba->memory.hw.devices & HW_TILT); - m_ui.hwRumble->setChecked(thread->gba->memory.hw.devices & HW_RUMBLE); - m_ui.hwGBPlayer->setChecked(thread->gba->memory.hw.devices & HW_GB_PLAYER_DETECTION); + m_ui.hwRTC->setChecked(gba->memory.hw.devices & HW_RTC); + m_ui.hwGyro->setChecked(gba->memory.hw.devices & HW_GYRO); + m_ui.hwLight->setChecked(gba->memory.hw.devices & HW_LIGHT_SENSOR); + m_ui.hwTilt->setChecked(gba->memory.hw.devices & HW_TILT); + m_ui.hwRumble->setChecked(gba->memory.hw.devices & HW_RUMBLE); + m_ui.hwGBPlayer->setChecked(gba->memory.hw.devices & HW_GB_PLAYER_DETECTION); - if (thread->gba->idleLoop != IDLE_LOOP_NONE) { - m_ui.idleLoop->setText(QString::number(thread->gba->idleLoop, 16)); + if (gba->idleLoop != IDLE_LOOP_NONE) { + m_ui.idleLoop->setText(QString::number(gba->idleLoop, 16)); } else { m_ui.idleLoop->clear(); } - GBAGetGameCode(thread->gba, m_override.id); - m_override.hardware = thread->gba->memory.hw.devices; - m_override.savetype = thread->gba->memory.savedata.type; - m_override.idleLoop = thread->gba->idleLoop; + GBAGetGameCode(gba, m_override.id); + m_override.hardware = gba->memory.hw.devices; + m_override.savetype = gba->memory.savedata.type; + m_override.idleLoop = gba->idleLoop; m_ui.idleLoop->setEnabled(false);
M src/platform/qt/OverrideView.hsrc/platform/qt/OverrideView.h

@@ -14,7 +14,7 @@ extern "C" {

#include "gba/context/overrides.h" } -struct GBAThread; +struct mCoreThread; namespace QGBA {

@@ -32,7 +32,7 @@ void saveOverride();

private slots: void updateOverrides(); - void gameStarted(GBAThread*); + void gameStarted(mCoreThread*); void gameStopped(); private:
M src/platform/qt/PaletteView.cppsrc/platform/qt/PaletteView.cpp

@@ -46,14 +46,14 @@ connect(m_ui.objGrid, &Swatch::indexPressed, [this] (int index) { selectIndex(index + 256); });

connect(m_ui.exportBG, &QAbstractButton::clicked, [this] () { exportPalette(0, 256); }); connect(m_ui.exportOBJ, &QAbstractButton::clicked, [this] () { exportPalette(256, 256); }); - connect(controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(close())); + connect(controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close())); } void PaletteView::updatePalette() { - if (!m_controller->thread() || !m_controller->thread()->gba) { + if (!m_controller->thread() || !m_controller->thread()->core) { return; } - const uint16_t* palette = m_controller->thread()->gba->video.palette; + const uint16_t* palette = static_cast<GBA*>(m_controller->thread()->core->board)->video.palette; for (int i = 0; i < 256; ++i) { m_ui.bgGrid->setColor(i, palette[i]); m_ui.objGrid->setColor(i, palette[i + 256]);

@@ -63,7 +63,7 @@ m_ui.objGrid->update();

} void PaletteView::selectIndex(int index) { - uint16_t color = m_controller->thread()->gba->video.palette[index]; + uint16_t color = static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[index]; m_ui.selected->setColor(0, color); uint32_t r = GBA_R5(color); uint32_t g = GBA_G5(color);

@@ -100,9 +100,9 @@ return;

} QString filter = dialog->selectedNameFilter(); if (filter.contains("*.pal")) { - GBAExportPaletteRIFF(vf, length, &m_controller->thread()->gba->video.palette[start]); + GBAExportPaletteRIFF(vf, length, &static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[start]); } else if (filter.contains("*.act")) { - GBAExportPaletteACT(vf, length, &m_controller->thread()->gba->video.palette[start]); + GBAExportPaletteACT(vf, length, &static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[start]); } vf->close(vf); m_controller->threadContinue();
M src/platform/qt/ROMInfo.cppsrc/platform/qt/ROMInfo.cpp

@@ -26,7 +26,7 @@

const NoIntroDB* db = GBAApp::app()->gameDB(); controller->threadInterrupt(); - GBA* gba = controller->thread()->gba; + GBA* gba = static_cast<GBA*>(controller->thread()->core->board); char title[13] = {}; GBAGetGameCode(gba, title); m_ui.id->setText(QLatin1String(title));
M src/platform/qt/SensorView.cppsrc/platform/qt/SensorView.cpp

@@ -9,6 +9,11 @@ #include "GameController.h"

#include "GamepadAxisEvent.h" #include "InputController.h" +extern "C" { +#include "core/core.h" +#include "gba/gba.h" +} + using namespace QGBA; SensorView::SensorView(GameController* controller, InputController* input, QWidget* parent)

@@ -105,7 +110,7 @@

void SensorView::updateSensors() { m_controller->threadInterrupt(); if (m_rotation->sample && - (!m_controller->isLoaded() || !(m_controller->thread()->gba->memory.hw.devices & (HW_GYRO | HW_TILT)))) { + (!m_controller->isLoaded() || !(static_cast<GBA*>(m_controller->thread()->core->board)->memory.hw.devices & (HW_GYRO | HW_TILT)))) { m_rotation->sample(m_rotation); m_rotation->sample(m_rotation); m_rotation->sample(m_rotation);
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -79,7 +79,6 @@ setAcceptDrops(true);

setAttribute(Qt::WA_DeleteOnClose); m_controller = new GameController(this); m_controller->setInputController(&m_inputController); - m_controller->setOverrides(m_config->overrides()); updateTitle(); m_display = Display::create(this);

@@ -95,13 +94,13 @@ m_screenWidget->setPixmap(m_logo);

m_screenWidget->setLockAspectRatio(m_logo.width(), m_logo.height()); setCentralWidget(m_screenWidget); - connect(m_controller, SIGNAL(gameStarted(GBAThread*)), this, SLOT(gameStarted(GBAThread*))); - connect(m_controller, SIGNAL(gameStarted(GBAThread*)), &m_inputController, SLOT(suspendScreensaver())); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_display, SLOT(stopDrawing())); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(gameStopped())); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), &m_inputController, SLOT(resumeScreensaver())); - connect(m_controller, SIGNAL(stateLoaded(GBAThread*)), m_display, SLOT(forceDraw())); - connect(m_controller, SIGNAL(rewound(GBAThread*)), m_display, SLOT(forceDraw())); + connect(m_controller, SIGNAL(gameStarted(mCoreThread*)), this, SLOT(gameStarted(mCoreThread*))); + connect(m_controller, SIGNAL(gameStarted(mCoreThread*)), &m_inputController, SLOT(suspendScreensaver())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), m_display, SLOT(stopDrawing())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(gameStopped())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), &m_inputController, SLOT(resumeScreensaver())); + connect(m_controller, SIGNAL(stateLoaded(mCoreThread*)), m_display, SLOT(forceDraw())); + connect(m_controller, SIGNAL(rewound(mCoreThread*)), m_display, SLOT(forceDraw())); connect(m_controller, &GameController::gamePaused, [this]() { QImage currentImage(reinterpret_cast<const uchar*>(m_controller->drawContext()), VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL, QImage::Format_RGBX8888);

@@ -110,18 +109,18 @@ pixmap.convertFromImage(currentImage);

m_screenWidget->setPixmap(pixmap); m_screenWidget->setLockAspectRatio(3, 2); }); - connect(m_controller, SIGNAL(gamePaused(GBAThread*)), m_display, SLOT(pauseDrawing())); + connect(m_controller, SIGNAL(gamePaused(mCoreThread*)), m_display, SLOT(pauseDrawing())); #ifndef Q_OS_MAC - connect(m_controller, SIGNAL(gamePaused(GBAThread*)), menuBar(), SLOT(show())); + connect(m_controller, SIGNAL(gamePaused(mCoreThread*)), menuBar(), SLOT(show())); connect(m_controller, &GameController::gameUnpaused, [this]() { if(isFullScreen()) { menuBar()->hide(); } }); #endif - connect(m_controller, SIGNAL(gamePaused(GBAThread*)), &m_inputController, SLOT(resumeScreensaver())); - connect(m_controller, SIGNAL(gameUnpaused(GBAThread*)), m_display, SLOT(unpauseDrawing())); - connect(m_controller, SIGNAL(gameUnpaused(GBAThread*)), &m_inputController, SLOT(suspendScreensaver())); + connect(m_controller, SIGNAL(gamePaused(mCoreThread*)), &m_inputController, SLOT(resumeScreensaver())); + connect(m_controller, SIGNAL(gameUnpaused(mCoreThread*)), m_display, SLOT(unpauseDrawing())); + connect(m_controller, SIGNAL(gameUnpaused(mCoreThread*)), &m_inputController, SLOT(suspendScreensaver())); connect(m_controller, SIGNAL(postLog(int, const QString&)), &m_log, SLOT(postLog(int, const QString&))); connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(recordFrame())); connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), m_display, SLOT(framePosted(const uint32_t*)));

@@ -132,7 +131,7 @@ connect(m_controller, SIGNAL(statusPosted(const QString&)), m_display, SLOT(showMessage(const QString&)));

connect(&m_log, SIGNAL(levelsSet(int)), m_controller, SLOT(setLogLevel(int))); connect(&m_log, SIGNAL(levelsEnabled(int)), m_controller, SLOT(enableLogLevel(int))); connect(&m_log, SIGNAL(levelsDisabled(int)), m_controller, SLOT(disableLogLevel(int))); - connect(this, SIGNAL(startDrawing(GBAThread*)), m_display, SLOT(startDrawing(GBAThread*)), Qt::QueuedConnection); + connect(this, SIGNAL(startDrawing(mCoreThread*)), m_display, SLOT(startDrawing(mCoreThread*)), Qt::QueuedConnection); connect(this, SIGNAL(shutdown()), m_display, SLOT(stopDrawing())); connect(this, SIGNAL(shutdown()), m_controller, SLOT(closeGame())); connect(this, SIGNAL(shutdown()), m_logView, SLOT(hide()));

@@ -254,7 +253,7 @@ if (ok) {

m_controller->setLoadStateExtdata(flags); } - m_controller->setOptions(opts); + m_controller->setConfig(m_config->config()); m_display->lockAspectRatio(opts->lockAspectRatio); m_display->filter(opts->resampleVideo);

@@ -418,8 +417,8 @@ if (!m_videoView) {

m_videoView = new VideoView(); connect(m_videoView, SIGNAL(recordingStarted(mAVStream*)), m_controller, SLOT(setAVStream(mAVStream*))); connect(m_videoView, SIGNAL(recordingStopped()), m_controller, SLOT(clearAVStream()), Qt::DirectConnection); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_videoView, SLOT(stopRecording())); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_videoView, SLOT(close())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), m_videoView, SLOT(stopRecording())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), m_videoView, SLOT(close())); connect(this, SIGNAL(shutdown()), m_videoView, SLOT(close())); } m_videoView->show();

@@ -432,8 +431,8 @@ if (!m_gifView) {

m_gifView = new GIFView(); connect(m_gifView, SIGNAL(recordingStarted(mAVStream*)), m_controller, SLOT(setAVStream(mAVStream*))); connect(m_gifView, SIGNAL(recordingStopped()), m_controller, SLOT(clearAVStream()), Qt::DirectConnection); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_gifView, SLOT(stopRecording())); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_gifView, SLOT(close())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), m_gifView, SLOT(stopRecording())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), m_gifView, SLOT(close())); connect(this, SIGNAL(shutdown()), m_gifView, SLOT(close())); } m_gifView->show();

@@ -597,7 +596,7 @@ enterFullScreen();

} } -void Window::gameStarted(GBAThread* context) { +void Window::gameStarted(mCoreThread* context) { char title[13] = { '\0' }; MutexLock(&context->stateMutex); if (context->state < THREAD_EXITING) {

@@ -611,10 +610,10 @@ foreach (QAction* action, m_gameActions) {

action->setDisabled(false); } multiplayerChanged(); - if (context->fname) { + /*if (context->fname) { setWindowFilePath(context->fname); appendMRU(context->fname); - } + }*/ updateTitle(); attachWidget(m_display);

@@ -716,11 +715,11 @@ m_controller->threadInterrupt();

if (m_controller->isLoaded()) { const NoIntroDB* db = GBAApp::app()->gameDB(); NoIntroGame game; - if (db && NoIntroDBLookupGameByCRC(db, m_controller->thread()->gba->romCrc32, &game)) { + if (db && NoIntroDBLookupGameByCRC(db, static_cast<GBA*>(m_controller->thread()->core->board)->romCrc32, &game)) { title = QLatin1String(game.name); } else { char gameTitle[13] = { '\0' }; - GBAGetGameTitle(m_controller->thread()->gba, gameTitle); + GBAGetGameTitle(static_cast<GBA*>(m_controller->thread()->core->board), gameTitle); title = gameTitle; } }

@@ -749,7 +748,7 @@ }

bool wasPaused = m_controller->isPaused(); m_stateWindow = new LoadSaveState(m_controller); connect(this, SIGNAL(shutdown()), m_stateWindow, SLOT(close())); - connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_stateWindow, SLOT(close())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), m_stateWindow, SLOT(close())); connect(m_stateWindow, &LoadSaveState::closed, [this]() { detachWidget(m_stateWindow); m_stateWindow = nullptr;

@@ -979,14 +978,14 @@

ConfigOption* videoSync = m_config->addOption("videoSync"); videoSync->addBoolean(tr("Sync to &video"), emulationMenu); videoSync->connect([this](const QVariant& value) { - m_controller->setVideoSync(value.toBool()); + reloadConfig(); }, this); m_config->updateOption("videoSync"); ConfigOption* audioSync = m_config->addOption("audioSync"); audioSync->addBoolean(tr("Sync to &audio"), emulationMenu); audioSync->connect([this](const QVariant& value) { - m_controller->setAudioSync(value.toBool()); + reloadConfig(); }, this); m_config->updateOption("audioSync");

@@ -1061,7 +1060,7 @@

QMenu* skipMenu = avMenu->addMenu(tr("Frame&skip")); ConfigOption* skip = m_config->addOption("frameskip"); skip->connect([this](const QVariant& value) { - m_controller->setFrameskip(value.toInt()); + reloadConfig(); }, this); for (int i = 0; i <= 10; ++i) { skip->addValue(QString::number(i), i, skipMenu);

@@ -1209,12 +1208,12 @@ addControlledAction(toolsMenu, ioViewer, "ioViewer");

ConfigOption* skipBios = m_config->addOption("skipBios"); skipBios->connect([this](const QVariant& value) { - m_controller->setSkipBIOS(value.toBool()); + reloadConfig(); }, this); ConfigOption* useBios = m_config->addOption("useBios"); useBios->connect([this](const QVariant& value) { - m_controller->setUseBIOS(value.toBool()); + reloadConfig(); }, this); ConfigOption* buffers = m_config->addOption("audioBuffers");

@@ -1229,7 +1228,7 @@ }, this);

ConfigOption* volume = m_config->addOption("volume"); volume->connect([this](const QVariant& value) { - m_controller->setVolume(value.toInt()); + reloadConfig(); }, this); ConfigOption* rewindEnable = m_config->addOption("rewindEnable");
M src/platform/qt/Window.hsrc/platform/qt/Window.h

@@ -50,7 +50,7 @@

void resizeFrame(int width, int height); signals: - void startDrawing(GBAThread*); + void startDrawing(mCoreThread*); void shutdown(); void audioBufferSamplesChanged(int samples); void sampleRateChanged(unsigned samples);

@@ -111,7 +111,7 @@ virtual void dropEvent(QDropEvent*) override;

virtual void mouseDoubleClickEvent(QMouseEvent*) override; private slots: - void gameStarted(GBAThread*); + void gameStarted(mCoreThread*); void gameStopped(); void gameCrashed(const QString&); void gameFailed();
M src/platform/sdl/main.csrc/platform/sdl/main.c

@@ -196,7 +196,7 @@ if (!mCoreLoadFile(renderer->core, args->fname)) {

return 1; } mCoreAutoloadSave(renderer->core); - // TODO: Create debugger + // TODO: Put back debugger if (args->patch) { struct VFile* patch = VFileOpen(args->patch, O_RDONLY);