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