mirror of https://github.com/mgba-emu/mgba.git
Qt: Add GameController::Interrupter
This commit is contained in:
parent
4cb243f15c
commit
7d009ec43c
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue