all repos — mgba @ a89bb0b814072869723edc05cc1dcf8249dd2c9a

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		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}