mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-25 07:21:14 +01:00
NetPlay: Allow manual adjustments to the pad buffer size. Hacked in all the functions that will be needed for wiimote support (not functional yet). Rumble is sent to the correct gamepad during netplay. Stop button works better. Games no longer hang on disconnect.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5434 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
6c934f7951
commit
ec11685a66
@ -417,7 +417,7 @@ u32 CEXIIPL::GetGCTime()
|
||||
#else
|
||||
|
||||
// hack in some netplay stuff
|
||||
u64 ltime = GetNetGCTime();
|
||||
u64 ltime = NetPlay_GetGCTime();
|
||||
if (0 == ltime)
|
||||
ltime = Common::Timer::GetLocalTimeSinceJan1970();
|
||||
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
static u32 GetGCTime();
|
||||
static u32 GetNetGCTime();
|
||||
static u32 NetPlay_GetGCTime();
|
||||
|
||||
static void Descrambler(u8* data, u32 size);
|
||||
|
||||
|
@ -134,7 +134,7 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||
u32 netValues[2] = {0};
|
||||
int NetPlay = 2;
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
NetPlay = GetNetInput(ISIDevice::m_iDeviceNumber, PadStatus, netValues);
|
||||
NetPlay = NetPlay_GetInput(ISIDevice::m_iDeviceNumber, PadStatus, netValues);
|
||||
#endif
|
||||
|
||||
if (NetPlay != 2)
|
||||
@ -271,8 +271,13 @@ void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll)
|
||||
{
|
||||
unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard
|
||||
unsigned int uStrength = command.Parameter2;
|
||||
if (pad->PAD_Rumble)
|
||||
pad->PAD_Rumble(ISIDevice::m_iDeviceNumber, uType, uStrength);
|
||||
|
||||
// get the correct pad number that should rumble locally when using netplay
|
||||
const u8 numPAD = NetPlay_GetPadNum(ISIDevice::m_iDeviceNumber);
|
||||
|
||||
if (numPAD < 4)
|
||||
if (pad->PAD_Rumble)
|
||||
pad->PAD_Rumble(numPAD, uType, uStrength);
|
||||
|
||||
if (!_Poll)
|
||||
{
|
||||
|
@ -102,7 +102,8 @@ public:
|
||||
virtual int RunBuffer(u8* _pBuffer, int _iLength);
|
||||
|
||||
// Send and Receive pad input from network
|
||||
static int GetNetInput(u8 numPAD, SPADStatus, u32 *PADStatus);
|
||||
static int NetPlay_GetInput(u8 numPAD, SPADStatus, u32 *PADStatus);
|
||||
static u8 NetPlay_GetPadNum(u8 numPAD);
|
||||
|
||||
// Return true on new data
|
||||
virtual bool GetData(u32& _Hi, u32& _Low);
|
||||
|
@ -494,6 +494,7 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
|
||||
{
|
||||
if (m_WiiMotes[i].IsConnected() == 3 && m_FreqDividerMote == 150 / (i + 1))
|
||||
{
|
||||
NetPlay_WiimoteUpdate(i);
|
||||
CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update(i);
|
||||
return true;
|
||||
}
|
||||
|
@ -95,6 +95,8 @@ public:
|
||||
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
void NetPlay_WiimoteUpdate(int _number);
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
|
@ -258,6 +258,8 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
|
||||
_dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->CID), "L2CAP: SendACLPacket to unknown channel %i", pHeader->CID);
|
||||
CChannelMap::iterator itr= m_Channel.find(pHeader->CID);
|
||||
|
||||
const int number = NetPlay_GetWiimoteNum(m_ConnectionHandle & 0xFF);
|
||||
|
||||
Common::PluginWiimote* mote = CPluginManager::GetInstance().GetWiimote(0);
|
||||
if (itr != m_Channel.end())
|
||||
{
|
||||
@ -269,11 +271,13 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
|
||||
break;
|
||||
|
||||
case HID_CONTROL_CHANNEL:
|
||||
mote->Wiimote_ControlChannel(m_ConnectionHandle & 0xFF, pHeader->CID, pData, DataSize);
|
||||
if (number < 4)
|
||||
mote->Wiimote_ControlChannel(number, pHeader->CID, pData, DataSize);
|
||||
break;
|
||||
|
||||
case HID_INTERRUPT_CHANNEL:
|
||||
mote->Wiimote_InterruptChannel(m_ConnectionHandle & 0xFF, pHeader->CID, pData, DataSize);
|
||||
if (number < 4)
|
||||
mote->Wiimote_InterruptChannel(number, pHeader->CID, pData, DataSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -854,6 +858,9 @@ void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLeng
|
||||
// ---------------------------------------------------
|
||||
void CWII_IPC_HLE_WiiMote::ReceiveL2capData(u16 scid, const void* _pData, u32 _Size)
|
||||
{
|
||||
if (NetPlay_WiimoteInput(m_ConnectionHandle & 0xFF, scid, _pData, _Size))
|
||||
return;
|
||||
|
||||
// Allocate DataFrame
|
||||
u8 DataFrame[1024];
|
||||
u32 Offset = 0;
|
||||
|
@ -170,6 +170,9 @@ public:
|
||||
void ExecuteL2capCmd(u8* _pData, u32 _Size); // From CPU
|
||||
void ReceiveL2capData(u16 scid, const void* _pData, u32 _Size); // From wiimote
|
||||
|
||||
int NetPlay_GetWiimoteNum(int _number);
|
||||
bool NetPlay_WiimoteInput(int _number, u16 _channelID, const void* _pData, u32& _Size);
|
||||
|
||||
void EventConnectionAccepted();
|
||||
void EventDisconnect();
|
||||
bool EventPagingChanged(u8 _pageMode);
|
||||
|
@ -934,6 +934,14 @@
|
||||
RelativePath=".\Src\NetPlay.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\NetPlayClient.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\NetPlayServer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\NetWindow.cpp"
|
||||
>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@
|
||||
#include "CommonTypes.h"
|
||||
//#define WIN32_LEAN_AND_MEAN
|
||||
#include "Thread.h"
|
||||
#include "Timer.h"
|
||||
|
||||
// hax, i hope something like this isn't needed on non-windows
|
||||
#define _WINSOCK2API_
|
||||
@ -17,6 +18,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
|
||||
class NetPlayDiag;
|
||||
|
||||
@ -30,7 +32,17 @@ public:
|
||||
u32 nLo;
|
||||
};
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2.1"
|
||||
class NetWiimote
|
||||
{
|
||||
public:
|
||||
NetWiimote& operator=(const NetWiimote&);
|
||||
NetWiimote(const u32 _size) : size(_size), data(new u8[size]) {}
|
||||
|
||||
const u32 size;
|
||||
u8* const data;
|
||||
};
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2.2"
|
||||
|
||||
#ifdef _M_X64
|
||||
#define NP_ARCH "x64"
|
||||
@ -39,11 +51,11 @@ public:
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" win-"NP_ARCH
|
||||
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" W"NP_ARCH
|
||||
#elif __APPLE__
|
||||
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" osx-"NP_ARCH
|
||||
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" M"NP_ARCH
|
||||
#else
|
||||
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" nix-"NP_ARCH
|
||||
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" L"NP_ARCH
|
||||
#endif
|
||||
|
||||
// messages
|
||||
@ -56,9 +68,13 @@ public:
|
||||
#define NP_MSG_PAD_MAPPING 0x61
|
||||
#define NP_MSG_PAD_BUFFER 0x62
|
||||
|
||||
#define NP_MSG_WIIMOTE_DATA 0x70
|
||||
#define NP_MSG_WIIMOTE_MAPPING 0x71 // just using pad mapping for now
|
||||
|
||||
#define NP_MSG_START_GAME 0xA0
|
||||
#define NP_MSG_CHANGE_GAME 0xA1
|
||||
#define NP_MSG_STOP_GAME 0xA2
|
||||
#define NP_MSG_DISABLE_GAME 0xA3
|
||||
|
||||
#define NP_MSG_READY 0xD0
|
||||
#define NP_MSG_NOT_READY 0xD1
|
||||
@ -67,25 +83,46 @@ public:
|
||||
#define NP_MSG_PONG 0xE1
|
||||
// end messages
|
||||
|
||||
// gui messages
|
||||
#define NP_GUI_UPDATE 0x10
|
||||
// end messages
|
||||
|
||||
typedef u8 MessageId;
|
||||
typedef u8 PlayerId;
|
||||
typedef s8 PadMapping;
|
||||
typedef u32 FrameNum;
|
||||
|
||||
enum
|
||||
{
|
||||
CON_ERR_SERVER_FULL = 1,
|
||||
CON_ERR_GAME_RUNNING,
|
||||
CON_ERR_VERSION_MISMATCH
|
||||
};
|
||||
|
||||
THREAD_RETURN NetPlayThreadFunc(void* arg);
|
||||
|
||||
// something like this should be in Common stuff
|
||||
class CritLocker
|
||||
{
|
||||
public:
|
||||
//CritLocker(const CritLocker&);
|
||||
CritLocker& operator=(const CritLocker&);
|
||||
CritLocker(Common::CriticalSection& crit) : m_crit(crit) { m_crit.Enter(); }
|
||||
~CritLocker() { m_crit.Leave(); }
|
||||
|
||||
private:
|
||||
Common::CriticalSection& m_crit;
|
||||
};
|
||||
|
||||
class NetPlay
|
||||
{
|
||||
public:
|
||||
NetPlay() : m_is_running(false), m_do_loop(true) {}
|
||||
NetPlay();
|
||||
virtual ~NetPlay();
|
||||
virtual void Entry() = 0;
|
||||
|
||||
bool is_connected;
|
||||
|
||||
// Send and receive pads values
|
||||
virtual bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues) = 0;
|
||||
void WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size);
|
||||
void WiimoteUpdate(int _number);
|
||||
bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
virtual bool ChangeGame(const std::string& game) = 0;
|
||||
virtual void GetPlayerList(std::string& list) = 0;
|
||||
virtual void SendChatMessage(const std::string& msg) = 0;
|
||||
@ -93,15 +130,23 @@ public:
|
||||
virtual bool StartGame(const std::string &path);
|
||||
virtual bool StopGame();
|
||||
|
||||
//void PushPadStates(unsigned int count);
|
||||
|
||||
u8 GetPadNum(u8 numPAD);
|
||||
|
||||
protected:
|
||||
//NetPlay(Common::ThreadFunc entry, void* arg) : m_thread(entry, arg) {}
|
||||
void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues);
|
||||
//void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues);
|
||||
void ClearBuffers();
|
||||
void UpdateGUI();
|
||||
void AppendChatGUI(const std::string& msg);
|
||||
virtual void SendPadState(const PadMapping local_nb, const NetPad& np) = 0;
|
||||
|
||||
struct
|
||||
{
|
||||
Common::CriticalSection send, players, buffer, other;
|
||||
Common::CriticalSection game;
|
||||
// lock order
|
||||
Common::CriticalSection players, buffer, send;
|
||||
} m_crit;
|
||||
|
||||
class Player
|
||||
@ -118,6 +163,9 @@ protected:
|
||||
|
||||
//LockingQueue<NetPad> m_pad_buffer[4];
|
||||
std::queue<NetPad> m_pad_buffer[4];
|
||||
std::map<FrameNum, NetWiimote> m_wiimote_buffer[4];
|
||||
|
||||
FrameNum m_wiimote_update_frame;
|
||||
|
||||
NetPlayDiag* m_dialog;
|
||||
sf::SocketTCP m_socket;
|
||||
@ -125,13 +173,22 @@ protected:
|
||||
sf::Selector<sf::SocketTCP> m_selector;
|
||||
|
||||
std::string m_selected_game;
|
||||
bool m_is_running;
|
||||
volatile bool m_is_running;
|
||||
volatile bool m_do_loop;
|
||||
|
||||
unsigned int m_target_buffer_size;
|
||||
|
||||
Player* m_local_player;
|
||||
|
||||
u32 m_on_game;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
void NetPlay_Enable(NetPlay* const np);
|
||||
void NetPlay_Disable();
|
||||
|
||||
class NetPlayServer : public NetPlay
|
||||
{
|
||||
public:
|
||||
@ -143,26 +200,38 @@ public:
|
||||
void GetPlayerList(std::string& list);
|
||||
|
||||
// Send and receive pads values
|
||||
bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
//bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
bool ChangeGame(const std::string& game);
|
||||
void SendChatMessage(const std::string& msg);
|
||||
|
||||
bool StartGame(const std::string &path);
|
||||
bool StopGame();
|
||||
|
||||
u64 CalculateMinimumBufferTime();
|
||||
void AdjustPadBufferSize(unsigned int size);
|
||||
|
||||
private:
|
||||
class Client : public Player
|
||||
{
|
||||
public:
|
||||
Client() : ping(0), on_game(0) {}
|
||||
|
||||
sf::SocketTCP socket;
|
||||
u64 ping;
|
||||
u32 on_game;
|
||||
};
|
||||
|
||||
void SendPadState(const PadMapping local_nb, const NetPad& np);
|
||||
void SendToClients(sf::Packet& packet, const PlayerId skip_pid = 0);
|
||||
unsigned int OnConnect(sf::SocketTCP& socket);
|
||||
unsigned int OnDisconnect(sf::SocketTCP& socket);
|
||||
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
|
||||
|
||||
std::map<sf::SocketTCP, Client> m_players;
|
||||
|
||||
Common::Timer m_ping_timer;
|
||||
u32 m_ping_key;
|
||||
bool m_update_pings;
|
||||
};
|
||||
|
||||
class NetPlayClient : public NetPlay
|
||||
@ -176,11 +245,13 @@ public:
|
||||
void GetPlayerList(std::string& list);
|
||||
|
||||
// Send and receive pads values
|
||||
bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
//bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
bool StartGame(const std::string &path);
|
||||
bool ChangeGame(const std::string& game);
|
||||
void SendChatMessage(const std::string& msg);
|
||||
|
||||
private:
|
||||
void SendPadState(const PadMapping local_nb, const NetPad& np);
|
||||
unsigned int OnData(sf::Packet& packet);
|
||||
|
||||
PlayerId m_pid;
|
||||
|
@ -28,7 +28,7 @@ BEGIN_EVENT_TABLE(NetPlayDiag, wxFrame)
|
||||
EVT_COMMAND(wxID_ANY, wxEVT_THREAD, NetPlayDiag::OnThread)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
NetPlay* netplay_ptr = NULL;
|
||||
static NetPlay* netplay_ptr = NULL;
|
||||
|
||||
NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* const game_list)
|
||||
: wxFrame(parent, wxID_ANY, wxT(NETPLAY_TITLEBAR), wxDefaultPosition, wxDefaultSize)
|
||||
@ -68,12 +68,12 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||
wxStaticText* const alert_lbl = new wxStaticText(connect_tab, wxID_ANY
|
||||
, wxT("ALERT:\n\nNetPlay will currently only work properly when using the following settings:")
|
||||
wxT("\n - Dual Core [OFF]")
|
||||
wxT("\n - Audio Throttle [OFF] (if using DSP HLE)")
|
||||
wxT("\n - DSP LLE Plugin (may not be needed)\n - DSPLLE on thread [OFF]")
|
||||
wxT("\n - Manually set the exact number of controller that will be used to [Standard Controller]")
|
||||
wxT("\n - Audio Throttle [OFF/ON] (try both)")
|
||||
wxT("\n - DSP LLE/HLE (try both)")
|
||||
wxT("\n - Manually set the exact number of controllers that will be used to [Standard Controller]")
|
||||
wxT("\n\nAll players should try to use the same Dolphin version and settings.")
|
||||
wxT("\nDisable all memory cards or send them to all players before starting.")
|
||||
wxT("\nWiimote support has not been implemented.\nWii games will likely desync for other reasons as well.")
|
||||
wxT("\nWiimote support has not been implemented.")
|
||||
wxT("\n\nYou must forward TCP port to host!!")
|
||||
, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
@ -285,9 +285,17 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game
|
||||
wxButton* const start_btn = new wxButton(panel, wxID_ANY, wxT("Start"));
|
||||
_connect_macro_(start_btn, NetPlayDiag::OnStart, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||
bottom_szr->Add(start_btn);
|
||||
wxButton* const stop_btn = new wxButton(panel, wxID_ANY, wxT("Stop [buggy]"));
|
||||
wxButton* const stop_btn = new wxButton(panel, wxID_ANY, wxT("Stop"));
|
||||
_connect_macro_(stop_btn, NetPlayDiag::OnStop, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||
bottom_szr->Add(stop_btn);
|
||||
bottom_szr->Add(new wxStaticText(panel, wxID_ANY, wxT("Buffer:")), 0, wxLEFT | wxCENTER, 5 );
|
||||
wxSpinCtrl* const padbuf_spin = new wxSpinCtrl(panel, wxID_ANY, wxT("20")
|
||||
, wxDefaultPosition, wxSize(64, -1), wxSP_ARROW_KEYS, 0, 200, 20);
|
||||
_connect_macro_(padbuf_spin, NetPlayDiag::OnAdjustBuffer, wxEVT_COMMAND_SPINCTRL_UPDATED, this);
|
||||
wxButton* const padbuf_btn = new wxButton(panel, wxID_ANY, wxT("?"), wxDefaultPosition, wxSize(22, -1));
|
||||
_connect_macro_(padbuf_btn, NetPlayDiag::OnPadBuffHelp, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||
bottom_szr->Add(padbuf_spin, 0, wxCENTER);
|
||||
bottom_szr->Add(padbuf_btn);
|
||||
}
|
||||
|
||||
bottom_szr->AddStretchSpacer(1);
|
||||
@ -364,6 +372,31 @@ void NetPlayDiag::OnStop(wxCommandEvent& event)
|
||||
::netplay_ptr->StopGame();
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnPadBuffHelp(wxCommandEvent& event)
|
||||
{
|
||||
// warning removal
|
||||
event.GetId();
|
||||
|
||||
const u64 time = ((NetPlayServer*)::netplay_ptr)->CalculateMinimumBufferTime();
|
||||
std::ostringstream ss;
|
||||
ss << "< Calculated from pings: required buffer: "
|
||||
<< time * (60/1000) << "(60fps) / "
|
||||
<< time * (50/1000) << "(50fps) >\n";
|
||||
|
||||
m_chat_text->AppendText(wxString(ss.str().c_str(), *wxConvCurrent));
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnAdjustBuffer(wxCommandEvent& event)
|
||||
{
|
||||
const int val = ((wxSpinCtrl*)event.GetEventObject())->GetValue();
|
||||
((NetPlayServer*)::netplay_ptr)->AdjustPadBufferSize(val);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "< Pad Buffer: " << val << " >";
|
||||
::netplay_ptr->SendChatMessage(ss.str());
|
||||
m_chat_text->AppendText(wxString(ss.str().c_str(), *wxConvCurrent).Append(wxT('\n')));
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnQuit(wxCommandEvent& event)
|
||||
{
|
||||
// warning removal
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/gbsizer.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <wx/spinctrl.h>
|
||||
//#include <wx/thread.h>
|
||||
|
||||
#include "GameListCtrl.h"
|
||||
@ -93,8 +94,10 @@ private:
|
||||
|
||||
void OnChat(wxCommandEvent& event);
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
void OnPadBuffHelp(wxCommandEvent& event);
|
||||
void OnThread(wxCommandEvent& event);
|
||||
void OnChangeGame(wxCommandEvent& event);
|
||||
void OnAdjustBuffer(wxCommandEvent& event);
|
||||
|
||||
wxListBox* m_player_lbox;
|
||||
wxTextCtrl* m_chat_text;
|
||||
|
@ -38,6 +38,8 @@ if wxenv['HAVE_WX']:
|
||||
'WxUtils.cpp',
|
||||
'MemoryCards/WiiSaveCrypted.cpp',
|
||||
'NetPlay.cpp',
|
||||
'NetPlayClient.cpp',
|
||||
'NetPlayServer.cpp',
|
||||
'NetWindow.cpp',
|
||||
]
|
||||
|
||||
|
@ -138,8 +138,3 @@ void Host_UpdateLeds(int bits){}
|
||||
void Host_UpdateSpeakerStatus(int index, int bits){}
|
||||
void Host_UpdateStatus(){}
|
||||
void Host_Message(int){}
|
||||
|
||||
int CSIDevice_GCController::GetNetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user