mirror of https://github.com/mgba-emu/mgba.git
Qt: Create MultiplayerController
This commit is contained in:
parent
5b40951c05
commit
6e467a0332
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "AudioProcessor.h"
|
||||
#include "InputController.h"
|
||||
#include "MultiplayerController.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QThread>
|
||||
|
@ -41,6 +42,7 @@ GameController::GameController(QObject* parent)
|
|||
, m_turbo(false)
|
||||
, m_turboForced(false)
|
||||
, m_inputController(nullptr)
|
||||
, m_multiplayer(nullptr)
|
||||
{
|
||||
m_renderer = new GBAVideoSoftwareRenderer;
|
||||
GBAVideoSoftwareRendererCreate(m_renderer);
|
||||
|
@ -140,12 +142,30 @@ GameController::~GameController() {
|
|||
m_audioThread->quit();
|
||||
m_audioThread->wait();
|
||||
disconnect();
|
||||
clearMultiplayerController();
|
||||
closeGame();
|
||||
GBACheatDeviceDestroy(&m_cheatDevice);
|
||||
delete m_renderer;
|
||||
delete[] m_drawContext;
|
||||
}
|
||||
|
||||
void GameController::setMultiplayerController(std::shared_ptr<MultiplayerController> controller) {
|
||||
if (controller == m_multiplayer) {
|
||||
return;
|
||||
}
|
||||
clearMultiplayerController();
|
||||
m_multiplayer = controller;
|
||||
controller->attachGame(this);
|
||||
}
|
||||
|
||||
void GameController::clearMultiplayerController() {
|
||||
if (!m_multiplayer) {
|
||||
return;
|
||||
}
|
||||
m_multiplayer->detachGame(this);
|
||||
m_multiplayer.reset();
|
||||
}
|
||||
|
||||
void GameController::setOverride(const GBACartridgeOverride& override) {
|
||||
m_threadContext.override = override;
|
||||
m_threadContext.hasOverride = true;
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <QMutex>
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
extern "C" {
|
||||
#include "gba/cheats.h"
|
||||
#include "gba/hardware.h"
|
||||
|
@ -32,6 +34,7 @@ namespace QGBA {
|
|||
|
||||
class AudioProcessor;
|
||||
class InputController;
|
||||
class MultiplayerController;
|
||||
|
||||
class GameController : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -59,6 +62,9 @@ public:
|
|||
void setInputController(InputController* controller) { m_inputController = controller; }
|
||||
void setOverrides(Configuration* overrides) { m_threadContext.overrides = overrides; }
|
||||
|
||||
void setMultiplayerController(std::shared_ptr<MultiplayerController> controller);
|
||||
void clearMultiplayerController();
|
||||
|
||||
void setOverride(const GBACartridgeOverride& override);
|
||||
void clearOverride() { m_threadContext.hasOverride = false; }
|
||||
|
||||
|
@ -162,6 +168,7 @@ private:
|
|||
bool m_turboForced;
|
||||
|
||||
InputController* m_inputController;
|
||||
std::shared_ptr<MultiplayerController> m_multiplayer;
|
||||
|
||||
struct GameControllerLux : GBALuminanceSource {
|
||||
GameController* p;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "MultiplayerController.h"
|
||||
|
||||
#include "GameController.h"
|
||||
|
||||
using namespace QGBA;
|
||||
|
||||
MultiplayerController::MultiplayerController() {
|
||||
|
@ -16,5 +18,46 @@ MultiplayerController::~MultiplayerController() {
|
|||
}
|
||||
|
||||
bool MultiplayerController::attachGame(GameController* controller) {
|
||||
return false;
|
||||
MutexLock(&m_lockstep.mutex);
|
||||
if (m_lockstep.attached == MAX_GBAS) {
|
||||
MutexUnlock(&m_lockstep.mutex);
|
||||
return false;
|
||||
}
|
||||
GBASIOLockstepNode* node = new GBASIOLockstepNode;
|
||||
GBASIOLockstepNodeCreate(node);
|
||||
GBASIOLockstepAttachNode(&m_lockstep, node);
|
||||
MutexUnlock(&m_lockstep.mutex);
|
||||
|
||||
controller->threadInterrupt();
|
||||
GBAThread* thread = controller->thread();
|
||||
if (controller->isLoaded()) {
|
||||
GBASIOSetDriver(&thread->gba->sio, &node->d, SIO_MULTI);
|
||||
}
|
||||
thread->sioDrivers.multiplayer = &node->d;
|
||||
controller->threadContinue();
|
||||
return true;
|
||||
}
|
||||
|
||||
void MultiplayerController::detachGame(GameController* controller) {
|
||||
controller->threadInterrupt();
|
||||
MutexLock(&m_lockstep.mutex);
|
||||
GBAThread* thread = nullptr;
|
||||
for (int i = 0; i < m_lockstep.attached; ++i) {
|
||||
thread = controller->thread();
|
||||
if (thread->sioDrivers.multiplayer == &m_lockstep.players[i]->d) {
|
||||
break;
|
||||
}
|
||||
thread = nullptr;
|
||||
}
|
||||
if (thread) {
|
||||
GBASIOLockstepNode* node = reinterpret_cast<GBASIOLockstepNode*>(thread->sioDrivers.multiplayer);
|
||||
if (controller->isLoaded()) {
|
||||
GBASIOSetDriver(&thread->gba->sio, nullptr, SIO_MULTI);
|
||||
}
|
||||
thread->sioDrivers.multiplayer = nullptr;
|
||||
GBASIOLockstepDetachNode(&m_lockstep, node);
|
||||
delete node;
|
||||
}
|
||||
MutexUnlock(&m_lockstep.mutex);
|
||||
controller->threadContinue();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
~MultiplayerController();
|
||||
|
||||
bool attachGame(GameController*);
|
||||
void detachGame(GameController*);
|
||||
|
||||
private:
|
||||
GBASIOLockstep m_lockstep;
|
||||
|
|
Loading…
Reference in New Issue