Merge branch 'wiimote-netplay'

Conflicts:
	Source/Core/Core/Src/NetPlayClient.cpp
	Source/Core/Core/Src/NetPlayClient.h
	Source/Core/Core/Src/NetPlayProto.h
	Source/Core/Core/Src/NetPlayServer.cpp
	Source/Core/Core/Src/NetPlayServer.h
	Source/Core/DolphinWX/Src/NetWindow.cpp
	Source/Core/DolphinWX/Src/NetWindow.h
This commit is contained in:
Rachel Bryk 2013-09-22 14:27:52 -04:00
commit f3469c16a5
12 changed files with 317 additions and 59 deletions

View File

@ -27,6 +27,7 @@ inline double round(double x) { return (x-floor(x))>0.5 ? ceil(x) : floor(x); }
#include "MatrixMath.h"
#include "../../Movie.h"
#include "NetPlayClient.h"
namespace
{
@ -339,7 +340,7 @@ bool Wiimote::Step()
m_rumble->controls[0]->control_ref->State(m_rumble_on);
// when a movie is active, this button status update is disabled (moved), because movies only record data reports.
if(!(Movie::IsPlayingInput() || Movie::IsRecordingInput()))
if(!(Movie::IsPlayingInput() || Movie::IsRecordingInput()) || NetPlay::IsNetPlayRunning())
{
UpdateButtonsStatus(has_focus);
}
@ -397,7 +398,7 @@ void Wiimote::UpdateButtonsStatus(bool has_focus)
void Wiimote::GetCoreData(u8* const data)
{
// when a movie is active, the button update happens here instead of Wiimote::Step, to avoid potential desync issues.
if(Movie::IsPlayingInput() || Movie::IsRecordingInput())
if(Movie::IsPlayingInput() || Movie::IsRecordingInput() || NetPlay::IsNetPlayRunning())
{
UpdateButtonsStatus(HAS_FOCUS);
}
@ -770,6 +771,12 @@ void Wiimote::Update()
}
}
}
if (NetPlay::IsNetPlayRunning())
{
NetPlay_GetWiimoteData(m_index, data, rptf.size);
if (rptf.core)
m_status.buttons = *(wm_core*)(data + rptf.core);
}
if (!Movie::IsPlayingInput())
{
Movie::CheckWiimoteStatus(m_index, data, rptf, m_reg_ir.mode);

View File

@ -158,6 +158,7 @@ private:
void WriteData(const wm_write_data* const wd);
void SendReadDataReply(ReadRequest& _request);
void SpeakerData(wm_speaker_data* sd);
bool NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size);
// control groups
Buttons *m_buttons, *m_dpad, *m_shake;

View File

@ -465,7 +465,6 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
if (m_WiiMotes[i].IsConnected())
{
NetPlay_WiimoteUpdate(i);
Wiimote::Update(i);
}
m_last_ticks = now;

View File

@ -265,7 +265,7 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
_dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->dcid), "L2CAP: SendACLPacket to unknown channel %i", pHeader->dcid);
CChannelMap::iterator itr= m_Channel.find(pHeader->dcid);
const int number = NetPlay_GetWiimoteNum(m_ConnectionHandle & 0xFF);
const int number = m_ConnectionHandle & 0xFF;
if (itr != m_Channel.end())
{
@ -862,8 +862,6 @@ 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];

View File

@ -56,7 +56,6 @@ public:
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();

View File

@ -18,6 +18,7 @@
#include "Core.h"
#include "ConfigManager.h"
#include "Movie.h"
#include "HW/WiimoteEmu/WiimoteEmu.h"
std::mutex crit_netplay_client;
static NetPlayClient * netplay_client = NULL;
@ -195,6 +196,15 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
}
break;
case NP_MSG_WIIMOTE_MAPPING :
{
for (PadMapping i = 0; i < 4; i++)
packet >> m_wiimote_map[i];
m_dialog->Update();
}
break;
case NP_MSG_PAD_DATA :
{
PadMapping map = 0;
@ -207,6 +217,27 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
}
break;
case NP_MSG_WIIMOTE_DATA :
{
PadMapping map = 0;
NetWiimote nw;
u8 size;
packet >> map >> size;
nw.resize(size);
u8* data = new u8[size];
for (unsigned int i = 0; i < size; ++i)
packet >> data[i];
nw.assign(data,data+size);
delete[] data;
// trusting server for good map value (>=0 && <4)
// add to wiimote buffer
m_wiimote_buffer[(unsigned)map].Push(nw);
}
break;
case NP_MSG_PAD_BUFFER :
{
u32 size = 0;
@ -353,6 +384,13 @@ void NetPlayClient::GetPlayerList(std::string& list, std::vector<int>& pid_list)
else
ss << '-';
}
for (unsigned int j = 0; j < 4; j++)
{
if (m_wiimote_map[j] == player->pid)
ss << j + 1;
else
ss << '-';
}
ss << " | " << player->ping << "ms\n";
pid_list.push_back(player->pid);
}
@ -399,6 +437,22 @@ void NetPlayClient::SendPadState(const PadMapping in_game_pad, const NetPad& np)
m_socket.Send(spac);
}
// called from ---CPU--- thread
void NetPlayClient::SendWiimoteState(const PadMapping in_game_pad, const NetWiimote& nw)
{
// send to server
sf::Packet spac;
spac << (MessageId)NP_MSG_WIIMOTE_DATA;
spac << in_game_pad;
u8 size = nw.size();
spac << size;
for (unsigned int i = 0; i < size; ++i)
spac << nw.data()[i];
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
m_socket.Send(spac);
}
// called from ---GUI--- thread
bool NetPlayClient::StartGame(const std::string &path)
{
@ -446,11 +500,17 @@ bool NetPlayClient::StartGame(const std::string &path)
UpdateDevices();
// temporary
// Needed to prevent locking up at boot if (when) the wiimotes connect out of order.
NetWiimote nw;
for (unsigned int i = 0; i<4; ++i)
for (unsigned int f = 0; f<2; ++f)
m_wiimote_buffer[i].Push(nw);
nw.resize(4, 0);
for (unsigned int w = 0; w < 4; ++w)
{
if (m_wiimote_map[w] != -1)
// probably overkill, but whatever
for (unsigned int i = 0; i < 7; ++i)
m_wiimote_buffer[w].Push(nw);
}
return true;
}
@ -482,8 +542,6 @@ void NetPlayClient::ClearBuffers()
while (m_wiimote_buffer[i].Size())
m_wiimote_buffer[i].Pop();
m_wiimote_input[i].clear();
}
}
@ -570,16 +628,95 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_stat
return true;
}
// called from ---CPU--- thread
void NetPlayClient::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size)
{
// XXX
}
// called from ---CPU--- thread
void NetPlayClient::WiimoteUpdate(int _number)
bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size)
{
// XXX
NetWiimote nw;
static u8 previousSize[4] = {4,4,4,4};
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
// in game mapping for this local wiimote
unsigned int in_game_num = LocalWiimoteToInGameWiimote(_number);
// does this local wiimote map in game?
if (in_game_num < 4)
{
if (previousSize[in_game_num] == size)
{
nw.assign(data, data + size);
do
{
// add to buffer
m_wiimote_buffer[in_game_num].Push(nw);
SendWiimoteState(in_game_num, nw);
} while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size * 200 / 120); // TODO: add a seperate setting for wiimote buffer?
}
else
{
while (m_wiimote_buffer[in_game_num].Size() > 0)
{
// Reporting mode changed, so previous buffer is no good.
m_wiimote_buffer[in_game_num].Pop();
}
nw.resize(size, 0);
m_wiimote_buffer[in_game_num].Push(nw);
m_wiimote_buffer[in_game_num].Push(nw);
m_wiimote_buffer[in_game_num].Push(nw);
previousSize[in_game_num] = size;
}
}
} // unlock players
while (previousSize[_number] == size && !m_wiimote_buffer[_number].Pop(nw))
{
// wait for receiving thread to push some data
Common::SleepCurrentThread(1);
if (false == m_is_running)
return false;
}
// Use a blank input, since we may not have any valid input.
if (previousSize[_number] != size)
{
nw.resize(size, 0);
m_wiimote_buffer[_number].Push(nw);
m_wiimote_buffer[_number].Push(nw);
}
// We should have used a blank input last time, so now we just need to pop through the old buffer, until we reach a good input
if (nw.size() != size)
{
u8 tries = 0;
// Clear the buffer and wait for new input, since we probably just changed reporting mode.
while (nw.size() != size)
{
while (!m_wiimote_buffer[_number].Pop(nw))
{
Common::SleepCurrentThread(1);
if (false == m_is_running)
return false;
}
++tries;
if (tries > m_target_buffer_size * 200 / 120)
break;
}
// If it still mismatches, it surely desynced
if (size != nw.size())
{
PanicAlert("Netplay has desynced. There is no way to recover from this.");
return false;
}
}
previousSize[_number] = size;
memcpy(data, nw.data(), size);
return true;
}
// called from ---GUI--- thread and ---NETPLAY--- thread (client side)
@ -614,6 +751,11 @@ void NetPlayClient::Stop()
if (m_pad_map[i] == m_local_player->pid)
isPadMapped = true;
}
for (unsigned int i = 0; i < 4; ++i)
{
if (m_wiimote_map[i] == m_local_player->pid)
isPadMapped = true;
}
// tell the server to stop if we have a pad mapped in game.
if (isPadMapped)
{
@ -660,6 +802,25 @@ u8 NetPlayClient::LocalPadToInGamePad(u8 local_pad)
return ingame_pad;
}
u8 NetPlayClient::LocalWiimoteToInGameWiimote(u8 local_pad)
{
// Figure out which in-game pad maps to which local pad.
// The logic we have here is that the local slots always
// go in order.
int local_pad_count = -1;
int ingame_pad = 0;
for (; ingame_pad < 4; ingame_pad++)
{
if (m_wiimote_map[ingame_pad] == m_local_player->pid)
local_pad_count++;
if (local_pad_count == local_pad)
break;
}
return ingame_pad;
}
// stuff hacked into dolphin
// called from ---CPU--- thread
@ -674,6 +835,16 @@ bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u
return false;
}
bool WiimoteEmu::Wiimote::NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size)
{
std::lock_guard<std::mutex> lk(crit_netplay_client);
if (netplay_client)
return netplay_client->WiimoteUpdate(wiimote, data, size);
else
return false;
}
bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
{
return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus);
@ -718,33 +889,6 @@ u8 CSIDevice_DanceMat::NetPlay_InGamePadToLocalPad(u8 numPAD)
return CSIDevice_GCController::NetPlay_InGamePadToLocalPad(numPAD);
}
// called from ---CPU--- thread
// wiimote update / used for frame counting
//void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number)
void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int)
{
}
// called from ---CPU--- thread
//
int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number)
{
return _number;
}
// called from ---CPU--- thread
// intercept wiimote input callback
//bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int _number, u16 _channelID, const void* _pData, u32& _Size)
bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&)
{
std::lock_guard<std::mutex> lk(crit_netplay_client);
if (netplay_client)
return true;
else
return false;
}
bool NetPlay::IsNetPlayRunning()
{
return netplay_client != NULL;

View File

@ -78,13 +78,14 @@ public:
void SendChatMessage(const std::string& msg);
// Send and receive pads values
void WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size);
void WiimoteUpdate(int _number);
bool WiimoteUpdate(int _number, u8* data, const u8 size);
bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
u8 LocalPadToInGamePad(u8 localPad);
u8 InGamePadToLocalPad(u8 localPad);
u8 LocalWiimoteToInGameWiimote(u8 local_pad);
protected:
void ClearBuffers();
@ -98,8 +99,6 @@ protected:
Common::FifoQueue<NetPad> m_pad_buffer[4];
Common::FifoQueue<NetWiimote> m_wiimote_buffer[4];
NetWiimote m_wiimote_input[4];
NetPlayUI* m_dialog;
sf::SocketTCP m_socket;
std::thread m_thread;
@ -116,12 +115,14 @@ protected:
u32 m_current_game;
PadMapping m_pad_map[4];
PadMapping m_wiimote_map[4];
bool m_is_recording;
private:
void UpdateDevices();
void SendPadState(const PadMapping in_game_pad, const NetPad& np);
void SendWiimoteState(const PadMapping in_game_pad, const NetWiimote& nw);
unsigned int OnData(sf::Packet& packet);
PlayerId m_pid;

View File

@ -25,12 +25,13 @@ struct Rpt : public std::vector<u8>
u16 channel;
};
typedef std::vector<Rpt> NetWiimote;
typedef std::vector<u8> NetWiimote;
#define NETPLAY_VERSION "Dolphin NetPlay 2013-09-03"
#define NETPLAY_VERSION "Dolphin NetPlay 2013-09-22"
const int NETPLAY_INITIAL_GCTIME = 1272737767;
// messages
enum
{
@ -44,7 +45,7 @@ enum
NP_MSG_PAD_BUFFER = 0x62,
NP_MSG_WIIMOTE_DATA = 0x70,
NP_MSG_WIIMOTE_MAPPING = 0x71, // just using pad mapping for now
NP_MSG_WIIMOTE_MAPPING = 0x71,
NP_MSG_START_GAME = 0xA0,
NP_MSG_CHANGE_GAME = 0xA1,

View File

@ -25,12 +25,14 @@ NetPlayServer::~NetPlayServer()
NetPlayServer::NetPlayServer(const u16 port) : is_connected(false), m_is_running(false)
{
memset(m_pad_map, -1, sizeof(m_pad_map));
memset(m_wiimote_map, -1, sizeof(m_wiimote_map));
if (m_socket.Listen(port))
{
is_connected = true;
m_do_loop = true;
m_selector.Add(m_socket);
m_thread = std::thread(std::mem_fun(&NetPlayServer::ThreadFunc), this);
m_target_buffer_size = 20;
}
}
@ -213,6 +215,7 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
m_players[socket] = player;
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
UpdatePadMapping(); // sync pad mappings with everyone
UpdateWiimoteMapping();
}
@ -258,6 +261,11 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
m_pad_map[i] = -1;
UpdatePadMapping();
for (int i = 0; i < 4; i++)
if (m_wiimote_map[i] == pid)
m_wiimote_map[i] = -1;
UpdateWiimoteMapping();
return 0;
}
@ -268,6 +276,12 @@ void NetPlayServer::GetPadMapping(PadMapping map[4])
map[i] = m_pad_map[i];
}
void NetPlayServer::GetWiimoteMapping(PadMapping map[4])
{
for (int i = 0; i < 4; i++)
map[i] = m_wiimote_map[i];
}
// called from ---GUI--- thread
void NetPlayServer::SetPadMapping(const PadMapping map[4])
{
@ -276,6 +290,14 @@ void NetPlayServer::SetPadMapping(const PadMapping map[4])
UpdatePadMapping();
}
// called from ---GUI--- thread
void NetPlayServer::SetWiimoteMapping(const PadMapping map[4])
{
for (int i = 0; i < 4; i++)
m_wiimote_map[i] = map[i];
UpdateWiimoteMapping();
}
// called from ---GUI--- thread and ---NETPLAY--- thread
void NetPlayServer::UpdatePadMapping()
{
@ -286,6 +308,16 @@ void NetPlayServer::UpdatePadMapping()
SendToClients(spac);
}
// called from ---NETPLAY--- thread
void NetPlayServer::UpdateWiimoteMapping()
{
sf::Packet spac;
spac << (MessageId)NP_MSG_WIIMOTE_MAPPING;
for (int i = 0; i < 4; i++)
spac << m_wiimote_map[i];
SendToClients(spac);
}
// called from ---GUI--- thread and ---NETPLAY--- thread
void NetPlayServer::AdjustPadBufferSize(unsigned int size)
{
@ -358,6 +390,39 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
}
break;
case NP_MSG_WIIMOTE_DATA :
{
// if this is wiimote data from the last game still being received, ignore it
if (player.current_game != m_current_game)
break;
PadMapping map = 0;
u8 size;
packet >> map >> size;
u8* data = new u8[size];
for (unsigned int i = 0; i < size; ++i)
packet >> data[i];
// If the data is not from the correct player,
// then disconnect them.
if (m_wiimote_map[map] != player.pid)
return 1;
// relay to clients
sf::Packet spac;
spac << (MessageId)NP_MSG_WIIMOTE_DATA;
spac << map;
spac << size;
for (unsigned int i = 0; i < size; ++i)
spac << data[i];
delete[] data;
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
SendToClients(spac, player.pid);
}
break;
case NP_MSG_PONG :
{
const u32 ping = m_ping_timer.GetTimeElapsed();

View File

@ -37,6 +37,9 @@ public:
void GetPadMapping(PadMapping map[]);
void SetPadMapping(const PadMapping map[]);
void GetWiimoteMapping(PadMapping map[]);
void SetWiimoteMapping(const PadMapping map[]);
void AdjustPadBufferSize(unsigned int size);
bool is_connected;
@ -63,6 +66,7 @@ private:
unsigned int OnDisconnect(sf::SocketTCP& socket);
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
void UpdatePadMapping();
void UpdateWiimoteMapping();
NetSettings m_settings;
@ -74,6 +78,7 @@ private:
u32 m_current_game;
unsigned int m_target_buffer_size;
PadMapping m_pad_map[4];
PadMapping m_wiimote_map[4];
std::map<sf::SocketTCP, Client> m_players;

View File

@ -107,10 +107,11 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
" - DSP Emulator Engine Must be the same on all computers!\n"
" - DSP on Dedicated Thread [OFF]\n"
" - Framelimit NOT set to [Audio]\n"
" - Manually set the exact number of wiimotes to be used to [Emulated Wiimote]\n"
"\n"
"All players should use the same Dolphin version and settings.\n"
"All memory cards must be identical between players or disabled.\n"
"Wiimote support has not been implemented!\n"
"Wiimote support is probably terrible. Don't use it.\n"
"\n"
"The host must have the chosen TCP port open/forwarded!\n"),
wxDefaultPosition, wxDefaultSize);
@ -562,12 +563,15 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent&)
void NetPlayDiag::OnConfigPads(wxCommandEvent&)
{
PadMapping mapping[4];
PadMapping wiimotemapping[4];
std::vector<const Player *> player_list;
netplay_server->GetPadMapping(mapping);
netplay_server->GetWiimoteMapping(wiimotemapping);
netplay_client->GetPlayers(player_list);
PadMapDiag pmd(this, mapping, player_list);
PadMapDiag pmd(this, mapping, wiimotemapping, player_list);
pmd.ShowModal();
netplay_server->SetPadMapping(mapping);
netplay_server->SetWiimoteMapping(wiimotemapping);
}
bool NetPlayDiag::IsRecording()
@ -602,9 +606,10 @@ void ChangeGameDiag::OnPick(wxCommandEvent& event)
EndModal(wxID_OK);
}
PadMapDiag::PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector<const Player *>& player_list)
PadMapDiag::PadMapDiag(wxWindow* const parent, PadMapping map[], PadMapping wiimotemap[], std::vector<const Player *>& player_list)
: wxDialog(parent, wxID_ANY, _("Configure Pads"), wxDefaultPosition, wxDefaultSize)
, m_mapping(map)
, m_wiimapping (wiimotemap)
, m_player_list(player_list)
{
wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL);
@ -615,6 +620,11 @@ PadMapDiag::PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector<con
for (unsigned int i = 0; i < m_player_list.size(); i++)
player_names.Add(m_player_list[i]->name);
wxString wiimote_names[5];
wiimote_names[0] = _("None");
for (unsigned int i=1; i < 5; ++i)
wiimote_names[i] = wxString(_("Wiimote ")) + (wxChar)(wxT('0')+i);
for (unsigned int i=0; i<4; ++i)
{
wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL);
@ -636,6 +646,27 @@ PadMapDiag::PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector<con
h_szr->AddSpacer(10);
}
for (unsigned int i=0; i<4; ++i)
{
wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL);
v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("Wiimote ")) + (wxChar)(wxT('0')+i))),
1, wxALIGN_CENTER_HORIZONTAL);
m_map_cbox[i+4] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names);
m_map_cbox[i+4]->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &PadMapDiag::OnAdjust, this);
if (m_wiimapping[i] == -1)
m_map_cbox[i+4]->Select(0);
else
for (unsigned int j = 0; j < m_player_list.size(); j++)
if (m_wiimapping[i] == m_player_list[j]->pid)
m_map_cbox[i+4]->Select(j + 1);
v_szr->Add(m_map_cbox[i+4], 1);
h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20);
h_szr->AddSpacer(10);
}
wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
main_szr->Add(h_szr);
main_szr->AddSpacer(5);
@ -655,6 +686,12 @@ void PadMapDiag::OnAdjust(wxCommandEvent& event)
m_mapping[i] = m_player_list[player_idx - 1]->pid;
else
m_mapping[i] = -1;
player_idx = m_map_cbox[i+4]->GetSelection();
if (player_idx > 0)
m_wiimapping[i] = m_player_list[player_idx - 1]->pid;
else
m_wiimapping[i] = -1;
}
}

View File

@ -127,13 +127,14 @@ private:
class PadMapDiag : public wxDialog
{
public:
PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector<const Player *>& player_list);
PadMapDiag(wxWindow* const parent, PadMapping map[], PadMapping wiimotemap[], std::vector<const Player *>& player_list);
private:
void OnAdjust(wxCommandEvent& event);
wxChoice* m_map_cbox[4];
wxChoice* m_map_cbox[8];
PadMapping* const m_mapping;
PadMapping* const m_wiimapping;
std::vector<const Player *>& m_player_list;
};