NetPlay: Rework pad mapping
Pad mapping and the UI behind it is significantly confusing, and has been confusing users since NetPlay was introduced. As part of a large code cleanup to help NetPlay more stable, introduce a better pad mapping system where local pad mapping is handled by the client. Now, all the server and other clients know is which player have which controllers, and the clients only know this so they can show the pad mapping in the UI; they don't do anything else with it. A future cleanup will use this pad mapping data to completely ignore the pads configured in the settings pane on the host.
This commit is contained in:
parent
7a5374258e
commit
23ff31451f
|
@ -23,22 +23,6 @@ NetSettings g_NetPlaySettings;
|
|||
|
||||
#define RPT_SIZE_HACK (1 << 16)
|
||||
|
||||
NetPlayClient::Player::Player()
|
||||
{
|
||||
memset(pad_map, -1, sizeof(pad_map));
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
std::string NetPlayClient::Player::ToString() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |";
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-');
|
||||
ss << " | " << ping << "ms";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
NetPad::NetPad()
|
||||
{
|
||||
nHi = 0x00808080;
|
||||
|
@ -200,16 +184,8 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
|||
|
||||
case NP_MSG_PAD_MAPPING :
|
||||
{
|
||||
PlayerId pid;
|
||||
packet >> pid;
|
||||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
Player& player = m_players[pid];
|
||||
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
packet >> player.pad_map[i];
|
||||
}
|
||||
for (PadMapping i = 0; i < 4; i++)
|
||||
packet >> m_pad_map[i];
|
||||
|
||||
m_dialog->Update();
|
||||
}
|
||||
|
@ -223,7 +199,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
|||
|
||||
// trusting server for good map value (>=0 && <4)
|
||||
// add to pad buffer
|
||||
m_pad_buffer[(unsigned)map].Push(np);
|
||||
m_pad_buffer[map].Push(np);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -361,13 +337,36 @@ void NetPlayClient::GetPlayerList(std::string& list, std::vector<int>& pid_list)
|
|||
e = m_players.end();
|
||||
for ( ; i!=e; ++i)
|
||||
{
|
||||
ss << i->second.ToString() << '\n';
|
||||
pid_list.push_back(i->second.pid);
|
||||
const Player *player = &(i->second);
|
||||
ss << player->name << "[" << (int)player->pid << "] : " << player->revision << " | ";
|
||||
for (unsigned int j = 0; j < 4; j++)
|
||||
{
|
||||
if (m_pad_map[j] == player->pid)
|
||||
ss << j + 1;
|
||||
else
|
||||
ss << '-';
|
||||
}
|
||||
ss << " | " << player->ping << "ms\n";
|
||||
pid_list.push_back(player->pid);
|
||||
}
|
||||
|
||||
list = ss.str();
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
void NetPlayClient::GetPlayers(std::vector<const Player *> &player_list)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
std::map<PlayerId, Player>::const_iterator
|
||||
i = m_players.begin(),
|
||||
e = m_players.end();
|
||||
for ( ; i!=e; ++i)
|
||||
{
|
||||
const Player *player = &(i->second);
|
||||
player_list.push_back(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// called from ---GUI--- thread
|
||||
void NetPlayClient::SendChatMessage(const std::string& msg)
|
||||
|
@ -381,12 +380,12 @@ void NetPlayClient::SendChatMessage(const std::string& msg)
|
|||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
void NetPlayClient::SendPadState(const PadMapping local_nb, const NetPad& np)
|
||||
void NetPlayClient::SendPadState(const PadMapping in_game_pad, const NetPad& np)
|
||||
{
|
||||
// send to server
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PAD_DATA;
|
||||
spac << local_nb; // local pad num
|
||||
spac << in_game_pad;
|
||||
spac << np.nHi << np.nLo;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
|
@ -457,13 +456,35 @@ void NetPlayClient::ClearBuffers()
|
|||
// called from ---CPU--- thread
|
||||
bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
// The interface for this is extremely silly.
|
||||
//
|
||||
// Imagine a physical device that links three Gamecubes together
|
||||
// and emulates NetPlay that way. Which Gamecube controls which
|
||||
// in-game controllers can be configured on the device (m_pad_map)
|
||||
// but which sockets on each individual Gamecube should be used
|
||||
// to control which players? The solution that Dolphin uses is
|
||||
// that we hardcode the knowledge that they go in order, so if
|
||||
// you have a 3P game with three gamecubes, then every single
|
||||
// controller should be plugged into slot 1.
|
||||
//
|
||||
// If you have a 4P game, then one of the Gamecubes will have
|
||||
// a controller plugged into slot 1, and another in slot 2.
|
||||
//
|
||||
// The slot number is the "local" pad number, and what player
|
||||
// it actually means is the "in-game" pad number.
|
||||
//
|
||||
// The interface here gives us the status of local pads, and
|
||||
// expects to get back "in-game" pad numbers back in response.
|
||||
// e.g. it asks "here's the input that slot 1 has, and by the
|
||||
// way, what's the state of P1?"
|
||||
//
|
||||
// We should add this split between "in-game" pads and "local"
|
||||
// pads higher up.
|
||||
|
||||
// in game mapping for this local pad
|
||||
unsigned int in_game_num = m_local_player->pad_map[pad_nb];
|
||||
int in_game_num = GetPadNum(pad_nb);
|
||||
|
||||
// does this local pad map in game?
|
||||
// If this in-game pad is one of ours, then update from the
|
||||
// information given.
|
||||
if (in_game_num < 4)
|
||||
{
|
||||
NetPad np(pad_status);
|
||||
|
@ -476,89 +497,36 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_stat
|
|||
m_pad_buffer[in_game_num].Push(np);
|
||||
|
||||
// send
|
||||
SendPadState(pad_nb, np);
|
||||
SendPadState(in_game_num, np);
|
||||
}
|
||||
}
|
||||
|
||||
} // unlock players
|
||||
|
||||
//Common::Timer bufftimer;
|
||||
//bufftimer.Start();
|
||||
|
||||
// get padstate from buffer and send to game
|
||||
// Now, we need to swap out the local value with the values
|
||||
// retrieved from NetPlay. This could be the value we pushed
|
||||
// above if we're configured as P1 and the code is trying
|
||||
// to retrieve data for slot 1.
|
||||
while (!m_pad_buffer[pad_nb].Pop(*netvalues))
|
||||
{
|
||||
// wait for receiving thread to push some data
|
||||
Common::SleepCurrentThread(1);
|
||||
|
||||
if (false == m_is_running)
|
||||
if (!m_is_running)
|
||||
return false;
|
||||
|
||||
// TODO: check the time of bufftimer here,
|
||||
// if it gets pretty high, ask the user if they want to disconnect
|
||||
|
||||
// TODO: use a condition instead of sleeping
|
||||
Common::SleepCurrentThread(1);
|
||||
}
|
||||
|
||||
//u64 hangtime = bufftimer.GetTimeElapsed();
|
||||
//if (hangtime > 10)
|
||||
//{
|
||||
// std::ostringstream ss;
|
||||
// ss << "Pad " << (int)pad_nb << ": Had to wait " << hangtime << "ms for pad data. (increase pad Buffer maybe)";
|
||||
// Core::DisplayMessage(ss.str(), 1000);
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
void NetPlayClient::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
||||
{
|
||||
//// in game mapping for this local wiimote
|
||||
unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now
|
||||
|
||||
// does this local pad map in game?
|
||||
if (in_game_num < 4)
|
||||
{
|
||||
m_wiimote_input[_number].resize(m_wiimote_input[_number].size() + 1);
|
||||
m_wiimote_input[_number].back().assign((char*)_pData, (char*)_pData + _Size);
|
||||
m_wiimote_input[_number].back().channel = _channelID;
|
||||
}
|
||||
// XXX
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
void NetPlayClient::WiimoteUpdate(int _number)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
|
||||
// in game mapping for this local wiimote
|
||||
unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now
|
||||
|
||||
// does this local pad map in game?
|
||||
if (in_game_num < 4)
|
||||
{
|
||||
m_wiimote_buffer[in_game_num].Push(m_wiimote_input[_number]);
|
||||
|
||||
// TODO: send it
|
||||
|
||||
m_wiimote_input[_number].clear();
|
||||
}
|
||||
|
||||
} // unlock players
|
||||
|
||||
if (0 == m_wiimote_buffer[_number].Size())
|
||||
{
|
||||
//PanicAlert("PANIC");
|
||||
return;
|
||||
}
|
||||
|
||||
NetWiimote nw;
|
||||
m_wiimote_buffer[_number].Pop(nw);
|
||||
|
||||
NetWiimote::const_iterator
|
||||
i = nw.begin(), e = nw.end();
|
||||
for ( ; i!=e; ++i)
|
||||
Core::Callback_WiimoteInterruptChannel(_number, i->channel, &(*i)[0], (u32)i->size() + RPT_SIZE_HACK);
|
||||
// XXX
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread and ---NETPLAY--- thread (client side)
|
||||
|
@ -586,13 +554,21 @@ bool NetPlayClient::StopGame()
|
|||
// called from ---CPU--- thread
|
||||
u8 NetPlayClient::GetPadNum(u8 numPAD)
|
||||
{
|
||||
// TODO: i don't like that this loop is running everytime there is rumble
|
||||
unsigned int i = 0;
|
||||
for (; i<4; ++i)
|
||||
if (numPAD == m_local_player->pad_map[i])
|
||||
break;
|
||||
// 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_pad_map[ingame_pad] == m_local_player->pid)
|
||||
local_pad_count++;
|
||||
|
||||
return i;
|
||||
if (local_pad_count == numPAD)
|
||||
break;
|
||||
}
|
||||
|
||||
return ingame_pad;
|
||||
}
|
||||
|
||||
// stuff hacked into dolphin
|
||||
|
@ -658,22 +634,13 @@ u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD)
|
|||
//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)
|
||||
{
|
||||
//CritLocker crit(crit_netplay_client);
|
||||
|
||||
//if (netplay_client)
|
||||
// netplay_client->WiimoteUpdate(_number);
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
//
|
||||
int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number)
|
||||
{
|
||||
//CritLocker crit(crit_netplay_client);
|
||||
|
||||
//if (netplay_client)
|
||||
// return netplay_client->GetPadNum(_number); // just using gcpad mapping for now
|
||||
//else
|
||||
return _number;
|
||||
return _number;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
|
@ -684,19 +651,7 @@ bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&)
|
|||
std::lock_guard<std::mutex> lk(crit_netplay_client);
|
||||
|
||||
if (netplay_client)
|
||||
//{
|
||||
// if (_Size >= RPT_SIZE_HACK)
|
||||
// {
|
||||
// _Size -= RPT_SIZE_HACK;
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// netplay_client->WiimoteInput(_number, _channelID, _pData, _Size);
|
||||
// // don't use this packet
|
||||
return true;
|
||||
// }
|
||||
//}
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,15 @@ public:
|
|||
|
||||
extern NetSettings g_NetPlaySettings;
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
PlayerId pid;
|
||||
std::string name;
|
||||
std::string revision;
|
||||
u32 ping;
|
||||
};
|
||||
|
||||
class NetPlayClient
|
||||
{
|
||||
public:
|
||||
|
@ -59,6 +68,7 @@ public:
|
|||
~NetPlayClient();
|
||||
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
void GetPlayers(std::vector<const Player *>& player_list);
|
||||
|
||||
bool is_connected;
|
||||
|
||||
|
@ -84,19 +94,6 @@ protected:
|
|||
std::recursive_mutex players, send;
|
||||
} m_crit;
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
Player();
|
||||
std::string ToString() const;
|
||||
|
||||
PlayerId pid;
|
||||
std::string name;
|
||||
PadMapping pad_map[4];
|
||||
std::string revision;
|
||||
u32 ping;
|
||||
};
|
||||
|
||||
Common::FifoQueue<NetPad> m_pad_buffer[4];
|
||||
Common::FifoQueue<NetWiimote> m_wiimote_buffer[4];
|
||||
|
||||
|
@ -117,8 +114,10 @@ protected:
|
|||
|
||||
u32 m_current_game;
|
||||
|
||||
PadMapping m_pad_map[4];
|
||||
|
||||
private:
|
||||
void SendPadState(const PadMapping local_nb, const NetPad& np);
|
||||
void SendPadState(const PadMapping in_game_pad, const NetPad& np);
|
||||
unsigned int OnData(sf::Packet& packet);
|
||||
|
||||
PlayerId m_pid;
|
||||
|
|
|
@ -24,7 +24,7 @@ struct Rpt : public std::vector<u8>
|
|||
|
||||
typedef std::vector<Rpt> NetWiimote;
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-18"
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-23"
|
||||
|
||||
// messages
|
||||
enum
|
||||
|
|
|
@ -4,11 +4,6 @@
|
|||
|
||||
#include "NetPlayServer.h"
|
||||
|
||||
NetPlayServer::Client::Client()
|
||||
{
|
||||
memset(pad_map, -1, sizeof(pad_map));
|
||||
}
|
||||
|
||||
NetPlayServer::~NetPlayServer()
|
||||
{
|
||||
if (is_connected)
|
||||
|
@ -29,6 +24,7 @@ NetPlayServer::~NetPlayServer()
|
|||
// called from ---GUI--- thread
|
||||
NetPlayServer::NetPlayServer(const u16 port) : is_connected(false), m_is_running(false)
|
||||
{
|
||||
memset(m_pad_map, -1, sizeof(m_pad_map));
|
||||
if (m_socket.Listen(port))
|
||||
{
|
||||
is_connected = true;
|
||||
|
@ -155,45 +151,16 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
|||
rpac >> player.name;
|
||||
|
||||
// give new client first available id
|
||||
player.pid = 0;
|
||||
std::map<sf::SocketTCP, Client>::const_iterator
|
||||
i,
|
||||
e = m_players.end();
|
||||
for (PlayerId p = 1; 0 == player.pid; ++p)
|
||||
{
|
||||
for (i = m_players.begin(); ; ++i)
|
||||
{
|
||||
if (e == i)
|
||||
{
|
||||
player.pid = p;
|
||||
break;
|
||||
}
|
||||
if (p == i->second.pid)
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.pid = m_players.size() + 1;
|
||||
|
||||
// TODO: this is crappy
|
||||
// try to automatically assign new user a pad
|
||||
for (unsigned int m = 0; m < 4; ++m)
|
||||
{
|
||||
bool is_mapped[4] = {false,false,false,false};
|
||||
|
||||
for ( unsigned int m = 0; m<4; ++m)
|
||||
{
|
||||
for (i = m_players.begin(); i!=e; ++i)
|
||||
if (m_pad_map[m] == -1)
|
||||
{
|
||||
if (i->second.pad_map[m] >= 0)
|
||||
is_mapped[(unsigned)i->second.pad_map[m]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for ( unsigned int m = 0; m<4; ++m)
|
||||
if (false == is_mapped[m])
|
||||
{
|
||||
player.pad_map[0] = m;
|
||||
m_pad_map[m] = player.pid;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -221,6 +188,9 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
|||
}
|
||||
|
||||
// sync values with new client
|
||||
std::map<sf::SocketTCP, Client>::const_iterator
|
||||
i,
|
||||
e = m_players.end();
|
||||
for (i = m_players.begin(); i!=e; ++i)
|
||||
{
|
||||
spac.Clear();
|
||||
|
@ -279,83 +249,28 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
|||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
bool NetPlayServer::GetPadMapping(const int pid, int map[])
|
||||
void NetPlayServer::GetPadMapping(PadMapping map[4])
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
std::map<sf::SocketTCP, Client>::const_iterator
|
||||
i = m_players.begin(),
|
||||
e = m_players.end();
|
||||
for (; i!=e; ++i)
|
||||
if (pid == i->second.pid)
|
||||
break;
|
||||
|
||||
// player not found
|
||||
if (i == e)
|
||||
return false;
|
||||
|
||||
// get pad mapping
|
||||
for (unsigned int m = 0; m<4; ++m)
|
||||
map[m] = i->second.pad_map[m];
|
||||
|
||||
return true;
|
||||
for (int i = 0; i < 4; i++)
|
||||
map[i] = m_pad_map[i];
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
bool NetPlayServer::SetPadMapping(const int pid, const int map[])
|
||||
void NetPlayServer::SetPadMapping(const PadMapping map[4])
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
if (m_is_running)
|
||||
return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
std::map<sf::SocketTCP, Client>::iterator
|
||||
i = m_players.begin(),
|
||||
e = m_players.end();
|
||||
for (; i!=e; ++i)
|
||||
if (pid == i->second.pid)
|
||||
break;
|
||||
|
||||
// player not found
|
||||
if (i == e)
|
||||
return false;
|
||||
|
||||
Client& player = i->second;
|
||||
|
||||
// set pad mapping
|
||||
for (unsigned int m = 0; m<4; ++m)
|
||||
{
|
||||
player.pad_map[m] = (PadMapping)map[m];
|
||||
|
||||
// remove duplicate mappings
|
||||
for (i = m_players.begin(); i!=e; ++i)
|
||||
for (unsigned int p = 0; p<4; ++p)
|
||||
if (p != m || i->second.pid != pid)
|
||||
if (player.pad_map[m] == i->second.pad_map[p])
|
||||
i->second.pad_map[p] = -1;
|
||||
}
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
UpdatePadMapping(); // sync pad mappings with everyone
|
||||
|
||||
return true;
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_pad_map[i] = map[i];
|
||||
UpdatePadMapping();
|
||||
}
|
||||
|
||||
// called from ---NETPLAY--- thread
|
||||
// called from ---GUI--- thread and ---NETPLAY--- thread
|
||||
void NetPlayServer::UpdatePadMapping()
|
||||
{
|
||||
std::map<sf::SocketTCP, Client>::const_iterator
|
||||
i = m_players.begin(),
|
||||
e = m_players.end();
|
||||
for (; i!=e; ++i)
|
||||
{
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PAD_MAPPING;
|
||||
spac << i->second.pid;
|
||||
for (unsigned int pm = 0; pm<4; ++pm)
|
||||
spac << i->second.pad_map[pm];
|
||||
SendToClients(spac);
|
||||
}
|
||||
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PAD_MAPPING;
|
||||
for (int i = 0; i < 4; i++)
|
||||
spac << m_pad_map[i];
|
||||
SendToClients(spac);
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread and ---NETPLAY--- thread
|
||||
|
@ -415,23 +330,15 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
int hi, lo;
|
||||
packet >> map >> hi >> lo;
|
||||
|
||||
// check if client's pad indeed maps in game
|
||||
if (map >= 0 && map < 4)
|
||||
map = player.pad_map[(unsigned)map];
|
||||
else
|
||||
map = -1;
|
||||
|
||||
// if not, they are hacking, so disconnect them
|
||||
// this could happen right after a pad map change, but that isn't implemented yet
|
||||
if (map < 0)
|
||||
// If the data is not from the correct player,
|
||||
// then disconnect them.
|
||||
if (m_pad_map[map] != player.pid)
|
||||
return 1;
|
||||
|
||||
|
||||
// relay to clients
|
||||
// Relay to clients
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PAD_DATA;
|
||||
spac << map; // in game mapping
|
||||
spac << hi << lo;
|
||||
spac << map << hi << lo;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac, player.pid);
|
||||
|
|
|
@ -35,8 +35,8 @@ public:
|
|||
bool StartGame(const std::string &path);
|
||||
bool StopGame();
|
||||
|
||||
bool GetPadMapping(const int pid, int map[]);
|
||||
bool SetPadMapping(const int pid, const int map[]);
|
||||
void GetPadMapping(PadMapping map[]);
|
||||
void SetPadMapping(const PadMapping map[]);
|
||||
|
||||
void AdjustPadBufferSize(unsigned int size);
|
||||
|
||||
|
@ -50,11 +50,8 @@ private:
|
|||
class Client
|
||||
{
|
||||
public:
|
||||
Client();
|
||||
|
||||
PlayerId pid;
|
||||
std::string name;
|
||||
PadMapping pad_map[4];
|
||||
std::string revision;
|
||||
|
||||
sf::SocketTCP socket;
|
||||
|
@ -77,6 +74,7 @@ private:
|
|||
bool m_update_pings;
|
||||
u32 m_current_game;
|
||||
unsigned int m_target_buffer_size;
|
||||
PadMapping m_pad_map[4];
|
||||
|
||||
std::map<sf::SocketTCP, Client> m_players;
|
||||
|
||||
|
|
|
@ -559,23 +559,13 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent&)
|
|||
|
||||
void NetPlayDiag::OnConfigPads(wxCommandEvent&)
|
||||
{
|
||||
int mapping[4];
|
||||
|
||||
// get selected player id
|
||||
int pid = m_player_lbox->GetSelection();
|
||||
if (pid < 0)
|
||||
return;
|
||||
pid = m_playerids.at(pid);
|
||||
|
||||
if (false == netplay_server->GetPadMapping(pid, mapping))
|
||||
return;
|
||||
|
||||
PadMapDiag pmd(this, mapping);
|
||||
PadMapping mapping[4];
|
||||
std::vector<const Player *> player_list;
|
||||
netplay_server->GetPadMapping(mapping);
|
||||
netplay_client->GetPlayers(player_list);
|
||||
PadMapDiag pmd(this, mapping, player_list);
|
||||
pmd.ShowModal();
|
||||
|
||||
if (false == netplay_server->SetPadMapping(pid, mapping))
|
||||
PanicAlertT("Could not set pads. The player left or the game is currently running!\n"
|
||||
"(setting pads while the game is running is not yet supported)");
|
||||
netplay_server->SetPadMapping(mapping);
|
||||
}
|
||||
|
||||
ChangeGameDiag::ChangeGameDiag(wxWindow* const parent, const CGameListCtrl* const game_list, wxString& game_name)
|
||||
|
@ -605,45 +595,39 @@ void ChangeGameDiag::OnPick(wxCommandEvent& event)
|
|||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
PadMapDiag::PadMapDiag(wxWindow* const parent, int map[])
|
||||
PadMapDiag::PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector<const Player *>& player_list)
|
||||
: wxDialog(parent, wxID_ANY, _("Configure Pads"), wxDefaultPosition, wxDefaultSize)
|
||||
, m_mapping(map)
|
||||
, m_player_list(player_list)
|
||||
{
|
||||
wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
h_szr->AddSpacer(20);
|
||||
|
||||
// labels
|
||||
wxBoxSizer* const label_szr = new wxBoxSizer(wxVERTICAL);
|
||||
label_szr->Add(new wxStaticText(this, wxID_ANY, _("Local")), 0, wxALIGN_TOP);
|
||||
label_szr->AddStretchSpacer(1);
|
||||
label_szr->Add(new wxStaticText(this, wxID_ANY, _("In-Game")), 0, wxALIGN_BOTTOM);
|
||||
|
||||
h_szr->Add(label_szr, 1, wxTOP | wxEXPAND, 20);
|
||||
|
||||
// set up choices
|
||||
wxString pad_names[5];
|
||||
pad_names[0] = _("None");
|
||||
for (unsigned int i=1; i<5; ++i)
|
||||
pad_names[i] = wxString(_("Pad ")) + (wxChar)(wxT('0')+i);
|
||||
wxArrayString player_names;
|
||||
player_names.Add(_("None"));
|
||||
for (unsigned int i = 0; i < m_player_list.size(); i++)
|
||||
player_names.Add(m_player_list[i]->name);
|
||||
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
{
|
||||
wxChoice* const pad_cbox = m_map_cbox[i]
|
||||
= new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 5, pad_names);
|
||||
pad_cbox->Select(m_mapping[i] + 1);
|
||||
|
||||
pad_cbox->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &PadMapDiag::OnAdjust, this);
|
||||
|
||||
wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL);
|
||||
v_szr->Add(new wxStaticText(this,wxID_ANY, pad_names[i + 1]), 1, wxALIGN_CENTER_HORIZONTAL);
|
||||
v_szr->Add(pad_cbox, 1);
|
||||
v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("Pad ")) + (wxChar)(wxT('0')+i))),
|
||||
1, wxALIGN_CENTER_HORIZONTAL);
|
||||
|
||||
m_map_cbox[i] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names);
|
||||
m_map_cbox[i]->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &PadMapDiag::OnAdjust, this);
|
||||
if (m_mapping[i] == -1)
|
||||
m_map_cbox[i]->Select(0);
|
||||
else
|
||||
for (unsigned int j = 0; j < m_player_list.size(); j++)
|
||||
if (m_mapping[i] == m_player_list[j]->pid)
|
||||
m_map_cbox[i]->Select(j + 1);
|
||||
|
||||
v_szr->Add(m_map_cbox[i], 1);
|
||||
|
||||
h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20);
|
||||
h_szr->AddSpacer(10);
|
||||
}
|
||||
|
||||
h_szr->AddSpacer(20);
|
||||
|
||||
wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
|
||||
main_szr->Add(h_szr);
|
||||
main_szr->AddSpacer(5);
|
||||
|
@ -656,8 +640,14 @@ PadMapDiag::PadMapDiag(wxWindow* const parent, int map[])
|
|||
void PadMapDiag::OnAdjust(wxCommandEvent& event)
|
||||
{
|
||||
(void)event;
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
m_mapping[i] = m_map_cbox[i]->GetSelection() - 1;
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
int player_idx = m_map_cbox[i]->GetSelection();
|
||||
if (player_idx > 0)
|
||||
m_mapping[i] = m_player_list[player_idx - 1]->pid;
|
||||
else
|
||||
m_mapping[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlay::StopGame()
|
||||
|
|
|
@ -124,13 +124,14 @@ private:
|
|||
class PadMapDiag : public wxDialog
|
||||
{
|
||||
public:
|
||||
PadMapDiag(wxWindow* const parent, int map[]);
|
||||
PadMapDiag(wxWindow* const parent, PadMapping map[], std::vector<const Player *>& player_list);
|
||||
|
||||
private:
|
||||
void OnAdjust(wxCommandEvent& event);
|
||||
|
||||
wxChoice* m_map_cbox[4];
|
||||
int* const m_mapping;
|
||||
PadMapping* const m_mapping;
|
||||
std::vector<const Player *>& m_player_list;
|
||||
};
|
||||
|
||||
namespace NetPlay
|
||||
|
|
Loading…
Reference in New Issue