all repos — mgba @ 50402c830729f2ba5a6fc3e6facfd8b258f7f97d

mGBA Game Boy Advance Emulator

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}