diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d5801063..ef487f075 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,10 +21,11 @@ file(GLOB GBA_SV_SRC ${CMAKE_SOURCE_DIR}/src/gba/supervisor/*.c) file(GLOB UTIL_SRC ${CMAKE_SOURCE_DIR}/src/util/*.[cSs]) file(GLOB VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/*.c) file(GLOB RENDERER_SRC ${CMAKE_SOURCE_DIR}/src/gba/renderers/video-software.c) +file(GLOB SIO_SRC ${CMAKE_SOURCE_DIR}/src/gba/sio/lockstep.c) file(GLOB THIRD_PARTY_SRC ${CMAKE_SOURCE_DIR}/src/third-party/inih/*.c) list(APPEND UTIL_SRC ${CMAKE_SOURCE_DIR}/src/platform/commandline.c) source_group("ARM core" FILES ${ARM_SRC}) -source_group("GBA board" FILES ${GBA_SRC} ${RENDERER_SRC}) +source_group("GBA board" FILES ${GBA_SRC} ${RENDERER_SRC} ${SIO_SRC}) source_group("GBA supervisor" FILES ${GBA_SV_SRC}) source_group("Utilities" FILES ${UTIL_SRC} ${VFS_SRC}}) include_directories(${CMAKE_SOURCE_DIR}/src/arm) @@ -275,6 +276,7 @@ set(SRC ${GBA_SV_SRC} ${DEBUGGER_SRC} ${RENDERER_SRC} + ${SIO_SRC} ${UTIL_SRC} ${VFS_SRC} ${OS_SRC} diff --git a/src/gba/sio.h b/src/gba/sio.h index 030218cc8..61e979385 100644 --- a/src/gba/sio.h +++ b/src/gba/sio.h @@ -30,11 +30,11 @@ struct GBASIO; struct GBASIODriver { struct GBASIO* p; - int (*init)(struct GBASIODriver* driver); + bool (*init)(struct GBASIODriver* driver); void (*deinit)(struct GBASIODriver* driver); - int (*load)(struct GBASIODriver* driver); - int (*unload)(struct GBASIODriver* driver); - int (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value); + bool (*load)(struct GBASIODriver* driver); + bool (*unload)(struct GBASIODriver* driver); + uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value); int32_t (*processEvents)(struct GBASIODriver* driver, int32_t cycles); }; diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c new file mode 100644 index 000000000..d7cfa268e --- /dev/null +++ b/src/gba/sio/lockstep.c @@ -0,0 +1,73 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "lockstep.h" + +#define LOCKSTEP_INCREMENT 2048 + +static bool GBASIOLockstepNodeInit(struct GBASIODriver* driver); +static void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver); +static bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver); +static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver); +static uint16_t GBASIOLockstepNodeWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); +static int32_t GBASIOLockstepNodeProcessEvents(struct GBASIODriver* driver, int32_t cycles); + +void GBASIOLockstepInit(struct GBASIOLockstep* lockstep) { + lockstep->players[0] = 0; + lockstep->players[1] = 0; + lockstep->players[2] = 0; + lockstep->players[3] = 0; + lockstep->attached = 0; + ConditionInit(&lockstep->barrier); +} + +void GBASIOLockstepDeinit(struct GBASIOLockstep* lockstep) { + ConditionDeinit(&lockstep->barrier); +} + +void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) { + node->d.init = GBASIOLockstepNodeInit; + node->d.deinit = GBASIOLockstepNodeDeinit; + node->d.load = GBASIOLockstepNodeLoad; + node->d.unload = GBASIOLockstepNodeUnload; + node->d.writeRegister = GBASIOLockstepNodeWriteRegister; + node->d.processEvents = GBASIOLockstepNodeProcessEvents; +} + +bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) { + if (lockstep->attached == MAX_GBAS) { + return false; + } + lockstep->players[lockstep->attached] = node; + ++lockstep->attached; + return true; +} + +bool GBASIOLockstepNodeInit(struct GBASIODriver* driver) { + UNUSED(driver); + return true; +} + +void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver) { + UNUSED(driver); +} + +bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { + UNUSED(driver); + return true; +} + +bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { + UNUSED(driver); + return true; +} + +static uint16_t GBASIOLockstepNodeWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { + return value; +} + +static int32_t GBASIOLockstepNodeProcessEvents(struct GBASIODriver* driver, int32_t cycles) { + return INT_MAX; +} diff --git a/src/gba/sio/lockstep.h b/src/gba/sio/lockstep.h new file mode 100644 index 000000000..c25025db6 --- /dev/null +++ b/src/gba/sio/lockstep.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef SIO_LOCKSTEP_H +#define SIO_LOCKSTEP_H + +#include "gba/sio.h" + +#include "util/threading.h" + +struct GBASIOLockstep { + struct GBASIOLockstepNode* players[MAX_GBAS]; + int attached; + + uint16_t data[MAX_GBAS]; + Condition barrier; +}; + +struct GBASIOLockstepNode { + struct GBASIODriver d; + struct GBASIOLockstep* p; +}; + +void GBASIOLockstepInit(struct GBASIOLockstep*); +void GBASIOLockstepDeinit(struct GBASIOLockstep*); + +void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode*); +bool GBASIOLockstepAttachNode(struct GBASIOLockstep*, struct GBASIOLockstepNode*); + +#endif diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 531ab4886..f87fa093b 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -51,6 +51,7 @@ set(SOURCE_FILES KeyEditor.cpp LoadSaveState.cpp LogView.cpp + MultiplayerController.cpp OverrideView.cpp SavestateButton.cpp SensorView.cpp diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp new file mode 100644 index 000000000..99b1ee8e0 --- /dev/null +++ b/src/platform/qt/MultiplayerController.cpp @@ -0,0 +1,20 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "MultiplayerController.h" + +using namespace QGBA; + +MultiplayerController::MultiplayerController() { + GBASIOLockstepInit(&m_lockstep); +} + +MultiplayerController::~MultiplayerController() { + GBASIOLockstepDeinit(&m_lockstep); +} + +bool MultiplayerController::attachGame(GameController* controller) { + return false; +} diff --git a/src/platform/qt/MultiplayerController.h b/src/platform/qt/MultiplayerController.h new file mode 100644 index 000000000..3a10d56f0 --- /dev/null +++ b/src/platform/qt/MultiplayerController.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef QGBA_MULTIPLAYER_CONTROLLER +#define QGBA_MULTIPLAYER_CONTROLLER + +extern "C" { +#include "gba/sio/lockstep.h" +} + +namespace QGBA { + +class GameController; + +class MultiplayerController { +public: + MultiplayerController(); + ~MultiplayerController(); + + bool attachGame(GameController*); + +private: + GBASIOLockstep m_lockstep; +}; + +} +#endif