Qt: Create MultiplayerController

This commit is contained in:
Jeffrey Pfau 2015-02-26 00:07:36 -08:00
parent 5b40951c05
commit 6e467a0332
4 changed files with 72 additions and 1 deletions

View File

@ -7,6 +7,7 @@
#include "AudioProcessor.h"
#include "InputController.h"
#include "MultiplayerController.h"
#include <QDateTime>
#include <QThread>
@ -41,6 +42,7 @@ GameController::GameController(QObject* parent)
, m_turbo(false)
, m_turboForced(false)
, m_inputController(nullptr)
, m_multiplayer(nullptr)
{
m_renderer = new GBAVideoSoftwareRenderer;
GBAVideoSoftwareRendererCreate(m_renderer);
@ -140,12 +142,30 @@ 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_threadContext.override = override;
m_threadContext.hasOverride = true;

View File

@ -12,6 +12,8 @@
#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
@ -59,6 +62,9 @@ public:
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 @@ private:
bool m_turboForced;
InputController* m_inputController;
std::shared_ptr<MultiplayerController> m_multiplayer;
struct GameControllerLux : GBALuminanceSource {
GameController* p;

View File

@ -5,6 +5,8 @@
* 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 @@ MultiplayerController::~MultiplayerController() {
}
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();
}

View File

@ -20,6 +20,7 @@ public:
~MultiplayerController();
bool attachGame(GameController*);
void detachGame(GameController*);
private:
GBASIOLockstep m_lockstep;