Made new Wiimote plugin not deinit SDL on shutdown. (Hacks, same thing old wiimote does, fixes the crash on emulation stop, refresh button still causes crash (damn SDL)) Minor new input plugin GUI changes. (left-click on rumble button opens control config dialog) Made NetPlay save/load settings to Dolphin.ini. Allow NetPlay host to adjust which/how many pads will be used in game. (more than one gamepad per Dolphin instance can be used on NetPlay) Worked on wiimote NetPlay a bit. (still nonfunctional) Improved SDL device numbering. Added some major hacks to ControllerInterface/SDL so XInput(360 controller) devices do not have their SDL interface shown in the device list on windows. (caused confusion for users)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5625 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
#include "HW/EXI_DeviceIPL.h"
|
||||
// to start/stop game
|
||||
#include "Frame.h"
|
||||
// for OSD msgs
|
||||
// for wiimote/ OSD messages
|
||||
#include "Core.h"
|
||||
|
||||
Common::CriticalSection crit_netplay_ptr;
|
||||
@@ -44,17 +44,6 @@ THREAD_RETURN NetPlayThreadFunc(void* arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//CritLocker::CritLocker(Common::CriticalSection& crit)
|
||||
// : m_crit(crit)
|
||||
//{
|
||||
// m_crit.Enter();
|
||||
//}
|
||||
//
|
||||
//CritLocker::~CritLocker()
|
||||
//{
|
||||
// m_crit.Leave();
|
||||
//}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
NetPlay::NetPlay()
|
||||
: m_is_running(false), m_do_loop(true)
|
||||
@@ -80,6 +69,10 @@ NetPlay::~NetPlay()
|
||||
{
|
||||
CritLocker crit(crit_netplay_ptr);
|
||||
::netplay_ptr = NULL;
|
||||
|
||||
// not perfect
|
||||
if (m_is_running)
|
||||
StopGame();
|
||||
}
|
||||
|
||||
NetPlay::Player::Player()
|
||||
@@ -145,6 +138,9 @@ void NetPlay::ClearBuffers()
|
||||
{
|
||||
while (m_pad_buffer[i].size())
|
||||
m_pad_buffer[i].pop();
|
||||
while (m_wiimote_buffer[i].size())
|
||||
m_wiimote_buffer[i].pop();
|
||||
m_wiimote_input[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,46 +208,63 @@ bool NetPlay::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, Ne
|
||||
// called from ---CPU--- thread
|
||||
void NetPlay::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
||||
{
|
||||
//m_crit.players.Enter(); // lock 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
|
||||
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)
|
||||
//{
|
||||
// //NetPad np(pad_status);
|
||||
// does this local pad map in game?
|
||||
if (in_game_num < 4)
|
||||
{
|
||||
m_crit.buffer.Enter();
|
||||
|
||||
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;
|
||||
|
||||
// m_crit.buffer.Enter(); // lock buffer
|
||||
// // adjust the buffer either up or down
|
||||
// //while (m_pad_buffer[in_game_num].size() <= m_target_buffer_size)
|
||||
// {
|
||||
// // add to buffer
|
||||
// //m_wiimote_buffer[in_game_num].push(np);
|
||||
|
||||
// // send
|
||||
// //SendPadState(pad_nb, np);
|
||||
// }
|
||||
// m_crit.buffer.Leave();
|
||||
//}
|
||||
|
||||
//// get pad from pad buffer and send to game
|
||||
//GetBufferedPad(pad_nb, netvalues);
|
||||
m_crit.buffer.Leave();
|
||||
}
|
||||
|
||||
m_crit.players.Leave();
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
void NetPlay::WiimoteUpdate(int _number)
|
||||
{
|
||||
// temporary
|
||||
if (_number)
|
||||
m_crit.players.Enter(); // lock 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_crit.buffer.Enter();
|
||||
m_wiimote_buffer[in_game_num].push(m_wiimote_input[_number]);
|
||||
|
||||
// TODO: send it
|
||||
|
||||
m_wiimote_input[_number].clear();
|
||||
m_crit.buffer.Leave();
|
||||
}
|
||||
|
||||
m_crit.players.Leave();
|
||||
|
||||
m_crit.buffer.Enter();
|
||||
|
||||
if (0 == m_wiimote_buffer[_number].size())
|
||||
{
|
||||
//PanicAlert("PANIC");
|
||||
return;
|
||||
}
|
||||
|
||||
m_crit.buffer.Enter(); // lock buffer
|
||||
++m_wiimote_update_frame;
|
||||
NetWiimote& nw = m_wiimote_buffer[_number].front();
|
||||
|
||||
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);
|
||||
|
||||
m_wiimote_buffer[_number].pop();
|
||||
m_crit.buffer.Leave();
|
||||
|
||||
// TODO: prolly do some wiimote input here
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
@@ -274,6 +287,14 @@ bool NetPlay::StartGame(const std::string &path)
|
||||
::main_frame->BootGame(path);
|
||||
//BootManager::BootCore(path);
|
||||
|
||||
// TODO: i dont know if i like this here
|
||||
ClearBuffers();
|
||||
// temporary
|
||||
NetWiimote nw;
|
||||
for (unsigned int i = 0; i<4; ++i)
|
||||
for (unsigned int f = 0; f<2; ++f)
|
||||
m_wiimote_buffer[i].push(nw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -353,20 +374,21 @@ u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD)
|
||||
// wiimote update / used for frame counting
|
||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number)
|
||||
{
|
||||
CritLocker crit(::crit_netplay_ptr);
|
||||
//CritLocker crit(::crit_netplay_ptr);
|
||||
|
||||
return;
|
||||
//if (::netplay_ptr)
|
||||
// ::netplay_ptr->WiimoteUpdate(_number);
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
//
|
||||
int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number)
|
||||
{
|
||||
CritLocker crit(::crit_netplay_ptr);
|
||||
//CritLocker crit(::crit_netplay_ptr);
|
||||
|
||||
if (::netplay_ptr)
|
||||
return ::netplay_ptr->GetPadNum(_number); // just using gcpad mapping for now
|
||||
else
|
||||
//if (::netplay_ptr)
|
||||
// return ::netplay_ptr->GetPadNum(_number); // just using gcpad mapping for now
|
||||
//else
|
||||
return _number;
|
||||
}
|
||||
|
||||
@@ -377,18 +399,19 @@ bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int _number, u16 _channelID, con
|
||||
CritLocker crit(::crit_netplay_ptr);
|
||||
|
||||
if (::netplay_ptr)
|
||||
{
|
||||
if (_Size >= RPT_SIZE_HACK)
|
||||
{
|
||||
_Size -= RPT_SIZE_HACK;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
::netplay_ptr->WiimoteInput(_number, _channelID, _pData, _Size);
|
||||
//{
|
||||
// if (_Size >= RPT_SIZE_HACK)
|
||||
// {
|
||||
// _Size -= RPT_SIZE_HACK;
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ::netplay_ptr->WiimoteInput(_number, _channelID, _pData, _Size);
|
||||
// // don't use this packet
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// }
|
||||
//}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,16 +32,13 @@ public:
|
||||
u32 nLo;
|
||||
};
|
||||
|
||||
class NetWiimote
|
||||
struct Rpt : public std::vector<u8>
|
||||
{
|
||||
public:
|
||||
NetWiimote& operator=(const NetWiimote&);
|
||||
NetWiimote(const u32 _size) : size(_size), data(new u8[size]) {}
|
||||
|
||||
const u32 size;
|
||||
u8* const data;
|
||||
u16 channel;
|
||||
};
|
||||
|
||||
typedef std::vector<Rpt> NetWiimote;
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2.2"
|
||||
|
||||
#ifdef _M_X64
|
||||
@@ -124,7 +121,7 @@ public:
|
||||
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 GetPlayerList(std::string& list, std::vector<int>& pid_list) = 0;
|
||||
virtual void SendChatMessage(const std::string& msg) = 0;
|
||||
|
||||
virtual bool StartGame(const std::string &path);
|
||||
@@ -161,11 +158,10 @@ protected:
|
||||
std::string revision;
|
||||
};
|
||||
|
||||
//LockingQueue<NetPad> m_pad_buffer[4];
|
||||
std::queue<NetPad> m_pad_buffer[4];
|
||||
std::map<FrameNum, NetWiimote> m_wiimote_buffer[4];
|
||||
std::queue<NetPad> m_pad_buffer[4];
|
||||
std::queue<NetWiimote> m_wiimote_buffer[4];
|
||||
|
||||
FrameNum m_wiimote_update_frame;
|
||||
NetWiimote m_wiimote_input[4];
|
||||
|
||||
NetPlayDiag* m_dialog;
|
||||
sf::SocketTCP m_socket;
|
||||
@@ -197,7 +193,7 @@ public:
|
||||
NetPlayServer(const u16 port, const std::string& name, NetPlayDiag* const npd = NULL, const std::string& game = "");
|
||||
~NetPlayServer();
|
||||
|
||||
void GetPlayerList(std::string& list);
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
|
||||
// Send and receive pads values
|
||||
//bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
@@ -207,6 +203,9 @@ public:
|
||||
bool StartGame(const std::string &path);
|
||||
bool StopGame();
|
||||
|
||||
bool GetPadMapping(const int pid, int map[]);
|
||||
bool SetPadMapping(const int pid, const int map[]);
|
||||
|
||||
u64 CalculateMinimumBufferTime();
|
||||
void AdjustPadBufferSize(unsigned int size);
|
||||
|
||||
@@ -226,6 +225,7 @@ private:
|
||||
unsigned int OnConnect(sf::SocketTCP& socket);
|
||||
unsigned int OnDisconnect(sf::SocketTCP& socket);
|
||||
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
|
||||
void UpdatePadMapping();
|
||||
|
||||
std::map<sf::SocketTCP, Client> m_players;
|
||||
|
||||
@@ -242,7 +242,7 @@ public:
|
||||
NetPlayClient(const std::string& address, const u16 port, const std::string& name, NetPlayDiag* const npd = NULL);
|
||||
~NetPlayClient();
|
||||
|
||||
void GetPlayerList(std::string& list);
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
|
||||
// Send and receive pads values
|
||||
//bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
|
||||
@@ -19,7 +19,7 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, const s
|
||||
is_connected = false;
|
||||
|
||||
// why is false successful? documentation says true is
|
||||
if (0 == m_socket.Connect(port, address))
|
||||
if (0 == m_socket.Connect(port, address, 5))
|
||||
{
|
||||
// send connect message
|
||||
sf::Packet spac;
|
||||
@@ -193,7 +193,9 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||
|
||||
case NP_MSG_START_GAME :
|
||||
{
|
||||
m_crit.buffer.Enter(); // lock buffer
|
||||
packet >> m_on_game;
|
||||
m_crit.buffer.Leave();
|
||||
|
||||
wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_START_GAME);
|
||||
m_dialog->GetEventHandler()->AddPendingEvent(evt);
|
||||
@@ -209,7 +211,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||
|
||||
case NP_MSG_DISABLE_GAME :
|
||||
{
|
||||
PanicAlert("Other client disconnected while game is running!! NetPlay is disabled. You must manually stop the game.");
|
||||
PanicAlert("Other client disconnected while game is running!! NetPlay is disabled. You manually stop the game.");
|
||||
CritLocker game_lock(m_crit.game); // lock game state
|
||||
m_is_running = false;
|
||||
NetPlay_Disable();
|
||||
@@ -257,7 +259,7 @@ void NetPlayClient::Entry()
|
||||
default :
|
||||
m_is_running = false;
|
||||
NetPlay_Disable();
|
||||
AppendChatGUI("< LOST CONNECION TO SERVER >");
|
||||
AppendChatGUI("< LOST CONNECTION TO SERVER >");
|
||||
PanicAlert("Lost connection to server!");
|
||||
m_do_loop = false;
|
||||
break;
|
||||
@@ -271,7 +273,7 @@ void NetPlayClient::Entry()
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
void NetPlayClient::GetPlayerList(std::string &list)
|
||||
void NetPlayClient::GetPlayerList(std::string& list, std::vector<int>& pid_list)
|
||||
{
|
||||
CritLocker player_lock(m_crit.players); // lock players
|
||||
|
||||
@@ -281,7 +283,10 @@ void NetPlayClient::GetPlayerList(std::string &list)
|
||||
i = m_players.begin(),
|
||||
e = m_players.end();
|
||||
for ( ; i!=e; ++i)
|
||||
{
|
||||
ss << i->second.ToString() << '\n';
|
||||
pid_list.push_back(i->second.pid);
|
||||
}
|
||||
|
||||
list = ss.str();
|
||||
}
|
||||
@@ -294,9 +299,9 @@ void NetPlayClient::SendChatMessage(const std::string& msg)
|
||||
spac << (MessageId)NP_MSG_CHAT_MESSAGE;
|
||||
spac << msg;
|
||||
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker player_lock(m_crit.players); // lock players
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
m_socket.Send(spac);
|
||||
m_crit.send.Leave();
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
@@ -308,9 +313,8 @@ void NetPlayClient::SendPadState(const PadMapping local_nb, const NetPad& np)
|
||||
spac << local_nb; // local pad num
|
||||
spac << np.nHi << np.nLo;
|
||||
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
m_socket.Send(spac);
|
||||
m_crit.send.Leave();
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
@@ -321,18 +325,15 @@ bool NetPlayClient::StartGame(const std::string &path)
|
||||
if (false == NetPlay::StartGame(path))
|
||||
return false;
|
||||
|
||||
// TODO: i dont like this here
|
||||
ClearBuffers();
|
||||
m_crit.buffer.Leave();
|
||||
|
||||
// tell server i started the game
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_START_GAME;
|
||||
spac << m_on_game;
|
||||
|
||||
m_crit.send.Enter(); // lock send
|
||||
m_crit.buffer.Leave();
|
||||
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
m_socket.Send(spac);
|
||||
m_crit.send.Leave();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ void NetPlayServer::Entry()
|
||||
spac << (MessageId)NP_MSG_PING;
|
||||
spac << m_ping_key;
|
||||
|
||||
CritLocker player_lock(m_crit.players);
|
||||
//CritLocker player_lock(m_crit.players);
|
||||
CritLocker send_lock(m_crit.send);
|
||||
m_ping_timer.Start();
|
||||
SendToClients(spac);
|
||||
@@ -218,14 +218,6 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
||||
spac << player.pid;
|
||||
socket.Send(spac);
|
||||
|
||||
// send user their pad mapping
|
||||
spac.Clear();
|
||||
spac << (MessageId)NP_MSG_PAD_MAPPING;
|
||||
spac << player.pid;
|
||||
for (unsigned int pm = 0; pm<4; ++pm)
|
||||
spac << player.pad_map[pm];
|
||||
socket.Send(spac);
|
||||
|
||||
// send new client the selected game
|
||||
spac.Clear();
|
||||
spac << (MessageId)NP_MSG_CHANGE_GAME;
|
||||
@@ -239,13 +231,6 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
||||
spac << (MessageId)NP_MSG_PLAYER_JOIN;
|
||||
spac << i->second.pid << i->second.name << i->second.revision;
|
||||
socket.Send(spac);
|
||||
|
||||
spac.Clear();
|
||||
spac << (MessageId)NP_MSG_PAD_MAPPING;
|
||||
spac << i->second.pid;
|
||||
for (unsigned int pm = 0; pm<4; ++pm)
|
||||
spac << i->second.pad_map[pm];
|
||||
socket.Send(spac);
|
||||
}
|
||||
|
||||
// LEAVE
|
||||
@@ -254,6 +239,9 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
||||
// add client to the player list
|
||||
m_crit.players.Enter(); // lock players
|
||||
m_players[socket] = player;
|
||||
m_crit.send.Enter(); // lock send
|
||||
UpdatePadMapping(); // sync pad mappings with everyone
|
||||
m_crit.send.Leave();
|
||||
m_crit.players.Leave();
|
||||
|
||||
// add client to selector/ used for receiving
|
||||
@@ -277,9 +265,8 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_DISABLE_GAME;
|
||||
// this thread doesnt need players lock
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac);
|
||||
m_crit.send.Leave();
|
||||
}
|
||||
|
||||
sf::Packet spac;
|
||||
@@ -288,20 +275,100 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
||||
|
||||
m_selector.Remove(socket);
|
||||
|
||||
m_crit.players.Enter(); // lock players
|
||||
CritLocker player_lock(m_crit.players); // lock players
|
||||
m_players.erase(m_players.find(socket));
|
||||
m_crit.players.Leave();
|
||||
|
||||
// alert other players of disconnect
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac);
|
||||
m_crit.send.Leave();
|
||||
|
||||
UpdateGUI();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
bool NetPlayServer::GetPadMapping(const int pid, int map[])
|
||||
{
|
||||
CritLocker player_lock(m_crit.players); // lock 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;
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
bool NetPlayServer::SetPadMapping(const int pid, const int map[])
|
||||
{
|
||||
CritLocker game_lock(m_crit.game); // lock game
|
||||
if (m_is_running)
|
||||
return false;
|
||||
|
||||
CritLocker player_lock(m_crit.players); // lock 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;
|
||||
}
|
||||
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
UpdatePadMapping(); // sync pad mappings with everyone
|
||||
|
||||
UpdateGUI();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// called from ---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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread and ---NETPLAY--- thread
|
||||
u64 NetPlayServer::CalculateMinimumBufferTime()
|
||||
{
|
||||
@@ -312,7 +379,7 @@ u64 NetPlayServer::CalculateMinimumBufferTime()
|
||||
e = m_players.end();
|
||||
std::priority_queue<unsigned int> pings;
|
||||
for ( ;i!=e; ++i)
|
||||
pings.push(i->second.ping);
|
||||
pings.push(i->second.ping/2);
|
||||
|
||||
unsigned int required_ms = pings.top();
|
||||
// if there is more than 1 client, buffersize must be >= (2 highest ping times combined)
|
||||
@@ -339,11 +406,9 @@ void NetPlayServer::AdjustPadBufferSize(unsigned int size)
|
||||
spac << (MessageId)NP_MSG_PAD_BUFFER;
|
||||
spac << (u32)m_target_buffer_size;
|
||||
|
||||
m_crit.players.Enter(); // lock players
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker player_lock(m_crit.players); // lock players
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac);
|
||||
m_crit.send.Leave();
|
||||
m_crit.players.Leave();
|
||||
}
|
||||
|
||||
// called from ---NETPLAY--- thread
|
||||
@@ -414,9 +479,8 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
||||
spac << map; // in game mapping
|
||||
spac << np.nHi << np.nLo;
|
||||
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac, player.pid);
|
||||
m_crit.send.Leave();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -452,9 +516,9 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
void NetPlayServer::GetPlayerList(std::string &list)
|
||||
void NetPlayServer::GetPlayerList(std::string& list, std::vector<int>& pid_list)
|
||||
{
|
||||
CritLocker player_lock(m_crit.players);
|
||||
CritLocker player_lock(m_crit.players); // lock players
|
||||
|
||||
std::ostringstream ss;
|
||||
|
||||
@@ -462,7 +526,10 @@ void NetPlayServer::GetPlayerList(std::string &list)
|
||||
i = m_players.begin(),
|
||||
e = m_players.end();
|
||||
for ( ; i!=e; ++i)
|
||||
{
|
||||
ss << i->second.ToString() << " " << i->second.ping << "ms\n";
|
||||
pid_list.push_back(i->second.pid);
|
||||
}
|
||||
|
||||
list = ss.str();
|
||||
}
|
||||
@@ -475,9 +542,8 @@ void NetPlayServer::SendChatMessage(const std::string& msg)
|
||||
spac << (PlayerId)0; // server id always 0
|
||||
spac << msg;
|
||||
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac);
|
||||
m_crit.send.Leave();
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
@@ -492,11 +558,9 @@ bool NetPlayServer::ChangeGame(const std::string &game)
|
||||
spac << (MessageId)NP_MSG_CHANGE_GAME;
|
||||
spac << game;
|
||||
|
||||
m_crit.players.Enter(); // lock players
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker player_lock(m_crit.players); // lock players
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac);
|
||||
m_crit.send.Leave();
|
||||
m_crit.players.Leave();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -510,9 +574,8 @@ void NetPlayServer::SendPadState(const PadMapping local_nb, const NetPad& np)
|
||||
spac << m_local_player->pad_map[local_nb]; // in-game pad num
|
||||
spac << np.nHi << np.nLo;
|
||||
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac);
|
||||
m_crit.send.Leave();
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
@@ -525,7 +588,6 @@ bool NetPlayServer::StartGame(const std::string &path)
|
||||
|
||||
// TODO: i dont like this here
|
||||
m_on_game = Common::Timer::GetTimeMs();
|
||||
ClearBuffers();
|
||||
m_crit.buffer.Leave();
|
||||
|
||||
// no change, just update with clients
|
||||
@@ -536,11 +598,9 @@ bool NetPlayServer::StartGame(const std::string &path)
|
||||
spac << (MessageId)NP_MSG_START_GAME;
|
||||
spac << m_on_game;
|
||||
|
||||
m_crit.players.Enter(); // lock players
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker player_lock(m_crit.players); // lock players
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac);
|
||||
m_crit.send.Leave();
|
||||
m_crit.players.Leave();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -556,11 +616,9 @@ bool NetPlayServer::StopGame()
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_STOP_GAME;
|
||||
|
||||
m_crit.players.Enter(); // lock players
|
||||
m_crit.send.Enter(); // lock send
|
||||
CritLocker player_lock(m_crit.players); // lock players
|
||||
CritLocker send_lock(m_crit.send); // lock send
|
||||
SendToClients(spac);
|
||||
m_crit.players.Leave();
|
||||
m_crit.send.Leave();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <FileUtil.h>
|
||||
#include <IniFile.h>
|
||||
|
||||
#include "NetPlay.h"
|
||||
#include "NetWindow.h"
|
||||
|
||||
@@ -34,13 +37,18 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||
: wxFrame(parent, wxID_ANY, wxT(NETPLAY_TITLEBAR), wxDefaultPosition, wxDefaultSize)
|
||||
, m_game_list(game_list)
|
||||
{
|
||||
//PanicAlert("ALERT: NetPlay is not 100%% functional !!!!");
|
||||
IniFile inifile;
|
||||
inifile.Load(std::string(File::GetUserPath(D_CONFIG_IDX)) + "Dolphin.ini");
|
||||
IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay");
|
||||
|
||||
wxPanel* const panel = new wxPanel(this);
|
||||
|
||||
// top row
|
||||
wxStaticText* const nick_lbl = new wxStaticText(panel, wxID_ANY, wxT("Nickname :"), wxDefaultPosition, wxDefaultSize);
|
||||
m_nickname_text = new wxTextCtrl(panel, wxID_ANY, wxT("Player"));
|
||||
|
||||
std::string nickname;
|
||||
netplay_section.Get("Nickname", &nickname, "Player");
|
||||
m_nickname_text = new wxTextCtrl(panel, wxID_ANY, wxString::FromAscii(nickname.c_str()));
|
||||
|
||||
wxBoxSizer* const nick_szr = new wxBoxSizer(wxHORIZONTAL);
|
||||
nick_szr->Add(nick_lbl, 0, wxCENTER);
|
||||
@@ -58,9 +66,17 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||
// connect tab
|
||||
{
|
||||
wxStaticText* const ip_lbl = new wxStaticText(connect_tab, wxID_ANY, wxT("Address :"), wxDefaultPosition, wxDefaultSize);
|
||||
m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, wxT("localhost"));
|
||||
|
||||
std::string address;
|
||||
netplay_section.Get("Address", &address, "localhost");
|
||||
m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, wxString::FromAscii(address.c_str()));
|
||||
|
||||
wxStaticText* const port_lbl = new wxStaticText(connect_tab, wxID_ANY, wxT("Port :"), wxDefaultPosition, wxDefaultSize);
|
||||
m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, wxT("2626"));
|
||||
|
||||
// string? w/e
|
||||
std::string port;
|
||||
netplay_section.Get("ConnectPort", &port, "2626");
|
||||
m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, wxString::FromAscii(port.c_str()));
|
||||
|
||||
wxButton* const connect_btn = new wxButton(connect_tab, wxID_ANY, wxT("Connect"));
|
||||
_connect_macro_(connect_btn, NetPlaySetupDiag::OnJoin, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||
@@ -96,7 +112,11 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||
// host tab
|
||||
{
|
||||
wxStaticText* const port_lbl = new wxStaticText(host_tab, wxID_ANY, wxT("Port :"), wxDefaultPosition, wxDefaultSize);
|
||||
m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, wxT("2626"));
|
||||
|
||||
// string? w/e
|
||||
std::string port;
|
||||
netplay_section.Get("HostPort", &port, "2626");
|
||||
m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, wxString::FromAscii(port.c_str()));
|
||||
|
||||
wxButton* const host_btn = new wxButton(host_tab, wxID_ANY, wxT("Host"));
|
||||
_connect_macro_(host_btn, NetPlaySetupDiag::OnHost, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||
@@ -143,6 +163,21 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl*
|
||||
Show();
|
||||
}
|
||||
|
||||
NetPlaySetupDiag::~NetPlaySetupDiag()
|
||||
{
|
||||
IniFile inifile;
|
||||
const std::string dolphin_ini = std::string(File::GetUserPath(D_CONFIG_IDX)) + "Dolphin.ini";
|
||||
inifile.Load(dolphin_ini);
|
||||
IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay");
|
||||
|
||||
netplay_section.Set("Nickname", m_nickname_text->GetValue().mb_str());
|
||||
netplay_section.Set("Address", m_connect_ip_text->GetValue().mb_str());
|
||||
netplay_section.Set("ConnectPort", m_connect_port_text->GetValue().mb_str());
|
||||
netplay_section.Set("HostPort", m_host_port_text->GetValue().mb_str());
|
||||
|
||||
inifile.Save(dolphin_ini);
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::OnHost(wxCommandEvent& event)
|
||||
{
|
||||
// warning removal
|
||||
@@ -266,8 +301,8 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game
|
||||
// player list
|
||||
if (is_hosting)
|
||||
{
|
||||
wxButton* const player_config_btn = new wxButton(panel, wxID_ANY, wxT("Configure Pads [not implemented]"));
|
||||
player_config_btn->Disable();
|
||||
wxButton* const player_config_btn = new wxButton(panel, wxID_ANY, wxT("Configure Pads"));
|
||||
_connect_macro_(player_config_btn, NetPlayDiag::OnConfigPads, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||
player_szr->Add(player_config_btn, 0, wxEXPAND | wxTOP, 5);
|
||||
}
|
||||
|
||||
@@ -380,8 +415,8 @@ void NetPlayDiag::OnPadBuffHelp(wxCommandEvent& event)
|
||||
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";
|
||||
<< time * (60.0f/1000) << "(60fps) / "
|
||||
<< time * (50.0f/1000) << "(50fps) >\n";
|
||||
|
||||
m_chat_text->AppendText(wxString(ss.str().c_str(), *wxConvCurrent));
|
||||
}
|
||||
@@ -412,14 +447,19 @@ void NetPlayDiag::OnThread(wxCommandEvent& event)
|
||||
event.GetId();
|
||||
|
||||
// player list
|
||||
m_playerids.clear();
|
||||
std::string tmps;
|
||||
::netplay_ptr->GetPlayerList(tmps);
|
||||
::netplay_ptr->GetPlayerList(tmps, m_playerids);
|
||||
|
||||
const int selection = m_player_lbox->GetSelection();
|
||||
|
||||
m_player_lbox->Clear();
|
||||
std::istringstream ss(tmps);
|
||||
while (std::getline(ss, tmps))
|
||||
m_player_lbox->Append(wxString(tmps.c_str(), *wxConvCurrent));
|
||||
|
||||
m_player_lbox->SetSelection(selection);
|
||||
|
||||
switch (event.GetId())
|
||||
{
|
||||
case NP_GUI_EVT_CHANGE_GAME :
|
||||
@@ -472,6 +512,30 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent& event)
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnConfigPads(wxCommandEvent& event)
|
||||
{
|
||||
// warning removal
|
||||
event.GetId();
|
||||
|
||||
int mapping[4];
|
||||
|
||||
// get selected player id
|
||||
int pid = m_player_lbox->GetSelection();
|
||||
if (pid < 0)
|
||||
return;
|
||||
pid = m_playerids.at(pid);
|
||||
|
||||
if (false == ((NetPlayServer*)::netplay_ptr)->GetPadMapping(pid, mapping))
|
||||
return;
|
||||
|
||||
PadMapDiag* const pmd = new PadMapDiag(this, mapping);
|
||||
pmd->ShowModal();
|
||||
pmd->Destroy();
|
||||
|
||||
if (false == ((NetPlayServer*)::netplay_ptr)->SetPadMapping(pid, mapping))
|
||||
PanicAlert("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)");
|
||||
}
|
||||
|
||||
ChangeGameDiag::ChangeGameDiag(wxWindow* const parent, const CGameListCtrl* const game_list, wxString& game_name)
|
||||
: wxDialog(parent, wxID_ANY, wxT("Change Game"), wxDefaultPosition, wxDefaultSize)
|
||||
, m_game_name(game_name)
|
||||
@@ -510,3 +574,58 @@ void ChangeGameDiag::OnPick(wxCommandEvent& event)
|
||||
m_game_name = m_game_lbox->GetStringSelection();
|
||||
Destroy();
|
||||
}
|
||||
|
||||
PadMapDiag::PadMapDiag(wxWindow* const parent, int map[])
|
||||
: wxDialog(parent, wxID_ANY, wxT("Configure Pads"), wxDefaultPosition, wxDefaultSize)
|
||||
, m_mapping(map)
|
||||
{
|
||||
wxPanel* const panel = new wxPanel(this);
|
||||
|
||||
wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
h_szr->AddSpacer(20);
|
||||
|
||||
// labels
|
||||
wxBoxSizer* const label_szr = new wxBoxSizer(wxVERTICAL);
|
||||
label_szr->Add(new wxStaticText(panel,wxID_ANY, wxT("Local")), 0, wxALIGN_TOP);
|
||||
label_szr->AddStretchSpacer(1);
|
||||
label_szr->Add(new wxStaticText(panel,wxID_ANY, wxT("In-Game")), 0, wxALIGN_BOTTOM);
|
||||
|
||||
h_szr->Add(label_szr, 1, wxTOP | wxBOTTOM | wxEXPAND, 20);
|
||||
|
||||
// set up choices
|
||||
wxString pad_names[5];
|
||||
pad_names[0] = wxT("None");
|
||||
for (unsigned int i=1; i<5; ++i)
|
||||
pad_names[i] = wxString(wxT("Pad ")) + (wxChar)(wxT('0')+i);
|
||||
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
{
|
||||
wxChoice* const pad_cbox = m_map_cbox[i]
|
||||
= new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 5, pad_names);
|
||||
pad_cbox->Select(m_mapping[i] + 1);
|
||||
|
||||
_connect_macro_(pad_cbox, PadMapDiag::OnAdjust, wxEVT_COMMAND_CHOICE_SELECTED, this);
|
||||
|
||||
wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL);
|
||||
v_szr->Add(new wxStaticText(panel,wxID_ANY, pad_names[i + 1]), 1, wxALIGN_CENTER_HORIZONTAL);
|
||||
v_szr->Add(pad_cbox, 1);
|
||||
|
||||
h_szr->Add(v_szr, 1, wxTOP | wxBOTTOM | wxEXPAND, 20);
|
||||
}
|
||||
|
||||
h_szr->AddSpacer(20);
|
||||
|
||||
panel->SetSizerAndFit(h_szr);
|
||||
|
||||
wxBoxSizer* const dlg_szr = new wxBoxSizer(wxVERTICAL);
|
||||
dlg_szr->Add(panel, 1, wxEXPAND);
|
||||
SetSizerAndFit(dlg_szr);
|
||||
}
|
||||
|
||||
void PadMapDiag::OnAdjust(wxCommandEvent& event)
|
||||
{
|
||||
(void)event;
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
m_mapping[i] = m_map_cbox[i]->GetSelection() - 1;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class NetPlaySetupDiag : public wxFrame
|
||||
{
|
||||
public:
|
||||
NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* const game_list);
|
||||
|
||||
~NetPlaySetupDiag();
|
||||
private:
|
||||
void OnJoin(wxCommandEvent& event);
|
||||
void OnHost(wxCommandEvent& event);
|
||||
@@ -98,6 +98,7 @@ private:
|
||||
void OnThread(wxCommandEvent& event);
|
||||
void OnChangeGame(wxCommandEvent& event);
|
||||
void OnAdjustBuffer(wxCommandEvent& event);
|
||||
void OnConfigPads(wxCommandEvent& event);
|
||||
|
||||
wxListBox* m_player_lbox;
|
||||
wxTextCtrl* m_chat_text;
|
||||
@@ -106,6 +107,8 @@ private:
|
||||
std::string m_selected_game;
|
||||
wxButton* m_game_btn;
|
||||
|
||||
std::vector<int> m_playerids;
|
||||
|
||||
const CGameListCtrl* const m_game_list;
|
||||
//NetPlay* const m_netplay;
|
||||
};
|
||||
@@ -124,5 +127,17 @@ private:
|
||||
wxString& m_game_name;
|
||||
};
|
||||
|
||||
class PadMapDiag : public wxDialog
|
||||
{
|
||||
public:
|
||||
PadMapDiag(wxWindow* const parent, int map[]);
|
||||
|
||||
private:
|
||||
void OnAdjust(wxCommandEvent& event);
|
||||
|
||||
wxChoice* m_map_cbox[4];
|
||||
int* const m_mapping;
|
||||
};
|
||||
|
||||
#endif // _NETWINDOW_H_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user