mirror of https://github.com/mgba-emu/mgba.git
GBA SIO: Disable sync of secondary units
This commit is contained in:
parent
08b78cb468
commit
ba4f3ae9c6
|
@ -129,11 +129,7 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (node->id) {
|
||||
node->p->signal(node->p, 1 << node->id);
|
||||
} else {
|
||||
node->p->addCycles(node->p, 0, node->eventDiff);
|
||||
}
|
||||
node->p->unload(node->p, node->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ struct GBASIOLockstep {
|
|||
bool (*wait)(struct GBASIOLockstep*, unsigned mask);
|
||||
void (*addCycles)(struct GBASIOLockstep*, int id, int32_t cycles);
|
||||
int32_t (*useCycles)(struct GBASIOLockstep*, int id, int32_t cycles);
|
||||
void (*unload)(struct GBASIOLockstep*, int id);
|
||||
void* context;
|
||||
#ifndef NDEBUG
|
||||
int transferId;
|
||||
|
|
|
@ -50,6 +50,7 @@ GameController::GameController(QObject* parent)
|
|||
, m_audioThread(new QThread(this))
|
||||
, m_audioProcessor(AudioProcessor::create())
|
||||
, m_pauseAfterFrame(false)
|
||||
, m_sync(true)
|
||||
, m_videoSync(VIDEO_SYNC)
|
||||
, m_audioSync(AUDIO_SYNC)
|
||||
, m_fpsTarget(-1)
|
||||
|
@ -938,10 +939,13 @@ void GameController::setTurbo(bool set, bool forced) {
|
|||
if (m_turboForced && !forced) {
|
||||
return;
|
||||
}
|
||||
if (m_turbo == set && m_turboForced == forced) {
|
||||
if (m_turbo == set && m_turboForced == (set && forced)) {
|
||||
// Don't interrupt the thread if we don't need to
|
||||
return;
|
||||
}
|
||||
if (!m_sync) {
|
||||
return;
|
||||
}
|
||||
m_turbo = set;
|
||||
m_turboForced = set && forced;
|
||||
enableTurbo();
|
||||
|
@ -954,25 +958,41 @@ void GameController::setTurboSpeed(float ratio) {
|
|||
|
||||
void GameController::enableTurbo() {
|
||||
threadInterrupt();
|
||||
bool shouldRedoSamples = false;
|
||||
if (!m_turbo) {
|
||||
shouldRedoSamples = m_threadContext.sync.fpsTarget != m_fpsTarget;
|
||||
m_threadContext.sync.fpsTarget = m_fpsTarget;
|
||||
m_threadContext.sync.audioWait = m_audioSync;
|
||||
m_threadContext.sync.videoFrameWait = m_videoSync;
|
||||
} else if (m_turboSpeed <= 0) {
|
||||
shouldRedoSamples = m_threadContext.sync.fpsTarget != m_fpsTarget;
|
||||
m_threadContext.sync.fpsTarget = m_fpsTarget;
|
||||
m_threadContext.sync.audioWait = false;
|
||||
m_threadContext.sync.videoFrameWait = false;
|
||||
} else {
|
||||
shouldRedoSamples = m_threadContext.sync.fpsTarget != m_fpsTarget * m_turboSpeed;
|
||||
m_threadContext.sync.fpsTarget = m_fpsTarget * m_turboSpeed;
|
||||
m_threadContext.sync.audioWait = true;
|
||||
m_threadContext.sync.videoFrameWait = false;
|
||||
}
|
||||
if (m_audioProcessor) {
|
||||
if (m_audioProcessor && shouldRedoSamples) {
|
||||
redoSamples(m_audioProcessor->getBufferSamples());
|
||||
}
|
||||
threadContinue();
|
||||
}
|
||||
|
||||
void GameController::setSync(bool enable) {
|
||||
m_turbo = false;
|
||||
m_turboForced = false;
|
||||
if (!enable) {
|
||||
m_threadContext.sync.audioWait = false;
|
||||
m_threadContext.sync.videoFrameWait = false;
|
||||
} else {
|
||||
m_threadContext.sync.audioWait = m_audioSync;
|
||||
m_threadContext.sync.videoFrameWait = m_videoSync;
|
||||
}
|
||||
m_sync = enable;
|
||||
}
|
||||
void GameController::setAVStream(mAVStream* stream) {
|
||||
threadInterrupt();
|
||||
m_stream = stream;
|
||||
|
|
|
@ -135,7 +135,8 @@ public slots:
|
|||
void loadBackupState();
|
||||
void saveBackupState();
|
||||
void setTurbo(bool, bool forced = true);
|
||||
void setTurboSpeed(float ratio = -1);
|
||||
void setTurboSpeed(float ratio);
|
||||
void setSync(bool);
|
||||
void setAVStream(mAVStream*);
|
||||
void clearAVStream();
|
||||
void reloadAudioDriver();
|
||||
|
@ -197,6 +198,7 @@ private:
|
|||
QAtomicInt m_pauseAfterFrame;
|
||||
QList<std::function<void ()>> m_resetActions;
|
||||
|
||||
bool m_sync;
|
||||
bool m_videoSync;
|
||||
bool m_audioSync;
|
||||
float m_fpsTarget;
|
||||
|
|
|
@ -56,9 +56,11 @@ MultiplayerController::MultiplayerController() {
|
|||
if (!id) {
|
||||
for (int i = 1; i < controller->m_players.count(); ++i) {
|
||||
Player* player = &controller->m_players[i];
|
||||
if (player->node->mode != controller->m_players[0].node->mode) {
|
||||
if (player->node->d.p->mode != controller->m_players[0].node->d.p->mode) {
|
||||
player->controller->setSync(true);
|
||||
continue;
|
||||
}
|
||||
player->controller->setSync(false);
|
||||
player->cyclesPosted += cycles;
|
||||
if (player->awake < 1) {
|
||||
player->node->nextEvent += player->cyclesPosted;
|
||||
|
@ -67,6 +69,7 @@ MultiplayerController::MultiplayerController() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
controller->m_players[id].controller->setSync(true);
|
||||
controller->m_players[id].cyclesPosted += cycles;
|
||||
}
|
||||
controller->m_lock.unlock();
|
||||
|
@ -84,6 +87,31 @@ MultiplayerController::MultiplayerController() {
|
|||
controller->m_lock.unlock();
|
||||
return cycles;
|
||||
};
|
||||
m_lockstep.unload = [](GBASIOLockstep* lockstep, int id) {
|
||||
MultiplayerController* controller = static_cast<MultiplayerController*>(lockstep->context);
|
||||
controller->m_lock.lock();
|
||||
Player* player = &controller->m_players[id];
|
||||
if (id) {
|
||||
player->controller->setSync(true);
|
||||
player->waitMask &= ~(1 << id);
|
||||
if (!player->waitMask && player->awake < 1) {
|
||||
mCoreThreadStopWaiting(player->controller->thread());
|
||||
player->awake = 1;
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < controller->m_players.count(); ++i) {
|
||||
Player* player = &controller->m_players[i];
|
||||
player->controller->setSync(true);
|
||||
player->cyclesPosted += lockstep->players[0]->eventDiff;
|
||||
if (player->awake < 1) {
|
||||
player->node->nextEvent += player->cyclesPosted;
|
||||
mCoreThreadStopWaiting(player->controller->thread());
|
||||
player->awake = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
controller->m_lock.unlock();
|
||||
};
|
||||
}
|
||||
|
||||
MultiplayerController::~MultiplayerController() {
|
||||
|
|
Loading…
Reference in New Issue