Qt: Add GameController::Interrupter

This commit is contained in:
Jeffrey Pfau 2016-10-26 17:35:18 -07:00
parent 4cb243f15c
commit 7d009ec43c
8 changed files with 55 additions and 52 deletions

View File

@ -125,10 +125,9 @@ void CheatsView::save() {
}
void CheatsView::addSet() {
m_controller->threadInterrupt();
GameController::Interrupter interrupter(m_controller);
mCheatSet* set = m_controller->cheatDevice()->createSet(m_controller->cheatDevice(), nullptr);
m_model.addSet(set);
m_controller->threadContinue();
}
void CheatsView::removeSet() {
@ -137,11 +136,10 @@ void CheatsView::removeSet() {
if (selection.count() < 1) {
return;
}
m_controller->threadInterrupt();
GameController::Interrupter interrupter(m_controller);
for (const QModelIndex& index : selection) {
m_model.removeAt(selection[0]);
}
m_controller->threadContinue();
}
void CheatsView::enterCheat(int codeType) {

View File

@ -38,19 +38,17 @@ void DebuggerController::detach() {
if (!isAttached()) {
return;
}
m_gameController->threadInterrupt();
GameController::Interrupter interrupter(m_gameController);
shutdownInternal();
m_gameController->setDebugger(nullptr);
m_gameController->threadContinue();
}
void DebuggerController::breakInto() {
if (!isAttached()) {
return;
}
m_gameController->threadInterrupt();
GameController::Interrupter interrupter(m_gameController);
mDebuggerEnter(m_debugger, DEBUGGER_ENTER_MANUAL, 0);
m_gameController->threadContinue();
}
void DebuggerController::shutdown() {
@ -58,9 +56,8 @@ void DebuggerController::shutdown() {
if (!isAttached()) {
return;
}
m_gameController->threadInterrupt();
GameController::Interrupter interrupter(m_gameController);
shutdownInternal();
m_gameController->threadContinue();
}
void DebuggerController::shutdownInternal() {

View File

@ -35,7 +35,7 @@ void GDBController::setBindAddress(uint32_t bindAddress) {
}
void GDBController::listen() {
m_gameController->threadInterrupt();
GameController::Interrupter interrupter(m_gameController);
if (!isAttached()) {
attach();
}
@ -45,7 +45,6 @@ void GDBController::listen() {
detach();
emit listenFailed();
}
m_gameController->threadContinue();
}
void GDBController::shutdownInternal() {

View File

@ -320,9 +320,8 @@ void GameController::clearMultiplayerController() {
void GameController::setOverride(Override* override) {
m_override = override;
if (isLoaded()) {
threadInterrupt();
Interrupter interrupter(this);
m_override->identify(m_threadContext.core);
threadContinue();
}
}
@ -334,10 +333,9 @@ void GameController::clearOverride() {
void GameController::setConfig(const mCoreConfig* config) {
m_config = config;
if (isLoaded()) {
threadInterrupt();
Interrupter interrupter(this);
mCoreLoadForeignConfig(m_threadContext.core, config);
m_audioProcessor->setInput(&m_threadContext);
threadContinue();
}
}
@ -350,13 +348,12 @@ mDebugger* GameController::debugger() {
}
void GameController::setDebugger(mDebugger* debugger) {
threadInterrupt();
Interrupter interrupter(this);
if (debugger) {
mDebuggerAttach(debugger, m_threadContext.core);
} else {
m_threadContext.core->detachDebugger(m_threadContext.core);
}
threadContinue();
}
#endif
@ -518,9 +515,8 @@ void GameController::yankPak() {
if (!m_gameOpen) {
return;
}
threadInterrupt();
Interrupter interrupter(this);
GBAYankROM(static_cast<GBA*>(m_threadContext.core->board));
threadContinue();
}
void GameController::replaceGame(const QString& path) {
@ -534,10 +530,9 @@ void GameController::replaceGame(const QString& path) {
return;
}
m_fname = info.canonicalFilePath();
threadInterrupt();
Interrupter interrupter(this);
mDirectorySetDetachBase(&m_threadContext.core->dirs);
mCoreLoadFile(m_threadContext.core, m_fname.toLocal8Bit().constData());
threadContinue();
}
void GameController::loadPatch(const QString& path) {
@ -675,12 +670,11 @@ void GameController::reset() {
}
bool wasPaused = isPaused();
setPaused(false);
threadInterrupt();
Interrupter interrupter(this);
mCoreThreadReset(&m_threadContext);
if (wasPaused) {
setPaused(true);
}
threadContinue();
}
void GameController::threadInterrupt() {
@ -703,7 +697,7 @@ void GameController::frameAdvance() {
void GameController::setRewind(bool enable, int capacity) {
if (m_gameOpen) {
threadInterrupt();
Interrupter interrupter(this);
if (m_threadContext.core->opts.rewindEnable && m_threadContext.core->opts.rewindBufferCapacity > 0) {
mCoreRewindContextDeinit(&m_threadContext.rewind);
}
@ -712,7 +706,6 @@ void GameController::setRewind(bool enable, int capacity) {
if (enable && capacity > 0) {
mCoreRewindContextInit(&m_threadContext.rewind, capacity);
}
threadContinue();
}
}
@ -915,7 +908,7 @@ void GameController::setVideoLayerEnabled(int layer, bool enable) {
}
void GameController::setFPSTarget(float fps) {
threadInterrupt();
Interrupter interrupter(this);
m_fpsTarget = fps;
m_threadContext.sync.fpsTarget = fps;
if (m_turbo && m_turboSpeed > 0) {
@ -924,7 +917,6 @@ void GameController::setFPSTarget(float fps) {
if (m_audioProcessor) {
redoSamples(m_audioProcessor->getBufferSamples());
}
threadContinue();
}
void GameController::setUseBIOS(bool use) {
@ -1037,7 +1029,7 @@ void GameController::setTurboSpeed(float ratio) {
}
void GameController::enableTurbo() {
threadInterrupt();
Interrupter interrupter(this);
bool shouldRedoSamples = false;
if (!m_turbo) {
shouldRedoSamples = m_threadContext.sync.fpsTarget != m_fpsTarget;
@ -1058,7 +1050,6 @@ void GameController::enableTurbo() {
if (m_audioProcessor && shouldRedoSamples) {
redoSamples(m_audioProcessor->getBufferSamples());
}
threadContinue();
}
void GameController::setSync(bool enable) {
@ -1074,21 +1065,19 @@ void GameController::setSync(bool enable) {
m_sync = enable;
}
void GameController::setAVStream(mAVStream* stream) {
threadInterrupt();
Interrupter interrupter(this);
m_stream = stream;
if (isLoaded()) {
m_threadContext.core->setAVStream(m_threadContext.core, stream);
}
threadContinue();
}
void GameController::clearAVStream() {
threadInterrupt();
Interrupter interrupter(this);
m_stream = nullptr;
if (isLoaded()) {
m_threadContext.core->setAVStream(m_threadContext.core, nullptr);
}
threadContinue();
}
#ifdef USE_PNG
@ -1185,21 +1174,18 @@ void GameController::redoSamples(int samples) {
}
void GameController::setLogLevel(int levels) {
threadInterrupt();
Interrupter interrupter(this);
m_logLevels = levels;
threadContinue();
}
void GameController::enableLogLevel(int levels) {
threadInterrupt();
Interrupter interrupter(this);
m_logLevels |= levels;
threadContinue();
}
void GameController::disableLogLevel(int levels) {
threadInterrupt();
Interrupter interrupter(this);
m_logLevels &= ~levels;
threadContinue();
}
void GameController::pollEvents() {
@ -1233,25 +1219,23 @@ std::shared_ptr<mTileCache> GameController::tileCache() {
switch (platform()) {
#ifdef M_CORE_GBA
case PLATFORM_GBA: {
threadInterrupt();
Interrupter interrupter(this);
GBA* gba = static_cast<GBA*>(m_threadContext.core->board);
m_tileCache = std::make_shared<mTileCache>();
GBAVideoTileCacheInit(m_tileCache.get());
GBAVideoTileCacheAssociate(m_tileCache.get(), &gba->video);
mTileCacheSetPalette(m_tileCache.get(), 0);
threadContinue();
break;
}
#endif
#ifdef M_CORE_GB
case PLATFORM_GB: {
threadInterrupt();
Interrupter interrupter(this);
GB* gb = static_cast<GB*>(m_threadContext.core->board);
m_tileCache = std::make_shared<mTileCache>();
GBVideoTileCacheInit(m_tileCache.get());
GBVideoTileCacheAssociate(m_tileCache.get(), &gb->video);
mTileCacheSetPalette(m_tileCache.get(), 0);
threadContinue();
break;
}
#endif
@ -1260,3 +1244,22 @@ std::shared_ptr<mTileCache> GameController::tileCache() {
}
return m_tileCache;
}
GameController::Interrupter::Interrupter(GameController* parent, bool fromThread)
: m_parent(parent)
, m_fromThread(fromThread)
{
if (!m_fromThread) {
m_parent->threadInterrupt();
} else {
mCoreThreadInterruptFromThread(m_parent->thread());
}
}
GameController::Interrupter::~Interrupter() {
if (!m_fromThread) {
m_parent->threadContinue();
} else {
mCoreThreadContinue(m_parent->thread());
}
}

View File

@ -49,6 +49,16 @@ public:
static const bool VIDEO_SYNC = false;
static const bool AUDIO_SYNC = true;
class Interrupter {
public:
Interrupter(GameController*, bool fromThread = false);
~Interrupter();
private:
GameController* m_parent;
bool m_fromThread;
};
GameController(QObject* parent = nullptr);
~GameController();

View File

@ -134,18 +134,17 @@ void PaletteView::exportPalette(int start, int length) {
if (start + length > 512) {
length = 512 - start;
}
m_controller->threadInterrupt();
GameController::Interrupter interrupter(m_controller);
QFileDialog* dialog = GBAApp::app()->getSaveFileDialog(this, tr("Export palette"),
tr("Windows PAL (*.pal);;Adobe Color Table (*.act)"));
if (!dialog->exec()) {
m_controller->threadContinue();
return;
}
QString filename = dialog->selectedFiles()[0];
VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC);
if (!vf) {
LOG(QT, ERROR) << tr("Failed to open output palette file: %1").arg(filename);
m_controller->threadContinue();
return;
}
QString filter = dialog->selectedNameFilter();
@ -155,5 +154,4 @@ void PaletteView::exportPalette(int start, int length) {
exportPaletteACT(vf, length, &static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[start]);
}
vf->close(vf);
m_controller->threadContinue();
}

View File

@ -33,7 +33,7 @@ ROMInfo::ROMInfo(GameController* controller, QWidget* parent)
const NoIntroDB* db = GBAApp::app()->gameDB();
uint32_t crc32 = 0;
controller->threadInterrupt();
GameController::Interrupter interrupter(controller);
mCore* core = controller->thread()->core;
char title[17] = {};
core->getGameTitle(core, title);
@ -83,5 +83,4 @@ ROMInfo::ROMInfo(GameController* controller, QWidget* parent)
m_ui.crc->setText(tr("(unknown)"));
m_ui.name->setText(tr("(unknown)"));
}
controller->threadContinue();
}

View File

@ -108,7 +108,7 @@ bool SensorView::eventFilter(QObject*, QEvent* event) {
}
void SensorView::updateSensors() {
m_controller->threadInterrupt();
GameController::Interrupter interrupter(m_controller);
if (m_rotation->sample &&
(!m_controller->isLoaded() || !(static_cast<GBA*>(m_controller->thread()->core->board)->memory.hw.devices & (HW_GYRO | HW_TILT)))) {
m_rotation->sample(m_rotation);
@ -129,7 +129,6 @@ void SensorView::updateSensors() {
if (m_rotation->readGyroZ) {
m_ui.gyroView->setValue(m_rotation->readGyroZ(m_rotation));
}
m_controller->threadContinue();
}
void SensorView::setLuminanceValue(int value) {