lay down netplay code

This commit is contained in:
SimoneN64
2023-06-13 14:45:52 +02:00
parent c0c5a4f1c0
commit e8cd317d0d
6 changed files with 182 additions and 106 deletions

32
src/backend/Netplay.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include <Netplay.hpp>
#include "log.hpp"
#include <PIF.hpp>
namespace Netplay {
bool isHost = false;
bool connected = false;
n64::Controller players[4]{};
template <int port>
void SyncPlayers(n64::PIF& pif) {
if(connected) {
if(isHost) {
pif.PollController();
} else {
if constexpr (port == 0) {
Util::panic("It shouldn't be possible to be player 1 and not be the host");
} else if constexpr (port == 1) {
} else if constexpr (port == 2) {
} else if constexpr (port == 3) {
} else {
Util::panic("What the heeeeelll oh my gaaaa");
}
}
}
}
template void SyncPlayers(n64::PIF&);
}

11
src/backend/Netplay.hpp Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
#include <SFML/Network.hpp>
#include <PIF.hpp>
namespace Netplay {
extern bool isHost;
extern bool connected;
template <int port = 0>
void SyncPlayers(n64::PIF&);
}

View File

@@ -5,6 +5,8 @@
#include <SDL_keyboard.h> #include <SDL_keyboard.h>
#include <cic_nus_6105/n64_cic_nus_6105.hpp> #include <cic_nus_6105/n64_cic_nus_6105.hpp>
#include <cassert> #include <cassert>
#include <Netplay.hpp>
#include <PIF/Device.hpp>
#define MEMPAK_SIZE 32768 #define MEMPAK_SIZE 32768
@@ -329,108 +331,22 @@ void PIF::EepromWrite(const u8* cmd, u8* res, const Mem& mem) {
} }
} }
#define GET_BUTTON(gamecontroller, i) SDL_GameControllerGetButton(gamecontroller, i)
#define GET_AXIS(gamecontroller, axis) SDL_GameControllerGetAxis(gamecontroller, axis)
void PIF::UpdateController() { void PIF::UpdateController() {
if(gamepadConnected) { joybusDevices[channel].controller.a = players[channel].controller.a;
bool A = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_A); joybusDevices[channel].controller.b = players[channel].controller.b;
bool B = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_X); joybusDevices[channel].controller.z = players[channel].controller.z;
bool Z = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_TRIGGERLEFT) == SDL_JOYSTICK_AXIS_MAX; joybusDevices[channel].controller.start = players[channel].controller.start;
bool START = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_START); joybusDevices[channel].controller.dp_up = players[channel].controller.dp_up;
bool DUP = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_UP); joybusDevices[channel].controller.dp_down = players[channel].controller.dp_down;
bool DDOWN = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_DOWN); joybusDevices[channel].controller.dp_left = players[channel].controller.dp_left;
bool DLEFT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_LEFT); joybusDevices[channel].controller.dp_right = players[channel].controller.dp_right;
bool DRIGHT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); joybusDevices[channel].controller.joy_reset = players[channel].controller.joy_reset;
bool L = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); joybusDevices[channel].controller.l = players[channel].controller.l;
bool R = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); joybusDevices[channel].controller.r = players[channel].controller.r;
bool CUP = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) <= -127; joybusDevices[channel].controller.c_up = players[channel].controller.c_up;
bool CDOWN = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) >= 127; joybusDevices[channel].controller.c_down = players[channel].controller.c_down;
bool CLEFT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) <= -127; joybusDevices[channel].controller.c_left = players[channel].controller.c_left;
bool CRIGHT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) >= 127; joybusDevices[channel].controller.c_right = players[channel].controller.c_right;
joybusDevices[channel].controller.a = A;
joybusDevices[channel].controller.b = B;
joybusDevices[channel].controller.z = Z;
joybusDevices[channel].controller.start = START;
joybusDevices[channel].controller.dp_up = DUP;
joybusDevices[channel].controller.dp_down = DDOWN;
joybusDevices[channel].controller.dp_left = DLEFT;
joybusDevices[channel].controller.dp_right = DRIGHT;
joybusDevices[channel].controller.joy_reset = L && R && START;
joybusDevices[channel].controller.l = L;
joybusDevices[channel].controller.r = R;
joybusDevices[channel].controller.c_up = CUP;
joybusDevices[channel].controller.c_down = CDOWN;
joybusDevices[channel].controller.c_left = CLEFT;
joybusDevices[channel].controller.c_right = CRIGHT;
float xclamped = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTX);
if(xclamped < 0) {
xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN));
} else {
xclamped /= SDL_JOYSTICK_AXIS_MAX;
}
xclamped *= 86;
float yclamped = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTY);
if(yclamped < 0) {
yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN));
} else {
yclamped /= SDL_JOYSTICK_AXIS_MAX;
}
yclamped *= 86;
joybusDevices[channel].controller.joy_x = xclamped;
joybusDevices[channel].controller.joy_y = -yclamped;
if (joybusDevices[channel].controller.joy_reset) {
joybusDevices[channel].controller.start = false;
joybusDevices[channel].controller.joy_x = 0;
joybusDevices[channel].controller.joy_y = 0;
}
} else {
const uint8_t* state = SDL_GetKeyboardState(nullptr);
joybusDevices[channel].controller.a = state[SDL_SCANCODE_X];
joybusDevices[channel].controller.b = state[SDL_SCANCODE_C];
joybusDevices[channel].controller.z = state[SDL_SCANCODE_Z];
joybusDevices[channel].controller.start = state[SDL_SCANCODE_RETURN];
joybusDevices[channel].controller.dp_up = state[SDL_SCANCODE_PAGEUP];
joybusDevices[channel].controller.dp_down = state[SDL_SCANCODE_PAGEDOWN];
joybusDevices[channel].controller.dp_left = state[SDL_SCANCODE_HOME];
joybusDevices[channel].controller.dp_right = state[SDL_SCANCODE_END];
joybusDevices[channel].controller.joy_reset = state[SDL_SCANCODE_RETURN] && state[SDL_SCANCODE_A] && state[SDL_SCANCODE_S];
joybusDevices[channel].controller.l = state[SDL_SCANCODE_A];
joybusDevices[channel].controller.r = state[SDL_SCANCODE_S];
joybusDevices[channel].controller.c_up = state[SDL_SCANCODE_I];
joybusDevices[channel].controller.c_down = state[SDL_SCANCODE_K];
joybusDevices[channel].controller.c_left = state[SDL_SCANCODE_J];
joybusDevices[channel].controller.c_right = state[SDL_SCANCODE_L];
s16 xaxis = 0, yaxis = 0;
if (state[SDL_SCANCODE_LEFT]) {
xaxis = -86;
} else if (state[SDL_SCANCODE_RIGHT]) {
xaxis = 86;
}
if (state[SDL_SCANCODE_DOWN]) {
yaxis = -86;
} else if (state[SDL_SCANCODE_UP]) {
yaxis = 86;
}
joybusDevices[channel].controller.joy_x = xaxis;
joybusDevices[channel].controller.joy_y = yaxis;
if (joybusDevices[channel].controller.joy_reset) {
joybusDevices[channel].controller.start = false;
joybusDevices[channel].controller.joy_x = 0;
joybusDevices[channel].controller.joy_y = 0;
}
}
} }
void PIF::DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType) { void PIF::DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType) {

View File

@@ -100,6 +100,8 @@ struct PIF {
void CICChallenge(); void CICChallenge();
static void ExecutePIF(Mem& mem, Registers& regs); static void ExecutePIF(Mem& mem, Registers& regs);
static void DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType); static void DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType);
template <int port = 0>
void PollController();
void UpdateController(); void UpdateController();
bool ReadButtons(u8*) const; bool ReadButtons(u8*) const;
void ControllerID(u8*) const; void ControllerID(u8*) const;

View File

@@ -1,14 +1,17 @@
#include <PIF.hpp> #include <PIF.hpp>
#include <MupenMovie.hpp> #include <MupenMovie.hpp>
#include <PIF/Device.hpp>
#include <Netplay.hpp>
#include "log.hpp" #include "log.hpp"
#include <SDL2/SDL_keyboard.h>
namespace n64 { namespace n64 {
JoybusDevice players[4]{};
void PIF::InitDevices(SaveType saveType) { void PIF::InitDevices(SaveType saveType) {
joybusDevices[0].type = JOYBUS_CONTROLLER; for (int i = 0; i < 4; i++) { //TODO: make this configurable
joybusDevices[0].accessoryType = ACCESSORY_MEMPACK; joybusDevices[i].type = JOYBUS_CONTROLLER;
for (int i = 1; i < 4; i++) { //TODO: make this configurable joybusDevices[i].accessoryType = ACCESSORY_MEMPACK;
joybusDevices[i].type = JOYBUS_NONE;
joybusDevices[i].accessoryType = ACCESSORY_NONE;
} }
if (saveType == SAVE_EEPROM_4k) { if (saveType == SAVE_EEPROM_4k) {
@@ -21,6 +24,111 @@ void PIF::InitDevices(SaveType saveType) {
joybusDevices[5].type = JOYBUS_NONE; joybusDevices[5].type = JOYBUS_NONE;
} }
#define GET_BUTTON(gamecontroller, i) SDL_GameControllerGetButton(gamecontroller, i)
#define GET_AXIS(gamecontroller, axis) SDL_GameControllerGetAxis(gamecontroller, axis)
template <int port>
void PIF::PollController() {
if(gamepadConnected) {
bool A = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_A);
bool B = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_X);
bool Z = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_TRIGGERLEFT) == SDL_JOYSTICK_AXIS_MAX;
bool START = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_START);
bool DUP = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_UP);
bool DDOWN = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
bool DLEFT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
bool DRIGHT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
bool L = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
bool R = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
bool CUP = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) <= -127;
bool CDOWN = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) >= 127;
bool CLEFT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) <= -127;
bool CRIGHT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) >= 127;
players[port].controller.a = A;
players[port].controller.b = B;
players[port].controller.z = Z;
players[port].controller.start = START;
players[port].controller.dp_up = DUP;
players[port].controller.dp_down = DDOWN;
players[port].controller.dp_left = DLEFT;
players[port].controller.dp_right = DRIGHT;
players[port].controller.joy_reset = L && R && START;
players[port].controller.l = L;
players[port].controller.r = R;
players[port].controller.c_up = CUP;
players[port].controller.c_down = CDOWN;
players[port].controller.c_left = CLEFT;
players[port].controller.c_right = CRIGHT;
float xclamped = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTX);
if(xclamped < 0) {
xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN));
} else {
xclamped /= SDL_JOYSTICK_AXIS_MAX;
}
xclamped *= 86;
float yclamped = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTY);
if(yclamped < 0) {
yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN));
} else {
yclamped /= SDL_JOYSTICK_AXIS_MAX;
}
yclamped *= 86;
players[port].controller.joy_x = xclamped;
players[port].controller.joy_y = -yclamped;
if (players[port].controller.joy_reset) {
players[port].controller.start = false;
players[port].controller.joy_x = 0;
players[port].controller.joy_y = 0;
}
} else {
const uint8_t* state = SDL_GetKeyboardState(nullptr);
players[port].controller.a = state[SDL_SCANCODE_X];
players[port].controller.b = state[SDL_SCANCODE_C];
players[port].controller.z = state[SDL_SCANCODE_Z];
players[port].controller.start = state[SDL_SCANCODE_RETURN];
players[port].controller.dp_up = state[SDL_SCANCODE_PAGEUP];
players[port].controller.dp_down = state[SDL_SCANCODE_PAGEDOWN];
players[port].controller.dp_left = state[SDL_SCANCODE_HOME];
players[port].controller.dp_right = state[SDL_SCANCODE_END];
players[port].controller.joy_reset = state[SDL_SCANCODE_RETURN] && state[SDL_SCANCODE_A] && state[SDL_SCANCODE_S];
players[port].controller.l = state[SDL_SCANCODE_A];
players[port].controller.r = state[SDL_SCANCODE_S];
players[port].controller.c_up = state[SDL_SCANCODE_I];
players[port].controller.c_down = state[SDL_SCANCODE_K];
players[port].controller.c_left = state[SDL_SCANCODE_J];
players[port].controller.c_right = state[SDL_SCANCODE_L];
s16 xaxis = 0, yaxis = 0;
if (state[SDL_SCANCODE_LEFT]) {
xaxis = -86;
} else if (state[SDL_SCANCODE_RIGHT]) {
xaxis = 86;
}
if (state[SDL_SCANCODE_DOWN]) {
yaxis = -86;
} else if (state[SDL_SCANCODE_UP]) {
yaxis = 86;
}
players[port].controller.joy_x = xaxis;
players[port].controller.joy_y = yaxis;
if (players[port].controller.joy_reset) {
players[port].controller.start = false;
players[port].controller.joy_x = 0;
players[port].controller.joy_y = 0;
}
}
}
void PIF::ControllerID(u8 *res) const { void PIF::ControllerID(u8 *res) const {
if (channel < 6) { if (channel < 6) {
switch (joybusDevices[channel].type) { switch (joybusDevices[channel].type) {

View File

@@ -0,0 +1,7 @@
#pragma once
namespace n64 {
struct JoybusDevice;
extern JoybusDevice players[4];
}