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 emit gameAttached();
39 return true;
40}
41
42void MultiplayerController::detachGame(GameController* controller) {
43 controller->threadInterrupt();
44 MutexLock(&m_lockstep.mutex);
45 GBAThread* thread = nullptr;
46 for (int i = 0; i < m_lockstep.attached; ++i) {
47 thread = controller->thread();
48 if (thread->sioDrivers.multiplayer == &m_lockstep.players[i]->d) {
49 break;
50 }
51 thread = nullptr;
52 }
53 if (thread) {
54 GBASIOLockstepNode* node = reinterpret_cast<GBASIOLockstepNode*>(thread->sioDrivers.multiplayer);
55 if (controller->isLoaded()) {
56 GBASIOSetDriver(&thread->gba->sio, nullptr, SIO_MULTI);
57 }
58 thread->sioDrivers.multiplayer = nullptr;
59 GBASIOLockstepDetachNode(&m_lockstep, node);
60 delete node;
61 }
62 MutexUnlock(&m_lockstep.mutex);
63 controller->threadContinue();
64 emit gameDetached();
65}
66
67int MultiplayerController::playerId(GameController* controller) {
68 MutexLock(&m_lockstep.mutex);
69 int id = -1;
70 for (int i = 0; i < m_lockstep.attached; ++i) {
71 GBAThread* thread = controller->thread();
72 if (thread->sioDrivers.multiplayer == &m_lockstep.players[i]->d) {
73 id = i;
74 break;
75 }
76 }
77 MutexUnlock(&m_lockstep.mutex);
78 return id;
79}
80
81int MultiplayerController::attached() {
82 int num;
83 MutexLock(&m_lockstep.mutex);
84 num = m_lockstep.attached;
85 MutexUnlock(&m_lockstep.mutex);
86 return num;
87}