src/platform/qt/MultiplayerController.cpp (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "MultiplayerController.h"
7
8#include "GameController.h"
9
10using namespace QGBA;
11
12MultiplayerController::MultiplayerController() {
13 GBASIOLockstepInit(&m_lockstep);
14}
15
16MultiplayerController::~MultiplayerController() {
17 GBASIOLockstepDeinit(&m_lockstep);
18}
19
20bool MultiplayerController::attachGame(GameController* controller) {
21 MutexLock(&m_lockstep.mutex);
22 if (m_lockstep.attached == MAX_GBAS) {
23 MutexUnlock(&m_lockstep.mutex);
24 return false;
25 }
26 GBASIOLockstepNode* node = new GBASIOLockstepNode;
27 GBASIOLockstepNodeCreate(node);
28 GBASIOLockstepAttachNode(&m_lockstep, node);
29 MutexUnlock(&m_lockstep.mutex);
30
31 controller->threadInterrupt();
32 GBAThread* thread = controller->thread();
33 if (controller->isLoaded()) {
34 GBASIOSetDriver(&thread->gba->sio, &node->d, SIO_MULTI);
35 }
36 thread->sioDrivers.multiplayer = &node->d;
37 controller->threadContinue();
38 return true;
39}
40
41void MultiplayerController::detachGame(GameController* controller) {
42 controller->threadInterrupt();
43 MutexLock(&m_lockstep.mutex);
44 GBAThread* thread = nullptr;
45 for (int i = 0; i < m_lockstep.attached; ++i) {
46 thread = controller->thread();
47 if (thread->sioDrivers.multiplayer == &m_lockstep.players[i]->d) {
48 break;
49 }
50 thread = nullptr;
51 }
52 if (thread) {
53 GBASIOLockstepNode* node = reinterpret_cast<GBASIOLockstepNode*>(thread->sioDrivers.multiplayer);
54 if (controller->isLoaded()) {
55 GBASIOSetDriver(&thread->gba->sio, nullptr, SIO_MULTI);
56 }
57 thread->sioDrivers.multiplayer = nullptr;
58 GBASIOLockstepDetachNode(&m_lockstep, node);
59 delete node;
60 }
61 MutexUnlock(&m_lockstep.mutex);
62 controller->threadContinue();
63}
64
65int MultiplayerController::attached() {
66 int num;
67 MutexLock(&m_lockstep.mutex);
68 num = m_lockstep.attached;
69 MutexUnlock(&m_lockstep.mutex);
70 return num;
71}