all repos — mgba @ 6e467a0332446b2ac4c81f6cb63dc22e07792454

mGBA Game Boy Advance Emulator

Qt: Create MultiplayerController
Jeffrey Pfau jeffrey@endrift.com
Thu, 26 Feb 2015 00:07:36 -0800
commit

6e467a0332446b2ac4c81f6cb63dc22e07792454

parent

5b40951c05baa28ac43c84ffacfec6bd99692ed3

M src/platform/qt/GameController.cppsrc/platform/qt/GameController.cpp

@@ -7,6 +7,7 @@ #include "GameController.h"

#include "AudioProcessor.h" #include "InputController.h" +#include "MultiplayerController.h" #include <QDateTime> #include <QThread>

@@ -41,6 +42,7 @@ , m_audioSync(AUDIO_SYNC)

, m_turbo(false) , m_turboForced(false) , m_inputController(nullptr) + , m_multiplayer(nullptr) { m_renderer = new GBAVideoSoftwareRenderer; GBAVideoSoftwareRendererCreate(m_renderer);

@@ -140,10 +142,28 @@ GameController::~GameController() {

m_audioThread->quit(); m_audioThread->wait(); disconnect(); + clearMultiplayerController(); closeGame(); GBACheatDeviceDestroy(&m_cheatDevice); delete m_renderer; delete[] m_drawContext; +} + +void GameController::setMultiplayerController(std::shared_ptr<MultiplayerController> controller) { + if (controller == m_multiplayer) { + return; + } + clearMultiplayerController(); + m_multiplayer = controller; + controller->attachGame(this); +} + +void GameController::clearMultiplayerController() { + if (!m_multiplayer) { + return; + } + m_multiplayer->detachGame(this); + m_multiplayer.reset(); } void GameController::setOverride(const GBACartridgeOverride& override) {
M src/platform/qt/GameController.hsrc/platform/qt/GameController.h

@@ -12,6 +12,8 @@ #include <QObject>

#include <QMutex> #include <QString> +#include <memory> + extern "C" { #include "gba/cheats.h" #include "gba/hardware.h"

@@ -32,6 +34,7 @@ namespace QGBA {

class AudioProcessor; class InputController; +class MultiplayerController; class GameController : public QObject { Q_OBJECT

@@ -58,6 +61,9 @@ bool videoSync() const { return m_videoSync; }

void setInputController(InputController* controller) { m_inputController = controller; } void setOverrides(Configuration* overrides) { m_threadContext.overrides = overrides; } + + void setMultiplayerController(std::shared_ptr<MultiplayerController> controller); + void clearMultiplayerController(); void setOverride(const GBACartridgeOverride& override); void clearOverride() { m_threadContext.hasOverride = false; }

@@ -162,6 +168,7 @@ bool m_turbo;

bool m_turboForced; InputController* m_inputController; + std::shared_ptr<MultiplayerController> m_multiplayer; struct GameControllerLux : GBALuminanceSource { GameController* p;
M src/platform/qt/MultiplayerController.cppsrc/platform/qt/MultiplayerController.cpp

@@ -5,6 +5,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this

* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "MultiplayerController.h" +#include "GameController.h" + using namespace QGBA; MultiplayerController::MultiplayerController() {

@@ -16,5 +18,46 @@ GBASIOLockstepDeinit(&m_lockstep);

} bool MultiplayerController::attachGame(GameController* controller) { - return false; + MutexLock(&m_lockstep.mutex); + if (m_lockstep.attached == MAX_GBAS) { + MutexUnlock(&m_lockstep.mutex); + return false; + } + GBASIOLockstepNode* node = new GBASIOLockstepNode; + GBASIOLockstepNodeCreate(node); + GBASIOLockstepAttachNode(&m_lockstep, node); + MutexUnlock(&m_lockstep.mutex); + + controller->threadInterrupt(); + GBAThread* thread = controller->thread(); + if (controller->isLoaded()) { + GBASIOSetDriver(&thread->gba->sio, &node->d, SIO_MULTI); + } + thread->sioDrivers.multiplayer = &node->d; + controller->threadContinue(); + return true; +} + +void MultiplayerController::detachGame(GameController* controller) { + controller->threadInterrupt(); + MutexLock(&m_lockstep.mutex); + GBAThread* thread = nullptr; + for (int i = 0; i < m_lockstep.attached; ++i) { + thread = controller->thread(); + if (thread->sioDrivers.multiplayer == &m_lockstep.players[i]->d) { + break; + } + thread = nullptr; + } + if (thread) { + GBASIOLockstepNode* node = reinterpret_cast<GBASIOLockstepNode*>(thread->sioDrivers.multiplayer); + if (controller->isLoaded()) { + GBASIOSetDriver(&thread->gba->sio, nullptr, SIO_MULTI); + } + thread->sioDrivers.multiplayer = nullptr; + GBASIOLockstepDetachNode(&m_lockstep, node); + delete node; + } + MutexUnlock(&m_lockstep.mutex); + controller->threadContinue(); }
M src/platform/qt/MultiplayerController.hsrc/platform/qt/MultiplayerController.h

@@ -20,6 +20,7 @@ MultiplayerController();

~MultiplayerController(); bool attachGame(GameController*); + void detachGame(GameController*); private: GBASIOLockstep m_lockstep;