all repos — mgba @ c14da05d8dca225010677643c32fea5c0ac8517a

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